diff --git a/cmake/define.inc b/cmake/define.inc index 0687f6e376..ffef456087 100755 --- a/cmake/define.inc +++ b/cmake/define.inc @@ -69,7 +69,6 @@ IF (TD_LINUX_32) ENDIF () IF (TD_ARM_64) - ADD_DEFINITIONS(-D_M_X64) ADD_DEFINITIONS(-D_TD_ARM_64) ADD_DEFINITIONS(-D_TD_ARM_) ADD_DEFINITIONS(-DUSE_LIBICONV) @@ -86,17 +85,19 @@ IF (TD_ARM_32) ENDIF () IF (TD_MIPS_64) - ADD_DEFINITIONS(-D_TD_MIPS_64_) + ADD_DEFINITIONS(-D_TD_MIPS_) + ADD_DEFINITIONS(-D_TD_MIPS_64) ADD_DEFINITIONS(-DUSE_LIBICONV) MESSAGE(STATUS "mips64 is defined") - SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -gdwarf-2 -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") + SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -fsigned-char -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") ENDIF () IF (TD_MIPS_32) - ADD_DEFINITIONS(-D_TD_MIPS_32_) + ADD_DEFINITIONS(-D_TD_MIPS_) + ADD_DEFINITIONS(-D_TD_MIPS_32) ADD_DEFINITIONS(-DUSE_LIBICONV) MESSAGE(STATUS "mips32 is defined") - SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -gdwarf-2 -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") + SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") ENDIF () IF (TD_APLHINE) diff --git a/cmake/install.inc b/cmake/install.inc index 50dc4162f9..9e325531d5 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.27-dist.jar DESTINATION connector/jdbc) + INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.28-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/documentation20/cn/07.advanced-features/docs.md b/documentation20/cn/07.advanced-features/docs.md index 650a2ca96b..1077f299ee 100644 --- a/documentation20/cn/07.advanced-features/docs.md +++ b/documentation20/cn/07.advanced-features/docs.md @@ -120,7 +120,7 @@ if (async) { } ``` -TDengine中的订阅既可以是同步的,也可以是异步的,上面的代码会根据从命令行获取的参数`async`的值来决定使用哪种方式。这里,同步的意思是用户程序要直接调用`taos_consume`来拉取数据,而异步则由API在内部的另一个线程中调用`taos_consume`,然后把拉取到的数据交给回调函数`subscribe_callback`去处理。 +TDengine中的订阅既可以是同步的,也可以是异步的,上面的代码会根据从命令行获取的参数`async`的值来决定使用哪种方式。这里,同步的意思是用户程序要直接调用`taos_consume`来拉取数据,而异步则由API在内部的另一个线程中调用`taos_consume`,然后把拉取到的数据交给回调函数`subscribe_callback`去处理。(注意,`subscribe_callback` 中不宜做较为耗时的操作,否则有可能导致客户端阻塞等不可控的问题。) 参数`taos`是一个已经建立好的数据库连接,在同步模式下无特殊要求。但在异步模式下,需要注意它不会被其它线程使用,否则可能导致不可预计的错误,因为回调函数在API的内部线程中被调用,而TDengine的部分API不是线程安全的。 diff --git a/documentation20/cn/08.connector/docs.md b/documentation20/cn/08.connector/docs.md index 3dbf72a23e..ad3179c310 100644 --- a/documentation20/cn/08.connector/docs.md +++ b/documentation20/cn/08.connector/docs.md @@ -377,6 +377,7 @@ TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时 * res:查询结果集,注意结果集中可能没有记录 * param:调用 `taos_subscribe`时客户程序提供的附加参数 * code:错误码 + **注意**:在这个回调函数里不可以做耗时过长的处理,尤其是对于返回的结果集中数据较多的情况,否则有可能导致客户端阻塞等异常状态。如果必须进行复杂计算,则建议在另外的线程中进行处理。 * `TAOS_RES *taos_consume(TAOS_SUB *tsub)` diff --git a/documentation20/cn/11.administrator/docs.md b/documentation20/cn/11.administrator/docs.md index f8dc794d7d..72fcd05d52 100644 --- a/documentation20/cn/11.administrator/docs.md +++ b/documentation20/cn/11.administrator/docs.md @@ -144,7 +144,7 @@ TDengine集群中加入一个新的dnode时,涉及集群相关的一些参数 - numOfMnodes:系统中管理节点个数。默认值:3。 - balance:是否启动负载均衡。0:否,1:是。默认值:1。 - mnodeEqualVnodeNum: 一个mnode等同于vnode消耗的个数。默认值:4。 -- offlineThreshold: dnode离线阈值,超过该时间将导致该dnode从集群中删除。单位为秒,默认值:86400*10(即10天)。 +- offlineThreshold: dnode离线阈值,超过该时间将导致该dnode从集群中删除。单位为秒,默认值:86400*100(即100天)。 - statusInterval: dnode向mnode报告状态时长。单位为秒,默认值:1。 - maxTablesPerVnode: 每个vnode中能够创建的最大表个数。默认值:1000000。 - maxVgroupsPerDb: 每个数据库中能够使用的最大vgroup个数。 diff --git a/documentation20/cn/12.taos-sql/docs.md b/documentation20/cn/12.taos-sql/docs.md index 2415b7cd01..c754eae088 100644 --- a/documentation20/cn/12.taos-sql/docs.md +++ b/documentation20/cn/12.taos-sql/docs.md @@ -48,15 +48,15 @@ TDengine 缺省的时间戳是毫秒精度,但通过修改配置参数 enableM | 3 | BIGINT | 8 | 长整型,范围 [-2^63+1, 2^63-1], -2^63 用于 NULL | | 4 | FLOAT | 4 | 浮点型,有效位数 6-7,范围 [-3.4E38, 3.4E38] | | 5 | DOUBLE | 8 | 双精度浮点型,有效位数 15-16,范围 [-1.7E308, 1.7E308] | -| 6 | BINARY | 自定义 | 用于记录 ASCII 型字符串。理论上,最长可以有 16374 字节,但由于每行数据最多 16K 字节,实际上限一般小于理论值。 binary 仅支持字符串输入,字符串两端使用单引号引用,否则英文全部自动转化为小写。使用时须指定大小,如 binary(20) 定义了最长为 20 个字符的字符串,每个字符占 1 byte 的存储空间,此时如果用户字符串超出 20 字节将会报错。对于字符串内的单引号,可以用转义字符反斜线加单引号来表示,即 `\’`。 | +| 6 | BINARY | 自定义 | 记录二进制字节型字符串,建议只用于处理 ASCII 可见字符,中文等多字节字符需使用 nchar。理论上,最长可以有 16374 字节,但由于每行数据最多 16K 字节,实际上限一般小于理论值。binary 仅支持字符串输入,字符串两端使用单引号引用,否则英文全部自动转化为小写。使用时须指定大小,如 binary(20) 定义了最长为 20 个字节型字符的字符串,每个字节型字符占 1 byte 的存储空间,此时如果用户字符串超出 20 字节将会报错。对于字符串内的单引号,可以用转义字符反斜线加单引号来表示,即 `\’`。 | | 7 | SMALLINT | 2 | 短整型, 范围 [-32767, 32767], -32768 用于 NULL | | 8 | TINYINT | 1 | 单字节整型,范围 [-127, 127], -128 用于 NULL | | 9 | BOOL | 1 | 布尔型,{true, false} | -| 10 | NCHAR | 自定义 | 用于记录非 ASCII 型字符串,如中文字符。每个 nchar 字符占用 4 bytes 的存储空间。字符串两端使用单引号引用,字符串内的单引号需用转义字符 `\’`。nchar 使用时须指定字符串大小,类型为 nchar(10) 的列表示此列的字符串最多存储 10 个 nchar 字符,会固定占用 40 bytes 的空间。如果用户字符串长度超出声明长度,将会报错。 | +| 10 | NCHAR | 自定义 | 记录包含多字节字符在内的字符串,如中文字符。每个 nchar 字符占用 4 bytes 的存储空间。字符串两端使用单引号引用,字符串内的单引号需用转义字符 `\’`。nchar 使用时须指定字符串大小,类型为 nchar(10) 的列表示此列的字符串最多存储 10 个 nchar 字符,会固定占用 40 bytes 的空间。如果用户字符串长度超出声明长度,将会报错。 | **Tips**: 1. TDengine 对 SQL 语句中的英文字符不区分大小写,自动转化为小写执行。因此用户大小写敏感的字符串及密码,需要使用单引号将字符串引起来。 -2. 应避免使用 BINARY 类型来保存非 ASCII 型的字符串,会很容易导致数据乱码等错误。正确的做法是使用 NCHAR 类型来保存中文字符。 +2. **注意**,虽然 Binary 类型在底层存储上支持字节型的二进制字符,但不同编程语言对二进制数据的处理方式并不保证一致,因此建议在 Binary 类型中只存储 ASCII 可见字符,而避免存储不可见字符。多字节的数据,例如中文字符,则需要使用 nchar 类型进行保存。如果强行使用 Binary 类型保存中文字符,虽然有时也能正常读写,但并不带有字符集信息,很容易出现数据乱码甚至数据损坏。 ## 数据库管理 diff --git a/documentation20/cn/13.faq/docs.md b/documentation20/cn/13.faq/docs.md index 5a0f890cae..e561f91c94 100644 --- a/documentation20/cn/13.faq/docs.md +++ b/documentation20/cn/13.faq/docs.md @@ -102,7 +102,7 @@ TDengine 目前尚不支持删除功能,未来根据用户需求可能会支 批量插入。每条写入语句可以一张表同时插入多条记录,也可以同时插入多张表的多条记录。 -## 12. 最有效的写入数据的方法是什么?windows系统下插入的nchar类数据中的汉字被解析成了乱码如何解决? +## 12. windows系统下插入的nchar类数据中的汉字被解析成了乱码如何解决? Windows下插入nchar类的数据中如果有中文,请先确认系统的地区设置成了中国(在Control Panel里可以设置),这时cmd中的`taos`客户端应该已经可以正常工作了;如果是在IDE里开发Java应用,比如Eclipse, Intellij,请确认IDE里的文件编码为GBK(这是Java默认的编码类型),然后在生成Connection时,初始化客户端的配置,具体语句如下: ```JAVA diff --git a/src/client/inc/tscLocalMerge.h b/src/client/inc/tscLocalMerge.h index 581cd37cbd..dddc767534 100644 --- a/src/client/inc/tscLocalMerge.h +++ b/src/client/inc/tscLocalMerge.h @@ -44,24 +44,15 @@ typedef struct SLocalMerger { int32_t numOfCompleted; int32_t numOfVnode; SLoserTreeInfo * pLoserTree; - char * prevRowOfInput; tFilePage * pResultBuf; int32_t nResultBufSize; tFilePage * pTempBuffer; struct SQLFunctionCtx *pCtx; int32_t rowSize; // size of each intermediate result. - bool hasPrevRow; // cannot be released - bool hasUnprocessedRow; tOrderDescriptor * pDesc; SColumnModel * resColModel; SColumnModel* finalModel; tExtMemBuffer ** pExtMemBuffer; // disk-based buffer - SFillInfo* pFillInfo; // interpolation support structure - char* pFinalRes; // result data after interpo - tFilePage* discardData; - bool discard; - int32_t offset; // limit offset value - bool orderPrjOnSTable; // projection query on stable } SLocalMerger; typedef struct SRetrieveSupport { @@ -94,7 +85,7 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde void tscDestroyLocalMerger(SSqlObj *pSql); -int32_t tscDoLocalMerge(SSqlObj *pSql); +//int32_t tscDoLocalMerge(SSqlObj *pSql); #ifdef __cplusplus } diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h index 8d3729a632..bd9cd4a250 100644 --- a/src/client/inc/tscUtil.h +++ b/src/client/inc/tscUtil.h @@ -85,15 +85,13 @@ typedef struct SMergeTsCtx { int8_t compared; }SMergeTsCtx; - typedef struct SVgroupTableInfo { SVgroupInfo vgInfo; - SArray* itemList; //SArray + SArray *itemList; // SArray } SVgroupTableInfo; -static FORCE_INLINE SQueryInfo* tscGetQueryInfoDetail(SSqlCmd* pCmd, int32_t subClauseIndex) { +static FORCE_INLINE SQueryInfo* tscGetQueryInfo(SSqlCmd* pCmd, int32_t subClauseIndex) { assert(pCmd != NULL && subClauseIndex >= 0); - if (pCmd->pQueryInfo == NULL || subClauseIndex >= pCmd->numOfClause) { return NULL; } @@ -101,6 +99,8 @@ static FORCE_INLINE SQueryInfo* tscGetQueryInfoDetail(SSqlCmd* pCmd, int32_t sub return pCmd->pQueryInfo[subClauseIndex]; } +SQueryInfo* tscGetActiveQueryInfo(SSqlCmd* pCmd); + int32_t tscCreateDataBlock(size_t initialSize, int32_t rowSize, int32_t startOffset, SName* name, STableMeta* pTableMeta, STableDataBlocks** dataBlocks); void tscDestroyDataBlock(STableDataBlocks* pDataBlock, bool removeMeta); void tscSortRemoveDataBlockDupRows(STableDataBlocks* dataBuf); @@ -130,7 +130,13 @@ bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo); bool tscIsTWAQuery(SQueryInfo* pQueryInfo); bool tscIsSecondStageQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo); bool tscGroupbyColumn(SQueryInfo* pQueryInfo); -bool tscIsTopbotQuery(SQueryInfo* pQueryInfo); +bool tscIsTopBotQuery(SQueryInfo* pQueryInfo); +bool hasTagValOutput(SQueryInfo* pQueryInfo); +bool timeWindowInterpoRequired(SQueryInfo *pQueryInfo); +bool isStabledev(SQueryInfo* pQueryInfo); +bool isTsCompQuery(SQueryInfo* pQueryInfo); +bool isSimpleAggregate(SQueryInfo* pQueryInfo); +bool isBlockDistQuery(SQueryInfo* pQueryInfo); int32_t tscGetTopbotQueryParam(SQueryInfo* pQueryInfo); bool tscNonOrderedProjectionQueryOnSTable(SSqlCmd *pCmd, SQueryInfo *pQueryInfo, int32_t tableIndex); @@ -144,7 +150,7 @@ bool tscQueryTags(SQueryInfo* pQueryInfo); bool tscMultiRoundQuery(SQueryInfo* pQueryInfo, int32_t tableIndex); bool tscQueryBlockInfo(SQueryInfo* pQueryInfo); -SSqlExpr* tscAddFuncInSelectClause(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId, +SExprInfo* tscAddFuncInSelectClause(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId, SColumnIndex* pIndex, SSchema* pColSchema, int16_t colType); int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SStrToken* pzTableName, SSqlObj* pSql); @@ -175,27 +181,29 @@ void addExprParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes) int32_t tscGetResRowLength(SArray* pExprList); -SSqlExpr* tscSqlExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type, +SExprInfo* tscSqlExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type, int16_t size, int16_t resColId, int16_t interSize, bool isTagCol); -SSqlExpr* tscSqlExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type, +SExprInfo* tscSqlExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type, int16_t size, int16_t resColId, int16_t interSize, bool isTagCol); -SSqlExpr* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, int16_t type, +SExprInfo* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, int16_t type, int16_t size); size_t tscSqlExprNumOfExprs(SQueryInfo* pQueryInfo); -void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, SColumnIndex* pIndex); +void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, uint64_t uid); -SSqlExpr* tscSqlExprGet(SQueryInfo* pQueryInfo, int32_t index); +SExprInfo* tscSqlExprGet(SQueryInfo* pQueryInfo, int32_t index); int32_t tscSqlExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy); +void tscSqlExprAssign(SExprInfo* dst, const SExprInfo* src); void tscSqlExprInfoDestroy(SArray* pExprInfo); SColumn* tscColumnClone(const SColumn* src); -bool tscColumnExists(SArray* pColumnList, SColumnIndex* pColIndex); -SColumn* tscColumnListInsert(SArray* pColList, SColumnIndex* colIndex); -SArray* tscColumnListClone(const SArray* src, int16_t tableIndex); +bool tscColumnExists(SArray* pColumnList, int32_t columnIndex, uint64_t uid); +SColumn* tscColumnListInsert(SArray* pColumnList, int32_t columnIndex, uint64_t uid, SSchema* pSchema); void tscColumnListDestroy(SArray* pColList); +void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo); + void tscDequoteAndTrimToken(SStrToken* pToken); int32_t tscValidateName(SStrToken* pToken); @@ -217,8 +225,11 @@ bool tscShouldBeFreed(SSqlObj* pSql); STableMetaInfo* tscGetTableMetaInfoFromCmd(SSqlCmd *pCmd, int32_t subClauseIndex, int32_t tableIndex); STableMetaInfo* tscGetMetaInfo(SQueryInfo *pQueryInfo, int32_t tableIndex); -SQueryInfo *tscGetQueryInfoDetail(SSqlCmd* pCmd, int32_t subClauseIndex); -SQueryInfo *tscGetQueryInfoDetailSafely(SSqlCmd *pCmd, int32_t subClauseIndex); +void tscInitQueryInfo(SQueryInfo* pQueryInfo); +void tscClearSubqueryInfo(SSqlCmd* pCmd); +int32_t tscAddQueryInfo(SSqlCmd *pCmd); +SQueryInfo *tscGetQueryInfo(SSqlCmd* pCmd, int32_t subClauseIndex); +SQueryInfo *tscGetQueryInfoS(SSqlCmd *pCmd, int32_t subClauseIndex); void tscClearTableMetaInfo(STableMetaInfo* pTableMetaInfo); @@ -226,11 +237,7 @@ STableMetaInfo* tscAddTableMetaInfo(SQueryInfo* pQueryInfo, SName* name, STableM SVgroupsInfo* vgroupList, SArray* pTagCols, SArray* pVgroupTables); STableMetaInfo* tscAddEmptyMetaInfo(SQueryInfo *pQueryInfo); -int32_t tscAddSubqueryInfo(SSqlCmd *pCmd); -void tscInitQueryInfo(SQueryInfo* pQueryInfo); - -void tscClearSubqueryInfo(SSqlCmd* pCmd); void tscFreeVgroupTableInfo(SArray* pVgroupTables); SArray* tscVgroupTableInfoDup(SArray* pVgroupTables); void tscRemoveVgroupTableGroup(SArray* pVgroupTable, int32_t index); @@ -243,6 +250,8 @@ int32_t tscGetUdfFromNode(SSqlObj *pSql); void tscResetForNextRetrieve(SSqlRes* pRes); void tscDoQuery(SSqlObj* pSql); +void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo); +void doExecuteQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo); SVgroupsInfo* tscVgroupInfoClone(SVgroupsInfo *pInfo); void* tscVgroupInfoClear(SVgroupsInfo *pInfo); @@ -276,7 +285,7 @@ void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex); int16_t tscGetJoinTagColIdByUid(STagCond* pTagCond, uint64_t uid); int16_t tscGetTagColIndexById(STableMeta* pTableMeta, int16_t colId); -void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex); +void tscPrintSelNodeList(SSqlObj* pSql, int32_t subClauseIndex); bool hasMoreVnodesToTry(SSqlObj *pSql); bool hasMoreClauseToTry(SSqlObj* pSql); @@ -301,7 +310,10 @@ CChildTableMeta* tscCreateChildMeta(STableMeta* pTableMeta); uint32_t tscGetTableMetaMaxSize(); int32_t tscCreateTableMetaFromCChildMeta(STableMeta* pChild, const char* name); STableMeta* tscTableMetaDup(STableMeta* pTableMeta); +int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAttr, void* addr); +void tsCreateSQLFunctionCtx(SQueryInfo* pQueryInfo, SQLFunctionCtx* pCtx, SSchema* pSchema); +void* createQueryInfoFromQueryNode(SQueryInfo* pQueryInfo, SExprInfo* pExprs, STableGroupInfo* pTableGroupInfo, SOperatorInfo* pOperator, char* sql, void* addr, int32_t stage); void* malloc_throw(size_t size); void* calloc_throw(size_t nmemb, size_t size); diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index db3b679f93..0ffafe6c01 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -35,6 +35,7 @@ extern "C" { #include "qExecutor.h" #include "qSqlparser.h" #include "qTsbuf.h" +#include "qUtil.h" #include "tcmdtype.h" // forward declaration @@ -96,12 +97,22 @@ typedef struct STableMetaInfo { SArray *tagColList; // SArray, involved tag columns } STableMetaInfo; - typedef struct SColumnIndex { int16_t tableIndex; int16_t columnIndex; } SColumnIndex; +typedef struct SColumn { + uint64_t tableUid; + int32_t columnIndex; + SColumnInfo info; +} SColumn; + +typedef struct SInternalField { + TAOS_FIELD field; + bool visible; + SExprInfo *pExpr; +} SInternalField; typedef struct SFieldInfo { int16_t numOfOutput; // number of column in result @@ -109,43 +120,6 @@ typedef struct SFieldInfo { 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 - SColIndex colInfo; - uint64_t uid; // refactor use the pointer - int16_t functionId; // function id in aAgg array - int16_t resType; // return value type - int16_t resBytes; // length of return value - int32_t interBytes; // inter result buffer size - int16_t numOfParams; // argument value of each function - 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 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 SCond { uint64_t uid; int32_t len; // length of tag query condition data @@ -160,7 +134,7 @@ typedef struct SJoinNode { } SJoinNode; typedef struct SJoinInfo { - bool hasJoin; + bool hasJoin; SJoinNode* joinTables[TSDB_MAX_JOIN_TABLE_NUM]; } SJoinInfo; @@ -229,13 +203,14 @@ typedef struct SQueryInfo { SInterval interval; // tumble time window SSessionWindow sessionWindow; // session time window - SSqlGroupbyExpr groupbyExpr; // group by tags info + SSqlGroupbyExpr groupbyExpr; // groupby tags info SArray * colList; // SArray SFieldInfo fieldsInfo; - SArray * exprList; // SArray + SArray * exprList; // SArray SLimitVal limit; SLimitVal slimit; STagCond tagCond; + SOrderVal order; int16_t fillType; // final result fill type int16_t numOfTables; @@ -254,7 +229,17 @@ typedef struct SQueryInfo { int32_t round; // 0/1/.... int32_t bufLen; char* buf; - int32_t havingFieldNum; + SQInfo* pQInfo; // global merge operator + SArray* pDSOperator; // data source operator + SArray* pPhyOperator; // physical query execution plan + SQueryAttr* pQueryAttr; // query object + + struct SQueryInfo *sibling; // sibling + SArray *pUpstream; // SArray + struct SQueryInfo *pDownstream; + int32_t havingFieldNum; + bool globalMerge; // need global merge + bool arithmCalOnAgg; // arithmetic calculation on aggregate result. } SQueryInfo; typedef struct { @@ -263,15 +248,13 @@ typedef struct { char reserve1[3]; // fix bus error on arm32 bool autoCreated; // create table if it is not existed during retrieve table meta in mnode bool subCmd; - + union { int32_t count; int32_t numOfTablesInSubmit; }; uint32_t insertType; // TODO remove it - int32_t clauseIndex; // index of multiple subclause query - char * curSql; // current sql, resume position of sql after parsing paused int8_t parseFinished; char reserve2[3]; // fix bus error on arm32 @@ -281,22 +264,26 @@ typedef struct { uint32_t allocSize; char * payload; int32_t payloadLen; + SQueryInfo **pQueryInfo; int32_t numOfClause; + int32_t clauseIndex; // index of multiple subclause query + SQueryInfo *active; // current active query info + int32_t batchSize; // for parameter ('?') binding and batch processing 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. int32_t numOfTables; SHashObj *pTableBlockHashList; // data block for each table - SArray *pDataBlocks; // SArray. Merged submit block for each vgroup + SArray *pDataBlocks; // SArray. Merged submit block for each vgroup SArray *pUdfInfo; // user defined function information SArray } SSqlCmd; @@ -440,7 +427,7 @@ void tscInitMsgsFp(); int tsParseSql(SSqlObj *pSql, bool initial); void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet); -int tscProcessSql(SSqlObj *pSql); +int tscBuildAndSendRequest(SSqlObj *pSql, SQueryInfo* pQueryInfo); int tscRenewTableMeta(SSqlObj *pSql, int32_t tableIndex); void tscAsyncResultOnError(SSqlObj *pSql); @@ -455,6 +442,9 @@ void tscRestoreFuncForSTableQuery(SQueryInfo *pQueryInfo); int32_t tscCreateResPointerInfo(SSqlRes *pRes, SQueryInfo *pQueryInfo); void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo); +void tscSetResRawPtrRv(SSqlRes* pRes, SQueryInfo* pQueryInfo, SSDataBlock* pBlock); + +void handleDownstreamOperator(SSqlRes* pRes, SQueryInfo* pQueryInfo); void destroyTableNameList(SSqlCmd* pCmd); void tscResetSqlCmd(SSqlCmd *pCmd, bool removeMeta); @@ -502,47 +492,6 @@ int32_t tscSQLSyntaxErrMsg(char* msg, const char* additionalInfo, const char* s int32_t tscToSQLCmd(SSqlObj *pSql, struct SSqlInfo *pInfo); -static FORCE_INLINE void tscGetResultColumnChr(SSqlRes* pRes, SFieldInfo* pFieldInfo, int32_t columnIndex, int32_t offset) { - SInternalField* pInfo = (SInternalField*) TARRAY_GET_ELEM(pFieldInfo->internalField, columnIndex); - - int32_t type = pInfo->field.type; - int32_t bytes = pInfo->field.bytes; - - char* pData = pRes->data + (int32_t)(offset * pRes->numOfRows + bytes * pRes->row); - UNUSED(pData); - -// user defined constant value output columns - if (pInfo->pSqlExpr != NULL && TSDB_COL_IS_UD_COL(pInfo->pSqlExpr->colInfo.flag)) { - if (type == TSDB_DATA_TYPE_NCHAR || type == TSDB_DATA_TYPE_BINARY) { - pData = pInfo->pSqlExpr->param[1].pz; - pRes->length[columnIndex] = pInfo->pSqlExpr->param[1].nLen; - pRes->tsrow[columnIndex] = (pInfo->pSqlExpr->param[1].nType == TSDB_DATA_TYPE_NULL) ? NULL : (unsigned char*)pData; - } else { - assert(bytes == tDataTypes[type].bytes); - - pRes->tsrow[columnIndex] = isNull(pData, type) ? NULL : (unsigned char*)&pInfo->pSqlExpr->param[1].i64; - pRes->length[columnIndex] = bytes; - } - } else { - if (type == TSDB_DATA_TYPE_NCHAR || type == TSDB_DATA_TYPE_BINARY) { - int32_t realLen = varDataLen(pData); - assert(realLen <= bytes - VARSTR_HEADER_SIZE); - - pRes->tsrow[columnIndex] = (isNull(pData, type)) ? NULL : (unsigned char*)((tstr *)pData)->data; - if (realLen < pInfo->pSqlExpr->resBytes - VARSTR_HEADER_SIZE) { // todo refactor - *(pData + realLen + VARSTR_HEADER_SIZE) = 0; - } - - pRes->length[columnIndex] = realLen; - } else { - assert(bytes == tDataTypes[type].bytes); - - pRes->tsrow[columnIndex] = isNull(pData, type) ? NULL : (unsigned char*)pData; - pRes->length[columnIndex] = bytes; - } - } -} - extern int32_t sentinel; extern SHashObj *tscVgroupMap; extern SHashObj *tscTableMetaInfo; diff --git a/src/client/jni/com_taosdata_jdbc_TSDBJNIConnector.h b/src/client/jni/com_taosdata_jdbc_TSDBJNIConnector.h index 582bd6bac0..b3060e2c82 100644 --- a/src/client/jni/com_taosdata_jdbc_TSDBJNIConnector.h +++ b/src/client/jni/com_taosdata_jdbc_TSDBJNIConnector.h @@ -49,6 +49,14 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setOptions JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getTsCharset (JNIEnv *, jclass); +/* + * Class: com_taosdata_jdbc_TSDBJNIConnector + * Method: getResultTimePrecision + * Signature: (J)J + */ +JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TDDBJNIConnector_getResultTimePrecision + (JNIEnv *, jobject, jlong, jlong); + /* * Class: com_taosdata_jdbc_TSDBJNIConnector * Method: connectImp diff --git a/src/client/src/TSDBJNIConnector.c b/src/client/src/TSDBJNIConnector.c index 56e155311e..7447e36ac9 100644 --- a/src/client/src/TSDBJNIConnector.c +++ b/src/client/src/TSDBJNIConnector.c @@ -671,3 +671,20 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_validateCreateTab JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getTsCharset(JNIEnv *env, jobject jobj) { return (*env)->NewStringUTF(env, (const char *)tsCharset); } + +JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TDDBJNIConnector_getResultTimePrecision(JNIEnv *env, jobject jobj, jlong con, + jlong res) { + TAOS *tscon = (TAOS *)con; + if (tscon == NULL) { + jniError("jobj:%p, connection is closed", jobj); + return JNI_CONNECTION_NULL; + } + + TAOS_RES *result = (TAOS_RES *)res; + if (result == NULL) { + jniError("jobj:%p, conn:%p, resultset is null", jobj, tscon); + return JNI_RESULT_SET_NULL; + } + + return taos_result_precision(result); +} \ No newline at end of file diff --git a/src/client/src/tscAsync.c b/src/client/src/tscAsync.c index 0cfcff3a98..71c960b454 100644 --- a/src/client/src/tscAsync.c +++ b/src/client/src/tscAsync.c @@ -57,7 +57,7 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para strntolower(pSql->sqlstr, sqlstr, (int32_t)sqlLen); - tscDebugL("%p SQL: %s", pSql, pSql->sqlstr); + tscDebugL("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr); pCmd->curSql = pSql->sqlstr; int32_t code = tsParseSql(pSql, true); @@ -69,7 +69,8 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para return; } - tscDoQuery(pSql); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + executeQuery(pSql, pQueryInfo); } // TODO return the correct error code to client in tscQueueAsyncError @@ -179,7 +180,7 @@ static void tscProcessAsyncRetrieveImpl(void *param, TAOS_RES *tres, int numOfRo if (pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE) { tscFetchDatablockForSubquery(pSql); } else { - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); } } @@ -193,8 +194,8 @@ static void tscAsyncQueryRowsForNextVnode(void *param, TAOS_RES *tres, int numOf tscProcessAsyncRetrieveImpl(param, tres, numOfRows, tscAsyncFetchRowsProxy); } -void taos_fetch_rows_a(TAOS_RES *taosa, __async_cb_func_t fp, void *param) { - SSqlObj *pSql = (SSqlObj *)taosa; +void taos_fetch_rows_a(TAOS_RES *tres, __async_cb_func_t fp, void *param) { + SSqlObj *pSql = (SSqlObj *)tres; if (pSql == NULL || pSql->signature != pSql) { tscError("sql object is NULL"); tscQueueAsyncError(fp, param, TSDB_CODE_TSC_DISCONNECTED); @@ -206,18 +207,16 @@ void taos_fetch_rows_a(TAOS_RES *taosa, __async_cb_func_t fp, void *param) { // user-defined callback function is stored in fetchFp pSql->fetchFp = fp; - pSql->fp = tscAsyncFetchRowsProxy; + pSql->fp = tscAsyncFetchRowsProxy; + pSql->param = param; if (pRes->qId == 0) { - tscError("qhandle is NULL"); + tscError("qhandle is invalid"); pRes->code = TSDB_CODE_TSC_INVALID_QHANDLE; - pSql->param = param; - tscAsyncResultOnError(pSql); return; } - pSql->param = param; tscResetForNextRetrieve(pRes); // handle the sub queries of join query @@ -255,8 +254,9 @@ void taos_fetch_rows_a(TAOS_RES *taosa, __async_cb_func_t fp, void *param) { if (pCmd->command != TSDB_SQL_RETRIEVE_LOCALMERGE && pCmd->command < TSDB_SQL_LOCAL) { pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH; } - - tscProcessSql(pSql); + + SQueryInfo* pQueryInfo1 = tscGetActiveQueryInfo(&pSql->cmd); + tscBuildAndSendRequest(pSql, pQueryInfo1); } } @@ -283,7 +283,7 @@ void tscQueueAsyncError(void(*fp), void *param, int32_t code) { static void tscAsyncResultCallback(SSchedMsg *pMsg) { SSqlObj* pSql = (SSqlObj*)taosAcquireRef(tscObjRef, (int64_t)pMsg->ahandle); if (pSql == NULL || pSql->signature != pSql) { - tscDebug("%p SqlObj is freed, not add into queue async res", pSql); + tscDebug("%p SqlObj is freed, not add into queue async res", pMsg->ahandle); return; } @@ -323,7 +323,7 @@ static int32_t updateMetaBeforeRetryQuery(SSqlObj* pSql, STableMetaInfo* pTableM SSchema *pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta); for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i); + SSqlExpr *pExpr = &(tscSqlExprGet(pQueryInfo, i)->base); pExpr->uid = pTableMetaInfo->pTableMeta->id.uid; if (pExpr->colInfo.colIndex >= 0) { @@ -344,7 +344,7 @@ static int32_t updateMetaBeforeRetryQuery(SSqlObj* pSql, STableMetaInfo* pTableM // validate the table columns information for (int32_t i = 0; i < taosArrayGetSize(pQueryInfo->colList); ++i) { SColumn *pCol = taosArrayGetP(pQueryInfo->colList, i); - if (pCol->colIndex.columnIndex >= numOfCols) { + if (pCol->columnIndex >= numOfCols) { return pSql->retryReason; } } @@ -372,13 +372,13 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { goto _error; } - tscDebug("%p get %s successfully", pSql, msg); + tscDebug("0x%"PRIx64" get %s successfully", pSql->self, msg); if (pSql->pStream == NULL) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); // check if it is a sub-query of super table query first, if true, enter another routine if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, (TSDB_QUERY_TYPE_STABLE_SUBQUERY|TSDB_QUERY_TYPE_SUBQUERY|TSDB_QUERY_TYPE_TAG_FILTER_QUERY))) { - tscDebug("%p update local table meta, continue to process sql and send the corresponding query", pSql); + tscDebug("0x%"PRIx64" update local table meta, continue to process sql and send the corresponding query", pSql->self); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); @@ -396,13 +396,13 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { goto _error; } - // tscProcessSql can add error into async res - tscProcessSql(pSql); + // tscBuildAndSendRequest can add error into async res + tscBuildAndSendRequest(pSql, NULL); taosReleaseRef(tscObjRef, pSql->self); return; } else { // continue to process normal async query if (pCmd->parseFinished) { - tscDebug("%p update local table meta, continue to process sql and send corresponding query", pSql); + tscDebug("0x%"PRIx64" update local table meta, continue to process sql and send corresponding query", pSql->self); STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); code = tscGetTableMeta(pSql, pTableMetaInfo); @@ -416,7 +416,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { assert(pCmd->command != TSDB_SQL_INSERT); if (pCmd->command == TSDB_SQL_SELECT) { - tscDebug("%p redo parse sql string and proceed", pSql); + tscDebug("0x%"PRIx64" redo parse sql string and proceed", pSql->self); pCmd->parseFinished = false; tscResetSqlCmd(pCmd, true); @@ -428,15 +428,15 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { goto _error; } - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); } else { // in all other cases, simple retry - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); } taosReleaseRef(tscObjRef, pSql->self); return; } else { - tscDebug("%p continue parse sql after get table meta", pSql); + tscDebug("0x%"PRIx64" continue parse sql after get table meta", pSql->self); code = tsParseSql(pSql, false); if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { @@ -447,21 +447,29 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { } if (pCmd->insertType == TSDB_QUERY_TYPE_STMT_INSERT) { - STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); + STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); code = tscGetTableMeta(pSql, pTableMetaInfo); if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { taosReleaseRef(tscObjRef, pSql->self); return; } else { - assert(code == TSDB_CODE_SUCCESS); + assert(code == TSDB_CODE_SUCCESS); } (*pSql->fp)(pSql->param, pSql, code); - taosReleaseRef(tscObjRef, pSql->self); - return; + } else if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT)) { + if (pCmd->dataSourceType == DATA_FROM_DATA_FILE) { + tscImportDataFromFile(pSql); + } else { + tscHandleMultivnodeInsert(pSql); + } + } else { + SQueryInfo* pQueryInfo1 = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + executeQuery(pSql, pQueryInfo1); } - // proceed to invoke the tscDoQuery(); + taosReleaseRef(tscObjRef, pSql->self); + return; } } @@ -486,7 +494,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { } } - tscDebug("%p stream:%p meta is updated, start new query, command:%d", pSql, pSql->pStream, pSql->cmd.command); + tscDebug("0x%"PRIx64" stream:%p meta is updated, start new query, command:%d", pSql->self, pSql->pStream, pSql->cmd.command); if (!pSql->cmd.parseFinished) { tsParseSql(pSql, false); } @@ -498,7 +506,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { return; } - tscDoQuery(pSql); +// tscDoQuery(pSql); taosReleaseRef(tscObjRef, pSql->self); diff --git a/src/client/src/tscLocal.c b/src/client/src/tscLocal.c index 188ba29a97..b4d03ec461 100644 --- a/src/client/src/tscLocal.c +++ b/src/client/src/tscLocal.c @@ -53,7 +53,7 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) { SSqlRes *pRes = &pSql->res; // one column for each row - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableMeta * pMeta = pTableMetaInfo->pTableMeta; @@ -154,14 +154,14 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, pSql->cmd.numOfCols = numOfCols; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); pQueryInfo->order.order = TSDB_ORDER_ASC; TAOS_FIELD f = {.type = TSDB_DATA_TYPE_BINARY, .bytes = (TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE}; tstrncpy(f.name, "Field", sizeof(f.name)); SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, + pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE, -1000, (TSDB_COL_NAME_LEN - 1), false); rowLen += ((TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE); @@ -171,7 +171,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, tstrncpy(f.name, "Type", sizeof(f.name)); pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(typeColLength + VARSTR_HEADER_SIZE), + pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(typeColLength + VARSTR_HEADER_SIZE), -1000, typeColLength, false); rowLen += typeColLength + VARSTR_HEADER_SIZE; @@ -181,7 +181,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, tstrncpy(f.name, "Length", sizeof(f.name)); pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_INT, sizeof(int32_t), + pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_INT, sizeof(int32_t), -1000, sizeof(int32_t), false); rowLen += sizeof(int32_t); @@ -191,7 +191,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, tstrncpy(f.name, "Note", sizeof(f.name)); pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(noteColLength + VARSTR_HEADER_SIZE), + pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(noteColLength + VARSTR_HEADER_SIZE), -1000, noteColLength, false); rowLen += noteColLength + VARSTR_HEADER_SIZE; @@ -199,7 +199,7 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols, } static int32_t tscProcessDescribeTable(SSqlObj *pSql) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); assert(tscGetMetaInfo(pQueryInfo, 0)->pTableMeta != NULL); @@ -389,7 +389,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const SColumnIndex index = {0}; pSql->cmd.numOfCols = 2; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); pQueryInfo->order.order = TSDB_ORDER_ASC; TAOS_FIELD f; @@ -404,7 +404,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const } SInternalField* pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, f.bytes, -1000, f.bytes - VARSTR_HEADER_SIZE, false); + pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, f.bytes, -1000, f.bytes - VARSTR_HEADER_SIZE, false); rowLen += f.bytes; @@ -417,7 +417,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const } pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f); - pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, + pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, (int16_t)(ddlLen + VARSTR_HEADER_SIZE), -1000, ddlLen, false); rowLen += ddlLen + VARSTR_HEADER_SIZE; @@ -427,7 +427,7 @@ static int32_t tscSCreateBuildResultFields(SSqlObj *pSql, BuildType type, const static int32_t tscSCreateSetValueToResObj(SSqlObj *pSql, int32_t rowLen, const char *tableName, const char *ddl) { SSqlRes *pRes = &pSql->res; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); int32_t numOfRows = 1; if (strlen(ddl) == 0) { @@ -444,7 +444,7 @@ static int32_t tscSCreateSetValueToResObj(SSqlObj *pSql, int32_t rowLen, const c return 0; } static int32_t tscSCreateBuildResult(SSqlObj *pSql, BuildType type, const char *str, const char *result) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); int32_t rowLen = tscSCreateBuildResultFields(pSql, type, result); tscFieldInfoUpdateOffset(pQueryInfo); @@ -552,7 +552,7 @@ static int32_t tscGetTableTagColumnName(SSqlObj *pSql, char **result) { return TSDB_CODE_SUCCESS; } static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, char *ddl) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableMeta * pMeta = pTableMetaInfo->pTableMeta; @@ -606,7 +606,7 @@ static int32_t tscRebuildDDLForSubTable(SSqlObj *pSql, const char *tableName, ch } static int32_t tscRebuildDDLForNormalTable(SSqlObj *pSql, const char *tableName, char *ddl) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableMeta * pMeta = pTableMetaInfo->pTableMeta; @@ -633,7 +633,7 @@ static int32_t tscRebuildDDLForNormalTable(SSqlObj *pSql, const char *tableName, } static int32_t tscRebuildDDLForSuperTable(SSqlObj *pSql, const char *tableName, char *ddl) { char *result = ddl; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableMeta * pMeta = pTableMetaInfo->pTableMeta; @@ -674,7 +674,7 @@ static int32_t tscRebuildDDLForSuperTable(SSqlObj *pSql, const char *tableName, } static int32_t tscProcessShowCreateTable(SSqlObj *pSql) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); assert(pTableMetaInfo->pTableMeta != NULL); @@ -700,7 +700,7 @@ static int32_t tscProcessShowCreateTable(SSqlObj *pSql) { } static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); @@ -727,7 +727,7 @@ static int32_t tscProcessShowCreateDatabase(SSqlObj *pSql) { return TSDB_CODE_TSC_ACTION_IN_PROGRESS; } static int32_t tscProcessCurrentUser(SSqlObj *pSql) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); pExpr->resBytes = TSDB_USER_LEN + TSDB_DATA_TYPE_BINARY; @@ -754,7 +754,7 @@ static int32_t tscProcessCurrentDB(SSqlObj *pSql) { extractDBName(pSql->pTscObj->db, db); pthread_mutex_unlock(&pSql->pTscObj->mutex); - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex); SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); pExpr->resType = TSDB_DATA_TYPE_BINARY; @@ -781,7 +781,7 @@ static int32_t tscProcessCurrentDB(SSqlObj *pSql) { static int32_t tscProcessServerVer(SSqlObj *pSql) { const char* v = pSql->pTscObj->sversion; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex); SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); pExpr->resType = TSDB_DATA_TYPE_BINARY; @@ -804,7 +804,7 @@ static int32_t tscProcessServerVer(SSqlObj *pSql) { } static int32_t tscProcessClientVer(SSqlObj *pSql) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); pExpr->resType = TSDB_DATA_TYPE_BINARY; @@ -856,7 +856,7 @@ static int32_t tscProcessServStatus(SSqlObj *pSql) { return pSql->res.code; } - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); int32_t val = 1; @@ -870,7 +870,7 @@ void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnNa pCmd->numOfCols = 1; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); pQueryInfo->order.order = TSDB_ORDER_ASC; tscFieldInfoClear(&pQueryInfo->fieldsInfo); @@ -882,7 +882,7 @@ void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnNa tscInitResObjForLocalQuery(pSql, 1, (int32_t)valueLength); SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, 0); - pInfo->pSqlExpr = taosArrayGetP(pQueryInfo->exprList, 0); + pInfo->pExpr = taosArrayGetP(pQueryInfo->exprList, 0); memcpy(pRes->data, val, pInfo->field.bytes); } diff --git a/src/client/src/tscLocalMerge.c b/src/client/src/tscLocalMerge.c index 0fe751d03b..e989c91efc 100644 --- a/src/client/src/tscLocalMerge.c +++ b/src/client/src/tscLocalMerge.c @@ -31,6 +31,8 @@ typedef struct SCompareParam { int32_t groupOrderType; } SCompareParam; +bool needToMergeRv(SSDataBlock* pBlock, SArray* columnIndex, int32_t index, char **buf); + int32_t treeComparator(const void *pLeft, const void *pRight, void *param) { int32_t pLeftIdx = *(int32_t *)pLeft; int32_t pRightIdx = *(int32_t *)pRight; @@ -57,123 +59,55 @@ int32_t treeComparator(const void *pLeft, const void *pRight, void *param) { } } -static void tscInitSqlContext(SSqlCmd *pCmd, SLocalMerger *pReducer, tOrderDescriptor *pDesc) { - /* - * the fields and offset attributes in pCmd and pModel may be different due to - * merge requirement. So, the final result in pRes structure is formatted in accordance with the pCmd object. - */ - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); +// todo merge with vnode side function +void tsCreateSQLFunctionCtx(SQueryInfo* pQueryInfo, SQLFunctionCtx* pCtx, SSchema* pSchema) { size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - SQLFunctionCtx *pCtx = &pReducer->pCtx[i]; - SSqlExpr * pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i); - pCtx->pOutput = pReducer->pResultBuf->data + pExpr->offset * pReducer->resColModel->capacity; - pCtx->order = pQueryInfo->order.order; - pCtx->functionId = pExpr->functionId; + pCtx[i].order = pQueryInfo->order.order; + pCtx[i].functionId = pExpr->base.functionId; - // input buffer hold only one point data - int16_t offset = getColumnModelOffset(pDesc->pColumnModel, i); - SSchema *pSchema = getColumnModelSchema(pDesc->pColumnModel, i); - - pCtx->pInput = pReducer->pTempBuffer->data + offset; + pCtx[i].order = pQueryInfo->order.order; + pCtx[i].functionId = pExpr->base.functionId; // input data format comes from pModel - pCtx->inputType = pSchema->type; - pCtx->inputBytes = pSchema->bytes; + pCtx[i].inputType = pSchema[i].type; + pCtx[i].inputBytes = pSchema[i].bytes; - // output data format yet comes from pCmd. - pCtx->outputBytes = pExpr->resBytes; - pCtx->outputType = pExpr->resType; + pCtx[i].outputBytes = pExpr->base.resBytes; + pCtx[i].outputType = pExpr->base.resType; - pCtx->size = 1; - pCtx->hasNull = true; - pCtx->currentStage = MERGE_STAGE; + // input buffer hold only one point data + pCtx[i].size = 1; + pCtx[i].hasNull = true; + pCtx[i].currentStage = MERGE_STAGE; // for top/bottom function, the output of timestamp is the first column - int32_t functionId = pExpr->functionId; + int32_t functionId = pExpr->base.functionId; if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF) { - pCtx->ptsOutputBuf = pReducer->pCtx[0].pOutput; - pCtx->param[2].i64 = pQueryInfo->order.order; - pCtx->param[2].nType = TSDB_DATA_TYPE_BIGINT; - pCtx->param[1].i64 = pQueryInfo->order.orderColId; + pCtx[i].ptsOutputBuf = pCtx[0].pOutput; + pCtx[i].param[2].i64 = pQueryInfo->order.order; + pCtx[i].param[2].nType = TSDB_DATA_TYPE_BIGINT; + pCtx[i].param[1].i64 = pQueryInfo->order.orderColId; + pCtx[i].param[0].i64 = pExpr->base.param[0].i64; // top/bot parameter } else if (functionId == TSDB_FUNC_APERCT) { - pCtx->param[0].i64 = pExpr->param[0].i64; - pCtx->param[0].nType = pExpr->param[0].nType; + pCtx[i].param[0].i64 = pExpr->base.param[0].i64; + pCtx[i].param[0].nType = pExpr->base.param[0].nType; } else if (functionId == TSDB_FUNC_BLKINFO) { - pCtx->param[0].i64 = pExpr->param[0].i64; - pCtx->param[0].nType = pExpr->param[0].nType; - pCtx->numOfParams = 1; + pCtx[i].param[0].i64 = pExpr->base.param[0].i64; + pCtx[i].param[0].nType = pExpr->base.param[0].nType; + pCtx[i].numOfParams = 1; } - pCtx->interBufBytes = pExpr->interBytes; - pCtx->resultInfo = calloc(1, pCtx->interBufBytes + sizeof(SResultRowCellInfo)); - pCtx->stableQuery = true; + pCtx[i].interBufBytes = pExpr->base.interBytes; + pCtx[i].stableQuery = true; } - - int16_t n = 0; - int16_t tagLen = 0; - SQLFunctionCtx **pTagCtx = calloc(pQueryInfo->fieldsInfo.numOfOutput, POINTER_BYTES); - - SQLFunctionCtx *pCtx = NULL; - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_TAG_DUMMY || pExpr->functionId == TSDB_FUNC_TS_DUMMY) { - tagLen += pExpr->resBytes; - pTagCtx[n++] = &pReducer->pCtx[i]; - } else if (pExpr->functionId < 0) { - continue; - } else if ((aAggs[pExpr->functionId].status & TSDB_FUNCSTATE_SELECTIVITY) != 0) { - pCtx = &pReducer->pCtx[i]; - } - } - - if (n == 0 || pCtx == NULL) { - free(pTagCtx); - } else { - pCtx->tagInfo.pTagCtxList = pTagCtx; - pCtx->tagInfo.numOfTagCols = n; - pCtx->tagInfo.tagsLen = tagLen; - } -} - -static SFillColInfo* createFillColInfo(SQueryInfo* pQueryInfo) { - int32_t numOfCols = (int32_t)tscNumOfFields(pQueryInfo); - int32_t offset = 0; - - SFillColInfo* pFillCol = calloc(numOfCols, sizeof(SFillColInfo)); - for(int32_t i = 0; i < numOfCols; ++i) { - SInternalField* pIField = taosArrayGet(pQueryInfo->fieldsInfo.internalField, i); - - if (pIField->pArithExprInfo == NULL) { - SSqlExpr* pExpr = pIField->pSqlExpr; - - pFillCol[i].col.bytes = pExpr->resBytes; - pFillCol[i].col.type = (int8_t)pExpr->resType; - pFillCol[i].col.colId = pExpr->colInfo.colId; - pFillCol[i].flag = pExpr->colInfo.flag; - pFillCol[i].col.offset = offset; - pFillCol[i].functionId = pExpr->functionId; - pFillCol[i].fillVal.i = pQueryInfo->fillVal[i]; - } else { - pFillCol[i].col.bytes = pIField->field.bytes; - pFillCol[i].col.type = (int8_t)pIField->field.type; - pFillCol[i].col.colId = -100; - pFillCol[i].flag = TSDB_COL_NORMAL; - pFillCol[i].col.offset = offset; - pFillCol[i].functionId = -1; - pFillCol[i].fillVal.i = pQueryInfo->fillVal[i]; - } - - offset += pFillCol[i].col.bytes; - } - - return pFillCol; } void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrderDescriptor *pDesc, - SColumnModel *finalmodel, SColumnModel *pFFModel, SSqlObj* pSql) { + SColumnModel *finalmodel, SColumnModel *pFFModel, SSqlObj *pSql) { SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; @@ -195,7 +129,7 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde for (int32_t i = 0; i < numOfBuffer; ++i) { int32_t len = pMemBuffer[i]->fileMeta.flushoutData.nLength; if (len == 0) { - tscDebug("%p no data retrieved from orderOfVnode:%d", pSql, i + 1); + tscDebug("0x%"PRIx64" no data retrieved from orderOfVnode:%d", pSql->self, i + 1); continue; } @@ -205,7 +139,7 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde if (numOfFlush == 0 || numOfBuffer == 0) { tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer); pCmd->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; // no result, set the result empty - tscDebug("%p retrieved no data", pSql); + tscDebug("0x%"PRIx64" retrieved no data", pSql->self); return; } @@ -220,8 +154,8 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde size_t size = sizeof(SLocalMerger) + POINTER_BYTES * numOfFlush; - SLocalMerger *pReducer = (SLocalMerger *) calloc(1, size); - if (pReducer == NULL) { + SLocalMerger *pMerger = (SLocalMerger *) calloc(1, size); + if (pMerger == NULL) { tscError("%p failed to create local merge structure, out of memory", pSql); tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer); @@ -229,15 +163,15 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde return; } - pReducer->pExtMemBuffer = pMemBuffer; - pReducer->pLocalDataSrc = (SLocalDataSource **)&pReducer[1]; - assert(pReducer->pLocalDataSrc != NULL); + pMerger->pExtMemBuffer = pMemBuffer; + pMerger->pLocalDataSrc = (SLocalDataSource **)&pMerger[1]; + assert(pMerger->pLocalDataSrc != NULL); - pReducer->numOfBuffer = numOfFlush; - pReducer->numOfVnode = numOfBuffer; + pMerger->numOfBuffer = numOfFlush; + pMerger->numOfVnode = numOfBuffer; - pReducer->pDesc = pDesc; - tscDebug("%p the number of merged leaves is: %d", pSql, pReducer->numOfBuffer); + pMerger->pDesc = pDesc; + tscDebug("0x%"PRIx64" the number of merged leaves is: %d", pSql->self, pMerger->numOfBuffer); int32_t idx = 0; for (int32_t i = 0; i < numOfBuffer; ++i) { @@ -248,11 +182,11 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde if (ds == NULL) { tscError("%p failed to create merge structure", pSql); pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; - tfree(pReducer); + tfree(pMerger); return; } - pReducer->pLocalDataSrc[idx] = ds; + pMerger->pLocalDataSrc[idx] = ds; ds->pMemBuffer = pMemBuffer[i]; ds->flushoutIdx = j; @@ -260,12 +194,12 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde ds->pageId = 0; ds->rowIdx = 0; - tscDebug("%p load data from disk into memory, orderOfVnode:%d, total:%d", pSql, i + 1, idx + 1); + tscDebug("0x%"PRIx64" load data from disk into memory, orderOfVnode:%d, total:%d", pSql->self, i + 1, idx + 1); tExtMemBufferLoadData(pMemBuffer[i], &(ds->filePage), j, 0); #ifdef _DEBUG_VIEW printf("load data page into mem for build loser tree: %" PRIu64 " rows\n", ds->filePage.num); SSrcColumnInfo colInfo[256] = {0}; - SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo * pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); tscGetSrcColumnInfo(colInfo, pQueryInfo); @@ -274,7 +208,7 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde #endif if (ds->filePage.num == 0) { // no data in this flush, the index does not increase - tscDebug("%p flush data is empty, ignore %d flush record", pSql, idx); + tscDebug("0x%"PRIx64" flush data is empty, ignore %d flush record", pSql->self, idx); tfree(ds); continue; } @@ -285,99 +219,91 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde // no data actually, no need to merge result. if (idx == 0) { - tfree(pReducer); + tfree(pMerger); return; } - pReducer->numOfBuffer = idx; + pMerger->numOfBuffer = idx; SCompareParam *param = malloc(sizeof(SCompareParam)); if (param == NULL) { - tfree(pReducer); + tfree(pMerger); return; } - param->pLocalData = pReducer->pLocalDataSrc; - param->pDesc = pReducer->pDesc; - param->num = pReducer->pLocalDataSrc[0]->pMemBuffer->numOfElemsPerPage; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + param->pLocalData = pMerger->pLocalDataSrc; + param->pDesc = pMerger->pDesc; + param->num = pMerger->pLocalDataSrc[0]->pMemBuffer->numOfElemsPerPage; + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); param->groupOrderType = pQueryInfo->groupbyExpr.orderType; - pReducer->orderPrjOnSTable = tscOrderedProjectionQueryOnSTable(pCmd, pQueryInfo, 0); - pRes->code = tLoserTreeCreate(&pReducer->pLoserTree, pReducer->numOfBuffer, param, treeComparator); - if (pReducer->pLoserTree == NULL || pRes->code != 0) { + pRes->code = tLoserTreeCreate(&pMerger->pLoserTree, pMerger->numOfBuffer, param, treeComparator); + if (pMerger->pLoserTree == NULL || pRes->code != 0) { tfree(param); - tfree(pReducer); + tfree(pMerger); return; } // the input data format follows the old format, but output in a new format. // so, all the input must be parsed as old format - pReducer->pCtx = (SQLFunctionCtx *)calloc(tscSqlExprNumOfExprs(pQueryInfo), sizeof(SQLFunctionCtx)); - pReducer->rowSize = pMemBuffer[0]->nElemSize; + pMerger->pCtx = (SQLFunctionCtx *)calloc(tscSqlExprNumOfExprs(pQueryInfo), sizeof(SQLFunctionCtx)); + pMerger->rowSize = pMemBuffer[0]->nElemSize; - tscRestoreFuncForSTableQuery(pQueryInfo); tscFieldInfoUpdateOffset(pQueryInfo); - if (pReducer->rowSize > pMemBuffer[0]->pageSize) { + if (pMerger->rowSize > pMemBuffer[0]->pageSize) { assert(false); // todo fixed row size is larger than the minimum page size; } - pReducer->hasPrevRow = false; - pReducer->hasUnprocessedRow = false; - - pReducer->prevRowOfInput = (char *)calloc(1, pReducer->rowSize); - // used to keep the latest input row - pReducer->pTempBuffer = (tFilePage *)calloc(1, pReducer->rowSize + sizeof(tFilePage)); - pReducer->discardData = (tFilePage *)calloc(1, pReducer->rowSize + sizeof(tFilePage)); - pReducer->discard = false; + pMerger->pTempBuffer = (tFilePage *)calloc(1, pMerger->rowSize + sizeof(tFilePage)); - pReducer->nResultBufSize = pMemBuffer[0]->pageSize * 16; - pReducer->pResultBuf = (tFilePage *)calloc(1, pReducer->nResultBufSize + sizeof(tFilePage)); + pMerger->nResultBufSize = pMemBuffer[0]->pageSize * 16; + pMerger->pResultBuf = (tFilePage *)calloc(1, pMerger->nResultBufSize + sizeof(tFilePage)); - pReducer->resColModel = finalmodel; - pReducer->resColModel->capacity = pReducer->nResultBufSize; - pReducer->finalModel = pFFModel; + pMerger->resColModel = finalmodel; + pMerger->resColModel->capacity = pMerger->nResultBufSize; + pMerger->finalModel = pFFModel; - int32_t expandFactor = 1; if (finalmodel->rowSize > 0) { - bool topBotQuery = tscIsTopbotQuery(pQueryInfo); - if (topBotQuery) { - expandFactor = tscGetTopbotQueryParam(pQueryInfo); - pReducer->resColModel->capacity /= (finalmodel->rowSize * expandFactor); - pReducer->resColModel->capacity *= expandFactor; - } else { - pReducer->resColModel->capacity /= finalmodel->rowSize; - } + pMerger->resColModel->capacity /= finalmodel->rowSize; } - assert(finalmodel->rowSize > 0 && finalmodel->rowSize <= pReducer->rowSize); + assert(finalmodel->rowSize > 0 && finalmodel->rowSize <= pMerger->rowSize); - pReducer->pFinalRes = calloc(1, pReducer->rowSize * pReducer->resColModel->capacity); - - if (pReducer->pTempBuffer == NULL || pReducer->discardData == NULL || pReducer->pResultBuf == NULL || - pReducer->pFinalRes == NULL || pReducer->prevRowOfInput == NULL) { - tfree(pReducer->pTempBuffer); - tfree(pReducer->discardData); - tfree(pReducer->pResultBuf); - tfree(pReducer->pFinalRes); - tfree(pReducer->prevRowOfInput); - tfree(pReducer->pLoserTree); + if (pMerger->pTempBuffer == NULL || pMerger->pLoserTree == NULL) { + tfree(pMerger->pTempBuffer); + tfree(pMerger->pLoserTree); tfree(param); - tfree(pReducer); + tfree(pMerger); pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; return; } - pReducer->pTempBuffer->num = 0; - + pMerger->pTempBuffer->num = 0; tscCreateResPointerInfo(pRes, pQueryInfo); - tscInitSqlContext(pCmd, pReducer, pDesc); + + SSchema* pschema = calloc(pDesc->pColumnModel->numOfCols, sizeof(SSchema)); + for(int32_t i = 0; i < pDesc->pColumnModel->numOfCols; ++i) { + pschema[i] = pDesc->pColumnModel->pFields[i].field; + } + + tsCreateSQLFunctionCtx(pQueryInfo, pMerger->pCtx, pschema); +// setCtxInputOutputBuffer(pQueryInfo, pMerger->pCtx, pMerger, pDesc); + + tfree(pschema); + + int32_t maxBufSize = 0; + for (int32_t k = 0; k < tscSqlExprNumOfExprs(pQueryInfo); ++k) { + SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, k); + if (maxBufSize < pExpr->base.resBytes && pExpr->base.functionId == TSDB_FUNC_TAG) { + maxBufSize = pExpr->base.resBytes; + } + } // we change the capacity of schema to denote that there is only one row in temp buffer - pReducer->pDesc->pColumnModel->capacity = 1; + pMerger->pDesc->pColumnModel->capacity = 1; // restore the limitation value at the last stage if (tscOrderedProjectionQueryOnSTable(pCmd, pQueryInfo, 0)) { @@ -385,23 +311,22 @@ void tscCreateLocalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrde pQueryInfo->limit.offset = pQueryInfo->prjOffset; } - pReducer->offset = (int32_t)pQueryInfo->limit.offset; - - pRes->pLocalMerger = pReducer; + pRes->pLocalMerger = pMerger; pRes->numOfGroups = 0; - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); - STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); +// STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); +// STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); - TSKEY stime = (pQueryInfo->order.order == TSDB_ORDER_ASC)? pQueryInfo->window.skey : pQueryInfo->window.ekey; - int64_t revisedSTime = taosTimeTruncate(stime, &pQueryInfo->interval, tinfo.precision); +// TSKEY stime = (pQueryInfo->order.order == TSDB_ORDER_ASC)? pQueryInfo->window.skey : pQueryInfo->window.ekey; +// int64_t revisedSTime = taosTimeTruncate(stime, &pQueryInfo->interval, tinfo.precision); - if (pQueryInfo->fillType != TSDB_FILL_NONE) { - SFillColInfo* pFillCol = createFillColInfo(pQueryInfo); - pReducer->pFillInfo = taosCreateFillInfo(pQueryInfo->order.order, revisedSTime, pQueryInfo->groupbyExpr.numOfGroupCols, - 4096, (int32_t)pQueryInfo->fieldsInfo.numOfOutput, pQueryInfo->interval.sliding, pQueryInfo->interval.slidingUnit, - tinfo.precision, pQueryInfo->fillType, pFillCol, pSql); - } +// if (pQueryInfo->fillType != TSDB_FILL_NONE) { +// SFillColInfo* pFillCol = createFillColInfo(pQueryInfo); +// pMerger->pFillInfo = +// taosCreateFillInfo(pQueryInfo->order.order, revisedSTime, pQueryInfo->groupbyExpr.numOfGroupCols, 4096, +// (int32_t)pQueryInfo->fieldsInfo.numOfOutput, pQueryInfo->interval.sliding, +// pQueryInfo->interval.slidingUnit, tinfo.precision, pQueryInfo->fillType, pFillCol, pSql); +// } } static int32_t tscFlushTmpBufferImpl(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage, @@ -502,62 +427,34 @@ void tscDestroyLocalMerger(SSqlObj *pSql) { return; } - SSqlCmd * pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - // there is no more result, so we release all allocated resource SLocalMerger *pLocalMerge = (SLocalMerger *)atomic_exchange_ptr(&pRes->pLocalMerger, NULL); - if (pLocalMerge != NULL) { - pLocalMerge->pFillInfo = taosDestroyFillInfo(pLocalMerge->pFillInfo); + tfree(pLocalMerge->pResultBuf); + tfree(pLocalMerge->pCtx); - if (pLocalMerge->pCtx != NULL) { - int32_t numOfExprs = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); - for (int32_t i = 0; i < numOfExprs; ++i) { - SQLFunctionCtx *pCtx = &pLocalMerge->pCtx[i]; - - tVariantDestroy(&pCtx->tag); - tfree(pCtx->resultInfo); - - if (pCtx->tagInfo.pTagCtxList != NULL) { - tfree(pCtx->tagInfo.pTagCtxList); - } - } - - tfree(pLocalMerge->pCtx); - } - - tfree(pLocalMerge->prevRowOfInput); - - tfree(pLocalMerge->pTempBuffer); - tfree(pLocalMerge->pResultBuf); - - if (pLocalMerge->pLoserTree) { - tfree(pLocalMerge->pLoserTree->param); - tfree(pLocalMerge->pLoserTree); - } - - tfree(pLocalMerge->pFinalRes); - tfree(pLocalMerge->discardData); - - tscLocalReducerEnvDestroy(pLocalMerge->pExtMemBuffer, pLocalMerge->pDesc, pLocalMerge->resColModel, pLocalMerge->finalModel, - pLocalMerge->numOfVnode); - for (int32_t i = 0; i < pLocalMerge->numOfBuffer; ++i) { - tfree(pLocalMerge->pLocalDataSrc[i]); - } - - pLocalMerge->numOfBuffer = 0; - pLocalMerge->numOfCompleted = 0; - free(pLocalMerge); - } else { - tscDebug("%p already freed or another free function is invoked", pSql); + if (pLocalMerge->pLoserTree) { + tfree(pLocalMerge->pLoserTree->param); + tfree(pLocalMerge->pLoserTree); } - tscDebug("%p free local reducer finished", pSql); + tscLocalReducerEnvDestroy(pLocalMerge->pExtMemBuffer, pLocalMerge->pDesc, pLocalMerge->resColModel, + pLocalMerge->finalModel, pLocalMerge->numOfVnode); + for (int32_t i = 0; i < pLocalMerge->numOfBuffer; ++i) { + tfree(pLocalMerge->pLocalDataSrc[i]); + } + + pLocalMerge->numOfBuffer = 0; + pLocalMerge->numOfCompleted = 0; + tfree(pLocalMerge->pTempBuffer); + + free(pLocalMerge); + + tscDebug("0x%"PRIx64" free local reducer finished", pSql->self); } static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCmd, SColumnModel *pModel) { int32_t numOfGroupByCols = 0; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetActiveQueryInfo(pCmd); if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) { numOfGroupByCols = pQueryInfo->groupbyExpr.numOfGroupCols; @@ -577,11 +474,19 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) { int32_t numOfInternalOutput = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); - int32_t startCols = numOfInternalOutput - pQueryInfo->groupbyExpr.numOfGroupCols; // the last "pQueryInfo->groupbyExpr.numOfGroupCols" columns are order-by columns for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) { - orderColIndexList[i] = startCols++; + SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i); + for(int32_t j = 0; j < numOfInternalOutput; ++j) { + SExprInfo* pExprInfo = tscSqlExprGet(pQueryInfo, j); + + int32_t functionId = pExprInfo->base.functionId; + if (pColIndex->colId == pExprInfo->base.colInfo.colId && (functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TAG)) { + orderColIndexList[i] = j; + break; + } + } } if (pQueryInfo->interval.interval != 0) { @@ -598,8 +503,8 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm } else { size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { + SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { orderColIndexList[0] = i; } } @@ -619,49 +524,6 @@ static int32_t createOrderDescriptor(tOrderDescriptor **pOrderDesc, SSqlCmd *pCm } } -bool isSameGroup(SSqlCmd *pCmd, SLocalMerger *pReducer, char *pPrev, tFilePage *tmpBuffer) { - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - - // disable merge procedure for column projection query - int16_t functionId = pReducer->pCtx[0].functionId; - if (pReducer->orderPrjOnSTable) { - return true; - } - - if (functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_ARITHM) { - return false; - } - - tOrderDescriptor *pOrderDesc = pReducer->pDesc; - SColumnOrderInfo* orderInfo = &pOrderDesc->orderInfo; - - // no group by columns, all data belongs to one group - int32_t numOfCols = orderInfo->numOfCols; - if (numOfCols <= 0) { - return true; - } - - if (orderInfo->colIndex[numOfCols - 1] == PRIMARYKEY_TIMESTAMP_COL_INDEX) { - /* - * super table interval query - * if the order columns is the primary timestamp, all result data belongs to one group - */ - assert(pQueryInfo->interval.interval > 0); - if (numOfCols == 1) { - return true; - } - } else { // simple group by query - assert(pQueryInfo->interval.interval == 0); - } - - // only one row exists - int32_t index = orderInfo->colIndex[0]; - int32_t offset = (pOrderDesc->pColumnModel)->pFields[index].offset; - - int32_t ret = memcmp(pPrev + offset, tmpBuffer->data + offset, pOrderDesc->pColumnModel->rowSize - offset); - return ret == 0; -} - int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOrderDescriptor **pOrderDesc, SColumnModel **pFinalModel, SColumnModel** pFFModel, uint32_t nBufferSizes) { SSqlCmd *pCmd = &pSql->cmd; @@ -671,7 +533,7 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr SColumnModel *pModel = NULL; *pFinalModel = NULL; - SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo * pQueryInfo = tscGetActiveQueryInfo(pCmd); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); (*pMemBuffer) = (tExtMemBuffer **)malloc(POINTER_BYTES * pSql->subState.numOfSub); @@ -692,13 +554,13 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr int32_t rlen = 0; for (int32_t i = 0; i < size; ++i) { - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i); - pSchema[i].bytes = pExpr->resBytes; - pSchema[i].type = (int8_t)pExpr->resType; - tstrncpy(pSchema[i].name, pExpr->aliasName, tListLen(pSchema[i].name)); + pSchema[i].bytes = pExpr->base.resBytes; + pSchema[i].type = (int8_t)pExpr->base.resType; + tstrncpy(pSchema[i].name, pExpr->base.aliasName, tListLen(pSchema[i].name)); - rlen += pExpr->resBytes; + rlen += pExpr->base.resBytes; } int32_t capacity = 0; @@ -731,17 +593,17 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr memset(pSchema, 0, sizeof(SSchema) * size); for (int32_t i = 0; i < size; ++i) { - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i); SSchema p1 = {0}; - if (pExpr->colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (pExpr->base.colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) { p1 = *tGetTbnameColumnSchema(); - } else if (TSDB_COL_IS_UD_COL(pExpr->colInfo.flag)) { - p1.bytes = pExpr->resBytes; - p1.type = (uint8_t) pExpr->resType; - tstrncpy(p1.name, pExpr->aliasName, tListLen(p1.name)); + } else if (TSDB_COL_IS_UD_COL(pExpr->base.colInfo.flag)) { + p1.bytes = pExpr->base.resBytes; + p1.type = (uint8_t) pExpr->base.resType; + tstrncpy(p1.name, pExpr->base.aliasName, tListLen(p1.name)); } else { - p1 = *tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIndex); + p1 = *tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->base.colInfo.colIndex); } int32_t inter = 0; @@ -750,7 +612,7 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr // the final result size and type in the same as query on single table. // so here, set the flag to be false; - int32_t functionId = pExpr->functionId; + int32_t functionId = pExpr->base.functionId; if (functionId >= TSDB_FUNC_TS && functionId <= TSDB_FUNC_DIFF) { type = pModel->pFields[i].field.type; bytes = pModel->pFields[i].field.bytes; @@ -882,874 +744,143 @@ void adjustLoserTreeFromNewData(SLocalMerger *pLocalMerge, SLocalDataSource *pOn } } -void savePrevRecordAndSetupFillInfo(SLocalMerger *pLocalMerge, SQueryInfo *pQueryInfo, SFillInfo *pFillInfo) { - // discard following dataset in the same group and reset the interpolation information - STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); +//TODO it is not ordered, fix it +static void savePrevOrderColumns(char** prevRow, SArray* pColumnList, SSDataBlock* pBlock, int32_t rowIndex, bool* hasPrev) { + int32_t size = (int32_t) taosArrayGetSize(pColumnList); - STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); + for(int32_t i = 0; i < size; ++i) { + SColIndex* index = taosArrayGet(pColumnList, i); + SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, index->colIndex); + assert(index->colId == pColInfo->info.colId); - if (pFillInfo != NULL) { - int64_t stime = (pQueryInfo->window.skey < pQueryInfo->window.ekey) ? pQueryInfo->window.skey : pQueryInfo->window.ekey; - int64_t revisedSTime = taosTimeTruncate(stime, &pQueryInfo->interval, tinfo.precision); - - taosResetFillInfo(pFillInfo, revisedSTime); + memcpy(prevRow[i], pColInfo->pData + pColInfo->info.bytes * rowIndex, pColInfo->info.bytes); } - pLocalMerge->discard = true; - pLocalMerge->discardData->num = 0; - - SColumnModel *pModel = pLocalMerge->pDesc->pColumnModel; - tColModelAppend(pModel, pLocalMerge->discardData, pLocalMerge->prevRowOfInput, 0, 1, 1); + (*hasPrev) = true; } -static void genFinalResWithoutFill(SSqlRes* pRes, SLocalMerger *pLocalMerge, SQueryInfo* pQueryInfo) { - assert(pQueryInfo->interval.interval == 0 || pQueryInfo->fillType == TSDB_FILL_NONE); - - tFilePage * pBeforeFillData = pLocalMerge->pResultBuf; - - pRes->data = pLocalMerge->pFinalRes; - pRes->numOfRows = (int32_t) pBeforeFillData->num; - - if (pQueryInfo->limit.offset > 0) { - if (pQueryInfo->limit.offset < pRes->numOfRows) { - int32_t prevSize = (int32_t) pBeforeFillData->num; - tColModelErase(pLocalMerge->finalModel, pBeforeFillData, prevSize, 0, (int32_t)pQueryInfo->limit.offset - 1); - - /* remove the hole in column model */ - tColModelCompact(pLocalMerge->finalModel, pBeforeFillData, prevSize); - - pRes->numOfRows -= (int32_t) pQueryInfo->limit.offset; - pQueryInfo->limit.offset = 0; - } else { - pQueryInfo->limit.offset -= pRes->numOfRows; - pRes->numOfRows = 0; - } +static void setTagValueForMultipleRows(SQLFunctionCtx* pCtx, int32_t numOfOutput, int32_t numOfRows) { + if (numOfRows <= 1) { + return ; } - if (pRes->numOfRowsGroup >= pQueryInfo->limit.limit && pQueryInfo->limit.limit > 0) { - pRes->numOfRows = 0; - pBeforeFillData->num = 0; - pLocalMerge->discard = true; - return; - } - - pRes->numOfRowsGroup += pRes->numOfRows; - - // impose the limitation of output rows on the final result - if (pQueryInfo->limit.limit >= 0 && pRes->numOfRowsGroup > pQueryInfo->limit.limit) { - int32_t prevSize = (int32_t)pBeforeFillData->num; - int32_t overflow = (int32_t)(pRes->numOfRowsGroup - pQueryInfo->limit.limit); - assert(overflow < pRes->numOfRows); - - pRes->numOfRowsGroup = pQueryInfo->limit.limit; - pRes->numOfRows -= overflow; - pBeforeFillData->num -= overflow; - - tColModelCompact(pLocalMerge->finalModel, pBeforeFillData, prevSize); - - // set remain data to be discarded, and reset the interpolation information - savePrevRecordAndSetupFillInfo(pLocalMerge, pQueryInfo, pLocalMerge->pFillInfo); - } - - memcpy(pRes->data, pBeforeFillData->data, (size_t)(pRes->numOfRows * pLocalMerge->finalModel->rowSize)); - - pRes->numOfClauseTotal += pRes->numOfRows; - pBeforeFillData->num = 0; -} - -/* - * Note: pRes->pLocalMerge may be null, due to the fact that "tscDestroyLocalMerger" is called - * by "interuptHandler" function in shell - */ -static void doFillResult(SSqlObj *pSql, SLocalMerger *pLocalMerge, bool doneOutput) { - SSqlCmd *pCmd = &pSql->cmd; - SSqlRes *pRes = &pSql->res; - - tFilePage *pBeforeFillData = pLocalMerge->pResultBuf; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - SFillInfo *pFillInfo = pLocalMerge->pFillInfo; - - // todo extract function - int64_t actualETime = (pQueryInfo->order.order == TSDB_ORDER_ASC)? pQueryInfo->window.ekey: pQueryInfo->window.skey; - - void** pResPages = malloc(POINTER_BYTES * pQueryInfo->fieldsInfo.numOfOutput); - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { - TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i); - pResPages[i] = calloc(1, pField->bytes * pLocalMerge->resColModel->capacity); - } - - while (1) { - int64_t newRows = taosFillResultDataBlock(pFillInfo, pResPages, pLocalMerge->resColModel->capacity); - - if (pQueryInfo->limit.offset < newRows) { - newRows -= pQueryInfo->limit.offset; - - if (pQueryInfo->limit.offset > 0) { - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { - TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i); - memmove(pResPages[i], ((char*)pResPages[i]) + pField->bytes * pQueryInfo->limit.offset, - (size_t)(newRows * pField->bytes)); - } - } - - pRes->data = pLocalMerge->pFinalRes; - pRes->numOfRows = (int32_t) newRows; - - pQueryInfo->limit.offset = 0; - break; - } else { - pQueryInfo->limit.offset -= newRows; - pRes->numOfRows = 0; - - if (!taosFillHasMoreResults(pFillInfo)) { - if (!doneOutput) { // reduce procedure has not completed yet, but current results for fill are exhausted - break; - } - - // all output in current group are completed - int32_t totalRemainRows = (int32_t)getNumOfResultsAfterFillGap(pFillInfo, actualETime, pLocalMerge->resColModel->capacity); - if (totalRemainRows <= 0) { - break; - } - } - } - } - - if (pRes->numOfRows > 0) { - int32_t currentTotal = (int32_t)(pRes->numOfRowsGroup + pRes->numOfRows); - - if (pQueryInfo->limit.limit >= 0 && currentTotal > pQueryInfo->limit.limit) { - int32_t overflow = (int32_t)(currentTotal - pQueryInfo->limit.limit); - - pRes->numOfRows -= overflow; - assert(pRes->numOfRows >= 0); - - /* set remain data to be discarded, and reset the interpolation information */ - savePrevRecordAndSetupFillInfo(pLocalMerge, pQueryInfo, pFillInfo); - } - - int32_t offset = 0; - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { - TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i); - memcpy(pRes->data + offset * pRes->numOfRows, pResPages[i], (size_t)(pField->bytes * pRes->numOfRows)); - offset += pField->bytes; - } - - pRes->numOfRowsGroup += pRes->numOfRows; - pRes->numOfClauseTotal += pRes->numOfRows; - } - - pBeforeFillData->num = 0; - for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { - tfree(pResPages[i]); - } - - tfree(pResPages); -} - -static void savePreviousRow(SLocalMerger *pLocalMerge, tFilePage *tmpBuffer) { - SColumnModel *pColumnModel = pLocalMerge->pDesc->pColumnModel; - assert(pColumnModel->capacity == 1 && tmpBuffer->num == 1); - - // copy to previous temp buffer - for (int32_t i = 0; i < pColumnModel->numOfCols; ++i) { - SSchema *pSchema = getColumnModelSchema(pColumnModel, i); - int16_t offset = getColumnModelOffset(pColumnModel, i); - - memcpy(pLocalMerge->prevRowOfInput + offset, tmpBuffer->data + offset, pSchema->bytes); - } - - tmpBuffer->num = 0; - pLocalMerge->hasPrevRow = true; -} - -static void doExecuteFinalMerge(SSqlCmd *pCmd, SLocalMerger *pLocalMerge, bool needInit) { - // the tag columns need to be set before all functions execution - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - - size_t size = tscSqlExprNumOfExprs(pQueryInfo); - for (int32_t j = 0; j < size; ++j) { - SQLFunctionCtx *pCtx = &pLocalMerge->pCtx[j]; - - // tags/tags_dummy function, the tag field of SQLFunctionCtx is from the input buffer - int32_t functionId = pCtx->functionId; - if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS_DUMMY) { - tVariantDestroy(&pCtx->tag); - char* input = pCtx->pInput; - - if (pCtx->inputType == TSDB_DATA_TYPE_BINARY || pCtx->inputType == TSDB_DATA_TYPE_NCHAR) { - assert(varDataLen(input) <= pCtx->inputBytes); - tVariantCreateFromBinary(&pCtx->tag, varDataVal(input), varDataLen(input), pCtx->inputType); - } else { - tVariantCreateFromBinary(&pCtx->tag, input, pCtx->inputBytes, pCtx->inputType); - } - - } else if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) { - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, j); - pCtx->param[0].i64 = pExpr->param[0].i64; - } - - pCtx->currentStage = MERGE_STAGE; - if (functionId < 0) { - continue; - } - - if (needInit) { - aAggs[pCtx->functionId].init(pCtx, pCtx->resultInfo); - } - } - - for (int32_t j = 0; j < size; ++j) { - int32_t functionId = pLocalMerge->pCtx[j].functionId; - if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) { + for (int32_t k = 0; k < numOfOutput; ++k) { + if (pCtx[k].functionId != TSDB_FUNC_TAG) { continue; } - if (functionId < 0) { - int32_t output = 0; + int32_t inc = numOfRows - 1; // tsdb_func_tag function only produce one row of result + char* src = pCtx[k].pOutput; - SUdfInfo* pUdfInfo = taosArrayGet(pCmd->pUdfInfo, -1 * functionId - 1); - assert (pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE); - - if (pUdfInfo->funcs[TSDB_UDF_FUNC_MERGE]) { - (*(udfMergeFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_MERGE])(pLocalMerge->pCtx[j].pInput, pLocalMerge->pCtx[j].size, pLocalMerge->pCtx[j].pOutput, &output, &pUdfInfo->init); - - // set the output value exist - pLocalMerge->pCtx[j].resultInfo->numOfRes = output; - if (output > 0) { - pLocalMerge->pCtx[j].resultInfo->hasResult = DATA_SET_FLAG; - } - } - } else { - aAggs[functionId].mergeFunc(&pLocalMerge->pCtx[j]); - } - } -} - -static void handleUnprocessedRow(SSqlCmd *pCmd, SLocalMerger *pLocalMerge, tFilePage *tmpBuffer) { - if (pLocalMerge->hasUnprocessedRow) { - pLocalMerge->hasUnprocessedRow = false; - doExecuteFinalMerge(pCmd, pLocalMerge, true); - savePreviousRow(pLocalMerge, tmpBuffer); - } -} - -static int64_t getNumOfResultLocal(SQueryInfo *pQueryInfo, SQLFunctionCtx *pCtx) { - int64_t maxOutput = 0; - - size_t size = tscSqlExprNumOfExprs(pQueryInfo); - for (int32_t j = 0; j < size; ++j) { - /* - * ts, tag, tagprj function can not decide the output number of current query - * the number of output result is decided by main output - */ - int32_t functionId = pCtx[j].functionId; - if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TAG) { - continue; - } - - SResultRowCellInfo* pResInfo = GET_RES_INFO(&pCtx[j]); - if (maxOutput < pResInfo->numOfRes) { - maxOutput = pResInfo->numOfRes; - } - } - - return maxOutput; -} - -/* - * in handling the top/bottom query, which produce more than one rows result, - * the tsdb_func_tags only fill the first row of results, the remain rows need to - * filled with the same result, which is the tags, specified in group by clause - * - */ -static void fillMultiRowsOfTagsVal(SQueryInfo *pQueryInfo, int32_t numOfRes, SLocalMerger *pLocalMerge) { - int32_t maxBufSize = 0; // find the max tags column length to prepare the buffer - size_t size = tscSqlExprNumOfExprs(pQueryInfo); - - for (int32_t k = 0; k < size; ++k) { - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, k); - if (maxBufSize < pExpr->resBytes && pExpr->functionId == TSDB_FUNC_TAG) { - maxBufSize = pExpr->resBytes; - } - } - - assert(maxBufSize >= 0); - - char *buf = malloc((size_t)maxBufSize); - for (int32_t k = 0; k < size; ++k) { - SQLFunctionCtx *pCtx = &pLocalMerge->pCtx[k]; - if (pCtx->functionId != TSDB_FUNC_TAG) { - continue; - } - - int32_t inc = numOfRes - 1; // tsdb_func_tag function only produce one row of result - memset(buf, 0, (size_t)maxBufSize); - memcpy(buf, pCtx->pOutput, (size_t)pCtx->outputBytes); - - char* next = pCtx->pOutput; for (int32_t i = 0; i < inc; ++i) { - next += pCtx->outputBytes; - memcpy(next, buf, (size_t)pCtx->outputBytes); + pCtx[k].pOutput += pCtx[k].outputBytes; + memcpy(pCtx[k].pOutput, src, (size_t)pCtx[k].outputBytes); } } - - free(buf); } -int32_t finalizeRes(SSqlCmd *pCmd, SQueryInfo *pQueryInfo, SLocalMerger *pLocalMerge) { - size_t size = tscSqlExprNumOfExprs(pQueryInfo); - - for (int32_t k = 0; k < size; ++k) { - SQLFunctionCtx* pCtx = &pLocalMerge->pCtx[k]; +static void doExecuteFinalMergeRv(SOperatorInfo* pOperator, int32_t numOfExpr, SSDataBlock* pBlock) { + SMultiwayMergeInfo* pInfo = pOperator->info; + SQLFunctionCtx* pCtx = pInfo->binfo.pCtx; - if (pCtx->functionId < 0) { - int32_t output = 0; - SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); - void *interBuf = (void *)GET_ROWCELL_INTERBUF(pResInfo); + char** add = calloc(pBlock->info.numOfCols, POINTER_BYTES); + for(int32_t i = 0; i < pBlock->info.numOfCols; ++i) { + add[i] = pCtx[i].pInput; + pCtx[i].size = 1; + } - SUdfInfo* pUdfInfo = taosArrayGet(pCmd->pUdfInfo, -1 * pCtx->functionId - 1); - assert (pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE); - - if (pUdfInfo && pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE]) { - (*(udfFinalizeFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE])(pCtx->pOutput, interBuf, &output, &pUdfInfo->init); - - // set the output value exist - pCtx->resultInfo->numOfRes = output; - if (output > 0) { - pCtx->resultInfo->hasResult = DATA_SET_FLAG; + for(int32_t i = 0; i < pBlock->info.rows; ++i) { + if (pInfo->hasPrev) { + if (needToMergeRv(pBlock, pInfo->orderColumnList, i, pInfo->prevRow)) { + for (int32_t j = 0; j < numOfExpr; ++j) { + pCtx[j].pInput = add[j] + pCtx[j].inputBytes * i; } - } - } else { - aAggs[pCtx->functionId].xFinalize(pCtx); - } - } - pLocalMerge->hasPrevRow = false; - - int32_t numOfRes = (int32_t)getNumOfResultLocal(pQueryInfo, pLocalMerge->pCtx); - pLocalMerge->pResultBuf->num += numOfRes; - - fillMultiRowsOfTagsVal(pQueryInfo, numOfRes, pLocalMerge); - return numOfRes; -} - -/* - * points merge: - * points are merged according to the sort info, which is tags columns and timestamp column. - * In case of points without either tags columns or timestamp, such as - * results generated by simple aggregation function, we merge them all into one points - * *Exception*: column projection query, required no merge procedure - */ -bool needToMerge(SSqlCmd *pCmd, SQueryInfo *pQueryInfo, SLocalMerger *pLocalMerge, tFilePage *tmpBuffer) { - int32_t ret = 0; // merge all result by default - - int16_t functionId = pLocalMerge->pCtx[0].functionId; - - // todo opt performance - if ((/*functionId == TSDB_FUNC_PRJ || */functionId == TSDB_FUNC_ARITHM) || (tscIsProjectionQueryOnSTable(pCmd, pQueryInfo, 0) && pQueryInfo->distinctTag == false)) { // column projection query - ret = 1; // disable merge procedure - } else { - tOrderDescriptor *pDesc = pLocalMerge->pDesc; - if (pDesc->orderInfo.numOfCols > 0) { - if (pDesc->tsOrder == TSDB_ORDER_ASC) { // asc - // todo refactor comparator - ret = compare_a(pLocalMerge->pDesc, 1, 0, pLocalMerge->prevRowOfInput, 1, 0, tmpBuffer->data); - } else { // desc - ret = compare_d(pLocalMerge->pDesc, 1, 0, pLocalMerge->prevRowOfInput, 1, 0, tmpBuffer->data); - } - } - } - - /* if ret == 0, means the result belongs to the same group */ - return (ret == 0); -} - -static bool reachGroupResultLimit(SQueryInfo *pQueryInfo, SSqlRes *pRes) { - return (pRes->numOfGroups >= pQueryInfo->slimit.limit && pQueryInfo->slimit.limit >= 0); -} - -static bool saveGroupResultInfo(SSqlObj *pSql) { - SSqlCmd *pCmd = &pSql->cmd; - SSqlRes *pRes = &pSql->res; - - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - - if (pRes->numOfRowsGroup > 0) { - pRes->numOfGroups += 1; - } - - // the output group is limited by the slimit clause - if (reachGroupResultLimit(pQueryInfo, pRes)) { - return true; - } - - // pRes->pGroupRec = realloc(pRes->pGroupRec, pRes->numOfGroups*sizeof(SResRec)); - // pRes->pGroupRec[pRes->numOfGroups-1].numOfRows = pRes->numOfRows; - // pRes->pGroupRec[pRes->numOfGroups-1].numOfClauseTotal = pRes->numOfClauseTotal; - - 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; + for (int32_t j = 0; j < numOfExpr; ++j) { + int32_t functionId = pCtx[j].functionId; + if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) { + continue; + } + aAggs[functionId].mergeFunc(&pCtx[j]); + } } else { - continue; + for(int32_t j = 0; j < numOfExpr; ++j) { // TODO refactor + int32_t functionId = pCtx[j].functionId; + if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) { + continue; + } + aAggs[functionId].xFinalize(&pCtx[j]); + } + + int32_t numOfRows = getNumOfResult(pOperator->pRuntimeEnv, pInfo->binfo.pCtx, pOperator->numOfOutput); + setTagValueForMultipleRows(pCtx, pOperator->numOfOutput, numOfRows); + + pInfo->binfo.pRes->info.rows += numOfRows; + + for(int32_t j = 0; j < numOfExpr; ++j) { + pCtx[j].pOutput += (pCtx[j].outputBytes * numOfRows); + if (pCtx[j].functionId == TSDB_FUNC_TOP || pCtx[j].functionId == TSDB_FUNC_BOTTOM) { + pCtx[j].ptsOutputBuf = pCtx[0].pOutput; + } + } + + for(int32_t j = 0; j < numOfExpr; ++j) { + aAggs[pCtx[j].functionId].init(&pCtx[j], pCtx[j].resultInfo); + } + + for (int32_t j = 0; j < numOfExpr; ++j) { + pCtx[j].pInput = add[j] + pCtx[j].inputBytes * i; + } + + for (int32_t j = 0; j < numOfExpr; ++j) { + int32_t functionId = pCtx[j].functionId; + if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) { + continue; + } + aAggs[functionId].mergeFunc(&pCtx[j]); + } } } else { - if (fp == notNullOperator) { - qualified = true; - break; - } else if (fp == isNullOperator) { - continue; + for (int32_t j = 0; j < numOfExpr; ++j) { + pCtx[j].pInput = add[j] + pCtx[j].inputBytes * i; + } + + for (int32_t j = 0; j < numOfExpr; ++j) { + int32_t functionId = pCtx[j].functionId; + if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) { + continue; + } + aAggs[functionId].mergeFunc(&pCtx[j]); } } - if (fp(&filterElem, input, input, type)) { - qualified = true; - break; + savePrevOrderColumns(pInfo->prevRow, pInfo->orderColumnList, pBlock, i, &pInfo->hasPrev); + } + + { + for(int32_t i = 0; i < pBlock->info.numOfCols; ++i) { + pCtx[i].pInput = add[i]; } } - *notSkipped = qualified; - - return TSDB_CODE_SUCCESS; + tfree(add); } - -int32_t doHavingFilter(SQueryInfo* pQueryInfo, tFilePage* pOutput, bool* notSkipped) { - *notSkipped = true; - - if (pQueryInfo->havingFieldNum <= 0) { - return TSDB_CODE_SUCCESS; +bool needToMergeRv(SSDataBlock* pBlock, SArray* columnIndexList, int32_t index, char **buf) { + int32_t ret = 0; + size_t size = taosArrayGetSize(columnIndexList); + if (size > 0) { + ret = compare_aRv(pBlock, columnIndexList, (int32_t) size, index, buf, TSDB_ORDER_ASC); } - //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 - * @param pLocalMerge - * @param noMoreCurrentGroupRes - * @return if current group is skipped, return false, and do NOT record it into pRes->numOfGroups - */ -bool genFinalResults(SSqlObj *pSql, SLocalMerger *pLocalMerge, bool noMoreCurrentGroupRes) { - SSqlCmd *pCmd = &pSql->cmd; - SSqlRes *pRes = &pSql->res; - - SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - tFilePage * pResBuf = pLocalMerge->pResultBuf; - SColumnModel *pModel = pLocalMerge->resColModel; - - pRes->code = TSDB_CODE_SUCCESS; - - /* - * Ignore the output of the current group since this group is skipped by user - * We set the numOfRows to be 0 and discard the possible remain results. - */ - if (pQueryInfo->slimit.offset > 0) { - pRes->numOfRows = 0; - pQueryInfo->slimit.offset -= 1; - pLocalMerge->discard = !noMoreCurrentGroupRes; - - if (pLocalMerge->discard) { - SColumnModel *pInternModel = pLocalMerge->pDesc->pColumnModel; - tColModelAppend(pInternModel, pLocalMerge->discardData, pLocalMerge->pTempBuffer->data, 0, 1, 1); - } - - return false; - } - - tColModelCompact(pModel, pResBuf, pModel->capacity); - - if (tscIsSecondStageQuery(pCmd, pQueryInfo)) { - 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); - } else { - SFillInfo* pFillInfo = pLocalMerge->pFillInfo; - if (pFillInfo != NULL) { - TSKEY ekey = (pQueryInfo->order.order == TSDB_ORDER_ASC)? pQueryInfo->window.ekey: pQueryInfo->window.skey; - - taosFillSetStartInfo(pFillInfo, (int32_t)pResBuf->num, ekey); - taosFillCopyInputDataFromOneFilePage(pFillInfo, pResBuf); - } - - doFillResult(pSql, pLocalMerge, noMoreCurrentGroupRes); - } - - return true; -} - -void resetOutputBuf(SQueryInfo *pQueryInfo, SLocalMerger *pLocalMerge) {// reset output buffer to the beginning - size_t t = tscSqlExprNumOfExprs(pQueryInfo); - for (int32_t i = 0; i < t; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - pLocalMerge->pCtx[i].pOutput = pLocalMerge->pResultBuf->data + pExpr->offset * pLocalMerge->resColModel->capacity; - - if (pExpr->functionId == TSDB_FUNC_TOP || pExpr->functionId == TSDB_FUNC_BOTTOM || pExpr->functionId == TSDB_FUNC_DIFF) { - pLocalMerge->pCtx[i].ptsOutputBuf = pLocalMerge->pCtx[0].pOutput; - } - } - - memset(pLocalMerge->pResultBuf, 0, pLocalMerge->nResultBufSize + sizeof(tFilePage)); -} - -static void resetEnvForNewResultset(SSqlRes *pRes, SSqlCmd *pCmd, SLocalMerger *pLocalMerge) { - // In handling data in other groups, we need to reset the interpolation information for a new group data - pRes->numOfRows = 0; - pRes->numOfRowsGroup = 0; - - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - - pQueryInfo->limit.offset = pLocalMerge->offset; - - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); - STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); - - // for group result interpolation, do not return if not data is generated - if (pQueryInfo->fillType != TSDB_FILL_NONE) { - TSKEY skey = (pQueryInfo->order.order == TSDB_ORDER_ASC)? pQueryInfo->window.skey:pQueryInfo->window.ekey;//MIN(pQueryInfo->window.skey, pQueryInfo->window.ekey); - int64_t newTime = taosTimeTruncate(skey, &pQueryInfo->interval, tinfo.precision); - taosResetFillInfo(pLocalMerge->pFillInfo, newTime); - } + // if ret == 0, means the result belongs to the same group + return (ret == 0); } static bool isAllSourcesCompleted(SLocalMerger *pLocalMerge) { return (pLocalMerge->numOfBuffer == pLocalMerge->numOfCompleted); } -static bool doBuildFilledResultForGroup(SSqlObj *pSql) { - SSqlCmd *pCmd = &pSql->cmd; - SSqlRes *pRes = &pSql->res; - - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - SLocalMerger *pLocalMerge = pRes->pLocalMerger; - SFillInfo *pFillInfo = pLocalMerge->pFillInfo; - - if (pFillInfo != NULL && taosFillHasMoreResults(pFillInfo)) { - assert(pQueryInfo->fillType != TSDB_FILL_NONE); - - tFilePage *pFinalDataBuf = pLocalMerge->pResultBuf; - int64_t etime = *(int64_t *)(pFinalDataBuf->data + TSDB_KEYSIZE * (pFillInfo->numOfRows - 1)); - - // the first column must be the timestamp column - int32_t rows = (int32_t) getNumOfResultsAfterFillGap(pFillInfo, etime, pLocalMerge->resColModel->capacity); - if (rows > 0) { // do fill gap - doFillResult(pSql, pLocalMerge, false); - } - - return true; - } else { - return false; - } -} - -static bool doHandleLastRemainData(SSqlObj *pSql) { - SSqlCmd *pCmd = &pSql->cmd; - SSqlRes *pRes = &pSql->res; - - SLocalMerger *pLocalMerge = pRes->pLocalMerger; - SFillInfo *pFillInfo = pLocalMerge->pFillInfo; - - bool prevGroupCompleted = (!pLocalMerge->discard) && pLocalMerge->hasUnprocessedRow; - - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - - if ((isAllSourcesCompleted(pLocalMerge) && !pLocalMerge->hasPrevRow) || pLocalMerge->pLocalDataSrc[0] == NULL || - prevGroupCompleted) { - // if fillType == TSDB_FILL_NONE, return directly - if (pQueryInfo->fillType != TSDB_FILL_NONE && - ((pRes->numOfRowsGroup < pQueryInfo->limit.limit && pQueryInfo->limit.limit > 0) || (pQueryInfo->limit.limit < 0))) { - int64_t etime = (pQueryInfo->order.order == TSDB_ORDER_ASC)? pQueryInfo->window.ekey : pQueryInfo->window.skey; - - int32_t rows = (int32_t)getNumOfResultsAfterFillGap(pFillInfo, etime, pLocalMerge->resColModel->capacity); - if (rows > 0) { - doFillResult(pSql, pLocalMerge, true); - } - } - - /* - * 1. numOfRows == 0, means no interpolation results are generated. - * 2. if all local data sources are consumed, and no un-processed rows exist. - * - * No results will be generated and query completed. - */ - if (pRes->numOfRows > 0 || (isAllSourcesCompleted(pLocalMerge) && (!pLocalMerge->hasUnprocessedRow))) { - return true; - } - - // start to process result for a new group and save the result info of previous group - if (saveGroupResultInfo(pSql)) { - return true; - } - - resetEnvForNewResultset(pRes, pCmd, pLocalMerge); - } - - return false; -} - -static void doProcessResultInNextWindow(SSqlObj *pSql, int32_t numOfRes) { - SSqlCmd *pCmd = &pSql->cmd; - SSqlRes *pRes = &pSql->res; - - SLocalMerger *pLocalMerge = pRes->pLocalMerger; - SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - size_t size = tscSqlExprNumOfExprs(pQueryInfo); - - for (int32_t k = 0; k < size; ++k) { - SQLFunctionCtx *pCtx = &pLocalMerge->pCtx[k]; - pCtx->pOutput += pCtx->outputBytes * numOfRes; - - // set the correct output timestamp column position - if (pCtx->functionId == TSDB_FUNC_TOP || pCtx->functionId == TSDB_FUNC_BOTTOM) { - pCtx->ptsOutputBuf = ((char *)pCtx->ptsOutputBuf + TSDB_KEYSIZE * numOfRes); - } - } - - doExecuteFinalMerge(pCmd, pLocalMerge, true); -} - -int32_t tscDoLocalMerge(SSqlObj *pSql) { - SSqlCmd *pCmd = &pSql->cmd; - SSqlRes *pRes = &pSql->res; - - tscResetForNextRetrieve(pRes); - - if (pSql->signature != pSql || pRes == NULL || pRes->pLocalMerger == NULL) { // all data has been processed - if (pRes->code == TSDB_CODE_SUCCESS) { - return pRes->code; - } - - tscError("%p local merge abort due to error occurs, code:%s", pSql, tstrerror(pRes->code)); - return pRes->code; - } - - SLocalMerger *pLocalMerge = pRes->pLocalMerger; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - tFilePage *tmpBuffer = pLocalMerge->pTempBuffer; - - int32_t remain = 1; - if (tscIsTopbotQuery(pQueryInfo)) { - remain = tscGetTopbotQueryParam(pQueryInfo); - } - - if (doHandleLastRemainData(pSql)) { - return TSDB_CODE_SUCCESS; - } - - if (doBuildFilledResultForGroup(pSql)) { - return TSDB_CODE_SUCCESS; - } - - SLoserTreeInfo *pTree = pLocalMerge->pLoserTree; - - // clear buffer - handleUnprocessedRow(pCmd, pLocalMerge, tmpBuffer); - SColumnModel *pModel = pLocalMerge->pDesc->pColumnModel; - - while (1) { - if (isAllSourcesCompleted(pLocalMerge)) { - break; - } - -#ifdef _DEBUG_VIEW - printf("chosen data in pTree[0] = %d\n", pTree->pNode[0].index); -#endif - assert((pTree->pNode[0].index < pLocalMerge->numOfBuffer) && (pTree->pNode[0].index >= 0) && tmpBuffer->num == 0); - - // chosen from loser tree - SLocalDataSource *pOneDataSrc = pLocalMerge->pLocalDataSrc[pTree->pNode[0].index]; - - tColModelAppend(pModel, tmpBuffer, pOneDataSrc->filePage.data, pOneDataSrc->rowIdx, 1, - pOneDataSrc->pMemBuffer->pColumnModel->capacity); - -#if defined(_DEBUG_VIEW) - printf("chosen row:\t"); - SSrcColumnInfo colInfo[256] = {0}; - tscGetSrcColumnInfo(colInfo, pQueryInfo); - - tColModelDisplayEx(pModel, tmpBuffer->data, tmpBuffer->num, pModel->capacity, colInfo); -#endif - - if (pLocalMerge->discard) { - assert(pLocalMerge->hasUnprocessedRow == false); - - /* current record belongs to the same group of previous record, need to discard it */ - if (isSameGroup(pCmd, pLocalMerge, pLocalMerge->discardData->data, tmpBuffer)) { - tmpBuffer->num = 0; - pOneDataSrc->rowIdx += 1; - - adjustLoserTreeFromNewData(pLocalMerge, pOneDataSrc, pTree); - - // all inputs are exhausted, abort current process - if (isAllSourcesCompleted(pLocalMerge)) { - break; - } - - // data belongs to the same group needs to be discarded - continue; - } else { - pLocalMerge->discard = false; - pLocalMerge->discardData->num = 0; - - if (saveGroupResultInfo(pSql)) { - return TSDB_CODE_SUCCESS; - } - - resetEnvForNewResultset(pRes, pCmd, pLocalMerge); - } - } - - if (pLocalMerge->hasPrevRow) { - if (needToMerge(pCmd, pQueryInfo, pLocalMerge, tmpBuffer)) { - // belong to the group of the previous row, continue process it - doExecuteFinalMerge(pCmd, pLocalMerge, false); - - // copy to buffer - savePreviousRow(pLocalMerge, tmpBuffer); - } else { - /* - * current row does not belong to the group of previous row. - * so the processing of previous group is completed. - */ - int32_t numOfRes = finalizeRes(pCmd, pQueryInfo, pLocalMerge); - bool sameGroup = isSameGroup(pCmd, pLocalMerge, pLocalMerge->prevRowOfInput, tmpBuffer); - - tFilePage *pResBuf = pLocalMerge->pResultBuf; - - /* - * if the previous group does NOT generate any result (pResBuf->num == 0), - * continue to process results instead of return results. - */ - if ((!sameGroup && pResBuf->num > 0) || (pResBuf->num + remain >= pLocalMerge->resColModel->capacity)) { - // does not belong to the same group - bool notSkipped = genFinalResults(pSql, pLocalMerge, !sameGroup); - - // this row needs to discard, since it belongs to the group of previous - if (pLocalMerge->discard && sameGroup) { - pLocalMerge->hasUnprocessedRow = false; - tmpBuffer->num = 0; - } else { // current row does not belongs to the previous group, so it is not be handled yet. - pLocalMerge->hasUnprocessedRow = true; - } - - resetOutputBuf(pQueryInfo, pLocalMerge); - pOneDataSrc->rowIdx += 1; - - // here we do not check the return value - adjustLoserTreeFromNewData(pLocalMerge, pOneDataSrc, pTree); - - if (pRes->numOfRows == 0) { - handleUnprocessedRow(pCmd, pLocalMerge, tmpBuffer); - - if (!sameGroup) { - /* - * previous group is done, prepare for the next group - * If previous group is not skipped, keep it in pRes->numOfGroups - */ - if (notSkipped && saveGroupResultInfo(pSql)) { - return TSDB_CODE_SUCCESS; - } - - resetEnvForNewResultset(pRes, pCmd, pLocalMerge); - } - } else { - /* - * if next record belongs to a new group, we do not handle this record here. - * We start the process in a new round. - */ - if (sameGroup) { - handleUnprocessedRow(pCmd, pLocalMerge, tmpBuffer); - } - } - - // current group has no result, - if (pRes->numOfRows == 0) { - continue; - } else { - return TSDB_CODE_SUCCESS; - } - } else { // result buffer is not full - doProcessResultInNextWindow(pSql, numOfRes); - savePreviousRow(pLocalMerge, tmpBuffer); - } - } - } else { - doExecuteFinalMerge(pCmd, pLocalMerge, true); - savePreviousRow(pLocalMerge, tmpBuffer); // copy the processed row to buffer - } - - pOneDataSrc->rowIdx += 1; - adjustLoserTreeFromNewData(pLocalMerge, pOneDataSrc, pTree); - } - - if (pLocalMerge->hasPrevRow) { - finalizeRes(pCmd, pQueryInfo, pLocalMerge); - } - - if (pLocalMerge->pResultBuf->num) { - genFinalResults(pSql, pLocalMerge, true); - } - - return TSDB_CODE_SUCCESS; -} - void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen) { SSqlRes *pRes = &pObj->res; if (pRes->pLocalMerger != NULL) { @@ -1788,8 +919,8 @@ int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_ arithSup.data = calloc(arithSup.numOfCols, POINTER_BYTES); for(int32_t k = 0; k < arithSup.numOfCols; ++k) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, k); - arithSup.data[k] = (pOutput->data + pOutput->num* pExpr->offset); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, k); + arithSup.data[k] = (pOutput->data + pOutput->num* pExpr->base.offset); } int32_t offset = 0; @@ -1798,12 +929,12 @@ int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_ SInternalField* pSup = TARRAY_GET_ELEM(pQueryInfo->fieldsInfo.internalField, i); // calculate the result from several other columns - if (pSup->pArithExprInfo != NULL) { - arithSup.pArithExpr = pSup->pArithExprInfo; - arithmeticTreeTraverse(arithSup.pArithExpr->pExpr, (int32_t) pOutput->num, pbuf + pOutput->num*offset, &arithSup, TSDB_ORDER_ASC, getArithmeticInputSrc); + if (pSup->pExpr->pExpr != NULL) { + arithSup.pExprInfo = pSup->pExpr; + arithmeticTreeTraverse(arithSup.pExprInfo->pExpr, (int32_t) pOutput->num, pbuf + pOutput->num*offset, &arithSup, TSDB_ORDER_ASC, getArithmeticInputSrc); } else { - SSqlExpr* pExpr = pSup->pSqlExpr; - memcpy(pbuf + pOutput->num * offset, pExpr->offset * pOutput->num + pOutput->data, (size_t)(pExpr->resBytes * pOutput->num)); + SExprInfo* pExpr = pSup->pExpr; + memcpy(pbuf + pOutput->num * offset, pExpr->base.offset * pOutput->num + pOutput->data, (size_t)(pExpr->base.resBytes * pOutput->num)); } offset += pSup->field.bytes; @@ -1816,3 +947,365 @@ int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_ return offset; } + +#define COLMODEL_GET_VAL(data, schema, allrow, rowId, colId) \ + (data + (schema)->pFields[colId].offset * (allrow) + (rowId) * (schema)->pFields[colId].field.bytes) + +static void appendOneRowToDataBlock(SSDataBlock *pBlock, char *buf, SColumnModel *pModel, int32_t rowIndex, + int32_t maxRows) { + for (int32_t i = 0; i < pBlock->info.numOfCols; ++i) { + SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, i); + char* p = pColInfo->pData + pBlock->info.rows * pColInfo->info.bytes; + + char *src = COLMODEL_GET_VAL(buf, pModel, maxRows, rowIndex, i); + memmove(p, src, pColInfo->info.bytes); + } + + pBlock->info.rows += 1; +} + +SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup) { + SOperatorInfo* pOperator = (SOperatorInfo*) param; + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + SMultiwayMergeInfo *pInfo = pOperator->info; + + SLocalMerger *pMerger = pInfo->pMerge; + SLoserTreeInfo *pTree = pMerger->pLoserTree; + SColumnModel *pModel = pMerger->pDesc->pColumnModel; + tFilePage *tmpBuffer = pMerger->pTempBuffer; + + pInfo->binfo.pRes->info.rows = 0; + + while(1) { + if (isAllSourcesCompleted(pMerger)) { + break; + } + +#ifdef _DEBUG_VIEW + printf("chosen data in pTree[0] = %d\n", pTree->pNode[0].index); +#endif + + assert((pTree->pNode[0].index < pMerger->numOfBuffer) && (pTree->pNode[0].index >= 0) && tmpBuffer->num == 0); + + // chosen from loser tree + SLocalDataSource *pOneDataSrc = pMerger->pLocalDataSrc[pTree->pNode[0].index]; + bool sameGroup = true; + if (pInfo->hasPrev) { + int32_t numOfCols = (int32_t)taosArrayGetSize(pInfo->orderColumnList); + + // if this row belongs to current result set group + for (int32_t i = 0; i < numOfCols; ++i) { + SColIndex * pIndex = taosArrayGet(pInfo->orderColumnList, i); + SColumnInfoData *pColInfo = taosArrayGet(pInfo->binfo.pRes->pDataBlock, pIndex->colIndex); + + char *newRow = + COLMODEL_GET_VAL(pOneDataSrc->filePage.data, pModel, pOneDataSrc->pMemBuffer->pColumnModel->capacity, + pOneDataSrc->rowIdx, pIndex->colIndex); + + char * data = pInfo->prevRow[i]; + int32_t ret = columnValueAscendingComparator(data, newRow, pColInfo->info.type, pColInfo->info.bytes); + if (ret == 0) { + continue; + } else { + sameGroup = false; + *newgroup = true; + break; + } + } + } + + if (!sameGroup || !pInfo->hasPrev) { //save the data + int32_t numOfCols = (int32_t)taosArrayGetSize(pInfo->orderColumnList); + + for (int32_t i = 0; i < numOfCols; ++i) { + SColIndex * pIndex = taosArrayGet(pInfo->orderColumnList, i); + SColumnInfoData *pColInfo = taosArrayGet(pInfo->binfo.pRes->pDataBlock, pIndex->colIndex); + + char *curCol = + COLMODEL_GET_VAL(pOneDataSrc->filePage.data, pModel, pOneDataSrc->pMemBuffer->pColumnModel->capacity, + pOneDataSrc->rowIdx, pIndex->colIndex); + memcpy(pInfo->prevRow[i], curCol, pColInfo->info.bytes); + } + + pInfo->hasPrev = true; + } + + if (!sameGroup && pInfo->binfo.pRes->info.rows > 0) { + return pInfo->binfo.pRes; + } + + appendOneRowToDataBlock(pInfo->binfo.pRes, pOneDataSrc->filePage.data, pModel, pOneDataSrc->rowIdx, pOneDataSrc->pMemBuffer->pColumnModel->capacity); + +#if defined(_DEBUG_VIEW) + printf("chosen row:\t"); + SSrcColumnInfo colInfo[256] = {0}; + tscGetSrcColumnInfo(colInfo, pQueryInfo); + + tColModelDisplayEx(pModel, tmpBuffer->data, tmpBuffer->num, pModel->capacity, colInfo); +#endif + + pOneDataSrc->rowIdx += 1; + adjustLoserTreeFromNewData(pMerger, pOneDataSrc, pTree); + + if (pInfo->binfo.pRes->info.rows >= pInfo->bufCapacity) { + return pInfo->binfo.pRes; + } + } + + pOperator->status = OP_EXEC_DONE; + return (pInfo->binfo.pRes->info.rows > 0)? pInfo->binfo.pRes:NULL; +} + +static bool isSameGroupRv(SArray* orderColumnList, SSDataBlock* pBlock, char** dataCols) { + int32_t numOfCols = (int32_t) taosArrayGetSize(orderColumnList); + for (int32_t i = 0; i < numOfCols; ++i) { + SColIndex *pIndex = taosArrayGet(orderColumnList, i); + + SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, pIndex->colIndex); + assert(pIndex->colId == pColInfo->info.colId); + + char *data = dataCols[i]; + int32_t ret = columnValueAscendingComparator(data, pColInfo->pData, pColInfo->info.type, pColInfo->info.bytes); + if (ret == 0) { + continue; + } else { + return false; + } + } + + return true; +} + +SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) { + SOperatorInfo* pOperator = (SOperatorInfo*) param; + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + SMultiwayMergeInfo *pAggInfo = pOperator->info; + SOperatorInfo *upstream = pOperator->upstream; + + *newgroup = false; + bool handleData = false; + pAggInfo->binfo.pRes->info.rows = 0; + + { + if (pAggInfo->hasDataBlockForNewGroup) { + pAggInfo->binfo.pRes->info.rows = 0; + pAggInfo->hasPrev = false; // now we start from a new group data set. + + // not belongs to the same group, return the result of current group; + setInputDataBlock(pOperator, pAggInfo->binfo.pCtx, pAggInfo->pExistBlock, TSDB_ORDER_ASC); + updateOutputBuf(&pAggInfo->binfo, &pAggInfo->bufCapacity, pAggInfo->pExistBlock->info.rows); + + { // reset output buffer + for(int32_t j = 0; j < pOperator->numOfOutput; ++j) { + SQLFunctionCtx* pCtx = &pAggInfo->binfo.pCtx[j]; + aAggs[pCtx->functionId].init(pCtx, pCtx->resultInfo); + } + } + + doExecuteFinalMergeRv(pOperator, pOperator->numOfOutput, pAggInfo->pExistBlock); + + savePrevOrderColumns(pAggInfo->currentGroupColData, pAggInfo->groupColumnList, pAggInfo->pExistBlock, 0, + &pAggInfo->hasGroupColData); + pAggInfo->pExistBlock = NULL; + pAggInfo->hasDataBlockForNewGroup = false; + handleData = true; + *newgroup = true; + } + } + + SSDataBlock* pBlock = NULL; + while(1) { + bool prev = *newgroup; + pBlock = upstream->exec(upstream, newgroup); + if (pBlock == NULL) { + *newgroup = prev; + break; + } + + if (pAggInfo->hasGroupColData) { + bool sameGroup = isSameGroupRv(pAggInfo->groupColumnList, pBlock, pAggInfo->currentGroupColData); + if (!sameGroup) { + *newgroup = true; + pAggInfo->hasDataBlockForNewGroup = true; + pAggInfo->pExistBlock = pBlock; + savePrevOrderColumns(pAggInfo->prevRow, pAggInfo->groupColumnList, pBlock, 0, &pAggInfo->hasPrev); + break; + } + } + + // not belongs to the same group, return the result of current group + setInputDataBlock(pOperator, pAggInfo->binfo.pCtx, pBlock, TSDB_ORDER_ASC); + updateOutputBuf(&pAggInfo->binfo, &pAggInfo->bufCapacity, pBlock->info.rows * pAggInfo->resultRowFactor); + + doExecuteFinalMergeRv(pOperator, pOperator->numOfOutput, pBlock); + savePrevOrderColumns(pAggInfo->currentGroupColData, pAggInfo->groupColumnList, pBlock, 0, &pAggInfo->hasGroupColData); + handleData = true; + } + + if (handleData) { // data in current group is all handled + for(int32_t j = 0; j < pOperator->numOfOutput; ++j) { + int32_t functionId = pAggInfo->binfo.pCtx[j].functionId; + if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) { + continue; + } + + aAggs[functionId].xFinalize(&pAggInfo->binfo.pCtx[j]); + } + + int32_t numOfRows = getNumOfResult(pOperator->pRuntimeEnv, pAggInfo->binfo.pCtx, pOperator->numOfOutput); + pAggInfo->binfo.pRes->info.rows += numOfRows; + + setTagValueForMultipleRows(pAggInfo->binfo.pCtx, pOperator->numOfOutput, numOfRows); + } + + SSDataBlock* pRes = pAggInfo->binfo.pRes; + { + SColumnInfoData* pInfoData = taosArrayGet(pRes->pDataBlock, 0); + + if (pInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP && pRes->info.rows > 0) { + STimeWindow* w = &pRes->info.window; + + // TODO in case of desc order, swap it + w->skey = *(int64_t*)pInfoData->pData; + w->ekey = *(int64_t*)(((char*)pInfoData->pData) + TSDB_KEYSIZE * (pRes->info.rows - 1)); + + if (pOperator->pRuntimeEnv->pQueryAttr->order.order == TSDB_ORDER_DESC) { + SWAP(w->skey, w->ekey, TSKEY); + assert(w->skey <= w->ekey); + } + } + } + + return (pRes->info.rows != 0)? pRes:NULL; +} + +static SSDataBlock* skipGroupBlock(SOperatorInfo* pOperator, bool* newgroup) { + SSLimitOperatorInfo *pInfo = pOperator->info; + assert(pInfo->currentGroupOffset >= 0); + + SSDataBlock* pBlock = NULL; + if (pInfo->currentGroupOffset == 0) { + pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + if (pBlock == NULL) { + setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); + pOperator->status = OP_EXEC_DONE; + } + + if (*newgroup == false && pInfo->limit.limit > 0 && pInfo->rowsTotal >= pInfo->limit.limit) { + while ((*newgroup) == false) { // ignore the remain blocks + pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + if (pBlock == NULL) { + setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); + pOperator->status = OP_EXEC_DONE; + return NULL; + } + } + } + + return pBlock; + } + + pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + if (pBlock == NULL) { + setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); + pOperator->status = OP_EXEC_DONE; + return NULL; + } + + while(1) { + if (*newgroup) { + pInfo->currentGroupOffset -= 1; + *newgroup = false; + } + + while ((*newgroup) == false) { + pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + if (pBlock == NULL) { + setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); + pOperator->status = OP_EXEC_DONE; + return NULL; + } + } + + // now we have got the first data block of the next group. + if (pInfo->currentGroupOffset == 0) { + return pBlock; + } + } + + return NULL; +} + +SSDataBlock* doSLimit(void* param, bool* newgroup) { + SOperatorInfo *pOperator = (SOperatorInfo *)param; + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + SSLimitOperatorInfo *pInfo = pOperator->info; + + SSDataBlock *pBlock = NULL; + while (1) { + pBlock = skipGroupBlock(pOperator, newgroup); + if (pBlock == NULL) { + setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); + pOperator->status = OP_EXEC_DONE; + return NULL; + } + + if (*newgroup) { // a new group arrives + pInfo->groupTotal += 1; + pInfo->rowsTotal = 0; + pInfo->currentOffset = pInfo->limit.offset; + } + + assert(pInfo->currentGroupOffset == 0); + + if (pInfo->currentOffset >= pBlock->info.rows) { + pInfo->currentOffset -= pBlock->info.rows; + } else { + if (pInfo->currentOffset == 0) { + break; + } + + int32_t remain = (int32_t)(pBlock->info.rows - pInfo->currentOffset); + pBlock->info.rows = remain; + + // move the remain rows of this data block to the front. + 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, pColInfoData->pData + bytes * pInfo->currentOffset, remain * bytes); + } + + pInfo->currentOffset = 0; + break; + } + } + + if (pInfo->slimit.limit > 0 && pInfo->groupTotal > pInfo->slimit.limit) { // reach the group limit, abort + return NULL; + } + + if (pInfo->limit.limit > 0 && (pInfo->rowsTotal + pBlock->info.rows >= pInfo->limit.limit)) { + pBlock->info.rows = (int32_t)(pInfo->limit.limit - pInfo->rowsTotal); + pInfo->rowsTotal = pInfo->limit.limit; + + if (pInfo->slimit.limit > 0 && pInfo->groupTotal >= pInfo->slimit.limit) { + pOperator->status = OP_EXEC_DONE; + } + + // setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); + } else { + pInfo->rowsTotal += pBlock->info.rows; + } + + return pBlock; +} diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c index 920937928f..68c974359c 100644 --- a/src/client/src/tscParseInsert.c +++ b/src/client/src/tscParseInsert.c @@ -748,7 +748,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC const int32_t STABLE_INDEX = 1; SSqlCmd * pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); char *sql = *sqlstr; @@ -829,6 +829,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC index = 0; sToken = tStrGetToken(sql, &index, false); if (sToken.type != TK_TAGS && sToken.type != TK_LP) { + tscDestroyBoundColumnInfo(&spd); return tscInvalidSQLErrMsg(pCmd->payload, "keyword TAGS expected", sToken.z); } @@ -841,6 +842,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC char* end = NULL; code = parseBoundColumns(pCmd, &spd, pTagSchema, sql, &end); if (code != TSDB_CODE_SUCCESS) { + tscDestroyBoundColumnInfo(&spd); return code; } @@ -858,11 +860,13 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC sql += index; if (sToken.type != TK_LP) { + tscDestroyBoundColumnInfo(&spd); return tscInvalidSQLErrMsg(pCmd->payload, "( is expected", sToken.z); } SKVRowBuilder kvRowBuilder = {0}; if (tdInitKVRowBuilder(&kvRowBuilder) < 0) { + tscDestroyBoundColumnInfo(&spd); return TSDB_CODE_TSC_OUT_OF_MEMORY; } @@ -875,6 +879,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC if (TK_ILLEGAL == sToken.type) { tdDestroyKVRowBuilder(&kvRowBuilder); + tscDestroyBoundColumnInfo(&spd); return TSDB_CODE_TSC_INVALID_SQL; } @@ -892,6 +897,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC code = tsParseOneColumn(pSchema, &sToken, tagVal, pCmd->payload, &sql, false, tinfo.precision); if (code != TSDB_CODE_SUCCESS) { tdDestroyKVRowBuilder(&kvRowBuilder); + tscDestroyBoundColumnInfo(&spd); return code; } @@ -1065,7 +1071,7 @@ int tsParseInsertSql(SSqlObj *pSql) { int32_t totalNum = 0; int32_t code = TSDB_CODE_SUCCESS; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); assert(pQueryInfo != NULL); STableMetaInfo *pTableMetaInfo = (pQueryInfo->numOfTables == 0)? tscAddEmptyMetaInfo(pQueryInfo):tscGetMetaInfo(pQueryInfo, 0); @@ -1089,7 +1095,7 @@ int tsParseInsertSql(SSqlObj *pSql) { str = pCmd->curSql; } - tscDebug("%p create data block list hashList:%p", pSql, pCmd->pTableBlockHashList); + tscDebug("0x%"PRIx64" create data block list hashList:%p", pSql->self, pCmd->pTableBlockHashList); while (1) { int32_t index = 0; @@ -1285,7 +1291,7 @@ int tsInsertInitialCheck(SSqlObj *pSql) { pCmd->count = 0; pCmd->command = TSDB_SQL_INSERT; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetailSafely(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfoS(pCmd, pCmd->clauseIndex); TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT | pCmd->insertType); @@ -1303,7 +1309,7 @@ int tsParseSql(SSqlObj *pSql, bool initial) { SSqlCmd* pCmd = &pSql->cmd; if ((!pCmd->parseFinished) && (!initial)) { - tscDebug("%p resume to parse sql: %s", pSql, pCmd->curSql); + tscDebug("0x%"PRIx64" resume to parse sql: %s", pSql->self, pCmd->curSql); } ret = tscAllocPayload(&pSql->cmd, TSDB_DEFAULT_PAYLOAD_SIZE); @@ -1375,7 +1381,7 @@ static int doPackSendDataBlock(SSqlObj *pSql, int32_t numOfRows, STableDataBlock return code; } - return tscProcessSql(pSql); + return tscBuildAndSendRequest(pSql, NULL); } typedef struct SImportFileSupport { @@ -1521,6 +1527,7 @@ void tscImportDataFromFile(SSqlObj *pSql) { } assert(pCmd->dataSourceType == DATA_FROM_DATA_FILE && strlen(pCmd->payload) != 0); + pCmd->active = pCmd->pQueryInfo[0]; SImportFileSupport *pSupporter = calloc(1, sizeof(SImportFileSupport)); SSqlObj *pNew = createSubqueryObj(pSql, 0, parseFileSendDataBlock, pSupporter, TSDB_SQL_INSERT, NULL); diff --git a/src/client/src/tscPrepare.c b/src/client/src/tscPrepare.c index 4efaf7c2b5..c3c8986e2f 100644 --- a/src/client/src/tscPrepare.c +++ b/src/client/src/tscPrepare.c @@ -815,7 +815,7 @@ static int insertStmtExecute(STscStmt* stmt) { pRes->numOfRows = 0; pRes->numOfTotal = 0; - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); // wait for the callback function to post the semaphore tsem_wait(&pSql->rspSem); diff --git a/src/client/src/tscProfile.c b/src/client/src/tscProfile.c index 3b0e1b5775..7ffc9bc310 100644 --- a/src/client/src/tscProfile.c +++ b/src/client/src/tscProfile.c @@ -61,7 +61,7 @@ void tscAddIntoSqlList(SSqlObj *pSql) { pSql->stime = taosGetTimestampMs(); pSql->listed = 1; - tscDebug("%p added into sqlList", pSql); + tscDebug("0x%"PRIx64" added into sqlList", pSql->self); } void tscSaveSlowQueryFpCb(void *param, TAOS_RES *result, int code) { @@ -99,7 +99,7 @@ void tscSaveSlowQuery(SSqlObj *pSql) { return; } - tscDebug("%p query time:%" PRId64 " sql:%s", pSql, pSql->res.useconds, pSql->sqlstr); + tscDebug("0x%"PRIx64" query time:%" PRId64 " sql:%s", pSql->self, pSql->res.useconds, pSql->sqlstr); int32_t sqlSize = (int32_t)(TSDB_SLOW_QUERY_SQL_LEN + size); char *sql = malloc(sqlSize); @@ -141,7 +141,7 @@ void tscRemoveFromSqlList(SSqlObj *pSql) { pSql->listed = 0; tscSaveSlowQuery(pSql); - tscDebug("%p removed from sqlList", pSql); + tscDebug("0x%"PRIx64" removed from sqlList", pSql->self); } void tscKillQuery(STscObj *pObj, uint32_t killId) { @@ -158,7 +158,7 @@ void tscKillQuery(STscObj *pObj, uint32_t killId) { if (pSql == NULL) { tscError("failed to kill query, id:%d, it may have completed/terminated", killId); } else { - tscDebug("%p query is killed, queryId:%d", pSql, killId); + tscDebug("0x%"PRIx64" query is killed, queryId:%d", pSql->self, killId); taos_stop_query(pSql); } } @@ -213,7 +213,7 @@ void tscKillStream(STscObj *pObj, uint32_t killId) { pthread_mutex_unlock(&pObj->mutex); if (pStream) { - tscDebug("%p stream:%p is killed, streamId:%d", pStream->pSql, pStream, killId); + tscDebug("0x%"PRIx64" stream:%p is killed, streamId:%d", pStream->pSql->self, pStream, killId); if (pStream->callback) { pStream->callback(pStream->param); } @@ -249,8 +249,8 @@ int tscBuildQueryStreamDesc(void *pMsg, STscObj *pObj) { pQdesc->stime = htobe64(pSql->stime); pQdesc->queryId = htonl(pSql->queryId); //pQdesc->useconds = htobe64(pSql->res.useconds); - pQdesc->useconds = htobe64(now - pSql->stime); // use local time instead of sever rsp elapsed time - pQdesc->qHandle = htobe64(pSql->res.qId); + pQdesc->useconds = htobe64(now - pSql->stime); + pQdesc->qId = htobe64(pSql->res.qId); pHeartbeat->numOfQueries++; pQdesc++; @@ -273,7 +273,7 @@ int tscBuildQueryStreamDesc(void *pMsg, STscObj *pObj) { pSdesc->num = htobe64(pStream->num); pSdesc->useconds = htobe64(pStream->useconds); - pSdesc->stime = htobe64(pStream->stime - pStream->interval.interval); + pSdesc->stime = (pStream->stime == INT64_MIN) ? htobe64(pStream->stime) : htobe64(pStream->stime - pStream->interval.interval); pSdesc->ctime = htobe64(pStream->ctime); pSdesc->slidingTime = htobe64(pStream->interval.sliding); diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 554f78f2d7..51596c1347 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -58,7 +58,7 @@ typedef struct SConvertFunc { int32_t execFuncId; } SConvertFunc; -static SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tableIndex); +static SExprInfo* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tableIndex); static int32_t setShowInfo(SSqlObj* pSql, SSqlInfo* pInfo); static char* getAccountId(SSqlObj* pSql); @@ -75,27 +75,27 @@ static void getColumnName(tSqlExprItem* pItem, char* resultFieldName, int32_t na static int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t colIndex, tSqlExprItem* pItem, bool finalResult); static int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes, - int8_t type, char* fieldName, SSqlExpr* pSqlExpr); + int8_t type, char* fieldName, SExprInfo* pSqlExpr); static uint8_t convertOptr(SStrToken *pToken); -static int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, SArray* pSelectList, bool isSTable, bool joinQuery, bool timeWindowQuery); +static int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelNodeList, bool isSTable, bool joinQuery, bool timeWindowQuery); static bool validateIpAddress(const char* ip, size_t size); static bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo); static bool functionCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, bool joinQuery, bool twQuery); -static int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd); +static int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd); -static int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySqlNode); +static int32_t validateIntervalNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode); static int32_t parseIntervalOffset(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* offsetToken); static int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* pSliding); static int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExprItem* pItem); -static int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql); -static int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySQL); -static int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySqlNode, SSchema* pSchema); +static int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql); +static int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode); +static int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode, SSchema* pSchema); static int32_t tsRewriteFieldNameIfNecessary(SSqlCmd* pCmd, SQueryInfo* pQueryInfo); static int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo); @@ -112,24 +112,25 @@ static bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField); static bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo); static bool hasNormalColumnFilter(SQueryInfo* pQueryInfo); -static int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t index, SQuerySqlNode* pQuerySqlNode, SSqlObj* pSql); +static int32_t validateLimitNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t index, SSqlNode* pSqlNode, SSqlObj* pSql); static int32_t parseCreateDBOptions(SSqlCmd* pCmd, SCreateDbInfo* pCreateDbSql); static int32_t getColumnIndexByName(SSqlCmd* pCmd, const SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex); static int32_t getTableIndexByName(SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex); static int32_t getTableIndexImpl(SStrToken* pTableToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex); static int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo); -static int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySqlNode); +static int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode); static int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCreateDbMsg* pCreate); -static SColumnList getColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex); +static SColumnList createColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex); static int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* pInfo); static int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo); static int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo); -static int32_t doValidateSqlNode(SSqlObj* pSql, SQuerySqlNode* pQuerySqlNode, int32_t index); -static int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQueryInfo* pQueryInfo, SArray* pCols, int64_t *uid); +static int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, int32_t index); +static int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQueryInfo* pQueryInfo, SArray* pCols, uint64_t *uid); static bool validateDebugFlag(int32_t v); +static int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo); static bool isTimeWindowQuery(SQueryInfo* pQueryInfo) { return pQueryInfo->interval.interval > 0 || pQueryInfo->sessionWindow.gap > 0; @@ -289,7 +290,7 @@ int32_t handleUserDefinedFunc(SSqlObj* pSql, struct SSqlInfo* pInfo) { const char *msg3 = "invalid outputtype"; const char *msg4 = "invalid script"; SSqlCmd *pCmd = &pSql->cmd; - + switch (pInfo->type) { case TSDB_SQL_CREATE_FUNCTION: { SCreateFuncInfo *createInfo = &pInfo->pMiscInfo->funcOpt; @@ -311,20 +312,20 @@ int32_t handleUserDefinedFunc(SSqlObj* pSql, struct SSqlInfo* pInfo) { createInfo->path.z[createInfo->path.n] = 0; strdequote(createInfo->path.z); - + if (strlen(createInfo->path.z) >= PATH_MAX) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); } - + int32_t ret = readFromFile(createInfo->path.z, &len, &buf); if (ret) { return ret; } - //distinguish *.lua and *.so + //distinguish *.lua and *.so int32_t pathLen = (int32_t)strlen(createInfo->path.z); if ((pathLen > 3) && (0 == strncmp(createInfo->path.z + pathLen - 3, "lua", 3)) && !isValidScript(buf, len)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); - } + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); + } //TODO CHECK CODE if (len + sizeof(SCreateFuncMsg) > pSql->cmd.allocSize) { @@ -349,12 +350,12 @@ int32_t handleUserDefinedFunc(SSqlObj* pSql, struct SSqlInfo* pInfo) { pMsg->codeLen = htonl(len); memcpy(pMsg->code, buf, len); tfree(buf); - + break; } case TSDB_SQL_DROP_FUNCTION: { SStrToken* t0 = taosArrayGet(pInfo->pMiscInfo->a, 0); - + SDropFuncMsg *pMsg = (SDropFuncMsg *)pSql->cmd.payload; t0->z[t0->n] = 0; @@ -391,7 +392,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { return tscSQLSyntaxErrMsg(tscGetErrorMsgPayload(pCmd), NULL, pInfo->msg); } - SQueryInfo* pQueryInfo = tscGetQueryInfoDetailSafely(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfoS(pCmd, pCmd->clauseIndex); if (pQueryInfo == NULL) { pRes->code = terrno; return pRes->code; @@ -488,7 +489,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { break; } - case TSDB_SQL_CREATE_FUNCTION: + case TSDB_SQL_CREATE_FUNCTION: case TSDB_SQL_DROP_FUNCTION: { code = handleUserDefinedFunc(pSql, pInfo); if (code != TSDB_CODE_SUCCESS) { @@ -760,35 +761,38 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { case TSDB_SQL_SELECT: { const char* msg1 = "columns in select clause not identical"; - for (int32_t i = pCmd->numOfClause; i < pInfo->subclauseInfo.numOfClause; ++i) { - SQueryInfo* pqi = tscGetQueryInfoDetailSafely(pCmd, i); - if (pqi == NULL) { + size_t size = taosArrayGetSize(pInfo->list); + for (int32_t i = pCmd->numOfClause; i < size; ++i) { + SQueryInfo* p = tscGetQueryInfoS(pCmd, i); + if (p == NULL) { pRes->code = terrno; return pRes->code; } } - assert(pCmd->numOfClause == pInfo->subclauseInfo.numOfClause); - for (int32_t i = pCmd->clauseIndex; i < pInfo->subclauseInfo.numOfClause; ++i) { - SQuerySqlNode* pQuerySqlNode = pInfo->subclauseInfo.pClause[i]; - tscTrace("%p start to parse %dth subclause, total:%d", pSql, i, pInfo->subclauseInfo.numOfClause); - if ((code = doValidateSqlNode(pSql, pQuerySqlNode, i)) != TSDB_CODE_SUCCESS) { + assert(pCmd->numOfClause == size); + for (int32_t i = pCmd->clauseIndex; i < size; ++i) { + SSqlNode* pSqlNode = taosArrayGetP(pInfo->list, i); + tscTrace("%p start to parse %dth subclause, total:%d", pSql, i, (int32_t) size); + if ((code = validateSqlNode(pSql, pSqlNode, i)) != TSDB_CODE_SUCCESS) { return code; } - tscPrintSelectClause(pSql, i); + tscPrintSelNodeList(pSql, i); pCmd->clauseIndex += 1; } // restore the clause index pCmd->clauseIndex = 0; + // set the command/global limit parameters from the first subclause to the sqlcmd object - SQueryInfo* pQueryInfo1 = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo* pQueryInfo1 = tscGetQueryInfo(pCmd, 0); pCmd->command = pQueryInfo1->command; // if there is only one element, the limit of clause is the limit of global result. + // validate the select node for "UNION ALL" subclause for (int32_t i = 1; i < pCmd->numOfClause; ++i) { - SQueryInfo* pQueryInfo2 = tscGetQueryInfoDetail(pCmd, i); + SQueryInfo* pQueryInfo2 = tscGetQueryInfo(pCmd, i); int32_t ret = tscFieldInfoCompare(&pQueryInfo1->fieldsInfo, &pQueryInfo2->fieldsInfo); if (ret != 0) { @@ -849,7 +853,7 @@ static bool isTopBottomQuery(SQueryInfo* pQueryInfo) { size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId; + int32_t functionId = tscSqlExprGet(pQueryInfo, i)->base.functionId; if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) { return true; @@ -861,7 +865,7 @@ static bool isTopBottomQuery(SQueryInfo* pQueryInfo) { // need to add timestamp column in result set, if it is a time window query static int32_t addPrimaryTsColumnForTimeWindowQuery(SQueryInfo* pQueryInfo) { - uint64_t uid = tscSqlExprGet(pQueryInfo, 0)->uid; + uint64_t uid = tscSqlExprGet(pQueryInfo, 0)->base.uid; int32_t tableIndex = COLUMN_INDEX_INITIAL_VAL; for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { @@ -908,8 +912,8 @@ static int32_t checkInvalidExprForTimeWindow(SSqlCmd* pCmd, SQueryInfo* pQueryIn */ size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_COUNT && TSDB_COL_IS_TAG(pExpr->colInfo.flag)) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId == TSDB_FUNC_COUNT && TSDB_COL_IS_TAG(pExpr->base.colInfo.flag)) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } } @@ -925,7 +929,7 @@ static int32_t checkInvalidExprForTimeWindow(SSqlCmd* pCmd, SQueryInfo* pQueryIn return addPrimaryTsColumnForTimeWindowQuery(pQueryInfo); } -int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySqlNode) { +int32_t validateIntervalNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode) { const char* msg2 = "interval cannot be less than 10 ms"; const char* msg3 = "sliding cannot be used without interval"; @@ -934,8 +938,8 @@ int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySqlNode STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); - if (!TPARSER_HAS_TOKEN(pQuerySqlNode->interval.interval)) { - if (TPARSER_HAS_TOKEN(pQuerySqlNode->sliding)) { + if (!TPARSER_HAS_TOKEN(pSqlNode->interval.interval)) { + if (TPARSER_HAS_TOKEN(pSqlNode->sliding)) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); } @@ -948,7 +952,7 @@ int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySqlNode } // interval is not null - SStrToken *t = &pQuerySqlNode->interval.interval; + SStrToken *t = &pSqlNode->interval.interval; if (parseNatualDuration(t->z, t->n, &pQueryInfo->interval.interval, &pQueryInfo->interval.intervalUnit) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_SQL; } @@ -965,11 +969,11 @@ int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySqlNode } } - if (parseIntervalOffset(pCmd, pQueryInfo, &pQuerySqlNode->interval.offset) != TSDB_CODE_SUCCESS) { + if (parseIntervalOffset(pCmd, pQueryInfo, &pSqlNode->interval.offset) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_SQL; } - if (parseSlidingClause(pCmd, pQueryInfo, &pQuerySqlNode->sliding) != TSDB_CODE_SUCCESS) { + if (parseSlidingClause(pCmd, pQueryInfo, &pSqlNode->sliding) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_SQL; } @@ -977,19 +981,19 @@ int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySqlNode return checkInvalidExprForTimeWindow(pCmd, pQueryInfo); } -int32_t parseSessionClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode * pQuerySqlNode) { +int32_t validateSessionNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode * pSqlNode) { const char* msg1 = "gap should be fixed time window"; const char* msg2 = "only one type time window allowed"; const char* msg3 = "invalid column name"; const char* msg4 = "invalid time window"; // no session window - if (!TPARSER_HAS_TOKEN(pQuerySqlNode->sessionVal.gap)) { + if (!TPARSER_HAS_TOKEN(pSqlNode->sessionVal.gap)) { return TSDB_CODE_SUCCESS; } - SStrToken* col = &pQuerySqlNode->sessionVal.col; - SStrToken* gap = &pQuerySqlNode->sessionVal.gap; + SStrToken* col = &pSqlNode->sessionVal.col; + SStrToken* gap = &pSqlNode->sessionVal.gap; char timeUnit = 0; if (parseNatualDuration(gap->z, gap->n, &pQueryInfo->sessionWindow.gap, &timeUnit) != TSDB_CODE_SUCCESS) { @@ -1131,7 +1135,7 @@ int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SStrToken* pTableNam if (acctId == NULL || strlen(acctId) <= 0) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); } - + code = tNameSetAcctId(&pTableMetaInfo->name, acctId); if (code != 0) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); @@ -1541,20 +1545,17 @@ int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStr return (totalLen < TSDB_TABLE_FNAME_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_SQL; } -void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, SColumnIndex* pIndex) { - SColumnIndex tsCol = {.tableIndex = pIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX}; - tscColumnListInsert(pQueryInfo->colList, &tsCol); +void tscInsertPrimaryTsSourceColumn(SQueryInfo* pQueryInfo, uint64_t tableUid) { + SSchema s = {.type = TSDB_DATA_TYPE_TIMESTAMP, .bytes = TSDB_KEYSIZE, .colId = PRIMARYKEY_TIMESTAMP_COL_INDEX}; + tscColumnListInsert(pQueryInfo->colList, PRIMARYKEY_TIMESTAMP_COL_INDEX, tableUid, &s); } -static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t exprIndex, tSqlExprItem* pItem) { +static int32_t handleArithmeticExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t exprIndex, tSqlExprItem* pItem) { const char* msg1 = "invalid column name, illegal column type, or columns in arithmetic expression from two tables"; const char* msg2 = "invalid arithmetic expression in select clause"; const char* msg3 = "tag columns can not be used in arithmetic expression"; const char* msg4 = "columns from different table mixed up in arithmetic expression"; - // arithmetic function in select clause - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex); - SColumnList columnList = {0}; int32_t arithmeticType = NON_ARITHMEIC_EXPR; @@ -1576,12 +1577,12 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t // expr string is set as the parameter of function SColumnIndex index = {.tableIndex = tableIndex}; - SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE, sizeof(double), + SExprInfo* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_ARITHM, &index, TSDB_DATA_TYPE_DOUBLE, sizeof(double), getNewResColId(pQueryInfo), sizeof(double), false); char* name = (pItem->aliasName != NULL)? pItem->aliasName:pItem->pNode->token.z; - size_t len = MIN(sizeof(pExpr->aliasName), pItem->pNode->token.n + 1); - tstrncpy(pExpr->aliasName, name, len); + size_t len = MIN(sizeof(pExpr->base.aliasName), pItem->pNode->token.n + 1); + tstrncpy(pExpr->base.aliasName, name, len); tExprNode* pNode = NULL; SArray* colList = taosArrayInit(10, sizeof(SColIndex)); @@ -1619,11 +1620,11 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t char* c = tbufGetData(&bw, false); // set the serialized binary string as the parameter of arithmetic expression - addExprParams(pExpr, c, TSDB_DATA_TYPE_BINARY, (int32_t)len); - insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->aliasName, pExpr); + addExprParams(&pExpr->base, c, TSDB_DATA_TYPE_BINARY, (int32_t)len); + insertResultField(pQueryInfo, exprIndex, &columnList, sizeof(double), TSDB_DATA_TYPE_DOUBLE, pExpr->base.aliasName, pExpr); // add ts column - tscInsertPrimaryTsSourceColumn(pQueryInfo, &index); + tscInsertPrimaryTsSourceColumn(pQueryInfo, pExpr->base.uid); tbufCloseWriter(&bw); taosArrayDestroy(colList); @@ -1645,41 +1646,41 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t int32_t slot = tscNumOfFields(pQueryInfo) - 1; SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, slot); - if (pInfo->pSqlExpr == NULL) { - SExprInfo* pArithExprInfo = calloc(1, sizeof(SExprInfo)); + if (pInfo->pExpr == NULL) { + SExprInfo* pExprInfo = calloc(1, sizeof(SExprInfo)); // arithmetic expression always return result in the format of double float - pArithExprInfo->bytes = sizeof(double); - pArithExprInfo->interBytes = sizeof(double); - pArithExprInfo->type = TSDB_DATA_TYPE_DOUBLE; + pExprInfo->base.resBytes = sizeof(double); + pExprInfo->base.interBytes = sizeof(double); + pExprInfo->base.resType = TSDB_DATA_TYPE_DOUBLE; - pArithExprInfo->base.functionId = TSDB_FUNC_ARITHM; - pArithExprInfo->base.numOfParams = 1; - pArithExprInfo->base.resColId = getNewResColId(pQueryInfo); + pExprInfo->base.functionId = TSDB_FUNC_ARITHM; + pExprInfo->base.numOfParams = 1; + pExprInfo->base.resColId = getNewResColId(pQueryInfo); - int32_t ret = exprTreeFromSqlExpr(pCmd, &pArithExprInfo->pExpr, pItem->pNode, pQueryInfo, NULL, &pArithExprInfo->uid); + int32_t ret = exprTreeFromSqlExpr(pCmd, &pExprInfo->pExpr, pItem->pNode, pQueryInfo, NULL, &(pExprInfo->base.uid)); if (ret != TSDB_CODE_SUCCESS) { - tExprTreeDestroy(pArithExprInfo->pExpr, NULL); + tExprTreeDestroy(pExprInfo->pExpr, NULL); return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "invalid expression in select clause"); } - pInfo->pArithExprInfo = pArithExprInfo; + pInfo->pExpr = pExprInfo; } SBufferWriter bw = tbufInitWriter(NULL, false); TRY(0) { - exprTreeToBinary(&bw, pInfo->pArithExprInfo->pExpr); + exprTreeToBinary(&bw, pInfo->pExpr->pExpr); } CATCH(code) { tbufCloseWriter(&bw); UNUSED(code); // TODO: other error handling } END_TRY - SSqlFuncMsg* pFuncMsg = &pInfo->pArithExprInfo->base; - pFuncMsg->arg[0].argBytes = (int16_t) tbufTell(&bw); - pFuncMsg->arg[0].argValue.pz = tbufGetData(&bw, true); - pFuncMsg->arg[0].argType = TSDB_DATA_TYPE_BINARY; + SSqlExpr* pSqlExpr = &pInfo->pExpr->base; + pSqlExpr->param[0].nLen = (int16_t) tbufTell(&bw); + pSqlExpr->param[0].pz = tbufGetData(&bw, true); + pSqlExpr->param[0].nType = TSDB_DATA_TYPE_BINARY; // tbufCloseWriter(&bw); // TODO there is a memory leak } @@ -1688,7 +1689,7 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t } static void addProjectQueryCol(SQueryInfo* pQueryInfo, int32_t startPos, SColumnIndex* pIndex, tSqlExprItem* pItem) { - SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, pIndex->columnIndex, pIndex->tableIndex); + SExprInfo* pExpr = doAddProjectCol(pQueryInfo, pIndex->columnIndex, pIndex->tableIndex); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; @@ -1696,7 +1697,7 @@ static void addProjectQueryCol(SQueryInfo* pQueryInfo, int32_t startPos, SColumn SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, pIndex->columnIndex); char* colName = (pItem->aliasName == NULL) ? pSchema->name : pItem->aliasName; - tstrncpy(pExpr->aliasName, colName, sizeof(pExpr->aliasName)); + tstrncpy(pExpr->base.aliasName, colName, sizeof(pExpr->base.aliasName)); SColumnList ids = {0}; ids.num = 1; @@ -1707,15 +1708,15 @@ static void addProjectQueryCol(SQueryInfo* pQueryInfo, int32_t startPos, SColumn ids.num = 0; } - insertResultField(pQueryInfo, startPos, &ids, pExpr->resBytes, (int8_t)pExpr->resType, pExpr->aliasName, pExpr); + insertResultField(pQueryInfo, startPos, &ids, pExpr->base.resBytes, (int8_t)pExpr->base.resType, pExpr->base.aliasName, pExpr); } static void addPrimaryTsColIntoResult(SQueryInfo* pQueryInfo) { // primary timestamp column has been added already size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { return; } } @@ -1753,7 +1754,7 @@ void genUdfList(SArray* pUdfInfo, tSqlExpr *pNode) { if (pNode == NULL) { return; } - + if (pNode->type == SQL_NODE_EXPR) { genUdfList(pUdfInfo, pNode->pLeft); genUdfList(pUdfInfo, pNode->pRight); @@ -1767,7 +1768,7 @@ void genUdfList(SArray* pUdfInfo, tSqlExpr *pNode) { info.name = strndup(pNode->operand.z, pNode->operand.n); int32_t functionId = (int32_t)taosArrayGetSize(pUdfInfo) * (-1) - 1; info.functionId = functionId; - + taosArrayPush(pUdfInfo, &info); } } @@ -1782,7 +1783,7 @@ static int32_t checkForUdf(SSqlObj* pSql, SArray* pSelection) { pCmd->pUdfInfo = taosArrayInit(4, sizeof(struct SUdfInfo)); size_t nExpr = taosArrayGetSize(pSelection); - + for (int32_t i = 0; i < nExpr; ++i) { tSqlExprItem* pItem = taosArrayGet(pSelection, i); @@ -1811,25 +1812,30 @@ static SUdfInfo* isValidUdf(SArray* pUdfInfo, const char* name, int32_t len) { return NULL; } -int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, SArray* pSelectList, bool isSTable, bool joinQuery, bool timeWindowQuery) { - assert(pSelectList != NULL && pCmd != NULL); +int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelNodeList, bool isSTable, bool joinQuery, + bool timeWindowQuery) { + assert(pSelNodeList != NULL && pCmd != NULL); + const char* msg1 = "too many items in selection clause"; const char* msg2 = "functions or others can not be mixed up"; const char* msg3 = "not support query expression"; + const char* msg4 = "only support distinct one tag"; const char* msg5 = "invalid function name"; - const char* msg6 = "only support distinct one tag"; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex); + // too many result columns not support order by in query + if (taosArrayGetSize(pSelNodeList) > TSDB_MAX_COLUMNS) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + } if (pQueryInfo->colList == NULL) { pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES); } bool hasDistinct = false; - size_t numOfExpr = taosArrayGetSize(pSelectList); + size_t numOfExpr = taosArrayGetSize(pSelNodeList); for (int32_t i = 0; i < numOfExpr; ++i) { int32_t outputIndex = (int32_t)tscSqlExprNumOfExprs(pQueryInfo); - tSqlExprItem* pItem = taosArrayGet(pSelectList, i); + tSqlExprItem* pItem = taosArrayGet(pSelNodeList, i); if (hasDistinct == false) { hasDistinct = (pItem->distinct == true); @@ -1858,7 +1864,7 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, SArray* pSelectLis return TSDB_CODE_TSC_INVALID_SQL; } } else if (type == SQL_NODE_EXPR) { - int32_t code = handleArithmeticExpr(pCmd, clauseIndex, i, pItem); + int32_t code = handleArithmeticExpr(pCmd, pQueryInfo, i, pItem); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -1867,13 +1873,13 @@ 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); } } if (hasDistinct == true) { if (!isValidDistinctSql(pQueryInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); } pQueryInfo->distinctTag = true; } @@ -1891,29 +1897,30 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, SArray* pSelectLis return TSDB_CODE_SUCCESS; } -int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes, - int8_t type, char* fieldName, SSqlExpr* pSqlExpr) { - - for (int32_t i = 0; i < pIdList->num; ++i) { - int32_t tableId = pIdList->ids[i].tableIndex; - STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[tableId]; - - int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta); - if (pIdList->ids[i].columnIndex >= numOfCols) { +int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pColList, int16_t bytes, + int8_t type, char* fieldName, SExprInfo* pSqlExpr) { + for (int32_t i = 0; i < pColList->num; ++i) { + int32_t tableIndex = pColList->ids[i].tableIndex; + STableMeta* pTableMeta = pQueryInfo->pTableMetaInfo[tableIndex]->pTableMeta; + + int32_t numOfCols = tscGetNumOfColumns(pTableMeta); + if (pColList->ids[i].columnIndex >= numOfCols) { continue; } - - tscColumnListInsert(pQueryInfo->colList, &(pIdList->ids[i])); + + uint64_t uid = pTableMeta->id.uid; + SSchema* pSchema = tscGetTableSchema(pTableMeta); + tscColumnListInsert(pQueryInfo->colList, pColList->ids[i].columnIndex, uid, &pSchema[pColList->ids[i].columnIndex]); } TAOS_FIELD f = tscCreateField(type, fieldName, bytes); SInternalField* pInfo = tscFieldInfoInsert(&pQueryInfo->fieldsInfo, outputIndex, &f); - pInfo->pSqlExpr = pSqlExpr; + pInfo->pExpr = pSqlExpr; return TSDB_CODE_SUCCESS; } -SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tableIndex) { +SExprInfo* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tableIndex) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex); STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; int32_t numOfCols = tscGetNumOfColumns(pTableMeta); @@ -1925,7 +1932,7 @@ SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tabl if (functionId == TSDB_FUNC_TAGPRJ) { index.columnIndex = colIndex - tscGetNumOfColumns(pTableMeta); - tscColumnListInsert(pTableMetaInfo->tagColList, &index); + tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pSchema); } else { index.columnIndex = colIndex; } @@ -1935,26 +1942,26 @@ SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t colIndex, int32_t tabl (functionId == TSDB_FUNC_TAGPRJ)); } -SSqlExpr* tscAddFuncInSelectClause(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId, +SExprInfo* tscAddFuncInSelectClause(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId, SColumnIndex* pIndex, SSchema* pColSchema, int16_t flag) { int16_t colId = getNewResColId(pQueryInfo); - SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, outputColIndex, functionId, pIndex, pColSchema->type, + SExprInfo* pExpr = tscSqlExprInsert(pQueryInfo, outputColIndex, functionId, pIndex, pColSchema->type, pColSchema->bytes, colId, pColSchema->bytes, TSDB_COL_IS_TAG(flag)); - tstrncpy(pExpr->aliasName, pColSchema->name, sizeof(pExpr->aliasName)); + tstrncpy(pExpr->base.aliasName, pColSchema->name, sizeof(pExpr->base.aliasName)); - SColumnList ids = getColumnList(1, pIndex->tableIndex, pIndex->columnIndex); + SColumnList ids = createColumnList(1, pIndex->tableIndex, pIndex->columnIndex); if (TSDB_COL_IS_TAG(flag)) { ids.num = 0; } insertResultField(pQueryInfo, outputColIndex, &ids, pColSchema->bytes, pColSchema->type, pColSchema->name, pExpr); - pExpr->colInfo.flag = flag; + pExpr->base.colInfo.flag = flag; STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pIndex->tableIndex); if (TSDB_COL_IS_TAG(flag)) { - tscColumnListInsert(pTableMetaInfo->tagColList, pIndex); + tscColumnListInsert(pTableMetaInfo->tagColList, pIndex->columnIndex, pTableMetaInfo->pTableMeta->id.uid, pColSchema); } return pExpr; @@ -1976,8 +1983,8 @@ static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColum } for (int32_t j = 0; j < numOfTotalColumns; ++j) { - SSqlExpr* pExpr = doAddProjectCol(pQueryInfo, j, pIndex->tableIndex); - tstrncpy(pExpr->aliasName, pSchema[j].name, sizeof(pExpr->aliasName)); + SExprInfo* pExpr = doAddProjectCol(pQueryInfo, j, pIndex->tableIndex); + tstrncpy(pExpr->base.aliasName, pSchema[j].name, sizeof(pExpr->base.aliasName)); pIndex->columnIndex = j; SColumnList ids = {0}; @@ -2017,7 +2024,10 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t } // add the primary timestamp column even though it is not required by user - tscInsertPrimaryTsSourceColumn(pQueryInfo, &index); + STableMeta* pTableMeta = pQueryInfo->pTableMetaInfo[index.tableIndex]->pTableMeta; + if (pTableMeta->tableType != TSDB_TEMP_TABLE) { + tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMeta->id.uid); + } } else if (optr == TK_STRING || optr == TK_INTEGER || optr == TK_FLOAT) { // simple column projection query SColumnIndex index = COLUMN_INDEX_INITIALIZER; @@ -2026,12 +2036,12 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t index.tableIndex = 0; SSchema colSchema = tGetUserSpecifiedColumnSchema(&pItem->pNode->value, &pItem->pNode->token, pItem->aliasName); - SSqlExpr* pExpr = + SExprInfo* pExpr = tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_PRJ, &index, &colSchema, TSDB_COL_UDC); // NOTE: the first parameter is reserved for the tag column id during join query process. - pExpr->numOfParams = 2; - tVariantAssign(&pExpr->param[1], &pItem->pNode->value); + pExpr->base.numOfParams = 2; + tVariantAssign(&pExpr->base.param[1], &pItem->pNode->value); } else if (optr == TK_ID) { SColumnIndex index = COLUMN_INDEX_INITIALIZER; @@ -2058,7 +2068,8 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t } // add the primary timestamp column even though it is not required by user - tscInsertPrimaryTsSourceColumn(pQueryInfo, &index); + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); + tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMetaInfo->pTableMeta->id.uid); } else { return TSDB_CODE_TSC_INVALID_SQL; } @@ -2088,30 +2099,30 @@ static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS bytes = pSchema->bytes; } - SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionID, pColIndex, type, bytes, getNewResColId(pQueryInfo), bytes, false); - tstrncpy(pExpr->aliasName, name, tListLen(pExpr->aliasName)); + SExprInfo* pExpr = tscSqlExprAppend(pQueryInfo, functionID, pColIndex, type, bytes, getNewResColId(pQueryInfo), bytes, false); + tstrncpy(pExpr->base.aliasName, name, tListLen(pExpr->base.aliasName)); if (cvtFunc.originFuncId == TSDB_FUNC_LAST_ROW && cvtFunc.originFuncId != functionID) { - pExpr->colInfo.flag |= TSDB_COL_NULL; + pExpr->base.colInfo.flag |= TSDB_COL_NULL; } // set reverse order scan data blocks for last query if (functionID == TSDB_FUNC_LAST) { - pExpr->numOfParams = 1; - pExpr->param[0].i64 = TSDB_ORDER_DESC; - pExpr->param[0].nType = TSDB_DATA_TYPE_INT; + pExpr->base.numOfParams = 1; + pExpr->base.param[0].i64 = TSDB_ORDER_DESC; + pExpr->base.param[0].nType = TSDB_DATA_TYPE_INT; } // for all queries, the timestamp column needs to be loaded - SColumnIndex index = {.tableIndex = pColIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX}; - tscColumnListInsert(pQueryInfo->colList, &index); + SSchema s = {.colId = PRIMARYKEY_TIMESTAMP_COL_INDEX, .bytes = TSDB_KEYSIZE, .type = TSDB_DATA_TYPE_TIMESTAMP,}; + tscColumnListInsert(pQueryInfo->colList, PRIMARYKEY_TIMESTAMP_COL_INDEX, pExpr->base.uid, &s); // if it is not in the final result, do not add it - SColumnList ids = getColumnList(1, pColIndex->tableIndex, pColIndex->columnIndex); + SColumnList ids = createColumnList(1, pColIndex->tableIndex, pColIndex->columnIndex); if (finalResult) { - insertResultField(pQueryInfo, resColIdx, &ids, bytes, (int8_t)type, pExpr->aliasName, pExpr); + insertResultField(pQueryInfo, resColIdx, &ids, bytes, (int8_t)type, pExpr->base.aliasName, pExpr); } else { - tscColumnListInsert(pQueryInfo->colList, &(ids.ids[0])); + tscColumnListInsert(pQueryInfo->colList, ids.ids[0].columnIndex, pExpr->base.uid, pSchema); } return TSDB_CODE_SUCCESS; @@ -2144,14 +2155,14 @@ static void updateLastScanOrderIfNeeded(SQueryInfo* pQueryInfo) { if (pQueryInfo->sessionWindow.gap > 0 || tscGroupbyColumn(pQueryInfo)) { size_t numOfExpr = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfExpr; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId != TSDB_FUNC_LAST && pExpr->functionId != TSDB_FUNC_LAST_DST) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId != TSDB_FUNC_LAST && pExpr->base.functionId != TSDB_FUNC_LAST_DST) { continue; } - pExpr->numOfParams = 1; - pExpr->param->i64 = TSDB_ORDER_ASC; - pExpr->param->nType = TSDB_DATA_TYPE_INT; + pExpr->base.numOfParams = 1; + pExpr->base.param->i64 = TSDB_ORDER_ASC; + pExpr->base.param->nType = TSDB_DATA_TYPE_INT; } } } @@ -2169,7 +2180,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col const char* msg7 = "normal table can not apply this function"; const char* msg8 = "multi-columns selection does not support alias column name"; const char* msg9 = "invalid function"; - const char* msg10 = "diff can no be applied to unsigned numeric type"; +// const char* msg10 = "diff can no be applied to unsigned numeric type"; switch (functionId) { case TSDB_FUNC_COUNT: { @@ -2178,7 +2189,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); } - SSqlExpr* pExpr = NULL; + SExprInfo* pExpr = NULL; SColumnIndex index = COLUMN_INDEX_INITIALIZER; if (pItem->pNode->pParam != NULL) { @@ -2188,7 +2199,8 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col if ((pToken->z == NULL || pToken->n == 0) && (TK_INTEGER != sqlOptr)) /*select count(1) from table*/ { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); - } + } + if (sqlOptr == TK_ALL) { // select table.* // check if the table name is valid or not @@ -2242,22 +2254,24 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName)); - getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1); + memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName)); + getColumnName(pItem, pExpr->base.aliasName, sizeof(pExpr->base.aliasName) - 1); - SColumnList ids = getColumnList(1, index.tableIndex, index.columnIndex); + SColumnList list = createColumnList(1, index.tableIndex, index.columnIndex); if (finalResult) { int32_t numOfOutput = tscNumOfFields(pQueryInfo); - insertResultField(pQueryInfo, numOfOutput, &ids, sizeof(int64_t), TSDB_DATA_TYPE_BIGINT, pExpr->aliasName, pExpr); + insertResultField(pQueryInfo, numOfOutput, &list, sizeof(int64_t), TSDB_DATA_TYPE_BIGINT, pExpr->base.aliasName, pExpr); } else { - for (int32_t i = 0; i < ids.num; ++i) { - tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i])); + for (int32_t i = 0; i < list.num; ++i) { + SSchema* ps = tscGetTableSchema(pTableMetaInfo->pTableMeta); + tscColumnListInsert(pQueryInfo->colList, list.ids[i].columnIndex, pTableMetaInfo->pTableMeta->id.uid, + &ps[list.ids[i].columnIndex]); } } // the time stamp may be always needed if (index.tableIndex < tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { - tscInsertPrimaryTsSourceColumn(pQueryInfo, &index); + tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMetaInfo->pTableMeta->id.uid); } return TSDB_CODE_SUCCESS; @@ -2300,12 +2314,11 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col // 2. check if sql function can be applied on this column data type pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); - int16_t colType = pSchema->type; - if (!IS_NUMERIC_TYPE(colType)) { + if (!IS_NUMERIC_TYPE(pSchema->type)) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); - } else if (IS_UNSIGNED_NUMERIC_TYPE(colType) && functionId == TSDB_FUNC_DIFF) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10); + } else if (IS_UNSIGNED_NUMERIC_TYPE(pSchema->type) && functionId == TSDB_FUNC_DIFF) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg9); } int16_t resultType = 0; @@ -2321,10 +2334,10 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col if (functionId == TSDB_FUNC_DIFF) { colIndex += 1; SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0}; - SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, + SExprInfo* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(pQueryInfo), TSDB_KEYSIZE, false); - SColumnList ids = getColumnList(1, 0, 0); + SColumnList ids = createColumnList(1, 0, 0); insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS_DUMMY].name, pExpr); } @@ -2333,7 +2346,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); } - SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pQueryInfo), resultSize, false); + SExprInfo* pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pQueryInfo), resultSize, false); if (functionId == TSDB_FUNC_LEASTSQR) { /* set the leastsquares parameters */ @@ -2342,33 +2355,31 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col return TSDB_CODE_TSC_INVALID_SQL; } - addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES); + addExprParams(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES); memset(val, 0, tListLen(val)); if (tVariantDump(&pParamElem[2].pNode->value, val, TSDB_DATA_TYPE_DOUBLE, true) < 0) { return TSDB_CODE_TSC_INVALID_SQL; } - addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double)); + addExprParams(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double)); } - SColumnList ids = {0}; - ids.num = 1; - ids.ids[0] = index; - - memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName)); - getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1); - + SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex); + + memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName)); + getColumnName(pItem, pExpr->base.aliasName, sizeof(pExpr->base.aliasName) - 1); + if (finalResult) { int32_t numOfOutput = tscNumOfFields(pQueryInfo); - insertResultField(pQueryInfo, numOfOutput, &ids, pExpr->resBytes, (int32_t)pExpr->resType, pExpr->aliasName, pExpr); + insertResultField(pQueryInfo, numOfOutput, &ids, pExpr->base.resBytes, (int32_t)pExpr->base.resType, + pExpr->base.aliasName, pExpr); } else { - for (int32_t i = 0; i < ids.num; ++i) { - tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i])); - } + assert(ids.num == 1); + tscColumnListInsert(pQueryInfo->colList, ids.ids[0].columnIndex, pExpr->base.uid, pSchema); } - tscInsertPrimaryTsSourceColumn(pQueryInfo, &index); + tscInsertPrimaryTsSourceColumn(pQueryInfo, pExpr->base.uid); return TSDB_CODE_SUCCESS; } case TSDB_FUNC_FIRST: @@ -2505,7 +2516,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta); + SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); // functions can not be applied to tags if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) { @@ -2513,8 +2524,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } // 2. valid the column type - int16_t colType = pSchema[index.columnIndex].type; - if (!IS_NUMERIC_TYPE(colType)) { + if (!IS_NUMERIC_TYPE(pSchema->type)) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } @@ -2525,12 +2535,12 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col tVariant* pVariant = &pParamElem[1].pNode->value; - int8_t resultType = pSchema[index.columnIndex].type; - int16_t resultSize = pSchema[index.columnIndex].bytes; + int8_t resultType = pSchema->type; + int16_t resultSize = pSchema->bytes; - char val[8] = {0}; - SSqlExpr* pExpr = NULL; - + char val[8] = {0}; + + SExprInfo* pExpr = NULL; if (functionId == TSDB_FUNC_PERCT || functionId == TSDB_FUNC_APERCT) { tVariantDump(pVariant, val, TSDB_DATA_TYPE_DOUBLE, true); @@ -2547,11 +2557,11 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col * for dp = 0, it is actually min, * for dp = 100, it is max, */ - tscInsertPrimaryTsSourceColumn(pQueryInfo, &index); + tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMetaInfo->pTableMeta->id.uid); colIndex += 1; // the first column is ts pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pQueryInfo), resultSize, false); - addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double)); + addExprParams(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double)); } else { tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true); @@ -2565,29 +2575,30 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col SColumnIndex index1 = {index.tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX}; pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(pQueryInfo), TSDB_KEYSIZE, false); - tstrncpy(pExpr->aliasName, aAggs[TSDB_FUNC_TS].name, sizeof(pExpr->aliasName)); + tstrncpy(pExpr->base.aliasName, aAggs[TSDB_FUNC_TS].name, sizeof(pExpr->base.aliasName)); const int32_t TS_COLUMN_INDEX = PRIMARYKEY_TIMESTAMP_COL_INDEX; - SColumnList ids = getColumnList(1, index.tableIndex, TS_COLUMN_INDEX); + SColumnList ids = createColumnList(1, index.tableIndex, TS_COLUMN_INDEX); insertResultField(pQueryInfo, TS_COLUMN_INDEX, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS].name, pExpr); colIndex += 1; // the first column is ts pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pQueryInfo), resultSize, false); - addExprParams(pExpr, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t)); + addExprParams(&pExpr->base, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t)); } - memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName)); - getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1); - - SColumnList ids = getColumnList(1, index.tableIndex, index.columnIndex); + memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName)); + getColumnName(pItem, pExpr->base.aliasName, sizeof(pExpr->base.aliasName) - 1); + + // todo refactor: tscColumnListInsert part + SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex); + if (finalResult) { - insertResultField(pQueryInfo, colIndex, &ids, resultSize, resultType, pExpr->aliasName, pExpr); + insertResultField(pQueryInfo, colIndex, &ids, resultSize, resultType, pExpr->base.aliasName, pExpr); } else { - for (int32_t i = 0; i < ids.num; ++i) { - tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i])); - } + assert(ids.num == 1); + tscColumnListInsert(pQueryInfo->colList, ids.ids[0].columnIndex, pExpr->base.uid, pSchema); } return TSDB_CODE_SUCCESS; @@ -2637,9 +2648,10 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } - tscColumnListInsert(pTableMetaInfo->tagColList, &index); + tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMetaInfo->pTableMeta->id.uid, + &pSchema[index.columnIndex]); SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); - + SSchema s = {0}; if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { s = *tGetTbnameColumnSchema(); @@ -2679,10 +2691,10 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col s.bytes = bytes; s.type = (uint8_t)resType; - SSqlExpr* pExpr = tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_BLKINFO, &index, &s, TSDB_COL_TAG); - pExpr->numOfParams = 1; - pExpr->param[0].i64 = pTableMetaInfo->pTableMeta->tableInfo.rowSize; - pExpr->param[0].nType = TSDB_DATA_TYPE_BIGINT; + SExprInfo* pExpr = tscAddFuncInSelectClause(pQueryInfo, 0, TSDB_FUNC_BLKINFO, &index, &s, TSDB_COL_TAG); + pExpr->base.numOfParams = 1; + pExpr->base.param[0].i64 = pTableMetaInfo->pTableMeta->tableInfo.rowSize; + pExpr->base.param[0].nType = TSDB_DATA_TYPE_BIGINT; return TSDB_CODE_SUCCESS; } @@ -2719,22 +2731,28 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col int16_t bytes = 0; getResultDataInfo(TSDB_DATA_TYPE_INT, 4, functionId, 0, &resType, &bytes, &inter, 0, false, pUdfInfo); - SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resType, bytes, + SExprInfo* pExpr = tscSqlExprAppend(pQueryInfo, functionId, &index, resType, bytes, getNewResColId(pQueryInfo), inter, false); - memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName)); - getColumnName(pItem, pExpr->aliasName, sizeof(pExpr->aliasName) - 1); + memset(pExpr->base.aliasName, 0, tListLen(pExpr->base.aliasName)); + getColumnName(pItem, pExpr->base.aliasName, sizeof(pExpr->base.aliasName) - 1); - SColumnList ids = getColumnList(1, index.tableIndex, index.columnIndex); + SSchema s = {0}; + s.type = resType; + s.bytes = bytes; + s.colId = pExpr->base.colInfo.colId; + + uint64_t uid = pTableMetaInfo->pTableMeta->id.uid; + SColumnList ids = createColumnList(1, index.tableIndex, index.columnIndex); if (finalResult) { - insertResultField(pQueryInfo, colIndex, &ids, pUdfInfo->resBytes, pUdfInfo->resType, pExpr->aliasName, pExpr); + insertResultField(pQueryInfo, colIndex, &ids, pUdfInfo->resBytes, pUdfInfo->resType, pExpr->base.aliasName, pExpr); } else { for (int32_t i = 0; i < ids.num; ++i) { - tscColumnListInsert(pQueryInfo->colList, &(ids.ids[i])); + tscColumnListInsert(pQueryInfo->colList, index.columnIndex, uid, &s); } } - tscInsertPrimaryTsSourceColumn(pQueryInfo, &index); + tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMetaInfo->pTableMeta->id.uid); return TSDB_CODE_SUCCESS; } } @@ -2743,7 +2761,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } // todo refactor -static SColumnList getColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex) { +static SColumnList createColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex) { assert(num == 1 && tableIndex >= 0); SColumnList columnList = {0}; @@ -3043,23 +3061,23 @@ int32_t tscTansformFuncForSTableQuery(SQueryInfo* pQueryInfo) { size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t k = 0; k < size; ++k) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, k); - int16_t functionId = aAggs[pExpr->functionId].stableFuncId; + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, k); + int16_t functionId = aAggs[pExpr->base.functionId].stableFuncId; - int32_t colIndex = pExpr->colInfo.colIndex; + int32_t colIndex = pExpr->base.colInfo.colIndex; SSchema* pSrcSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, colIndex); if ((functionId >= TSDB_FUNC_SUM && functionId <= TSDB_FUNC_TWA) || (functionId >= TSDB_FUNC_FIRST_DST && functionId <= TSDB_FUNC_STDDEV_DST) || (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_AVG_IRATE)) { - if (getResultDataInfo(pSrcSchema->type, pSrcSchema->bytes, functionId, (int32_t)pExpr->param[0].i64, &type, &bytes, + if (getResultDataInfo(pSrcSchema->type, pSrcSchema->bytes, functionId, (int32_t)pExpr->base.param[0].i64, &type, &bytes, &interBytes, 0, true, NULL) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_SQL; } - tscSqlExprUpdate(pQueryInfo, k, functionId, pExpr->colInfo.colIndex, TSDB_DATA_TYPE_BINARY, bytes); + tscSqlExprUpdate(pQueryInfo, k, functionId, pExpr->base.colInfo.colIndex, TSDB_DATA_TYPE_BINARY, bytes); // todo refactor - pExpr->interBytes = interBytes; + pExpr->base.interBytes = interBytes; } } @@ -3076,18 +3094,18 @@ void tscRestoreFuncForSTableQuery(SQueryInfo* pQueryInfo) { size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIndex); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->base.colInfo.colIndex); // the final result size and type in the same as query on single table. // so here, set the flag to be false; int32_t inter = 0; - int32_t functionId = pExpr->functionId; + int32_t functionId = pExpr->base.functionId; if (functionId < 0) { continue; } - + if (functionId >= TSDB_FUNC_TS && functionId <= TSDB_FUNC_DIFF) { continue; } @@ -3099,9 +3117,9 @@ void tscRestoreFuncForSTableQuery(SQueryInfo* pQueryInfo) { } else if (functionId == TSDB_FUNC_STDDEV_DST) { functionId = TSDB_FUNC_STDDEV; } - - getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &pExpr->resType, &pExpr->resBytes, - &inter, 0, false, NULL); + + getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &pExpr->base.resType, &pExpr->base.resBytes, &inter, + 0, false, NULL); } } @@ -3113,11 +3131,11 @@ bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) // filter sql function not supported by metric query yet. size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId; + int32_t functionId = tscSqlExprGet(pQueryInfo, i)->base.functionId; if (functionId < 0) { continue; } - + if ((aAggs[functionId].status & TSDB_FUNCSTATE_STABLE) == 0) { invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); return true; @@ -3168,7 +3186,7 @@ static bool functionCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, bool int32_t scalarUdf = 0; int32_t prjNum = 0; int32_t aggNum = 0; - + size_t numOfExpr = tscSqlExprNumOfExprs(pQueryInfo); assert(numOfExpr > 0); @@ -3179,20 +3197,19 @@ static bool functionCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, bool size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = startIdx; i < size; ++i) { - SSqlExpr* pExpr1 = tscSqlExprGet(pQueryInfo, i); - - int16_t functionId = pExpr1->functionId; + SExprInfo* pExpr1 = tscSqlExprGet(pQueryInfo, i); + int16_t functionId = pExpr1->base.functionId; if (functionId < 0) { SUdfInfo* pUdfInfo = taosArrayGet(pCmd->pUdfInfo, -1 * functionId - 1); pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE ? ++aggUdf : ++scalarUdf; continue; } - + if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY) { ++prjNum; - + continue; } @@ -3200,7 +3217,7 @@ static bool functionCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, bool ++prjNum; } - if (functionId == TSDB_FUNC_PRJ && (pExpr1->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX || TSDB_COL_IS_UD_COL(pExpr1->colInfo.flag))) { + if (functionId == TSDB_FUNC_PRJ && (pExpr1->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX || TSDB_COL_IS_UD_COL(pExpr1->base.colInfo.flag))) { continue; } @@ -3236,7 +3253,7 @@ static bool functionCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, bool return true; } -int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd) { +int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd) { const char* msg1 = "too many columns in group by clause"; const char* msg2 = "invalid column name in group by clause"; const char* msg3 = "columns from one table allowed as group by columns"; @@ -3322,14 +3339,14 @@ int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd) taosArrayPush(pGroupExpr->columnInfo, &colIndex); index.columnIndex = relIndex; - tscColumnListInsert(pTableMetaInfo->tagColList, &index); + tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pSchema); } else { // check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP || pSchema->type == TSDB_DATA_TYPE_FLOAT || pSchema->type == TSDB_DATA_TYPE_DOUBLE) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8); } - tscColumnListInsert(pQueryInfo->colList, &index); + tscColumnListInsert(pQueryInfo->colList, index.columnIndex, pTableMeta->id.uid, pSchema); SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId }; taosArrayPush(pGroupExpr->columnInfo, &colIndex); @@ -3346,33 +3363,29 @@ int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd) } -static SColumnFilterInfo* addColumnFilterInfo(SColumn* pColumn) { - if (pColumn == NULL) { - return NULL; - } +static SColumnFilterInfo* addColumnFilterInfo(SColumnFilterList* filterList) { + int32_t size = (filterList->numOfFilters) + 1; - int32_t size = pColumn->numOfFilters + 1; - - char* tmp = (char*) realloc((void*)(pColumn->filterInfo), sizeof(SColumnFilterInfo) * (size)); + char* tmp = (char*) realloc((void*)(filterList->filterInfo), sizeof(SColumnFilterInfo) * (size)); if (tmp != NULL) { - pColumn->filterInfo = (SColumnFilterInfo*)tmp; + filterList->filterInfo = (SColumnFilterInfo*)tmp; } else { return NULL; } - pColumn->numOfFilters++; + filterList->numOfFilters = size; - SColumnFilterInfo* pColFilterInfo = &pColumn->filterInfo[pColumn->numOfFilters - 1]; + SColumnFilterInfo* pColFilterInfo = &(filterList->filterInfo[size - 1]); memset(pColFilterInfo, 0, sizeof(SColumnFilterInfo)); return pColFilterInfo; } -static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SColumnFilterInfo* pColumnFilter, +static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t timePrecision, SColumnFilterInfo* pColumnFilter, int16_t colType, tSqlExpr* pExpr) { const char* msg = "not supported filter condition"; - tSqlExpr* pRight = pExpr->pRight; + tSqlExpr *pRight = pExpr->pRight; if (colType >= TSDB_DATA_TYPE_TINYINT && colType <= TSDB_DATA_TYPE_BIGINT) { colType = TSDB_DATA_TYPE_BIGINT; @@ -3383,6 +3396,10 @@ static int32_t doExtractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, if (TSDB_CODE_SUCCESS != retVal) { return retVal; } + } else if ((colType == TSDB_DATA_TYPE_TIMESTAMP) && (TSDB_DATA_TYPE_BIGINT == pRight->value.nType)) { + if ((timePrecision == TSDB_TIME_PRECISION_MILLI) && (pRight->flags & (1 << EXPR_FLAG_US_TIMESTAMP))) { + pRight->value.i64 /= 1000; + } } int32_t retVal = TSDB_CODE_SUCCESS; @@ -3524,7 +3541,7 @@ static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SC const char* msg2 = "binary column not support this operator"; const char* msg3 = "bool column not support this operator"; - SColumn* pColumn = tscColumnListInsert(pQueryInfo->colList, pIndex); + SColumn* pColumn = tscColumnListInsert(pQueryInfo->colList, pIndex->columnIndex, pTableMeta->id.uid, pSchema); SColumnFilterInfo* pColFilter = NULL; /* @@ -3533,10 +3550,10 @@ static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SC */ if (sqlOptr == TK_AND) { // this is a new filter condition on this column - if (pColumn->numOfFilters == 0) { - pColFilter = addColumnFilterInfo(pColumn); + if (pColumn->info.flist.numOfFilters == 0) { + pColFilter = addColumnFilterInfo(&pColumn->info.flist); } else { // update the existed column filter information, find the filter info here - pColFilter = &pColumn->filterInfo[0]; + pColFilter = &pColumn->info.flist.filterInfo[0]; } if (pColFilter == NULL) { @@ -3544,7 +3561,7 @@ static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SC } } else if (sqlOptr == TK_OR) { // TODO fixme: failed to invalid the filter expression: "col1 = 1 OR col2 = 2" - pColFilter = addColumnFilterInfo(pColumn); + pColFilter = addColumnFilterInfo(&pColumn->info.flist); if (pColFilter == NULL) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } @@ -3577,11 +3594,11 @@ static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SC } } - pColumn->colIndex = *pIndex; + pColumn->columnIndex = pIndex->columnIndex; + pColumn->tableUid = pTableMeta->id.uid; - int16_t colType = pSchema->type; - - return doExtractColumnFilterInfo(pCmd, pQueryInfo, pColFilter, colType, pExpr); + STableComInfo tinfo = tscGetTableInfo(pTableMeta); + return doExtractColumnFilterInfo(pCmd, pQueryInfo, tinfo.precision, pColFilter, pSchema->type, pExpr); } static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pTableCond, SStringBuilder* sb) { @@ -3643,9 +3660,9 @@ static int32_t getColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSq static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr) { int32_t code = 0; const char* msg1 = "timestamp required for join tables"; + const char* msg2 = "only support one join tag for each table"; const char* msg3 = "type of join columns must be identical"; const char* msg4 = "invalid column name in join condition"; - const char* msg5 = "only support one join tag for each table"; if (pExpr == NULL) { return TSDB_CODE_SUCCESS; @@ -3656,7 +3673,7 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS if (code) { return code; } - + return checkAndSetJoinCondInfo(pCmd, pQueryInfo, pExpr->pRight); } @@ -3674,23 +3691,25 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS if (*leftNode == NULL) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } - + (*leftNode)->uid = pTableMetaInfo->pTableMeta->id.uid; (*leftNode)->tagColId = pTagSchema1->colId; if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { + STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; + index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); - if (!tscColumnExists(pTableMetaInfo->tagColList, &index)) { - tscColumnListInsert(pTableMetaInfo->tagColList, &index); + if (!tscColumnExists(pTableMetaInfo->tagColList, index.columnIndex, pTableMetaInfo->pTableMeta->id.uid)) { + tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pTagSchema1); + if (taosArrayGetSize(pTableMetaInfo->tagColList) > 1) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); } } } int16_t leftIdx = index.tableIndex; - index = (SColumnIndex)COLUMN_INDEX_INITIALIZER; if (getColumnIndexByName(pCmd, &pExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); @@ -3710,11 +3729,13 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS (*rightNode)->tagColId = pTagSchema2->colId; if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); - if (!tscColumnExists(pTableMetaInfo->tagColList, &index)) { - tscColumnListInsert(pTableMetaInfo->tagColList, &index); + STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; + index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMeta); + if (!tscColumnExists(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid)) { + + tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->id.uid, pTagSchema2); if (taosArrayGetSize(pTableMetaInfo->tagColList) > 1) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); } } } @@ -3728,16 +3749,16 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS if ((*leftNode)->tagJoin == NULL) { (*leftNode)->tagJoin = taosArrayInit(2, sizeof(int16_t)); } - + if ((*rightNode)->tagJoin == NULL) { (*rightNode)->tagJoin = taosArrayInit(2, sizeof(int16_t)); - } - + } + taosArrayPush((*leftNode)->tagJoin, &rightIdx); taosArrayPush((*rightNode)->tagJoin, &leftIdx); - + pQueryInfo->tagCond.joinInfo.hasJoin = true; - + return TSDB_CODE_SUCCESS; } @@ -3806,15 +3827,15 @@ static int32_t validateSQLExpr(SSqlCmd* pCmd, tSqlExpr* pExpr, SQueryInfo* pQuer // Not supported data type in arithmetic expression uint64_t id = -1; for(int32_t i = 0; i < inc; ++i) { - SSqlExpr* p1 = tscSqlExprGet(pQueryInfo, i + outputIndex); - int16_t t = p1->resType; + SExprInfo* p1 = tscSqlExprGet(pQueryInfo, i + outputIndex); + int16_t t = p1->base.resType; if (t == TSDB_DATA_TYPE_BINARY || t == TSDB_DATA_TYPE_NCHAR || t == TSDB_DATA_TYPE_BOOL || t == TSDB_DATA_TYPE_TIMESTAMP) { return TSDB_CODE_TSC_INVALID_SQL; } if (i == 0) { - id = p1->uid; - } else if (id != p1->uid) { + id = p1->base.uid; + } else if (id != p1->base.uid) { return TSDB_CODE_TSC_INVALID_SQL; } } @@ -4095,7 +4116,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql return TSDB_CODE_TSC_OUT_OF_MEMORY; } } - + int16_t leftIdx = index.tableIndex; if (getColumnIndexByName(pCmd, &pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { @@ -4113,20 +4134,20 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql return TSDB_CODE_TSC_OUT_OF_MEMORY; } } - + int16_t rightIdx = index.tableIndex; if ((*leftNode)->tsJoin == NULL) { (*leftNode)->tsJoin = taosArrayInit(2, sizeof(int16_t)); } - + if ((*rightNode)->tsJoin == NULL) { (*rightNode)->tsJoin = taosArrayInit(2, sizeof(int16_t)); - } - + } + taosArrayPush((*leftNode)->tsJoin, &rightIdx); taosArrayPush((*rightNode)->tsJoin, &leftIdx); - + /* * to release expression, e.g., m1.ts = m2.ts, * since this expression is used to set the join query type @@ -4204,6 +4225,10 @@ int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr const char* msg1 = "query condition between different columns must use 'AND'"; + if ((*pExpr)->flags & (1 << EXPR_FLAG_TS_ERROR)) { + return TSDB_CODE_TSC_INVALID_SQL; + } + tSqlExpr* pLeft = (*pExpr)->pLeft; tSqlExpr* pRight = (*pExpr)->pRight; @@ -4241,6 +4266,14 @@ int32_t getQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr** pExpr exchangeExpr(*pExpr); + if (pLeft->tokenId == TK_ID && pRight->tokenId == TK_TIMESTAMP && (pRight->flags & (1 << EXPR_FLAG_TIMESTAMP_VAR))) { + return TSDB_CODE_TSC_INVALID_SQL; + } + + if ((pLeft->flags & (1 << EXPR_FLAG_TS_ERROR)) || (pRight->flags & (1 << EXPR_FLAG_TS_ERROR))) { + return TSDB_CODE_TSC_INVALID_SQL; + } + return handleExprInQueryCond(pCmd, pQueryInfo, pExpr, pCondExpr, type, parentOptr); } @@ -4374,8 +4407,8 @@ static bool validateFilterExpr(SQueryInfo* pQueryInfo) { for (int32_t i = 0; i < num; ++i) { SColumn* pCol = taosArrayGetP(pColList, i); - for (int32_t j = 0; j < pCol->numOfFilters; ++j) { - SColumnFilterInfo* pColFilter = &pCol->filterInfo[j]; + for (int32_t j = 0; j < pCol->info.flist.numOfFilters; ++j) { + SColumnFilterInfo* pColFilter = &pCol->info.flist.filterInfo[j]; int32_t lowerOptr = pColFilter->lowerRelOptr; int32_t upperOptr = pColFilter->upperRelOptr; @@ -4398,7 +4431,7 @@ static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlE const char* msg0 = "invalid timestamp"; const char* msg1 = "only one time stamp window allowed"; int32_t code = 0; - + if (pExpr == NULL) { return TSDB_CODE_SUCCESS; } @@ -4412,7 +4445,7 @@ static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlE if (code) { return code; } - + return getTimeRangeFromExpr(pCmd, pQueryInfo, pExpr->pRight); } else { SColumnIndex index = COLUMN_INDEX_INITIALIZER; @@ -4502,18 +4535,22 @@ static void doAddJoinTagsColumnsIntoTagList(SSqlCmd* pCmd, SQueryInfo* pQueryInf if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { tscError("%p: invalid column name (left)", pQueryInfo); } + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); - tscColumnListInsert(pTableMetaInfo->tagColList, &index); + + SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); + tscColumnListInsert(pTableMetaInfo->tagColList, &index, &pSchema[index.columnIndex]); if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { tscError("%p: invalid column name (right)", pQueryInfo); } + pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); - index.columnIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); - tscColumnListInsert(pTableMetaInfo->tagColList, &index); + + pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); + tscColumnListInsert(pTableMetaInfo->tagColList, &index, &pSchema[index.columnIndex]); } } */ @@ -4624,7 +4661,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE // TODO: more error handling } END_TRY - // add to source column list + // add to required table column list STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i); int64_t uid = pTableMetaInfo->pTableMeta->id.uid; int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta); @@ -4633,7 +4670,10 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE for(int32_t j = 0; j < num; ++j) { SColIndex* pIndex = taosArrayGet(colList, j); SColumnIndex index = {.tableIndex = i, .columnIndex = pIndex->colIndex - numOfCols}; - tscColumnListInsert(pTableMetaInfo->tagColList, &index); + + SSchema* s = tscGetTableSchema(pTableMetaInfo->pTableMeta); + tscColumnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMetaInfo->pTableMeta->id.uid, + &s[pIndex->colIndex]); } tsSetSTableQueryCond(&pQueryInfo->tagCond, uid, &bw); @@ -4663,10 +4703,10 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE int32_t validateJoinNodes(SQueryInfo* pQueryInfo, SSqlObj* pSql) { const char* msg1 = "timestamp required for join tables"; const char* msg2 = "tag required for join stables"; - + for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { - SJoinNode *node = pQueryInfo->tagCond.joinInfo.joinTables[i]; - + SJoinNode *node = pQueryInfo->tagCond.joinInfo.joinTables[i]; + if (node == NULL || node->tsJoin == NULL || taosArrayGetSize(node->tsJoin) <= 0) { return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg1); } @@ -4675,8 +4715,8 @@ int32_t validateJoinNodes(SQueryInfo* pQueryInfo, SSqlObj* pSql) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { - SJoinNode *node = pQueryInfo->tagCond.joinInfo.joinTables[i]; - + SJoinNode *node = pQueryInfo->tagCond.joinInfo.joinTables[i]; + if (node == NULL || node->tagJoin == NULL || taosArrayGetSize(node->tagJoin) <= 0) { return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg2); } @@ -4688,12 +4728,12 @@ int32_t validateJoinNodes(SQueryInfo* pQueryInfo, SSqlObj* pSql) { void mergeJoinNodesImpl(int8_t* r, int8_t* p, int16_t* tidx, SJoinNode** nodes, int32_t type) { - SJoinNode *node = nodes[*tidx]; + SJoinNode *node = nodes[*tidx]; SArray* arr = (type == 0) ? node->tsJoin : node->tagJoin; size_t size = taosArrayGetSize(arr); p[*tidx] = 1; - + for (int32_t j = 0; j < size; j++) { int16_t* idx = taosArrayGet(arr, j); r[*idx] = 1; @@ -4706,21 +4746,21 @@ void mergeJoinNodesImpl(int8_t* r, int8_t* p, int16_t* tidx, SJoinNode** nodes, int32_t mergeJoinNodes(SQueryInfo* pQueryInfo, SSqlObj* pSql) { const char* msg1 = "not all join tables have same timestamp"; const char* msg2 = "not all join tables have same tag"; - + int8_t r[TSDB_MAX_JOIN_TABLE_NUM] = {0}; int8_t p[TSDB_MAX_JOIN_TABLE_NUM] = {0}; - + for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) { mergeJoinNodesImpl(r, p, &i, pQueryInfo->tagCond.joinInfo.joinTables, 0); - + taosArrayClear(pQueryInfo->tagCond.joinInfo.joinTables[i]->tsJoin); - + for (int32_t j = 0; j < TSDB_MAX_JOIN_TABLE_NUM; ++j) { if (r[j]) { taosArrayPush(pQueryInfo->tagCond.joinInfo.joinTables[i]->tsJoin, &j); } } - + memset(r, 0, sizeof(r)); memset(p, 0, sizeof(p)); } @@ -4728,20 +4768,20 @@ int32_t mergeJoinNodes(SQueryInfo* pQueryInfo, SSqlObj* pSql) { if (taosArrayGetSize(pQueryInfo->tagCond.joinInfo.joinTables[0]->tsJoin) != pQueryInfo->numOfTables) { return invalidSqlErrMsg(tscGetErrorMsgPayload(&pSql->cmd), msg1); } - + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { for (int16_t i = 0; i < pQueryInfo->numOfTables; ++i) { mergeJoinNodesImpl(r, p, &i, pQueryInfo->tagCond.joinInfo.joinTables, 1); - + taosArrayClear(pQueryInfo->tagCond.joinInfo.joinTables[i]->tagJoin); - + for (int32_t j = 0; j < TSDB_MAX_JOIN_TABLE_NUM; ++j) { if (r[j]) { taosArrayPush(pQueryInfo->tagCond.joinInfo.joinTables[i]->tagJoin, &j); } } - + memset(r, 0, sizeof(r)); memset(p, 0, sizeof(p)); } @@ -4756,7 +4796,7 @@ int32_t mergeJoinNodes(SQueryInfo* pQueryInfo, SSqlObj* pSql) { } -int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql) { +int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql) { if (pExpr == NULL) { return TSDB_CODE_SUCCESS; } @@ -4838,7 +4878,7 @@ int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql ret = mergeJoinNodes(pQueryInfo, pSql); if (ret) { goto PARSE_WHERE_EXIT; - } + } } PARSE_WHERE_EXIT: @@ -4967,16 +5007,34 @@ int32_t tsRewriteFieldNameIfNecessary(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { return TSDB_CODE_SUCCESS; } -int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySQL) { - SArray* pFillToken = pQuerySQL->fillType; +int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode) { + SArray* pFillToken = pSqlNode->fillType; + if (pSqlNode->fillType == NULL) { + return TSDB_CODE_SUCCESS; + } + tVariantListItem* pItem = taosArrayGet(pFillToken, 0); const int32_t START_INTERPO_COL_IDX = 1; - const char* msg = "illegal value or data overflow"; const char* msg1 = "value is expected"; const char* msg2 = "invalid fill option"; const char* msg3 = "top/bottom not support fill"; + const char* msg4 = "illegal value or data overflow"; + const char* msg5 = "fill only available for interval query"; + + if ((!isTimeWindowQuery(pQueryInfo)) && (!tscIsPointInterpQuery(pQueryInfo))) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + } + + /* + * fill options are set at the end position, when all columns are set properly + * the columns may be increased due to group by operation + */ + if (checkQueryRangeForFill(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_SQL; + } + if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); @@ -5040,7 +5098,7 @@ int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQ tVariant* p = taosArrayGet(pFillToken, j); int32_t ret = tVariantDump(p, (char*)&pQueryInfo->fillVal[i], pField->type, true); if (ret != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4); } } @@ -5063,8 +5121,8 @@ int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQ size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); for(int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_TOP || pExpr->functionId == TSDB_FUNC_BOTTOM) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId == TSDB_FUNC_TOP || pExpr->base.functionId == TSDB_FUNC_BOTTOM) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); } } @@ -5089,7 +5147,7 @@ static void setDefaultOrderInfo(SQueryInfo* pQueryInfo) { } } -int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySqlNode, SSchema* pSchema) { +int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode, SSchema* pSchema) { const char* msg0 = "only support order by primary timestamp"; const char* msg1 = "invalid column name"; const char* msg2 = "order by primary timestamp or first tag in groupby clause allowed"; @@ -5104,11 +5162,11 @@ int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQueryInfo->order.orderColId = 0; return TSDB_CODE_SUCCESS; } - if (pQuerySqlNode->pSortOrder == NULL) { + if (pSqlNode->pSortOrder == NULL) { return TSDB_CODE_SUCCESS; } - SArray* pSortorder = pQuerySqlNode->pSortOrder; + SArray* pSortorder = pSqlNode->pSortOrder; /* * for table query, there is only one or none order option is allowed, which is the @@ -5176,24 +5234,24 @@ int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* if (orderByTags) { pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); - tVariantListItem* p1 = taosArrayGet(pQuerySqlNode->pSortOrder, 0); + tVariantListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0); pQueryInfo->groupbyExpr.orderType = p1->sortOrder; } else if (isTopBottomQuery(pQueryInfo)) { /* order of top/bottom query in interval is not valid */ - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0); - assert(pExpr->functionId == TSDB_FUNC_TS); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, 0); + assert(pExpr->base.functionId == TSDB_FUNC_TS); pExpr = tscSqlExprGet(pQueryInfo, 1); - if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { + if (pExpr->base.colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); } - tVariantListItem* p1 = taosArrayGet(pQuerySqlNode->pSortOrder, 0); + tVariantListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0); pQueryInfo->order.order = p1->sortOrder; pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId; return TSDB_CODE_SUCCESS; } else { - tVariantListItem* p1 = taosArrayGet(pQuerySqlNode->pSortOrder, 0); + tVariantListItem* p1 = taosArrayGet(pSqlNode->pSortOrder, 0); pQueryInfo->order.order = p1->sortOrder; pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX; @@ -5206,7 +5264,7 @@ int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* } if (s == 2) { - tVariantListItem *pItem = taosArrayGet(pQuerySqlNode->pSortOrder, 0); + tVariantListItem *pItem = taosArrayGet(pSqlNode->pSortOrder, 0); if (orderByTags) { pQueryInfo->groupbyExpr.orderIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta); pQueryInfo->groupbyExpr.orderType = pItem->sortOrder; @@ -5215,7 +5273,7 @@ int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX; } - pItem = taosArrayGet(pQuerySqlNode->pSortOrder, 1); + pItem = taosArrayGet(pSqlNode->pSortOrder, 1); tVariant* pVar2 = &pItem->pVar; SStrToken cname = {pVar2->nLen, pVar2->nType, pVar2->pz}; if (getColumnIndexByName(pCmd, &cname, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { @@ -5242,21 +5300,21 @@ int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* if (isTopBottomQuery(pQueryInfo)) { /* order of top/bottom query in interval is not valid */ - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0); - assert(pExpr->functionId == TSDB_FUNC_TS); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, 0); + assert(pExpr->base.functionId == TSDB_FUNC_TS); pExpr = tscSqlExprGet(pQueryInfo, 1); - if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { + if (pExpr->base.colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); } - tVariantListItem* pItem = taosArrayGet(pQuerySqlNode->pSortOrder, 0); + tVariantListItem* pItem = taosArrayGet(pSqlNode->pSortOrder, 0); pQueryInfo->order.order = pItem->sortOrder; pQueryInfo->order.orderColId = pSchema[index.columnIndex].colId; return TSDB_CODE_SUCCESS; } - tVariantListItem* pItem = taosArrayGet(pQuerySqlNode->pSortOrder, 0); + tVariantListItem* pItem = taosArrayGet(pSqlNode->pSortOrder, 0); pQueryInfo->order.order = pItem->sortOrder; } @@ -5293,7 +5351,7 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { SSqlCmd* pCmd = &pSql->cmd; SAlterTableInfo* pAlterSQL = pInfo->pAlterInfo; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, DEFAULT_TABLE_INDEX); @@ -5557,7 +5615,7 @@ int32_t validateSqlFunctionInStreamSql(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { size_t size = taosArrayGetSize(pQueryInfo->exprList); for (int32_t i = 0; i < size; ++i) { - int32_t functId = tscSqlExprGet(pQueryInfo, i)->functionId; + int32_t functId = tscSqlExprGet(pQueryInfo, i)->base.functionId; if (!IS_STREAM_QUERY_VALID(aAggs[functId].status)) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } @@ -5574,10 +5632,10 @@ int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQu size_t size = taosArrayGetSize(pQueryInfo->exprList); for (int32_t k = 0; k < size; ++k) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, k); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, k); - if (pExpr->functionId < 0) { - SUdfInfo* pUdfInfo = taosArrayGet(pCmd->pUdfInfo, -1 * pExpr->functionId - 1); + if (pExpr->base.functionId < 0) { + SUdfInfo* pUdfInfo = taosArrayGet(pCmd->pUdfInfo, -1 * pExpr->base.functionId - 1); if (pUdfInfo->funcType == TSDB_UDF_TYPE_SCALAR) { isProjectionFunction = true; break; @@ -5585,13 +5643,13 @@ int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQu continue; } } - + // projection query on primary timestamp, the selectivity function needs to be present. - if (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { + if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { bool hasSelectivity = false; for (int32_t j = 0; j < size; ++j) { - SSqlExpr* pEx = tscSqlExprGet(pQueryInfo, j); - if ((aAggs[pEx->functionId].status & TSDB_FUNCSTATE_SELECTIVITY) == TSDB_FUNCSTATE_SELECTIVITY) { + SExprInfo* pEx = tscSqlExprGet(pQueryInfo, j); + if ((aAggs[pEx->base.functionId].status & TSDB_FUNCSTATE_SELECTIVITY) == TSDB_FUNCSTATE_SELECTIVITY) { hasSelectivity = true; break; } @@ -5602,8 +5660,8 @@ int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQu } } - if ((pExpr->functionId == TSDB_FUNC_PRJ && pExpr->numOfParams == 0) || pExpr->functionId == TSDB_FUNC_DIFF || - pExpr->functionId == TSDB_FUNC_ARITHM) { + if ((pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.numOfParams == 0) || pExpr->base.functionId == TSDB_FUNC_DIFF || + pExpr->base.functionId == TSDB_FUNC_ARITHM) { isProjectionFunction = true; break; } @@ -5792,10 +5850,14 @@ bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo) { return true; } - return (pQueryInfo->window.skey == pQueryInfo->window.ekey) && (pQueryInfo->window.skey != 0); + if (pQueryInfo->window.skey == INT64_MIN || pQueryInfo->window.ekey == INT64_MAX) { + return false; + } + + return !(pQueryInfo->window.skey != pQueryInfo->window.ekey && pQueryInfo->interval.interval == 0); } -int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseIndex, SQuerySqlNode* pQuerySqlNode, SSqlObj* pSql) { +int32_t validateLimitNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseIndex, SSqlNode* pSqlNode, SSqlObj* pSql) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); const char* msg0 = "soffset/offset can not be less than 0"; @@ -5803,19 +5865,19 @@ int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseIn const char* msg2 = "slimit/soffset can not apply to projection query"; // handle the limit offset value, validate the limit - pQueryInfo->limit = pQuerySqlNode->limit; + pQueryInfo->limit = pSqlNode->limit; pQueryInfo->clauseLimit = pQueryInfo->limit.limit; - pQueryInfo->slimit = pQuerySqlNode->slimit; + pQueryInfo->slimit = pSqlNode->slimit; - tscDebug("%p limit:%" PRId64 ", offset:%" PRId64 " slimit:%" PRId64 ", soffset:%" PRId64, pSql, pQueryInfo->limit.limit, - pQueryInfo->limit.offset, pQueryInfo->slimit.limit, pQueryInfo->slimit.offset); + tscDebug("0x%"PRIx64" limit:%" PRId64 ", offset:%" PRId64 " slimit:%" PRId64 ", soffset:%" PRId64, pSql->self, + pQueryInfo->limit.limit, pQueryInfo->limit.offset, pQueryInfo->slimit.limit, pQueryInfo->slimit.offset); if (pQueryInfo->slimit.offset < 0 || pQueryInfo->limit.offset < 0) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0); } if (pQueryInfo->limit.limit == 0) { - tscDebug("%p limit 0, no output result", pSql); + tscDebug("0x%"PRIx64" limit 0, no output result", pSql->self); pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; return TSDB_CODE_SUCCESS; } @@ -5837,7 +5899,7 @@ int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseIn } if (pQueryInfo->slimit.limit == 0) { - tscDebug("%p slimit 0, no output result", pSql); + tscDebug("0x%"PRIx64" slimit 0, no output result", pSql->self); pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; return TSDB_CODE_SUCCESS; } @@ -5855,7 +5917,7 @@ int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseIn // No tables included. No results generated. Query results are empty. if (pTableMetaInfo->vgroupList->numOfVgroups == 0) { - tscDebug("%p no table in super table, no output result", pSql); + tscDebug("0x%"PRIx64" no table in super table, no output result", pSql->self); pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; return TSDB_CODE_SUCCESS; } @@ -5990,32 +6052,33 @@ int32_t parseCreateDBOptions(SSqlCmd* pCmd, SCreateDbInfo* pCreateDbSql) { } void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClauseIndex, int32_t tableIndex) { - SQueryInfo* pParentQueryInfo = tscGetQueryInfoDetail(&pParentObj->cmd, subClauseIndex); + SQueryInfo* pParentQueryInfo = tscGetQueryInfo(&pParentObj->cmd, subClauseIndex); if (pParentQueryInfo->groupbyExpr.numOfGroupCols > 0) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, subClauseIndex); - SSqlExpr* pExpr = NULL; + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, subClauseIndex); + SExprInfo* pExpr = NULL; size_t size = taosArrayGetSize(pQueryInfo->exprList); if (size > 0) { pExpr = tscSqlExprGet(pQueryInfo, (int32_t)size - 1); } - if (pExpr == NULL || pExpr->functionId != TSDB_FUNC_TAG) { + if (pExpr == NULL || pExpr->base.functionId != TSDB_FUNC_TAG) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pParentQueryInfo, tableIndex); - int16_t colId = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->id.uid); + uint64_t uid = pTableMetaInfo->pTableMeta->id.uid; + int16_t colId = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, uid); SSchema* pTagSchema = tscGetColumnSchemaById(pTableMetaInfo->pTableMeta, colId); int16_t colIndex = tscGetTagColIndexById(pTableMetaInfo->pTableMeta, colId); - SColumnIndex index = {.tableIndex = 0, .columnIndex = colIndex}; + SColumnIndex index = {.tableIndex = 0, .columnIndex = colIndex}; char* name = pTagSchema->name; int16_t type = pTagSchema->type; int16_t bytes = pTagSchema->bytes; pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, getNewResColId(pQueryInfo), bytes, true); - pExpr->colInfo.flag = TSDB_COL_TAG; + pExpr->base.colInfo.flag = TSDB_COL_TAG; // NOTE: tag column does not add to source column list SColumnList ids = {0}; @@ -6023,21 +6086,20 @@ void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClau int32_t relIndex = index.columnIndex; - pExpr->colInfo.colIndex = relIndex; + pExpr->base.colInfo.colIndex = relIndex; SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, 0); pColIndex->colIndex = relIndex; - index = (SColumnIndex) {.tableIndex = tableIndex, .columnIndex = relIndex}; - tscColumnListInsert(pTableMetaInfo->tagColList, &index); + tscColumnListInsert(pTableMetaInfo->tagColList, relIndex, uid, pTagSchema); } } } // limit the output to be 1 for each state value -static void doLimitOutputNormalColOfGroupby(SSqlExpr* pExpr) { +static void doLimitOutputNormalColOfGroupby(SExprInfo* pExpr) { int32_t outputRow = 1; - tVariantCreateFromBinary(&pExpr->param[0], (char*)&outputRow, sizeof(int32_t), TSDB_DATA_TYPE_INT); - pExpr->numOfParams = 1; + tVariantCreateFromBinary(&pExpr->base.param[0], (char*)&outputRow, sizeof(int32_t), TSDB_DATA_TYPE_INT); + pExpr->base.numOfParams = 1; } void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) { @@ -6054,7 +6116,7 @@ void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) { int32_t numOfFields = tscNumOfFields(pQueryInfo); SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, numOfFields - 1); - doLimitOutputNormalColOfGroupby(pInfo->pSqlExpr); + doLimitOutputNormalColOfGroupby(pInfo->pExpr); pInfo->visible = false; } @@ -6067,29 +6129,29 @@ static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) { bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_TAGPRJ || pExpr->functionId == TSDB_FUNC_TAG) { - pExpr->functionId = TSDB_FUNC_TAG_DUMMY; - tagLength += pExpr->resBytes; - } else if (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { - pExpr->functionId = TSDB_FUNC_TS_DUMMY; - tagLength += pExpr->resBytes; + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId == TSDB_FUNC_TAGPRJ || pExpr->base.functionId == TSDB_FUNC_TAG) { + pExpr->base.functionId = TSDB_FUNC_TAG_DUMMY; + tagLength += pExpr->base.resBytes; + } else if (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { + pExpr->base.functionId = TSDB_FUNC_TS_DUMMY; + tagLength += pExpr->base.resBytes; } } SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId < 0) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId < 0) { continue; } - - if ((pExpr->functionId != TSDB_FUNC_TAG_DUMMY && pExpr->functionId != TSDB_FUNC_TS_DUMMY) && - !(pExpr->functionId == TSDB_FUNC_PRJ && TSDB_COL_IS_UD_COL(pExpr->colInfo.flag))) { - SSchema* pColSchema = &pSchema[pExpr->colInfo.colIndex]; - getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->functionId, (int32_t)pExpr->param[0].i64, &pExpr->resType, - &pExpr->resBytes, &pExpr->interBytes, tagLength, isSTable, NULL); + + if ((pExpr->base.functionId != TSDB_FUNC_TAG_DUMMY && pExpr->base.functionId != TSDB_FUNC_TS_DUMMY) && + !(pExpr->base.functionId == TSDB_FUNC_PRJ && TSDB_COL_IS_UD_COL(pExpr->base.colInfo.flag))) { + SSchema* pColSchema = &pSchema[pExpr->base.colInfo.colIndex]; + getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->base.functionId, (int32_t)pExpr->base.param[0].i64, &pExpr->base.resType, + &pExpr->base.resBytes, &pExpr->base.interBytes, tagLength, isSTable, NULL); } } } @@ -6098,17 +6160,17 @@ static int32_t doUpdateSqlFunctionForColPrj(SQueryInfo* pQueryInfo) { size_t size = taosArrayGetSize(pQueryInfo->exprList); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_PRJ && (!TSDB_COL_IS_UD_COL(pExpr->colInfo.flag) && (pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX))) { + if (pExpr->base.functionId == TSDB_FUNC_PRJ && (!TSDB_COL_IS_UD_COL(pExpr->base.colInfo.flag) && (pExpr->base.colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX))) { bool qualifiedCol = false; for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) { SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j); - if (pExpr->colInfo.colId == pColIndex->colId) { + if (pExpr->base.colInfo.colId == pColIndex->colId) { qualifiedCol = true; doLimitOutputNormalColOfGroupby(pExpr); - pExpr->numOfParams = 1; + pExpr->base.numOfParams = 1; break; } } @@ -6141,10 +6203,10 @@ static bool onlyTagPrjFunction(SQueryInfo* pQueryInfo) { size_t size = taosArrayGetSize(pQueryInfo->exprList); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_PRJ) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId == TSDB_FUNC_PRJ) { hasColumnPrj = true; - } else if (pExpr->functionId == TSDB_FUNC_TAGPRJ) { + } else if (pExpr->base.functionId == TSDB_FUNC_TAGPRJ) { hasTagPrj = true; } } @@ -6158,12 +6220,12 @@ static bool allTagPrjInGroupby(SQueryInfo* pQueryInfo) { size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId != TSDB_FUNC_TAGPRJ) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId != TSDB_FUNC_TAGPRJ) { continue; } - if (!tagColumnInGroupby(&pQueryInfo->groupbyExpr, pExpr->colInfo.colId)) { + if (!tagColumnInGroupby(&pQueryInfo->groupbyExpr, pExpr->base.colInfo.colId)) { allInGroupby = false; break; } @@ -6177,9 +6239,9 @@ static void updateTagPrjFunction(SQueryInfo* pQueryInfo) { size_t size = taosArrayGetSize(pQueryInfo->exprList); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_TAGPRJ) { - pExpr->functionId = TSDB_FUNC_TAG; + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId == TSDB_FUNC_TAGPRJ) { + pExpr->base.functionId = TSDB_FUNC_TAG; } } } @@ -6200,18 +6262,18 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) size_t numOfExprs = taosArrayGetSize(pQueryInfo->exprList); for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i); - if (pExpr->functionId == TSDB_FUNC_TAGPRJ || - (pExpr->functionId == TSDB_FUNC_PRJ && pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX)) { + SExprInfo* pExpr = taosArrayGetP(pQueryInfo->exprList, i); + if (pExpr->base.functionId == TSDB_FUNC_TAGPRJ || + (pExpr->base.functionId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX)) { tagTsColExists = true; // selectivity + ts/tag column break; } } for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, i); + SExprInfo* pExpr = taosArrayGetP(pQueryInfo->exprList, i); - int16_t functionId = pExpr->functionId; + int16_t functionId = pExpr->base.functionId; if (functionId == TSDB_FUNC_TAGPRJ || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_ARITHM) { continue; @@ -6222,7 +6284,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) if (pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE) { ++numOfAggregation; } - + continue; } @@ -6256,14 +6318,14 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) * Otherwise, return with error code. */ for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - int16_t functionId = pExpr->functionId; + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + int16_t functionId = pExpr->base.functionId; if (functionId == TSDB_FUNC_TAGPRJ || (aAggs[functionId].status & TSDB_FUNCSTATE_SELECTIVITY) == 0) { continue; } if ((functionId == TSDB_FUNC_LAST_ROW) || - (functionId == TSDB_FUNC_LAST_DST && (pExpr->colInfo.flag & TSDB_COL_NULL) != 0)) { + (functionId == TSDB_FUNC_LAST_DST && (pExpr->base.colInfo.flag & TSDB_COL_NULL) != 0)) { // do nothing } else { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); @@ -6297,34 +6359,30 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, SSqlCmd* pCmd) } static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { - const char* msg2 = "interval not allowed in group by normal column"; + const char* msg1 = "interval not allowed in group by normal column"; STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); - SSchema s = *tGetTbnameColumnSchema(); SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta); - int16_t bytes = 0; - int16_t type = 0; - char* name = NULL; + + SSchema* tagSchema = NULL; + if (!UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) { + tagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); + } + + SSchema* s = NULL; for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) { SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i); int16_t colIndex = pColIndex->colIndex; + if (colIndex == TSDB_TBNAME_COLUMN_INDEX) { - type = s.type; - bytes = s.bytes; - name = s.name; + s = tGetTbnameColumnSchema(); } else { if (TSDB_COL_IS_TAG(pColIndex->flag)) { - SSchema* tagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); - - type = tagSchema[colIndex].type; - bytes = tagSchema[colIndex].bytes; - name = tagSchema[colIndex].name; + s = &tagSchema[colIndex]; } else { - type = pSchema[colIndex].type; - bytes = pSchema[colIndex].bytes; - name = pSchema[colIndex].name; + s = &pSchema[colIndex]; } } @@ -6332,34 +6390,33 @@ 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 = 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)); - - pExpr->colInfo.flag = TSDB_COL_TAG; + SExprInfo* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, s->type, s->bytes, + getNewResColId(pQueryInfo), s->bytes, true); + + memset(pExpr->base.aliasName, 0, sizeof(pExpr->base.aliasName)); + tstrncpy(pExpr->base.aliasName, s->name, sizeof(pExpr->base.aliasName)); + + pExpr->base.colInfo.flag = TSDB_COL_TAG; // NOTE: tag column does not add to source column list - SColumnList ids = getColumnList(1, 0, pColIndex->colIndex); - insertResultField(pQueryInfo, (int32_t)size - pQueryInfo->havingFieldNum, &ids, bytes, (int8_t)type, name, pExpr); + SColumnList ids = createColumnList(1, 0, pColIndex->colIndex); + insertResultField(pQueryInfo, (int32_t)size, &ids, s->bytes, (int8_t)s->type, s->name, pExpr); } else { // if this query is "group by" normal column, time window query is not allowed if (isTimeWindowQuery(pQueryInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } bool hasGroupColumn = false; for (int32_t j = 0; j < size; ++j) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, j); - if (pExpr->colInfo.colId == pColIndex->colId) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, j); + if ((pExpr->base.functionId == TSDB_FUNC_PRJ) && pExpr->base.colInfo.colId == pColIndex->colId) { + hasGroupColumn = true; break; } } - /* - * if the group by column does not required by user, add this column into the final result set - * but invisible to user - */ + //if the group by column does not required by user, add an invisible column into the final result set. if (!hasGroupColumn) { doAddGroupColumnForSubquery(pQueryInfo, i); } @@ -6376,8 +6433,8 @@ static int32_t doTagFunctionCheck(SQueryInfo* pQueryInfo) { int32_t numOfCols = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfCols; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - int32_t functionId = pExpr->functionId; + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + int32_t functionId = pExpr->base.functionId; if (functionId == TSDB_FUNC_TAGPRJ) { tagProjection = true; @@ -6385,7 +6442,7 @@ static int32_t doTagFunctionCheck(SQueryInfo* pQueryInfo) { } if (functionId == TSDB_FUNC_COUNT) { - assert(pExpr->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX); + assert(pExpr->base.colInfo.colId == TSDB_TBNAME_COLUMN_INDEX); tableCounting = true; } } @@ -6416,6 +6473,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) { // check if all the tags prj columns belongs to the group by columns if (onlyTagPrjFunction(pQueryInfo) && allTagPrjInGroupby(pQueryInfo)) { + // It is a groupby aggregate query, the tag project function is not suitable for this case. updateTagPrjFunction(pQueryInfo); return doAddGroupbyColumnsOnDemand(pCmd, pQueryInfo); } @@ -6423,18 +6481,18 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { // check all query functions in selection clause, multi-output functions are not allowed size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - int32_t functId = pExpr->functionId; + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + int32_t functId = pExpr->base.functionId; /* * group by normal columns. * Check if the column projection is identical to the group by column or not */ - if (functId == TSDB_FUNC_PRJ && pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) { + if (functId == TSDB_FUNC_PRJ && pExpr->base.colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) { bool qualified = false; for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) { SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, j); - if (pColIndex->colId == pExpr->colInfo.colId) { + if (pColIndex->colId == pExpr->base.colInfo.colId) { qualified = true; break; } @@ -6454,7 +6512,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } - if (functId == TSDB_FUNC_COUNT && pExpr->colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (functId == TSDB_FUNC_COUNT && pExpr->base.colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } } @@ -6463,10 +6521,6 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { return TSDB_CODE_TSC_INVALID_SQL; } - /* - * group by tag function must be not changed the function name, otherwise, the group operation may fail to - * divide the subset of final result. - */ if (doAddGroupbyColumnsOnDemand(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_SQL; } @@ -6481,12 +6535,12 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { return checkUpdateTagPrjFunctions(pQueryInfo, pCmd); } } -int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode* pQuerySqlNode) { +int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode) { const char* msg1 = "only one expression allowed"; const char* msg2 = "invalid expression in select clause"; const char* msg3 = "invalid function"; - SArray* pExprList = pQuerySqlNode->pSelectList; + SArray* pExprList = pSqlNode->pSelNodeList; size_t size = taosArrayGetSize(pExprList); if (size != 1) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); @@ -6538,12 +6592,12 @@ int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySqlNode } SColumnIndex ind = {0}; - SSqlExpr* pExpr1 = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG_DUMMY, &ind, TSDB_DATA_TYPE_INT, + SExprInfo* pExpr1 = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG_DUMMY, &ind, TSDB_DATA_TYPE_INT, tDataTypes[TSDB_DATA_TYPE_INT].bytes, getNewResColId(pQueryInfo), tDataTypes[TSDB_DATA_TYPE_INT].bytes, false); tSqlExprItem* item = taosArrayGet(pExprList, 0); const char* name = (item->aliasName != NULL)? item->aliasName:functionsInfo[index].name; - tstrncpy(pExpr1->aliasName, name, tListLen(pExpr1->aliasName)); + tstrncpy(pExpr1->base.aliasName, name, tListLen(pExpr1->base.aliasName)); return TSDB_CODE_SUCCESS; } @@ -6632,8 +6686,8 @@ int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCreateDbMsg* pCreate) { } // for debug purpose -void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, subClauseIndex); +void tscPrintSelNodeList(SSqlObj* pSql, int32_t subClauseIndex) { + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, subClauseIndex); int32_t size = (int32_t)tscSqlExprNumOfExprs(pQueryInfo); if (size == 0) { @@ -6642,26 +6696,26 @@ 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); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); char tmpBuf[1024] = {0}; int32_t tmpLen = 0; char *name = NULL; - - if (pExpr->functionId < 0) { - SUdfInfo* pUdfInfo = taosArrayGet(pSql->cmd.pUdfInfo, -1 * pExpr->functionId - 1); + + if (pExpr->base.functionId < 0) { + SUdfInfo* pUdfInfo = taosArrayGet(pSql->cmd.pUdfInfo, -1 * pExpr->base.functionId - 1); name = pUdfInfo->name; } else { - name = aAggs[pExpr->functionId].name; + name = aAggs[pExpr->base.functionId].name; } - + tmpLen = - sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", name, pExpr->uid, pExpr->colInfo.colId); + sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", name, pExpr->base.uid, pExpr->base.colInfo.colId); if (tmpLen + offset >= totalBufSize - 1) break; @@ -6676,14 +6730,14 @@ void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex) { assert(offset < totalBufSize); str[offset] = ']'; assert(offset < totalBufSize); - tscDebug("%p select clause:%s", pSql, str); + tscDebug("0x%"PRIx64" select clause:%s", pSql->self, str); } int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSqlInfo* pInfo) { const char* msg1 = "invalid table name"; SSqlCmd* pCmd = &pSql->cmd; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, subClauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, subClauseIndex); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); SCreateTableSql* pCreateTable = pInfo->pCreateTableInfo; @@ -6742,7 +6796,7 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { SSqlCmd* pCmd = &pSql->cmd; SCreateTableSql* pCreateTable = pInfo->pCreateTableInfo; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); // two table: the first one is for current table, and the secondary is for the super table. if (pQueryInfo->numOfTables < 2) { @@ -6780,7 +6834,6 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { size_t valSize = taosArrayGetSize(pValList); - // too long tag values will return invalid sql, not be truncated automatically SSchema *pTagSchema = tscGetTableTagSchema(pStableMetaInfo->pTableMeta); STagData *pTag = &pCreateTableInfo->tagdata; @@ -6790,7 +6843,6 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } - SArray* pNameList = NULL; size_t nameSize = 0; int32_t schemaSize = tscGetNumOfTags(pStableMetaInfo->pTableMeta); @@ -6947,7 +6999,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { const char* msg7 = "time interval is required"; SSqlCmd* pCmd = &pSql->cmd; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); assert(pQueryInfo->numOfTables == 1); SCreateTableSql* pCreateTable = pInfo->pCreateTableInfo; @@ -6955,18 +7007,18 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { // if sql specifies db, use it, otherwise use default db SStrToken* pName = &(pCreateTable->name); - SQuerySqlNode* pQuerySqlNode = pCreateTable->pSelect; + SSqlNode* pSqlNode = pCreateTable->pSelect; if (tscValidateName(pName) != TSDB_CODE_SUCCESS) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } - SFromInfo* pFromInfo = pInfo->pCreateTableInfo->pSelect->from; - if (pFromInfo == NULL || taosArrayGetSize(pFromInfo->tableList) == 0) { + SRelationInfo* pFromInfo = pInfo->pCreateTableInfo->pSelect->from; + if (pFromInfo == NULL || taosArrayGetSize(pFromInfo->list) == 0) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); } - STableNamePair* p1 = taosArrayGet(pFromInfo->tableList, 0); + STableNamePair* p1 = taosArrayGet(pFromInfo->list, 0); SStrToken srcToken = {.z = p1->name.z, .n = p1->name.n, .type = TK_STRING}; if (tscValidateName(&srcToken) != TSDB_CODE_SUCCESS) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); @@ -6982,24 +7034,24 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { return code; } - code = checkForUdf(pSql, pQuerySqlNode->pSelectList); + code = checkForUdf(pSql, pSqlNode->pSelNodeList); if (code != TSDB_CODE_SUCCESS) { return code; } bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo); - if (parseSelectClause(&pSql->cmd, 0, pQuerySqlNode->pSelectList, isSTable, false, false) != TSDB_CODE_SUCCESS) { + if (validateSelectNodeList(&pSql->cmd, pQueryInfo, pSqlNode->pSelNodeList, isSTable, false, false) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_SQL; } - if (pQuerySqlNode->pWhere != NULL) { // query condition in stream computing - if (parseWhereClause(pQueryInfo, &pQuerySqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { + if (pSqlNode->pWhere != NULL) { // query condition in stream computing + if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_SQL; } } // set interval value - if (parseIntervalClause(pSql, pQueryInfo, pQuerySqlNode) != TSDB_CODE_SUCCESS) { + if (validateIntervalNode(pSql, pQueryInfo, pSqlNode) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_SQL; } @@ -7017,7 +7069,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { return code; } - if (pQuerySqlNode->sqlstr.n > TSDB_MAX_SAVED_SQL_LEN) { + if (pSqlNode->sqlstr.n > TSDB_MAX_SAVED_SQL_LEN) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); } @@ -7035,12 +7087,12 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { * check if fill operation is available, the fill operation is parsed and executed during query execution, * not here. */ - if (pQuerySqlNode->fillType != NULL) { + if (pSqlNode->fillType != NULL) { if (pQueryInfo->interval.interval == 0) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); } - tVariantListItem* pItem = taosArrayGet(pQuerySqlNode->fillType, 0); + tVariantListItem* pItem = taosArrayGet(pSqlNode->fillType, 0); if (pItem->pVar.nType == TSDB_DATA_TYPE_BINARY) { if (!((strncmp(pItem->pVar.pz, "none", 4) == 0 && pItem->pVar.nLen == 4) || (strncmp(pItem->pVar.pz, "null", 4) == 0 && pItem->pVar.nLen == 4))) { @@ -7054,7 +7106,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { return TSDB_CODE_SUCCESS; } -static int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { +int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { const char* msg3 = "start(end) time of query range required or time range too large"; if (pQueryInfo->interval.interval == 0) { @@ -7089,9 +7141,50 @@ static int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { return TSDB_CODE_SUCCESS; } +// TODO normalize the function expression and compare it +int32_t tscGetExprFilters(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelectNodeList, tSqlExpr* pSqlExpr, + SExprInfo** pExpr) { + *pExpr = NULL; - int32_t tscInsertExprFields(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SInternalField** interField) { - tSqlExprItem item = {.pNode = pExpr, .aliasName = NULL, .distinct = false}; + size_t num = taosArrayGetSize(pSelectNodeList); + for(int32_t i = 0; i < num; ++i) { + tSqlExprItem* pItem = taosArrayGet(pSelectNodeList, i); + if (tSqlExprCompare(pItem->pNode, pSqlExpr) == 0) { // exists, not added it, + + SColumnIndex index = COLUMN_INDEX_INITIALIZER; + int32_t functionId = pSqlExpr->functionId; + if (pSqlExpr->pParam == NULL) { + index.columnIndex = 0; + index.tableIndex = 0; + } else { + tSqlExprItem* pParamElem = taosArrayGet(pSqlExpr->pParam, 0); + SStrToken* pToken = &pParamElem->pNode->colInfo; + getColumnIndexByName(pCmd, pToken, pQueryInfo, &index); + } + + size_t numOfNodeInSel = tscSqlExprNumOfExprs(pQueryInfo); + for(int32_t k = 0; k < numOfNodeInSel; ++k) { + SExprInfo* pExpr1 = tscSqlExprGet(pQueryInfo, k); + + if (pExpr1->base.functionId != functionId) { + continue; + } + + if (pExpr1->base.colInfo.colIndex != index.columnIndex) { + continue; + } + + ++pQueryInfo->havingFieldNum; + *pExpr = pExpr1; + break; + } + + assert(*pExpr != NULL); + return TSDB_CODE_SUCCESS; + } + } + + tSqlExprItem item = {.pNode = pSqlExpr, .aliasName = NULL, .distinct = false}; int32_t outputIndex = (int32_t)tscSqlExprNumOfExprs(pQueryInfo); @@ -7103,129 +7196,51 @@ static int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { ++pQueryInfo->havingFieldNum; size_t n = tscSqlExprNumOfExprs(pQueryInfo); - SSqlExpr* pSqlExpr = tscSqlExprGet(pQueryInfo, (int32_t)n - 1); + *pExpr = 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; + SInternalField* pField = taosArrayGet(pQueryInfo->fieldsInfo.internalField, n - 1); + pField->visible = false; 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) { +static int32_t handleExprInHavingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelectNodeList, 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* 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; - + // TODO refactor: validate the expression /* * in case of TK_AND filter condition, we first find the corresponding column and build the query condition together * the already existed condition. */ + SExprInfo *expr = NULL; if (sqlOptr == TK_AND) { - int32_t ret = tscGetExprFilters(pCmd, pQueryInfo, pExpr->pLeft, &pInfo); + int32_t ret = tscGetExprFilters(pCmd, pQueryInfo, pSelectNodeList, pExpr->pLeft, &expr); if (ret) { return ret; } - pColumn = pInfo->pFieldFilters->pFilters; - // this is a new filter condition on this column - if (pColumn->numOfFilters == 0) { - pColFilter = addColumnFilterInfo(pColumn); + if (expr->base.flist.numOfFilters == 0) { + pColFilter = addColumnFilterInfo(&expr->base.flist); } else { // update the existed column filter information, find the filter info here - pColFilter = &pColumn->filterInfo[0]; + pColFilter = &expr->base.flist.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); + int32_t ret = tscGetExprFilters(pCmd, pQueryInfo, pSelectNodeList, pExpr->pLeft, &expr); if (ret) { return ret; } - pColumn = pInfo->pFieldFilters->pFilters; - // TODO fixme: failed to invalid the filter expression: "col1 = 1 OR col2 = 2" - pColFilter = addColumnFilterInfo(pColumn); + // TODO refactor + pColFilter = addColumnFilterInfo(&expr->base.flist); if (pColFilter == NULL) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } @@ -7234,38 +7249,42 @@ static int32_t handleExprInHavingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t } pColFilter->filterstr = - ((pInfo->field.type == TSDB_DATA_TYPE_BINARY || pInfo->field.type == TSDB_DATA_TYPE_NCHAR) ? 1 : 0); + ((expr->base.resType == TSDB_DATA_TYPE_BINARY || expr->base.resType == 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 - ) { + && 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 (expr->base.resType == 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); + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); + STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; + + int32_t ret = doExtractColumnFilterInfo(pCmd, pQueryInfo, pTableMeta->tableInfo.precision, pColFilter, + expr->base.resType, pExpr); if (ret) { - return ret; + return ret; } - - return genExprFilter(pInfo->pFieldFilters); + + return TSDB_CODE_SUCCESS; } -int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, int32_t parentOptr) { +int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelectNodeList, tSqlExpr* pExpr, int32_t parentOptr) { if (pExpr == NULL) { return TSDB_CODE_SUCCESS; } @@ -7276,12 +7295,12 @@ int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, in tSqlExpr* pRight = pExpr->pRight; if (pExpr->tokenId == TK_AND || pExpr->tokenId == TK_OR) { - int32_t ret = getHavingExpr(pCmd, pQueryInfo, pExpr->pLeft, pExpr->tokenId); + int32_t ret = getHavingExpr(pCmd, pQueryInfo, pSelectNodeList, pExpr->pLeft, pExpr->tokenId); if (ret != TSDB_CODE_SUCCESS) { return ret; } - return getHavingExpr(pCmd, pQueryInfo, pExpr->pRight, pExpr->tokenId); + return getHavingExpr(pCmd, pQueryInfo, pSelectNodeList, pExpr->pRight, pExpr->tokenId); } if (pLeft == NULL || pRight == NULL) { @@ -7294,14 +7313,12 @@ int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, in exchangeExpr(pExpr); - pLeft = pExpr->pLeft; + 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); } @@ -7310,37 +7327,35 @@ int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, in 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)) { + tSqlExprItem* pParamItem = taosArrayGet(pLeft->pParam, i); + + tSqlExpr* pExpr1 = pParamItem->pNode; + if (pExpr1->tokenId != TK_ALL && + pExpr1->tokenId != TK_ID && + pExpr1->tokenId != TK_STRING && + pExpr1->tokenId != TK_INTEGER && + pExpr1->tokenId != TK_FLOAT) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } - if (pParamElem->pNode->tokenId == TK_ID) { + if (pExpr1->tokenId == TK_ID && (pExpr1->colInfo.z == NULL && pExpr1->colInfo.n == 0)) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + if (pExpr1->tokenId == TK_ID) { SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if ((getColumnIndexByName(pCmd, &pParamElem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS)) { + if ((getColumnIndexByName(pCmd, &pExpr1->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)) { + + if (index.columnIndex <= 0 || + index.columnIndex >= tscGetNumOfColumns(pTableMeta)) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } } @@ -7352,12 +7367,11 @@ int32_t getHavingExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, in return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } - return handleExprInHavingClause(pCmd, pQueryInfo, pExpr, parentOptr); + return handleExprInHavingClause(pCmd, pQueryInfo, pSelectNodeList, pExpr, parentOptr); } - - -int32_t parseHavingClause(SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SSqlCmd* pCmd, bool isSTable, int32_t joinQuery, int32_t timeWindowQuery) { +int32_t validateHavingClause(SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SSqlCmd* pCmd, SArray* pSelectNodeList, + 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"; @@ -7379,8 +7393,8 @@ int32_t parseHavingClause(SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SSqlCmd* pCmd } int32_t ret = 0; - - if ((ret = getHavingExpr(pCmd, pQueryInfo, pExpr, TK_AND)) != TSDB_CODE_SUCCESS) { + + if ((ret = getHavingExpr(pCmd, pQueryInfo, pSelectNodeList, pExpr, TK_AND)) != TSDB_CODE_SUCCESS) { return ret; } @@ -7392,39 +7406,113 @@ int32_t parseHavingClause(SQueryInfo* pQueryInfo, tSqlExpr* pExpr, SSqlCmd* pCmd return TSDB_CODE_SUCCESS; } +static int32_t doLoadAllTableMeta(SSqlObj* pSql, int32_t index, SSqlNode* pSqlNode, int32_t numOfTables) { + const char* msg1 = "invalid table name"; + const char* msg2 = "invalid table alias name"; + const char* msg3 = "alias name too long"; + int32_t code = TSDB_CODE_SUCCESS; + SSqlCmd* pCmd = &pSql->cmd; + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, index); + for (int32_t i = 0; i < numOfTables; ++i) { + if (pQueryInfo->numOfTables <= i) { // more than one table + tscAddEmptyMetaInfo(pQueryInfo); + } -int32_t doValidateSqlNode(SSqlObj* pSql, SQuerySqlNode* pQuerySqlNode, int32_t index) { - assert(pQuerySqlNode != NULL && (pQuerySqlNode->from == NULL || taosArrayGetSize(pQuerySqlNode->from->tableList) > 0)); + STableNamePair *item = taosArrayGet(pSqlNode->from->list, i); + SStrToken *oriName = &item->name; + + if (oriName->type == TK_INTEGER || oriName->type == TK_FLOAT) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + tscDequoteAndTrimToken(oriName); + if (tscValidateName(oriName) != TSDB_CODE_SUCCESS) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i); + code = tscSetTableFullName(pTableMetaInfo, oriName, pSql); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + + SStrToken* aliasName = &item->aliasName; + if (TPARSER_HAS_TOKEN(*aliasName)) { + if (aliasName->type == TK_INTEGER || aliasName->type == TK_FLOAT) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + } + + tscDequoteAndTrimToken(aliasName); + if (tscValidateName(aliasName) != TSDB_CODE_SUCCESS) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + } + + if (aliasName->n >= TSDB_TABLE_NAME_LEN) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + } + + strncpy(pTableMetaInfo->aliasName, aliasName->z, aliasName->n); + } else { + strncpy(pTableMetaInfo->aliasName, tNameGetTableName(&pTableMetaInfo->name), + tListLen(pTableMetaInfo->aliasName)); + } + + code = tscGetTableMeta(pSql, pTableMetaInfo); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + } + + return TSDB_CODE_SUCCESS; +} + +static STableMeta* extractTempTableMetaFromNestQuery(SQueryInfo* pUpstream) { + int32_t numOfColumns = pUpstream->fieldsInfo.numOfOutput; + + STableMeta* meta = calloc(1, sizeof(STableMeta) + sizeof(SSchema) * numOfColumns); + meta->tableType = TSDB_TEMP_TABLE; + + STableComInfo *info = &meta->tableInfo; + info->numOfColumns = numOfColumns; + info->numOfTags = 0; + + int32_t n = 0; + for(int32_t i = 0; i < numOfColumns; ++i) { + SInternalField* pField = tscFieldInfoGetInternalField(&pUpstream->fieldsInfo, i); + if (pField->visible) { + meta->schema[n].bytes = pField->field.bytes; + meta->schema[n].type = pField->field.type; + meta->schema[n].colId = pField->pExpr->base.resColId; + tstrncpy(meta->schema[n].name, pField->pExpr->base.aliasName, TSDB_COL_NAME_LEN); + n += 1; + } + } + + return meta; +} + +int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, int32_t index) { + assert(pSqlNode != NULL && (pSqlNode->from == NULL || taosArrayGetSize(pSqlNode->from->list) > 0)); - const char* msg0 = "invalid table name"; const char* msg1 = "point interpolation query needs timestamp"; - const char* msg2 = "fill only available for interval query"; + const char* msg2 = "too many tables in from clause"; const char* msg3 = "start(end) time of query range required or time range too large"; - const char* msg5 = "too many columns in selection clause"; - const char* msg6 = "too many tables in from clause"; - const char* msg7 = "invalid table alias name"; - const char* msg8 = "alias name too long"; int32_t code = TSDB_CODE_SUCCESS; SSqlCmd* pCmd = &pSql->cmd; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, index); - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, index); + STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); if (pTableMetaInfo == NULL) { pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo); } assert(pCmd->clauseIndex == index); - // too many result columns not support order by in query - if (taosArrayGetSize(pQuerySqlNode->pSelectList) > TSDB_MAX_COLUMNS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); - } - /* * handle the sql expression without from subclause * select current_database(); @@ -7432,94 +7520,81 @@ int32_t doValidateSqlNode(SSqlObj* pSql, SQuerySqlNode* pQuerySqlNode, int32_t i * select client_version(); * select server_state(); */ - if (pQuerySqlNode->from == NULL) { - assert(pQuerySqlNode->fillType == NULL && pQuerySqlNode->pGroupby == NULL && pQuerySqlNode->pWhere == NULL && - pQuerySqlNode->pSortOrder == NULL); - return doLocalQueryProcess(pCmd, pQueryInfo, pQuerySqlNode); + if (pSqlNode->from == NULL) { + assert(pSqlNode->fillType == NULL && pSqlNode->pGroupby == NULL && pSqlNode->pWhere == NULL && + pSqlNode->pSortOrder == NULL); + return doLocalQueryProcess(pCmd, pQueryInfo, pSqlNode); } - size_t fromSize = taosArrayGetSize(pQuerySqlNode->from->tableList); - if (fromSize > TSDB_MAX_JOIN_TABLE_NUM * 2) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); - } + if (pSqlNode->from->type == SQL_NODE_FROM_SUBQUERY) { + // parse the subquery in the first place + SArray* list = taosArrayGetP(pSqlNode->from->list, 0); + SSqlNode* p = taosArrayGetP(list, 0); - pQueryInfo->command = TSDB_SQL_SELECT; - - // set all query tables, which are maybe more than one. - for (int32_t i = 0; i < fromSize; ++i) { - STableNamePair* item = taosArrayGet(pQuerySqlNode->from->tableList, i); - SStrToken* pTableItem = &item->name; - - if (pTableItem->type != TSDB_DATA_TYPE_BINARY) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0); + code = validateSqlNode(pSql, p, 0); + if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { + return code; } - tscDequoteAndTrimToken(pTableItem); - - SStrToken tableName = {.z = pTableItem->z, .n = pTableItem->n, .type = TK_STRING}; - if (tscValidateName(&tableName) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0); - } - - if (pQueryInfo->numOfTables <= i) { // more than one table - tscAddEmptyMetaInfo(pQueryInfo); - } - - STableMetaInfo* pTableMetaInfo1 = tscGetMetaInfo(pQueryInfo, i); - code = tscSetTableFullName(pTableMetaInfo1, pTableItem, pSql); if (code != TSDB_CODE_SUCCESS) { return code; } - SStrToken* aliasName = &item->aliasName; - if (TPARSER_HAS_TOKEN(*aliasName)) { - if (aliasName->type != TSDB_DATA_TYPE_BINARY) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7); - } + pQueryInfo = pCmd->pQueryInfo[0]; - tscDequoteAndTrimToken(aliasName); + SQueryInfo* current = calloc(1, sizeof(SQueryInfo)); - SStrToken aliasName1 = {.z = aliasName->z, .n = aliasName->n, .type = TK_STRING}; - if (tscValidateName(&aliasName1) != TSDB_CODE_SUCCESS) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7); - } + tscInitQueryInfo(current); + taosArrayPush(current->pUpstream, &pQueryInfo); - if (aliasName1.n >= TSDB_TABLE_NAME_LEN) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8); - } + STableMeta* pTableMeta = extractTempTableMetaFromNestQuery(pQueryInfo); + STableMetaInfo* pTableMetaInfo1 = calloc(1, sizeof(STableMetaInfo)); + pTableMetaInfo1->pTableMeta = pTableMeta; - strncpy(pTableMetaInfo1->aliasName, aliasName1.z, aliasName1.n); - } else { - strncpy(pTableMetaInfo1->aliasName, tNameGetTableName(&pTableMetaInfo1->name), tListLen(pTableMetaInfo1->aliasName)); + current->pTableMetaInfo = calloc(1, POINTER_BYTES); + current->pTableMetaInfo[0] = pTableMetaInfo1; + current->numOfTables = 1; + current->order = pQueryInfo->order; + + pCmd->pQueryInfo[0] = current; + pQueryInfo->pDownstream = current; + + if (validateSelectNodeList(pCmd, current, pSqlNode->pSelNodeList, false, false, false) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_SQL; } - code = tscGetTableMeta(pSql, pTableMetaInfo1); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - } - - assert(pQueryInfo->numOfTables == taosArrayGetSize(pQuerySqlNode->from->tableList)); - bool isSTable = false; - - if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - isSTable = true; - code = tscGetSTableVgroupInfo(pSql, index); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - - TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_STABLE_QUERY); } else { - TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TABLE_QUERY); - } + pQueryInfo->command = TSDB_SQL_SELECT; - // parse the group by clause in the first place - if (parseGroupbyClause(pQueryInfo, pQuerySqlNode->pGroupby, pCmd) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; - } + size_t fromSize = taosArrayGetSize(pSqlNode->from->list); + if (fromSize > TSDB_MAX_JOIN_TABLE_NUM) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + } - code = checkForUdf(pSql, pQuerySqlNode->pSelectList); + // set all query tables, which are maybe more than one. + code = doLoadAllTableMeta(pSql, index, pSqlNode, (int32_t) fromSize); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + + bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo); + if (isSTable) { + code = tscGetSTableVgroupInfo(pSql, index); // TODO refactor: getTablemeta along with vgroupInfo + if (code != TSDB_CODE_SUCCESS) { + return code; + } + + TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_STABLE_QUERY); + } else { + TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TABLE_QUERY); + } + + // parse the group by clause in the first place + if (validateGroupbyNode(pQueryInfo, pSqlNode->pGroupby, pCmd) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_SQL; + } + + code = checkForUdf(pSql, pSqlNode->pSelNodeList); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -7527,119 +7602,110 @@ int32_t doValidateSqlNode(SSqlObj* pSql, SQuerySqlNode* pQuerySqlNode, int32_t i // set where info STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); - if (pQuerySqlNode->pWhere != NULL) { - if (parseWhereClause(pQueryInfo, &pQuerySqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { + if (pSqlNode->pWhere != NULL) { + if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_SQL; + } + + pSqlNode->pWhere = NULL; + if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) { + pQueryInfo->window.skey = pQueryInfo->window.skey / 1000; + pQueryInfo->window.ekey = pQueryInfo->window.ekey / 1000; + } + } else { // set the time rang + if (taosArrayGetSize(pSqlNode->from->list) > 1) { + // If it is a join query, no where clause is not allowed. + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "condition missing for join query "); + } + } + + int32_t joinQuery = (pSqlNode->from != NULL && taosArrayGetSize(pSqlNode->from->list) > 1); + int32_t timeWindowQuery = + (TPARSER_HAS_TOKEN(pSqlNode->interval.interval) || TPARSER_HAS_TOKEN(pSqlNode->sessionVal.gap)); + + if (validateSelectNodeList(pCmd, pQueryInfo, pSqlNode->pSelNodeList, isSTable, joinQuery, timeWindowQuery) != + TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_SQL; } - if (tinfo.precision == TSDB_TIME_PRECISION_MILLI) { - pQueryInfo->window.skey = pQueryInfo->window.skey / 1000; - pQueryInfo->window.ekey = pQueryInfo->window.ekey / 1000; - } - - pQuerySqlNode->pWhere = NULL; - - } else { // set the time rang - if (taosArrayGetSize(pQuerySqlNode->from->tableList) > 1) { // it is a join query, no where clause is not allowed. - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "condition missing for join query "); - } - } - - int32_t joinQuery = (pQuerySqlNode->from != NULL && taosArrayGetSize(pQuerySqlNode->from->tableList) > 1); - int32_t timeWindowQuery = - (TPARSER_HAS_TOKEN(pQuerySqlNode->interval.interval) || TPARSER_HAS_TOKEN(pQuerySqlNode->sessionVal.gap)); - - if (parseSelectClause(pCmd, index, pQuerySqlNode->pSelectList, isSTable, joinQuery, timeWindowQuery) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; - } - - // set order by info - if (parseOrderbyClause(pCmd, pQueryInfo, pQuerySqlNode, tscGetTableSchema(pTableMetaInfo->pTableMeta)) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; - } - - // set interval value - if (parseIntervalClause(pSql, pQueryInfo, pQuerySqlNode) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; - } else { - if (isTimeWindowQuery(pQueryInfo) && - (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) { + // set order by info + if (validateOrderbyNode(pCmd, pQueryInfo, pSqlNode, tscGetTableSchema(pTableMetaInfo->pTableMeta)) != + TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_SQL; } - } - // 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)) { + // set interval value + if (validateIntervalNode(pSql, pQueryInfo, pSqlNode) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_SQL; + } else { + if (isTimeWindowQuery(pQueryInfo) && + (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) { + return TSDB_CODE_TSC_INVALID_SQL; + } } - } - if (parseSessionClause(pCmd, pQueryInfo, pQuerySqlNode) != TSDB_CODE_SUCCESS) { - return TSDB_CODE_TSC_INVALID_SQL; - } - - // no result due to invalid query time range - if (pQueryInfo->window.skey > pQueryInfo->window.ekey) { - pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; - return TSDB_CODE_SUCCESS; - } - - if (!hasTimestampForPointInterpQuery(pQueryInfo)) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); - } - - // in case of join query, time range is required. - if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) { - int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey); - if (timeRange == 0 && pQueryInfo->window.skey == 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); - } - } - - if ((code = parseLimitClause(pCmd, pQueryInfo, index, pQuerySqlNode, pSql)) != TSDB_CODE_SUCCESS) { - return code; - } - - if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo)) != TSDB_CODE_SUCCESS) { - return code; - } - - updateLastScanOrderIfNeeded(pQueryInfo); - tscFieldInfoUpdateOffset(pQueryInfo); - - if (pQuerySqlNode->fillType != NULL) { - if (pQueryInfo->interval.interval == 0 && (!tscIsPointInterpQuery(pQueryInfo))) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); + // parse the having clause in the first place + if (validateHavingClause(pQueryInfo, pSqlNode->pHaving, pCmd, pSqlNode->pSelNodeList, joinQuery, timeWindowQuery) != + TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_SQL; } /* - * fill options are set at the end position, when all columns are set properly - * the columns may be increased due to group by operation + * transfer sql functions that need secondary merge into another format + * in dealing with super table queries such as: count/first/last */ - if ((code = checkQueryRangeForFill(pCmd, pQueryInfo)) != TSDB_CODE_SUCCESS) { + if (isSTable) { + tscTansformFuncForSTableQuery(pQueryInfo); + + if (hasUnsupportFunctionsForSTableQuery(pCmd, pQueryInfo)) { + return TSDB_CODE_TSC_INVALID_SQL; + } + } + + if (validateSessionNode(pCmd, pQueryInfo, pSqlNode) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_SQL; + } + + // no result due to invalid query time range + if (pQueryInfo->window.skey > pQueryInfo->window.ekey) { + pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; + return TSDB_CODE_SUCCESS; + } + + if (!hasTimestampForPointInterpQuery(pQueryInfo)) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); + } + + // in case of join query, time range is required. + if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) { + int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey); + if (timeRange == 0 && pQueryInfo->window.skey == 0) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3); + } + } + + if ((code = validateLimitNode(pCmd, pQueryInfo, index, pSqlNode, pSql)) != TSDB_CODE_SUCCESS) { return code; } - if ((code = parseFillClause(pCmd, pQueryInfo, pQuerySqlNode)) != TSDB_CODE_SUCCESS) { + if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo)) != TSDB_CODE_SUCCESS) { + return code; + } + + updateLastScanOrderIfNeeded(pQueryInfo); + tscFieldInfoUpdateOffset(pQueryInfo); + + if ((code = validateFillNode(pCmd, pQueryInfo, pSqlNode)) != TSDB_CODE_SUCCESS) { return code; } } + pQueryInfo->globalMerge = tscIsTwoStageSTableQuery(pCmd, pQueryInfo, 0); + pQueryInfo->arithmCalOnAgg = tscIsSecondStageQuery(pCmd, pQueryInfo); return TSDB_CODE_SUCCESS; // Does not build query message here } -int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQueryInfo* pQueryInfo, SArray* pCols, int64_t *uid) { +int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQueryInfo* pQueryInfo, SArray* pCols, uint64_t *uid) { tExprNode* pLeft = NULL; tExprNode* pRight= NULL; @@ -7653,6 +7719,7 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS if (pSqlExpr->pRight != NULL) { int32_t ret = exprTreeFromSqlExpr(pCmd, &pRight, pSqlExpr->pRight, pQueryInfo, pCols, uid); if (ret != TSDB_CODE_SUCCESS) { + tExprTreeDestroy(pLeft, NULL); return ret; } } @@ -7662,7 +7729,9 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS return TSDB_CODE_SUCCESS; } - if (pSqlExpr->pLeft == NULL) { + if (pSqlExpr->pLeft == NULL) { // it is the leaf node + assert(pSqlExpr->pRight == NULL); + if (pSqlExpr->type == SQL_NODE_VALUE) { *pExpr = calloc(1, sizeof(tExprNode)); (*pExpr)->nodeType = TSQL_NODE_VALUE; @@ -7681,15 +7750,15 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSqlExpr* pS size_t size = taosArrayGetSize(pQueryInfo->exprList); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* p1 = taosArrayGetP(pQueryInfo->exprList, i); + SExprInfo* p1 = taosArrayGetP(pQueryInfo->exprList, i); - if (strcmp((*pExpr)->pSchema->name, p1->aliasName) == 0) { - (*pExpr)->pSchema->type = (uint8_t)p1->resType; - (*pExpr)->pSchema->bytes = p1->resBytes; - (*pExpr)->pSchema->colId = p1->resColId; + if (strcmp((*pExpr)->pSchema->name, p1->base.aliasName) == 0) { + (*pExpr)->pSchema->type = (uint8_t)p1->base.resType; + (*pExpr)->pSchema->bytes = p1->base.resBytes; + (*pExpr)->pSchema->colId = p1->base.resColId; if (uid != NULL) { - *uid = p1->uid; + *uid = p1->base.uid; } break; @@ -7768,7 +7837,7 @@ bool hasNormalColumnFilter(SQueryInfo* pQueryInfo) { size_t numOfCols = taosArrayGetSize(pQueryInfo->colList); for (int32_t i = 0; i < numOfCols; ++i) { SColumn* pCol = taosArrayGetP(pQueryInfo->colList, i); - if (pCol->numOfFilters > 0) { + if (pCol->info.flist.numOfFilters > 0) { return true; } } @@ -7776,10 +7845,3 @@ bool hasNormalColumnFilter(SQueryInfo* pQueryInfo) { return false; } - - - - - - - diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 33ed8eda0d..0920542af2 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -24,6 +24,7 @@ #include "tsclient.h" #include "ttimer.h" #include "tlockfree.h" +#include "qPlan.h" int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo) = {0}; @@ -147,7 +148,7 @@ static void tscUpdateVgroupInfo(SSqlObj *pSql, SRpcEpSet *pEpSet) { // 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); + tscDebug("0x%"PRIx64" update the epSet in SqlObj, in use before:%d, after:%d", pSql->self, inUse, pSql->epSet.inUse); } @@ -245,11 +246,11 @@ void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) { if (pObj->hbrid != 0) { int32_t waitingDuring = tsShellActivityTimer * 500; - tscDebug("%p send heartbeat in %dms", pSql, waitingDuring); + tscDebug("0x%"PRIx64" send heartbeat in %dms", pSql->self, waitingDuring); taosTmrReset(tscProcessActivityTimer, waitingDuring, (void *)pObj->rid, tscTmr, &pObj->pTimer); } else { - tscDebug("%p start to close tscObj:%p, not send heartbeat again", pSql, pObj); + tscDebug("0x%"PRIx64" start to close tscObj:%p, not send heartbeat again", pSql->self, pObj); } } @@ -269,7 +270,7 @@ void tscProcessActivityTimer(void *handle, void *tmrId) { assert(pHB->self == pObj->hbrid); pHB->retry = 0; - int32_t code = tscProcessSql(pHB); + int32_t code = tscBuildAndSendRequest(pHB, NULL); taosReleaseRef(tscObjRef, pObj->hbrid); if (code != TSDB_CODE_SUCCESS) { @@ -326,7 +327,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { pSql->rpcRid = -1; if (pObj->signature != pObj) { - tscDebug("%p DB connection is closed, cmd:%d pObj:%p signature:%p", pSql, pCmd->command, pObj, pObj->signature); + tscDebug("0x%"PRIx64" DB connection is closed, cmd:%d pObj:%p signature:%p", pSql->self, pCmd->command, pObj, pObj->signature); taosRemoveRef(tscObjRef, handle); taosReleaseRef(tscObjRef, handle); @@ -334,10 +335,10 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { return; } - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); if (pQueryInfo != NULL && pQueryInfo->type == TSDB_QUERY_TYPE_FREE_RESOURCE) { - tscDebug("%p sqlObj needs to be released or DB connection is closed, cmd:%d type:%d, pObj:%p signature:%p", - pSql, pCmd->command, pQueryInfo->type, pObj, pObj->signature); + tscDebug("0x%"PRIx64" sqlObj needs to be released or DB connection is closed, cmd:%d type:%d, pObj:%p signature:%p", + pSql->self, pCmd->command, pQueryInfo->type, pObj, pObj->signature); taosRemoveRef(tscObjRef, handle); taosReleaseRef(tscObjRef, handle); @@ -396,13 +397,13 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { pRes->rspLen = 0; if (pRes->code == TSDB_CODE_TSC_QUERY_CANCELLED) { - tscDebug("%p query is cancelled, code:%s", pSql, tstrerror(pRes->code)); + tscDebug("0x%"PRIx64" query is cancelled, code:%s", pSql->self, tstrerror(pRes->code)); } else { pRes->code = rpcMsg->code; } if (pRes->code == TSDB_CODE_SUCCESS) { - tscDebug("%p reset retry counter to be 0 due to success rsp, old:%d", pSql, pSql->retry); + tscDebug("0x%"PRIx64" reset retry counter to be 0 due to success rsp, old:%d", pSql->self, pSql->retry); pSql->retry = 0; } @@ -437,10 +438,10 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { pMsg->numOfFailedBlocks = htonl(pMsg->numOfFailedBlocks); pRes->numOfRows += pMsg->affectedRows; - tscDebug("%p SQL cmd:%s, code:%s inserted rows:%d rspLen:%d", pSql, sqlCmd[pCmd->command], + tscDebug("0x%"PRIx64" SQL cmd:%s, code:%s inserted rows:%d rspLen:%d", pSql->self, sqlCmd[pCmd->command], tstrerror(pRes->code), pMsg->affectedRows, pRes->rspLen); } else { - tscDebug("%p SQL cmd:%s, code:%s rspLen:%d", pSql, sqlCmd[pCmd->command], tstrerror(pRes->code), pRes->rspLen); + tscDebug("0x%"PRIx64" SQL cmd:%s, code:%s rspLen:%d", pSql->self, sqlCmd[pCmd->command], tstrerror(pRes->code), pRes->rspLen); } } @@ -457,19 +458,16 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { (*pSql->fp)(pSql->param, pSql, rpcMsg->code); } - - if (shouldFree) { // in case of table-meta/vgrouplist query, automatically free it taosRemoveRef(tscObjRef, handle); - tscDebug("%p sqlObj is automatically freed", pSql); + tscDebug("0x%"PRIx64" sqlObj is automatically freed", pSql->self); } taosReleaseRef(tscObjRef, handle); - rpcFreeCont(rpcMsg->pCont); } -int doProcessSql(SSqlObj *pSql) { +int doBuildAndSendMsg(SSqlObj *pSql) { SSqlCmd *pCmd = &pSql->cmd; SSqlRes *pRes = &pSql->res; @@ -502,13 +500,16 @@ int doProcessSql(SSqlObj *pSql) { return TSDB_CODE_SUCCESS; } -int tscProcessSql(SSqlObj *pSql) { +int tscBuildAndSendRequest(SSqlObj *pSql, SQueryInfo* pQueryInfo) { char name[TSDB_TABLE_FNAME_LEN] = {0}; SSqlCmd *pCmd = &pSql->cmd; uint32_t type = 0; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + if (pQueryInfo == NULL) { + pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); + } + STableMetaInfo *pTableMetaInfo = NULL; if (pQueryInfo != NULL) { @@ -523,7 +524,7 @@ int tscProcessSql(SSqlObj *pSql) { assert((pQueryInfo->numOfTables == 0 && pQueryInfo->command == TSDB_SQL_HB) || pQueryInfo->numOfTables > 0); } - tscDebug("%p SQL cmd:%s will be processed, name:%s, type:%d", pSql, sqlCmd[pCmd->command], name, type); + tscDebug("0x%"PRIx64" SQL cmd:%s will be processed, name:%s, type:%d", pSql->self, sqlCmd[pCmd->command], name, type); if (pCmd->command < TSDB_SQL_MGMT) { // the pTableMetaInfo cannot be NULL if (pTableMetaInfo == NULL) { pSql->res.code = TSDB_CODE_TSC_APP_ERROR; @@ -533,15 +534,16 @@ int tscProcessSql(SSqlObj *pSql) { return (*tscProcessMsgRsp[pCmd->command])(pSql); } - return doProcessSql(pSql); + return doBuildAndSendMsg(pSql); } int tscBuildFetchMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SRetrieveTableMsg *pRetrieveMsg = (SRetrieveTableMsg *) pSql->cmd.payload; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex); - pRetrieveMsg->free = htons(pQueryInfo->type); - pRetrieveMsg->qId = htobe64(pSql->res.qId); + SQueryInfo *pQueryInfo = tscGetActiveQueryInfo(&pSql->cmd); + + pRetrieveMsg->free = htons(pQueryInfo->type); + pRetrieveMsg->qId = htobe64(pSql->res.qId); // todo valid the vgroupId at the client side STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); @@ -563,11 +565,12 @@ int tscBuildFetchMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } pRetrieveMsg->header.vgId = htonl(vgId); - tscDebug("%p build fetch msg from vgId:%d, vgIndex:%d, qId:%" PRIu64, pSql, vgId, vgIndex, pSql->res.qId); + tscDebug("0x%"PRIx64" build fetch msg from vgId:%d, vgIndex:%d, qId:0x%" PRIx64, pSql->self, vgId, vgIndex, pSql->res.qId); } else { STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; pRetrieveMsg->header.vgId = htonl(pTableMeta->vgId); - tscDebug("%p build fetch msg from only one vgroup, vgId:%d, qId:%" PRIu64, pSql, pTableMeta->vgId, pSql->res.qId); + tscDebug("0x%"PRIx64" build fetch msg from only one vgroup, vgId:%d, qId:0x%" PRIx64, pSql->self, pTableMeta->vgId, + pSql->res.qId); } pSql->cmd.payloadLen = sizeof(SRetrieveTableMsg); @@ -579,7 +582,7 @@ int tscBuildFetchMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } int tscBuildSubmitMsg(SSqlObj *pSql, SSqlInfo *pInfo) { - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta; char* pMsg = pSql->cmd.payload; @@ -606,7 +609,7 @@ int tscBuildSubmitMsg(SSqlObj *pSql, SSqlInfo *pInfo) { taosHashGetClone(tscVgroupMap, &pTableMeta->vgId, sizeof(pTableMeta->vgId), NULL, &vgroupInfo, sizeof(SNewVgroupInfo)); tscDumpEpSetFromVgroupInfo(&pSql->epSet, &vgroupInfo); - tscDebug("%p build submit msg, vgId:%d numOfTables:%d numberOfEP:%d", pSql, pTableMeta->vgId, pSql->cmd.numOfTablesInSubmit, + tscDebug("0x%"PRIx64" build submit msg, vgId:%d numOfTables:%d numberOfEP:%d", pSql->self, pTableMeta->vgId, pSql->cmd.numOfTablesInSubmit, pSql->epSet.numOfEps); return TSDB_CODE_SUCCESS; } @@ -618,12 +621,12 @@ static int32_t tscEstimateQueryMsgSize(SSqlObj *pSql, int32_t clauseIndex) { const static int32_t MIN_QUERY_MSG_PKT_SIZE = TSDB_MAX_BYTES_PER_ROW * 5; SSqlCmd* pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, clauseIndex); int32_t srcColListSize = (int32_t)(taosArrayGetSize(pQueryInfo->colList) * sizeof(SColumnInfo)); size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); - int32_t exprSize = (int32_t)(sizeof(SSqlFuncMsg) * numOfExprs * 2); + int32_t exprSize = (int32_t)(sizeof(SSqlExpr) * numOfExprs * 2); int32_t tsBufSize = (pQueryInfo->tsBuf != NULL) ? pQueryInfo->tsBuf->fileSize : 0; int32_t sqlLen = (int32_t) strlen(pSql->sqlstr) + 1; @@ -647,8 +650,8 @@ static int32_t tscEstimateQueryMsgSize(SSqlObj *pSql, int32_t clauseIndex) { tableSerialize + sqlLen + 4096 + pQueryInfo->bufLen; } -static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char *pMsg, int32_t *succeed) { - STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, pSql->cmd.clauseIndex, 0); +static char *doSerializeTableInfo(SQueryTableMsg *pQueryMsg, SSqlObj *pSql, STableMetaInfo *pTableMetaInfo, char *pMsg, + int32_t *succeed) { TSKEY dfltKey = htobe64(pQueryMsg->window.skey); STableMeta * pTableMeta = pTableMetaInfo->pTableMeta; @@ -665,14 +668,14 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char pVgroupInfo = &pTableMetaInfo->vgroupList->vgroups[index]; } else { tscError("%p No vgroup info found", pSql); - + *succeed = 0; return pMsg; } vgId = pVgroupInfo->vgId; tscSetDnodeEpSet(&pSql->epSet, pVgroupInfo); - tscDebug("%p query on stable, vgIndex:%d, numOfVgroups:%d", pSql, index, pTableMetaInfo->vgroupList->numOfVgroups); + tscDebug("0x%"PRIx64" query on stable, vgIndex:%d, numOfVgroups:%d", pSql->self, index, pTableMetaInfo->vgroupList->numOfVgroups); } else { vgId = pTableMeta->vgId; @@ -705,7 +708,7 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char int32_t numOfTables = (int32_t)taosArrayGetSize(pTableIdList->itemList); pQueryMsg->numOfTables = htonl(numOfTables); // set the number of tables - tscDebug("%p query on stable, vgId:%d, numOfTables:%d, vgIndex:%d, numOfVgroups:%d", pSql, + tscDebug("0x%"PRIx64" query on stable, vgId:%d, numOfTables:%d, vgIndex:%d, numOfVgroups:%d", pSql->self, pTableIdList->vgInfo.vgId, numOfTables, index, numOfVgroups); // serialize each table id info @@ -723,328 +726,219 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char char n[TSDB_TABLE_FNAME_LEN] = {0}; tNameExtractFullName(&pTableMetaInfo->name, n); - tscDebug("%p vgId:%d, query on table:%s, tid:%d, uid:%" PRIu64, pSql, htonl(pQueryMsg->head.vgId), n, pTableMeta->id.tid, pTableMeta->id.uid); + tscDebug("0x%"PRIx64" vgId:%d, query on table:%s, tid:%d, uid:%" PRIu64, pSql->self, htonl(pQueryMsg->head.vgId), n, pTableMeta->id.tid, pTableMeta->id.uid); return pMsg; } +// TODO refactor +static int32_t serializeColFilterInfo(SColumnFilterInfo* pColFilters, int16_t numOfFilters, char** pMsg) { + // append the filter information after the basic column information + for (int32_t f = 0; f < numOfFilters; ++f) { + SColumnFilterInfo *pColFilter = &pColFilters[f]; + + SColumnFilterInfo *pFilterMsg = (SColumnFilterInfo *)(*pMsg); + pFilterMsg->filterstr = htons(pColFilter->filterstr); + + (*pMsg) += sizeof(SColumnFilterInfo); + + 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; + } + } + + return TSDB_CODE_SUCCESS; +} + +static int32_t serializeSqlExpr(SSqlExpr* pExpr, STableMetaInfo* pTableMetaInfo, char** pMsg, void* addr) { + STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; + + // the queried table has been removed and a new table with the same name has already been created already + // return error msg + if (pExpr->uid != pTableMeta->id.uid) { + tscError("%p table has already been destroyed", addr); + return TSDB_CODE_TSC_INVALID_TABLE_NAME; + } + + //TODO disable it temporarily +// if (!tscValidateColumnId(pTableMetaInfo, pExpr->colInfo.colId, pExpr->numOfParams)) { +// tscError("%p table schema is not matched with parsed sql", addr); +// return TSDB_CODE_TSC_INVALID_SQL; +// } + + assert(pExpr->resColId < 0); + SSqlExpr* pSqlExpr = (SSqlExpr *)(*pMsg); + + SColIndex* pIndex = &pSqlExpr->colInfo; + + pIndex->colId = htons(pExpr->colInfo.colId); + pIndex->colIndex = htons(pExpr->colInfo.colIndex); + pIndex->flag = htons(pExpr->colInfo.flag); + pSqlExpr->uid = htobe64(pExpr->uid); + pSqlExpr->colType = htons(pExpr->colType); + pSqlExpr->colBytes = htons(pExpr->colBytes); + pSqlExpr->resType = htons(pExpr->resType); + pSqlExpr->resBytes = htons(pExpr->resBytes); + pSqlExpr->functionId = htons(pExpr->functionId); + pSqlExpr->numOfParams = htons(pExpr->numOfParams); + pSqlExpr->resColId = htons(pExpr->resColId); + pSqlExpr->flist.numOfFilters = htons(pExpr->flist.numOfFilters); + + (*pMsg) += sizeof(SSqlExpr); + for (int32_t j = 0; j < pExpr->numOfParams; ++j) { // todo add log + pSqlExpr->param[j].nType = htons((uint16_t)pExpr->param[j].nType); + pSqlExpr->param[j].nLen = htons(pExpr->param[j].nLen); + + if (pExpr->param[j].nType == TSDB_DATA_TYPE_BINARY) { + memcpy((*pMsg), pExpr->param[j].pz, pExpr->param[j].nLen); + (*pMsg) += pExpr->param[j].nLen; + } else { + pSqlExpr->param[j].i64 = htobe64(pExpr->param[j].i64); + } + } + + serializeColFilterInfo(pExpr->flist.filterInfo, pExpr->flist.numOfFilters, pMsg); + + return TSDB_CODE_SUCCESS; +} + int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SSqlCmd *pCmd = &pSql->cmd; + int32_t code = TSDB_CODE_SUCCESS; int32_t size = tscEstimateQueryMsgSize(pSql, pCmd->clauseIndex); if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) { tscError("%p failed to malloc for query msg", pSql); return TSDB_CODE_TSC_INVALID_SQL; // todo add test for this } - - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + + SQueryInfo *pQueryInfo = tscGetActiveQueryInfo(pCmd); + + SQueryAttr query = {{0}}; + tscCreateQueryFromQueryInfo(pQueryInfo, &query, pSql); + + SArray* tableScanOperator = createTableScanPlan(&query); + SArray* queryOperator = createExecOperatorPlan(&query); + STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableMeta * pTableMeta = pTableMetaInfo->pTableMeta; - size_t numOfSrcCols = taosArrayGetSize(pQueryInfo->colList); - if (numOfSrcCols <= 0 && !tscQueryTags(pQueryInfo) && !tscQueryBlockInfo(pQueryInfo)) { - tscError("%p illegal value of numOfCols in query msg: %" PRIu64 ", table cols:%d", pSql, (uint64_t)numOfSrcCols, - tscGetNumOfColumns(pTableMeta)); - - return TSDB_CODE_TSC_INVALID_SQL; - } - - if (pQueryInfo->interval.interval < 0) { - tscError("%p illegal value of aggregation time interval in query msg: %" PRId64, pSql, (int64_t)pQueryInfo->interval.interval); - return TSDB_CODE_TSC_INVALID_SQL; - } - - if (pQueryInfo->groupbyExpr.numOfGroupCols < 0) { - tscError("%p illegal value of numOfGroupCols in query msg: %d", pSql, pQueryInfo->groupbyExpr.numOfGroupCols); - return TSDB_CODE_TSC_INVALID_SQL; - } - SQueryTableMsg *pQueryMsg = (SQueryTableMsg *)pCmd->payload; tstrncpy(pQueryMsg->version, version, tListLen(pQueryMsg->version)); - int32_t numOfTags = (int32_t)taosArrayGetSize(pTableMetaInfo->tagColList); + int32_t numOfTags = query.numOfTags; int32_t sqlLen = (int32_t) strlen(pSql->sqlstr); - if (pQueryInfo->order.order == TSDB_ORDER_ASC) { - pQueryMsg->window.skey = htobe64(pQueryInfo->window.skey); - pQueryMsg->window.ekey = htobe64(pQueryInfo->window.ekey); + if (taosArrayGetSize(tableScanOperator) == 0) { + pQueryMsg->tableScanOperator = htonl(-1); } else { - pQueryMsg->window.skey = htobe64(pQueryInfo->window.ekey); - pQueryMsg->window.ekey = htobe64(pQueryInfo->window.skey); + int32_t* tablescanOp = taosArrayGet(tableScanOperator, 0); + pQueryMsg->tableScanOperator = htonl(*tablescanOp); } - pQueryMsg->order = htons(pQueryInfo->order.order); - pQueryMsg->orderColId = htons(pQueryInfo->order.orderColId); - pQueryMsg->fillType = htons(pQueryInfo->fillType); - pQueryMsg->limit = htobe64(pQueryInfo->limit.limit); - pQueryMsg->offset = htobe64(pQueryInfo->limit.offset); - pQueryMsg->numOfCols = htons((int16_t)taosArrayGetSize(pQueryInfo->colList)); - pQueryMsg->interval.interval = htobe64(pQueryInfo->interval.interval); - pQueryMsg->interval.sliding = htobe64(pQueryInfo->interval.sliding); - pQueryMsg->interval.offset = htobe64(pQueryInfo->interval.offset); - pQueryMsg->interval.intervalUnit = pQueryInfo->interval.intervalUnit; - pQueryMsg->interval.slidingUnit = pQueryInfo->interval.slidingUnit; - pQueryMsg->interval.offsetUnit = pQueryInfo->interval.offsetUnit; + pQueryMsg->window.skey = htobe64(query.window.skey); + pQueryMsg->window.ekey = htobe64(query.window.ekey); + + pQueryMsg->order = htons(query.order.order); + pQueryMsg->orderColId = htons(query.order.orderColId); + pQueryMsg->fillType = htons(query.fillType); + pQueryMsg->limit = htobe64(query.limit.limit); + pQueryMsg->offset = htobe64(query.limit.offset); + pQueryMsg->numOfCols = htons(query.numOfCols); + + pQueryMsg->interval.interval = htobe64(query.interval.interval); + pQueryMsg->interval.sliding = htobe64(query.interval.sliding); + pQueryMsg->interval.offset = htobe64(query.interval.offset); + pQueryMsg->interval.intervalUnit = query.interval.intervalUnit; + pQueryMsg->interval.slidingUnit = query.interval.slidingUnit; + pQueryMsg->interval.offsetUnit = query.interval.offsetUnit; + + pQueryMsg->stableQuery = query.stableQuery; + pQueryMsg->topBotQuery = query.topBotQuery; + pQueryMsg->groupbyColumn = query.groupbyColumn; + pQueryMsg->hasTagResults = query.hasTagResults; + pQueryMsg->timeWindowInterpo = query.timeWindowInterpo; + pQueryMsg->queryBlockDist = query.queryBlockDist; + pQueryMsg->stabledev = query.stabledev; + pQueryMsg->tsCompQuery = query.tsCompQuery; + pQueryMsg->simpleAgg = query.simpleAgg; + pQueryMsg->pointInterpQuery = query.pointInterpQuery; + pQueryMsg->needReverseScan = query.needReverseScan; + + pQueryMsg->numOfTags = htonl(numOfTags); + pQueryMsg->sqlstrLen = htonl(sqlLen); + pQueryMsg->sw.gap = htobe64(query.sw.gap); + pQueryMsg->sw.primaryColId = htonl(PRIMARYKEY_TIMESTAMP_COL_INDEX); + + pQueryMsg->secondStageOutput = htonl(query.numOfExpr2); + pQueryMsg->numOfOutput = htons((int16_t)query.numOfOutput); // this is the stage one output column number + pQueryMsg->numOfGroupCols = htons(pQueryInfo->groupbyExpr.numOfGroupCols); pQueryMsg->tagNameRelType = htons(pQueryInfo->tagCond.relType); pQueryMsg->tbnameCondLen = htonl(pQueryInfo->tagCond.tbnameCond.len); - pQueryMsg->numOfTags = htonl(numOfTags); pQueryMsg->queryType = htonl(pQueryInfo->type); - pQueryMsg->vgroupLimit = htobe64(pQueryInfo->vgroupLimit); - pQueryMsg->sqlstrLen = htonl(sqlLen); pQueryMsg->prevResultLen = htonl(pQueryInfo->bufLen); - pQueryMsg->sw.gap = htobe64(pQueryInfo->sessionWindow.gap); - pQueryMsg->sw.primaryColId = htonl(PRIMARYKEY_TIMESTAMP_COL_INDEX); - - if (pCmd->pUdfInfo != NULL) { - pQueryMsg->udfNum = htonl((uint32_t) taosArrayGetSize(pCmd->pUdfInfo)); - } else { - pQueryMsg->udfNum = 0; - } - - size_t numOfOutput = tscSqlExprNumOfExprs(pQueryInfo); - pQueryMsg->numOfOutput = htons((int16_t)numOfOutput); // this is the stage one output column number // set column list ids size_t numOfCols = taosArrayGetSize(pQueryInfo->colList); - char *pMsg = (char *)(pQueryMsg->colList) + numOfCols * sizeof(SColumnInfo); - SSchema *pSchema = tscGetTableSchema(pTableMeta); - + char *pMsg = (char *)(pQueryMsg->tableCols) + numOfCols * sizeof(SColumnInfo); + for (int32_t i = 0; i < numOfCols; ++i) { - SColumn *pCol = taosArrayGetP(pQueryInfo->colList, i); - SSchema *pColSchema = &pSchema[pCol->colIndex.columnIndex]; + SColumnInfo *pCol = &query.tableCols[i]; - if (pCol->colIndex.columnIndex >= tscGetNumOfColumns(pTableMeta) || !isValidDataType(pColSchema->type)) { - char n[TSDB_TABLE_FNAME_LEN] = {0}; - tNameExtractFullName(&pTableMetaInfo->name, n); - - - tscError("%p tid:%d uid:%" PRIu64" id:%s, column index out of range, numOfColumns:%d, index:%d, column name:%s", - pSql, pTableMeta->id.tid, pTableMeta->id.uid, n, tscGetNumOfColumns(pTableMeta), pCol->colIndex.columnIndex, - pColSchema->name); - return TSDB_CODE_TSC_INVALID_SQL; - } - - pQueryMsg->colList[i].colId = htons(pColSchema->colId); - pQueryMsg->colList[i].bytes = htons(pColSchema->bytes); - pQueryMsg->colList[i].type = htons(pColSchema->type); - pQueryMsg->colList[i].numOfFilters = htons(pCol->numOfFilters); + pQueryMsg->tableCols[i].colId = htons(pCol->colId); + pQueryMsg->tableCols[i].bytes = htons(pCol->bytes); + pQueryMsg->tableCols[i].type = htons(pCol->type); + pQueryMsg->tableCols[i].flist.numOfFilters = htons(pCol->flist.numOfFilters); // append the filter information after the basic column information - for (int32_t f = 0; f < pCol->numOfFilters; ++f) { - SColumnFilterInfo *pColFilter = &pCol->filterInfo[f]; + serializeColFilterInfo(pCol->flist.filterInfo, pCol->flist.numOfFilters, &pMsg); + } - SColumnFilterInfo *pFilterMsg = (SColumnFilterInfo *)pMsg; - pFilterMsg->filterstr = htons(pColFilter->filterstr); - - pMsg += sizeof(SColumnFilterInfo); - - 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 i = 0; i < query.numOfOutput; ++i) { + code = serializeSqlExpr(&query.pExpr1[i].base, pTableMetaInfo, &pMsg, pSql); + if (code != TSDB_CODE_SUCCESS) { + goto _end; } } - SSqlFuncMsg *pSqlFuncExpr = (SSqlFuncMsg *)pMsg; - for (int32_t i = 0; i < tscSqlExprNumOfExprs(pQueryInfo); ++i) { - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i); - - // the queried table has been removed and a new table with the same name has already been created already - // return error msg - if (pExpr->uid != pTableMeta->id.uid) { - tscError("%p table has already been destroyed", pSql); - return TSDB_CODE_TSC_INVALID_TABLE_NAME; + for (int32_t i = 0; i < query.numOfExpr2; ++i) { + code = serializeSqlExpr(&query.pExpr2[i].base, pTableMetaInfo, &pMsg, pSql); + if (code != TSDB_CODE_SUCCESS) { + goto _end; } - - if (!tscValidateColumnId(pTableMetaInfo, pExpr->colInfo.colId, pExpr->numOfParams)) { - tscError("%p table schema is not matched with parsed sql", pSql); - return TSDB_CODE_TSC_INVALID_SQL; - } - - assert(pExpr->resColId < 0); - - pSqlFuncExpr->colInfo.colId = htons(pExpr->colInfo.colId); - pSqlFuncExpr->colInfo.colIndex = htons(pExpr->colInfo.colIndex); - pSqlFuncExpr->colInfo.flag = htons(pExpr->colInfo.flag); - - if (TSDB_COL_IS_UD_COL(pExpr->colInfo.flag)) { - pSqlFuncExpr->colType = htons(pExpr->resType); - pSqlFuncExpr->colBytes = htons(pExpr->resBytes); - } else if (pExpr->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) { - SSchema *s = tGetTbnameColumnSchema(); - - pSqlFuncExpr->colType = htons(s->type); - pSqlFuncExpr->colBytes = htons(s->bytes); - } else if (pExpr->colInfo.colId == TSDB_BLOCK_DIST_COLUMN_INDEX) { - SSchema s = tGetBlockDistColumnSchema(); - - pSqlFuncExpr->colType = htons(s.type); - pSqlFuncExpr->colBytes = htons(s.bytes); - } else { - SSchema* s = tscGetColumnSchemaById(pTableMeta, pExpr->colInfo.colId); - pSqlFuncExpr->colType = htons(s->type); - pSqlFuncExpr->colBytes = htons(s->bytes); - } - - 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); - - if (pExpr->param[j].nType == TSDB_DATA_TYPE_BINARY) { - memcpy(pMsg, pExpr->param[j].pz, pExpr->param[j].nLen); - pMsg += pExpr->param[j].nLen; - } else { - pSqlFuncExpr->arg[j].argValue.i64 = htobe64(pExpr->param[j].i64); - } - } - - pSqlFuncExpr = (SSqlFuncMsg *)pMsg; - } - - size_t output = tscNumOfFields(pQueryInfo); - - if (tscIsSecondStageQuery(pCmd, pQueryInfo)) { - pQueryMsg->secondStageOutput = htonl((int32_t) output); - - SSqlFuncMsg *pSqlFuncExpr1 = (SSqlFuncMsg *)pMsg; - - for (int32_t i = 0; i < output; ++i) { - SInternalField* pField = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i); - SSqlExpr *pExpr = pField->pSqlExpr; - - // this should be switched to projection query - if (pExpr != NULL) { - // the queried table has been removed and a new table with the same name has already been created already - // return error msg - if (pExpr->uid != pTableMeta->id.uid) { - tscError("%p table has already been destroyed", pSql); - return TSDB_CODE_TSC_INVALID_TABLE_NAME; - } - - if (!tscValidateColumnId(pTableMetaInfo, pExpr->colInfo.colId, pExpr->numOfParams)) { - tscError("%p table schema is not matched with parsed sql", pSql); - return TSDB_CODE_TSC_INVALID_SQL; - } - - pSqlFuncExpr1->numOfParams = 0; // no params for projection query - pSqlFuncExpr1->functionId = htons(TSDB_FUNC_PRJ); - pSqlFuncExpr1->colInfo.colId = htons(pExpr->resColId); - pSqlFuncExpr1->colInfo.flag = htons(TSDB_COL_NORMAL); - - bool assign = false; - for (int32_t f = 0; f < tscSqlExprNumOfExprs(pQueryInfo); ++f) { - SSqlExpr *pe = tscSqlExprGet(pQueryInfo, f); - if (pe == pExpr) { - pSqlFuncExpr1->colInfo.colIndex = htons(f); - pSqlFuncExpr1->colType = htons(pe->resType); - pSqlFuncExpr1->colBytes = htons(pe->resBytes); - assign = true; - break; - } - } - - assert(assign); - pMsg += sizeof(SSqlFuncMsg); - pSqlFuncExpr1 = (SSqlFuncMsg *)pMsg; - } else { - assert(pField->pArithExprInfo != NULL); - SExprInfo* pExprInfo = pField->pArithExprInfo; - - pSqlFuncExpr1->colInfo.colId = htons(pExprInfo->base.colInfo.colId); - pSqlFuncExpr1->functionId = htons(pExprInfo->base.functionId); - pSqlFuncExpr1->numOfParams = htons(pExprInfo->base.numOfParams); - pMsg += sizeof(SSqlFuncMsg); - - for (int32_t j = 0; j < pExprInfo->base.numOfParams; ++j) { - // todo add log - pSqlFuncExpr1->arg[j].argType = htons((uint16_t)pExprInfo->base.arg[j].argType); - pSqlFuncExpr1->arg[j].argBytes = htons(pExprInfo->base.arg[j].argBytes); - - if (pExprInfo->base.arg[j].argType == TSDB_DATA_TYPE_BINARY) { - memcpy(pMsg, pExprInfo->base.arg[j].argValue.pz, pExprInfo->base.arg[j].argBytes); - pMsg += pExprInfo->base.arg[j].argBytes; - } else { - pSqlFuncExpr1->arg[j].argValue.i64 = htobe64(pExprInfo->base.arg[j].argValue.i64); - } - } - - pSqlFuncExpr1 = (SSqlFuncMsg *)pMsg; - } - } - } else { - pQueryMsg->secondStageOutput = 0; } int32_t succeed = 1; - + // serialize the table info (sid, uid, tags) - pMsg = doSerializeTableInfo(pQueryMsg, pSql, pMsg, &succeed); + pMsg = doSerializeTableInfo(pQueryMsg, pSql, pTableMetaInfo, pMsg, &succeed); if (succeed == 0) { - return TSDB_CODE_TSC_APP_ERROR; + code = TSDB_CODE_TSC_APP_ERROR; + goto _end; } - SSqlGroupbyExpr *pGroupbyExpr = &pQueryInfo->groupbyExpr; + SSqlGroupbyExpr *pGroupbyExpr = query.pGroupbyExpr; if (pGroupbyExpr->numOfGroupCols > 0) { pQueryMsg->orderByIdx = htons(pGroupbyExpr->orderIndex); pQueryMsg->orderType = htons(pGroupbyExpr->orderType); for (int32_t j = 0; j < pGroupbyExpr->numOfGroupCols; ++j) { SColIndex* pCol = taosArrayGet(pGroupbyExpr->columnInfo, j); - + *((int16_t *)pMsg) = htons(pCol->colId); pMsg += sizeof(pCol->colId); @@ -1053,48 +947,29 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { *((int16_t *)pMsg) += htons(pCol->flag); pMsg += sizeof(pCol->flag); - + memcpy(pMsg, pCol->name, tListLen(pCol->name)); pMsg += tListLen(pCol->name); } } - if (pQueryInfo->fillType != TSDB_FILL_NONE) { - for (int32_t i = 0; i < tscSqlExprNumOfExprs(pQueryInfo); ++i) { - *((int64_t *)pMsg) = htobe64(pQueryInfo->fillVal[i]); - pMsg += sizeof(pQueryInfo->fillVal[0]); + if (query.fillType != TSDB_FILL_NONE) { + for (int32_t i = 0; i < query.numOfOutput; ++i) { + *((int64_t *)pMsg) = htobe64(query.fillVal[i]); + pMsg += sizeof(query.fillVal[0]); } } - - if (numOfTags != 0) { - int32_t numOfColumns = tscGetNumOfColumns(pTableMeta); - int32_t numOfTagColumns = tscGetNumOfTags(pTableMeta); - int32_t total = numOfTagColumns + numOfColumns; - - pSchema = tscGetTableTagSchema(pTableMeta); - - for (int32_t i = 0; i < numOfTags; ++i) { - SColumn *pCol = taosArrayGetP(pTableMetaInfo->tagColList, i); - SSchema *pColSchema = &pSchema[pCol->colIndex.columnIndex]; - if ((pCol->colIndex.columnIndex >= numOfTagColumns || pCol->colIndex.columnIndex < -1) || - (!isValidDataType(pColSchema->type))) { - char n[TSDB_TABLE_FNAME_LEN] = {0}; - tNameExtractFullName(&pTableMetaInfo->name, n); + if (query.numOfTags > 0) { + for (int32_t i = 0; i < query.numOfTags; ++i) { + SColumnInfo* pTag = &query.tagColList[i]; - tscError("%p tid:%d uid:%" PRIu64 " id:%s, tag index out of range, totalCols:%d, numOfTags:%d, index:%d, column name:%s", - pSql, pTableMeta->id.tid, pTableMeta->id.uid, n, total, numOfTagColumns, pCol->colIndex.columnIndex, pColSchema->name); - - return TSDB_CODE_TSC_INVALID_SQL; - } - SColumnInfo* pTagCol = (SColumnInfo*) pMsg; - - pTagCol->colId = htons(pColSchema->colId); - pTagCol->bytes = htons(pColSchema->bytes); - pTagCol->type = htons(pColSchema->type); - pTagCol->numOfFilters = 0; - + pTagCol->colId = htons(pTag->colId); + pTagCol->bytes = htons(pTag->bytes); + pTagCol->type = htons(pTag->type); + pTagCol->flist.numOfFilters = 0; + pMsg += sizeof(SColumnInfo); } } @@ -1102,12 +977,12 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { // serialize tag column query condition if (pQueryInfo->tagCond.pCond != NULL && taosArrayGetSize(pQueryInfo->tagCond.pCond) > 0) { STagCond* pTagCond = &pQueryInfo->tagCond; - + SCond *pCond = tsGetSTableQueryCond(pTagCond, pTableMeta->id.uid); if (pCond != NULL && pCond->cond != NULL) { pQueryMsg->tagCondLen = htons(pCond->len); memcpy(pMsg, pCond->cond, pCond->len); - + pMsg += pCond->len; } } @@ -1124,21 +999,30 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } // compressed ts block - pQueryMsg->tsOffset = htonl((int32_t)(pMsg - pCmd->payload)); + pQueryMsg->tsBuf.tsOffset = htonl((int32_t)(pMsg - pCmd->payload)); if (pQueryInfo->tsBuf != NULL) { // note: here used the index instead of actual vnode id. int32_t vnodeIndex = pTableMetaInfo->vgroupIndex; - int32_t code = dumpFileBlockByGroupId(pQueryInfo->tsBuf, vnodeIndex, pMsg, &pQueryMsg->tsLen, &pQueryMsg->tsNumOfBlocks); + code = dumpFileBlockByGroupId(pQueryInfo->tsBuf, vnodeIndex, pMsg, &pQueryMsg->tsBuf.tsLen, &pQueryMsg->tsBuf.tsNumOfBlocks); if (code != TSDB_CODE_SUCCESS) { - return code; + goto _end; } - pMsg += pQueryMsg->tsLen; + pMsg += pQueryMsg->tsBuf.tsLen; - pQueryMsg->tsOrder = htonl(pQueryInfo->tsBuf->tsOrder); - pQueryMsg->tsLen = htonl(pQueryMsg->tsLen); - pQueryMsg->tsNumOfBlocks = htonl(pQueryMsg->tsNumOfBlocks); + pQueryMsg->tsBuf.tsOrder = htonl(pQueryInfo->tsBuf->tsOrder); + pQueryMsg->tsBuf.tsLen = htonl(pQueryMsg->tsBuf.tsLen); + pQueryMsg->tsBuf.tsNumOfBlocks = htonl(pQueryMsg->tsBuf.tsNumOfBlocks); + } + + int32_t numOfOperator = (int32_t) taosArrayGetSize(queryOperator); + pQueryMsg->numOfOperator = htonl(numOfOperator); + for(int32_t i = 0; i < numOfOperator; ++i) { + int32_t *operator = taosArrayGet(queryOperator, i); + *(int32_t*)pMsg = htonl(*operator); + + pMsg += sizeof(int32_t); } // support only one udf @@ -1161,7 +1045,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { *(int32_t*) pMsg = htonl(pUdfInfo->bufSize); pMsg += sizeof(pUdfInfo->bufSize); - + pQueryMsg->udfContentLen = htonl(pUdfInfo->contLen); memcpy(pMsg, pUdfInfo->content, pUdfInfo->contLen); @@ -1174,14 +1058,18 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { int32_t msgLen = (int32_t)(pMsg - pCmd->payload); - tscDebug("%p msg built success, len:%d bytes", pSql, msgLen); + tscDebug("0x%"PRIx64" msg built success, len:%d bytes", pSql->self, msgLen); pCmd->payloadLen = msgLen; pSql->cmd.msgType = TSDB_MSG_TYPE_QUERY; - + pQueryMsg->head.contLen = htonl(msgLen); assert(msgLen + minMsgSize() <= (int32_t)pCmd->allocSize); - return TSDB_CODE_SUCCESS; + _end: + freeQueryAttr(&query); + taosArrayDestroy(tableScanOperator); + taosArrayDestroy(queryOperator); + return code; } int32_t tscBuildCreateDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) { @@ -1207,7 +1095,7 @@ int32_t tscBuildCreateFuncMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pCmd->msgType = TSDB_MSG_TYPE_CM_CREATE_FUNCTION; pCmd->payloadLen = sizeof(SCreateFuncMsg) + htonl(pCreateFuncMsg->codeLen); - + return TSDB_CODE_SUCCESS; } @@ -1342,7 +1230,7 @@ int32_t tscBuildDropFuncMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pCmd->msgType = TSDB_MSG_TYPE_CM_DROP_FUNCTION; pCmd->payloadLen = sizeof(SDropFuncMsg); - + return TSDB_CODE_SUCCESS; } @@ -1533,7 +1421,7 @@ int tscBuildCreateTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SSchema *pSchema; SSqlCmd *pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); // Reallocate the payload size @@ -1602,7 +1490,7 @@ int tscBuildCreateTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pMsg = (char *)pSchema; if (type == TSQL_CREATE_STREAM) { // check if it is a stream sql - SQuerySqlNode *pQuerySql = pInfo->pCreateTableInfo->pSelect; + SSqlNode *pQuerySql = pInfo->pCreateTableInfo->pSelect; strncpy(pMsg, pQuerySql->sqlstr.z, pQuerySql->sqlstr.n + 1); pCreateMsg->sqlLen = htons(pQuerySql->sqlstr.n + 1); @@ -1622,7 +1510,7 @@ int tscBuildCreateTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { } int tscEstimateAlterTableMsgLength(SSqlCmd *pCmd) { - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); return minMsgSize() + sizeof(SAlterTableMsg) + sizeof(SSchema) * tscNumOfFields(pQueryInfo) + TSDB_EXTRA_PAYLOAD_SIZE; } @@ -1631,7 +1519,7 @@ int tscBuildAlterTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { int msgLen = 0; SSqlCmd *pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); @@ -1680,7 +1568,7 @@ int tscBuildUpdateTagMsg(SSqlObj* pSql, SSqlInfo *pInfo) { SUpdateTableTagValMsg* pUpdateMsg = (SUpdateTableTagValMsg*) pCmd->payload; pCmd->payloadLen = htonl(pUpdateMsg->head.contLen); - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); STableMeta *pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta; SNewVgroupInfo vgroupInfo = {.vgId = -1}; @@ -1716,7 +1604,7 @@ int tscBuildRetrieveFromMgmtMsg(SSqlObj *pSql, SSqlInfo *pInfo) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); SRetrieveTableMsg *pRetrieveMsg = (SRetrieveTableMsg*)pCmd->payload; pRetrieveMsg->qId = htobe64(pSql->res.qId); pRetrieveMsg->free = htons(pQueryInfo->type); @@ -1740,7 +1628,7 @@ static int tscLocalResultCommonBuilder(SSqlObj *pSql, int32_t numOfRes) { pRes->row = 0; pRes->rspType = 1; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); if (tscCreateResPointerInfo(pRes, pQueryInfo) != TSDB_CODE_SUCCESS) { return pRes->code; } @@ -1788,16 +1676,32 @@ int tscProcessRetrieveLocalMergeRsp(SSqlObj *pSql) { return code; } - pRes->code = tscDoLocalMerge(pSql); + // global aggregation may be the upstream for parent query + SQueryInfo *pQueryInfo = tscGetActiveQueryInfo(pCmd); + if (pQueryInfo->pQInfo == NULL) { + STableGroupInfo tableGroupInfo = {.numOfTables = 1, .pGroupList = taosArrayInit(1, POINTER_BYTES),}; + tableGroupInfo.map = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK); - if (pRes->code == TSDB_CODE_SUCCESS && pRes->numOfRows > 0) { - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - tscCreateResPointerInfo(pRes, pQueryInfo); - tscSetResRawPtr(pRes, pQueryInfo); + STableKeyInfo tableKeyInfo = {.pTable = NULL, .lastKey = INT64_MIN}; + + SArray* group = taosArrayInit(1, sizeof(STableKeyInfo)); + taosArrayPush(group, &tableKeyInfo); + taosArrayPush(tableGroupInfo.pGroupList, &group); + + SExprInfo* list = calloc(tscSqlExprNumOfExprs(pQueryInfo), sizeof(SExprInfo)); + for(int32_t i = 0; i < tscSqlExprNumOfExprs(pQueryInfo); ++i) { + SExprInfo* pExprInfo = tscSqlExprGet(pQueryInfo, i); + list[i] = *pExprInfo; + } + + pQueryInfo->pQInfo = createQueryInfoFromQueryNode(pQueryInfo, list, &tableGroupInfo, NULL, NULL, pRes->pLocalMerger, MERGE_STAGE); } - pRes->row = 0; - pRes->completed = (pRes->numOfRows == 0); + uint64_t localQueryId = 0; + qTableQuery(pQueryInfo->pQInfo, &localQueryId); + convertQueryResult(pRes, pQueryInfo); + + handleDownstreamOperator(pRes, pQueryInfo); code = pRes->code; if (pRes->code == TSDB_CODE_SUCCESS) { @@ -1845,7 +1749,7 @@ int tscBuildConnectMsg(SSqlObj *pSql, SSqlInfo *pInfo) { int tscBuildTableMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SSqlCmd *pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableInfoMsg *pInfoMsg = (STableInfoMsg *)pCmd->payload; @@ -1903,7 +1807,7 @@ int tscBuildMultiMeterMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) { assert(pCmd->payloadLen + minMsgSize() <= pCmd->allocSize); - tscDebug("%p build load multi-metermeta msg completed, numOfTables:%d, msg size:%d", pSql, pCmd->count, + tscDebug("0x%"PRIx64" build load multi-metermeta msg completed, numOfTables:%d, msg size:%d", pSql->self, pCmd->count, pCmd->payloadLen); return pCmd->payloadLen; @@ -1915,7 +1819,7 @@ int tscBuildSTableVgroupMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SSqlCmd *pCmd = &pSql->cmd; char* pMsg = pCmd->payload; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); SSTableVgroupMsg *pStableVgroupMsg = (SSTableVgroupMsg *)pMsg; pStableVgroupMsg->numOfTables = htonl(pQueryInfo->numOfTables); @@ -2105,7 +2009,7 @@ int tscProcessTableMetaRsp(SSqlObj *pSql) { } } - tscDebug("%p recv table meta, uid:%" PRIu64 ", tid:%d, name:%s", pSql, pTableMeta->id.uid, pTableMeta->id.tid, + tscDebug("0x%"PRIx64" recv table meta, uid:%" PRIu64 ", tid:%d, name:%s", pSql->self, pTableMeta->id.uid, pTableMeta->id.tid, tNameGetTableName(&pTableMetaInfo->name)); free(pTableMeta); @@ -2212,7 +2116,7 @@ int tscProcessMultiMeterMetaRsp(SSqlObj *pSql) { pSql->res.code = TSDB_CODE_SUCCESS; pSql->res.numOfTotal = i; - tscDebug("%p load multi-metermeta resp from complete num:%d", pSql, pSql->res.numOfTotal); + tscDebug("0x%"PRIx64" load multi-metermeta resp from complete num:%d", pSql->self, pSql->res.numOfTotal); #endif return TSDB_CODE_SUCCESS; @@ -2347,7 +2251,7 @@ int tscProcessShowRsp(SSqlObj *pSql) { SSqlRes *pRes = &pSql->res; SSqlCmd *pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); @@ -2379,15 +2283,16 @@ int tscProcessShowRsp(SSqlObj *pSql) { SColumnIndex index = {0}; pSchema = pMetaMsg->schema; - + + uint64_t uid = pTableMetaInfo->pTableMeta->id.uid; for (int16_t i = 0; i < pMetaMsg->numOfColumns; ++i, ++pSchema) { index.columnIndex = i; - tscColumnListInsert(pQueryInfo->colList, &index); + tscColumnListInsert(pQueryInfo->colList, i, uid, pSchema); TAOS_FIELD f = tscCreateField(pSchema->type, pSchema->name, pSchema->bytes); SInternalField* pInfo = tscFieldInfoAppend(pFieldInfo, &f); - pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, + pInfo->pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, pTableSchema[i].type, pTableSchema[i].bytes, getNewResColId(pQueryInfo), pTableSchema[i].bytes, false); } @@ -2406,7 +2311,7 @@ static void createHbObj(STscObj* pObj) { pSql->fp = tscProcessHeartBeatRsp; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetailSafely(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfoS(&pSql->cmd, 0); if (pQueryInfo == NULL) { terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; tfree(pSql); @@ -2427,7 +2332,7 @@ static void createHbObj(STscObj* pObj) { pSql->signature = pSql; registerSqlObj(pSql); - tscDebug("%p HB is allocated, pObj:%p", pSql, pObj); + tscDebug("0x%"PRIx64" HB is allocated, pObj:%p", pSql->self, pObj); pObj->hbrid = pSql->self; } @@ -2453,7 +2358,7 @@ int tscProcessConnectRsp(SSqlObj *pSql) { tscUpdateMgmtEpSet(pSql, &pConnect->epSet); for (int i = 0; i < pConnect->epSet.numOfEps; ++i) { - tscDebug("%p epSet.fqdn[%d]: %s, pObj:%p", pSql, i, pConnect->epSet.fqdn[i], pObj); + tscDebug("0x%"PRIx64" epSet.fqdn[%d]: %s, pObj:%p", pSql->self, i, pConnect->epSet.fqdn[i], pObj); } } @@ -2497,9 +2402,9 @@ int tscProcessDropTableRsp(SSqlObj *pSql) { tNameExtractFullName(&pTableMetaInfo->name, name); taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN)); - tscDebug("%p remove table meta after drop table:%s, numOfRemain:%d", pSql, name, (int32_t) taosHashGetSize(tscTableMetaInfo)); + tscDebug("0x%"PRIx64" remove table meta after drop table:%s, numOfRemain:%d", pSql->self, name, (int32_t) taosHashGetSize(tscTableMetaInfo)); - pTableMetaInfo->pTableMeta = NULL; + tfree(pTableMetaInfo->pTableMeta); return 0; } @@ -2509,7 +2414,7 @@ int tscProcessAlterTableMsgRsp(SSqlObj *pSql) { char name[TSDB_TABLE_FNAME_LEN] = {0}; tNameExtractFullName(&pTableMetaInfo->name, name); - tscDebug("%p remove tableMeta in hashMap after alter-table: %s", pSql, name); + tscDebug("0x%"PRIx64" remove tableMeta in hashMap after alter-table: %s", pSql->self, name); bool isSuperTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo); taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN)); @@ -2534,13 +2439,14 @@ int tscProcessShowCreateRsp(SSqlObj *pSql) { int tscProcessQueryRsp(SSqlObj *pSql) { SSqlRes *pRes = &pSql->res; - SQueryTableRsp *pQuery = (SQueryTableRsp *)pRes->pRsp; - pQuery->qId = htobe64(pQuery->qId); - pRes->qId = pQuery->qId; + SQueryTableRsp *pQueryAttr = (SQueryTableRsp *)pRes->pRsp; + pQueryAttr->qId = htobe64(pQueryAttr->qId); + pRes->qId = pQueryAttr->qId; pRes->data = NULL; + tscResetForNextRetrieve(pRes); - tscDebug("%p query rsp received, qId:%"PRIu64, pSql, pRes->qId); + tscDebug("0x%"PRIx64" query rsp received, qId:0x%"PRIx64, pSql->self, pRes->qId); return 0; } @@ -2563,7 +2469,7 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) { pRes->completed = (pRetrieve->completed == 1); pRes->data = pRetrieve->data; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetActiveQueryInfo(pCmd); if (tscCreateResPointerInfo(pRes, pQueryInfo) != TSDB_CODE_SUCCESS) { return pRes->code; } @@ -2577,6 +2483,8 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) { tscSetResRawPtr(pRes, pQueryInfo); } + handleDownstreamOperator(pRes, pQueryInfo); + if (pSql->pSubscription != NULL) { int32_t numOfCols = pQueryInfo->fieldsInfo.numOfOutput; @@ -2598,7 +2506,7 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) { } pRes->row = 0; - tscDebug("%p numOfRows:%d, offset:%" PRId64 ", complete:%d, qId:%"PRIu64, pSql, pRes->numOfRows, pRes->offset, + tscDebug("0x%"PRIx64" numOfRows:%d, offset:%" PRId64 ", complete:%d, qId:0x%"PRIx64, pSql->self, pRes->numOfRows, pRes->offset, pRes->completed, pRes->qId); return 0; @@ -2617,9 +2525,9 @@ static int32_t getTableMetaFromMnode(SSqlObj *pSql, STableMetaInfo *pTableMetaIn pNew->signature = pNew; pNew->cmd.command = TSDB_SQL_META; - tscAddSubqueryInfo(&pNew->cmd); + tscAddQueryInfo(&pNew->cmd); - SQueryInfo *pNewQueryInfo = tscGetQueryInfoDetailSafely(&pNew->cmd, 0); + SQueryInfo *pNewQueryInfo = tscGetQueryInfoS(&pNew->cmd, 0); pNew->cmd.autoCreated = pSql->cmd.autoCreated; // create table if not exists if (TSDB_CODE_SUCCESS != tscAllocPayload(&pNew->cmd, TSDB_DEFAULT_PAYLOAD_SIZE + pSql->cmd.payloadLen)) { @@ -2642,18 +2550,18 @@ static int32_t getTableMetaFromMnode(SSqlObj *pSql, STableMetaInfo *pTableMetaIn } } - tscDebug("%p new pSqlObj:%p to get tableMeta, auto create:%d", pSql, pNew, pNew->cmd.autoCreated); - registerSqlObj(pNew); + tscDebug("0x%"PRIx64" new pSqlObj:0x%"PRIx64" to get tableMeta, auto create:%d", pSql->self, pNew->self, + pNew->cmd.autoCreated); pNew->fp = tscTableMetaCallBack; pNew->param = (void *)pSql->self; - tscDebug("%p metaRid from %" PRId64 " to %" PRId64 , pSql, pSql->metaRid, pNew->self); + tscDebug("0x%"PRIx64" metaRid from %" PRId64 " to %" PRId64 , pSql->self, pSql->metaRid, pNew->self); pSql->metaRid = pNew->self; - int32_t code = tscProcessSql(pNew); + int32_t code = tscBuildAndSendRequest(pNew, NULL); if (code == TSDB_CODE_SUCCESS) { code = TSDB_CODE_TSC_ACTION_IN_PROGRESS; // notify application that current process needs to be terminated } @@ -2735,7 +2643,7 @@ int32_t tscGetUdfFromNode(SSqlObj *pSql) { pSql->metaRid = pNew->self; - int32_t code = tscProcessSql(pNew); + int32_t code = tscBuildAndSendRequest(pNew, NULL); if (code == TSDB_CODE_SUCCESS) { code = TSDB_CODE_TSC_ACTION_IN_PROGRESS; // notify application that current process needs to be terminated } @@ -2752,7 +2660,7 @@ int32_t tscGetUdfFromNode(SSqlObj *pSql) { int tscRenewTableMeta(SSqlObj *pSql, int32_t tableIndex) { SSqlCmd *pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex); char name[TSDB_TABLE_FNAME_LEN] = {0}; @@ -2764,7 +2672,7 @@ int tscRenewTableMeta(SSqlObj *pSql, int32_t tableIndex) { STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; if (pTableMeta) { - tscDebug("%p update table meta:%s, old meta numOfTags:%d, numOfCols:%d, uid:%" PRId64, pSql, name, + tscDebug("0x%"PRIx64" update table meta:%s, old meta numOfTags:%d, numOfCols:%d, uid:%" PRId64, pSql->self, name, tscGetNumOfTags(pTableMeta), tscGetNumOfColumns(pTableMeta), pTableMeta->id.uid); } @@ -2776,7 +2684,7 @@ int tscRenewTableMeta(SSqlObj *pSql, int32_t tableIndex) { } static bool allVgroupInfoRetrieved(SSqlCmd* pCmd, int32_t clauseIndex) { - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, clauseIndex); for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i); if (pTableMetaInfo->vgroupList == NULL) { @@ -2803,13 +2711,13 @@ int tscGetSTableVgroupInfo(SSqlObj *pSql, int32_t clauseIndex) { pNew->cmd.command = TSDB_SQL_STABLEVGROUP; // TODO TEST IT - SQueryInfo *pNewQueryInfo = tscGetQueryInfoDetailSafely(&pNew->cmd, 0); + SQueryInfo *pNewQueryInfo = tscGetQueryInfoS(&pNew->cmd, 0); if (pNewQueryInfo == NULL) { tscFreeSqlObj(pNew); return code; } - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, clauseIndex); for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { STableMetaInfo *pMInfo = tscGetMetaInfo(pQueryInfo, i); STableMeta* pTableMeta = tscTableMetaDup(pMInfo->pTableMeta); @@ -2824,16 +2732,16 @@ int tscGetSTableVgroupInfo(SSqlObj *pSql, int32_t clauseIndex) { pNewQueryInfo->numOfTables = pQueryInfo->numOfTables; registerSqlObj(pNew); - tscDebug("%p svgroupRid from %" PRId64 " to %" PRId64 , pSql, pSql->svgroupRid, pNew->self); + tscDebug("0x%"PRIx64" svgroupRid from %" PRId64 " to %" PRId64 , pSql->self, pSql->svgroupRid, pNew->self); pSql->svgroupRid = pNew->self; - tscDebug("%p new sqlObj:%p to get vgroupInfo, numOfTables:%d", pSql, pNew, pNewQueryInfo->numOfTables); + tscDebug("0x%"PRIx64" new sqlObj:%p to get vgroupInfo, numOfTables:%d", pSql->self, pNew, pNewQueryInfo->numOfTables); pNew->fp = tscTableMetaCallBack; pNew->param = (void *)pSql->self; - code = tscProcessSql(pNew); + code = tscBuildAndSendRequest(pNew, NULL); if (code == TSDB_CODE_SUCCESS) { code = TSDB_CODE_TSC_ACTION_IN_PROGRESS; } @@ -2913,7 +2821,7 @@ void tscInitMsgsFp() { tscProcessMsgRsp[TSDB_SQL_SHOW_CREATE_TABLE] = tscProcessShowCreateRsp; tscProcessMsgRsp[TSDB_SQL_SHOW_CREATE_DATABASE] = tscProcessShowCreateRsp; - + tscKeepConn[TSDB_SQL_SHOW] = 1; tscKeepConn[TSDB_SQL_RETRIEVE] = 1; tscKeepConn[TSDB_SQL_SELECT] = 1; diff --git a/src/client/src/tscSql.c b/src/client/src/tscSql.c index 05d9a284ad..eb16adbad7 100644 --- a/src/client/src/tscSql.c +++ b/src/client/src/tscSql.c @@ -191,7 +191,7 @@ TAOS *taos_connect_internal(const char *ip, const char *user, const char *pass, pSql->fp = syncConnCallback; pSql->param = pSql; - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); tsem_wait(&pSql->rspSem); if (pSql->res.code != TSDB_CODE_SUCCESS) { @@ -265,7 +265,7 @@ TAOS *taos_connect_a(char *ip, char *user, char *pass, char *db, uint16_t port, if (taos) *taos = pObj; pSql->fetchFp = fp; - pSql->res.code = tscProcessSql(pSql); + pSql->res.code = tscBuildAndSendRequest(pSql, NULL); tscDebug("%p DB async connection is opening", taos); return pObj; } @@ -292,7 +292,7 @@ void taos_close(TAOS *taos) { pHb->rpcRid = -1; } - tscDebug("%p HB is freed", pHb); + tscDebug("0x%"PRIx64" HB is freed", pHb->self); taosReleaseRef(tscObjRef, pHb->self); #ifdef __APPLE__ // to satisfy later tsem_destroy in taos_free_result @@ -373,7 +373,7 @@ int taos_num_fields(TAOS_RES *res) { if (pSql == NULL || pSql->signature != pSql) return 0; int32_t num = 0; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); if (pQueryInfo == NULL) { return num; } @@ -408,7 +408,7 @@ TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) { SSqlRes *pRes = &pSql->res; if (pSql == NULL || pSql->signature != pSql) return 0; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); if (pQueryInfo == NULL) { return NULL; } @@ -559,9 +559,9 @@ static bool tscKillQueryInDnode(SSqlObj* pSql) { return true; } - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); - if ((pQueryInfo == NULL) || tscIsTwoStageSTableQuery(pCmd, pQueryInfo, 0)) { + if ((pQueryInfo == NULL) || pQueryInfo->globalMerge) { return true; } @@ -576,9 +576,9 @@ static bool tscKillQueryInDnode(SSqlObj* pSql) { cmd == TSDB_SQL_FETCH)) { pQueryInfo->type = TSDB_QUERY_TYPE_FREE_RESOURCE; pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH; - tscDebug("%p send msg to dnode to free qhandle ASAP before free sqlObj, command:%s", pSql, sqlCmd[pCmd->command]); + tscDebug("0x%"PRIx64" send msg to dnode to free qhandle ASAP before free sqlObj, command:%s", pSql->self, sqlCmd[pCmd->command]); - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); return false; } @@ -594,7 +594,7 @@ void taos_free_result(TAOS_RES *res) { bool freeNow = tscKillQueryInDnode(pSql); if (freeNow) { - tscDebug("%p free sqlObj in cache", pSql); + tscDebug("0x%"PRIx64" free sqlObj in cache", pSql->self); taosReleaseRef(tscObjRef, pSql->self); } } @@ -672,9 +672,9 @@ char *taos_get_client_info() { return version; } static void tscKillSTableQuery(SSqlObj *pSql) { SSqlCmd* pCmd = &pSql->cmd; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); - if (!tscIsTwoStageSTableQuery(pCmd, pQueryInfo, 0)) { + if (!pQueryInfo->globalMerge) { return; } @@ -708,7 +708,7 @@ static void tscKillSTableQuery(SSqlObj *pSql) { tscUnlockByThread(&pSql->squeryLock); - tscDebug("%p super table query cancelled", pSql); + tscDebug("0x%"PRIx64" super table query cancelled", pSql->self); } void taos_stop_query(TAOS_RES *res) { @@ -717,15 +717,15 @@ void taos_stop_query(TAOS_RES *res) { return; } - tscDebug("%p start to cancel query", res); + tscDebug("0x%"PRIx64" start to cancel query", pSql->self); SSqlCmd *pCmd = &pSql->cmd; // set the error code for master pSqlObj firstly pSql->res.code = TSDB_CODE_TSC_QUERY_CANCELLED; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); - if (tscIsTwoStageSTableQuery(pCmd, pQueryInfo, 0)) { + if (pQueryInfo->globalMerge) { assert(pSql->rpcRid <= 0); tscKillSTableQuery(pSql); } else { @@ -744,7 +744,7 @@ void taos_stop_query(TAOS_RES *res) { } } - tscDebug("%p query is cancelled", res); + tscDebug("0x%"PRIx64" query is cancelled", pSql->self); } bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) { @@ -753,7 +753,7 @@ bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) { return true; } - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); if (pQueryInfo == NULL) { return true; } @@ -877,7 +877,7 @@ int taos_validate_sql(TAOS *taos, const char *sql) { pRes->numOfClauseTotal = 0; - tscDebug("%p Valid SQL: %s pObj:%p", pSql, sql, pObj); + tscDebug("0x%"PRIx64" Valid SQL: %s pObj:%p", pSql->self, sql, pObj); int32_t sqlLen = (int32_t)strlen(sql); if (sqlLen > tsMaxSQLStringLen) { @@ -889,7 +889,7 @@ int taos_validate_sql(TAOS *taos, const char *sql) { pSql->sqlstr = realloc(pSql->sqlstr, sqlLen + 1); if (pSql->sqlstr == NULL) { tscError("%p failed to malloc sql string buffer", pSql); - tscDebug("%p Valid SQL result:%d, %s pObj:%p", pSql, pRes->code, taos_errstr(pSql), pObj); + tscDebug("0x%"PRIx64" Valid SQL result:%d, %s pObj:%p", pSql->self, pRes->code, taos_errstr(pSql), pObj); tfree(pSql); return TSDB_CODE_TSC_OUT_OF_MEMORY; } @@ -914,7 +914,7 @@ int taos_validate_sql(TAOS *taos, const char *sql) { } if (code != TSDB_CODE_SUCCESS) { - tscDebug("%p Valid SQL result:%d, %s pObj:%p", pSql, code, taos_errstr(pSql), pObj); + tscDebug("0x%"PRIx64" Valid SQL result:%d, %s pObj:%p", pSql->self, code, taos_errstr(pSql), pObj); } taos_free_result(pSql); @@ -933,7 +933,7 @@ static int tscParseTblNameList(SSqlObj *pSql, const char *tblNameList, int32_t t int code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH; char *str = (char *)tblNameList; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetailSafely(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfoS(pCmd, pCmd->clauseIndex); if (pQueryInfo == NULL) { pSql->res.code = terrno; return terrno; @@ -1027,7 +1027,7 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) { pRes->numOfClauseTotal = 0; assert(pSql->fp == NULL); - tscDebug("%p tableNameList: %s pObj:%p", pSql, tableNameList, pObj); + tscDebug("0x%"PRIx64" tableNameList: %s pObj:%p", pSql->self, tableNameList, pObj); int32_t tblListLen = (int32_t)strlen(tableNameList); if (tblListLen > MAX_TABLE_NAME_LENGTH) { @@ -1048,7 +1048,7 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) { /* * set the qhandle to 0 before return in order to erase the qhandle value assigned in the previous successful query. - * If qhandle is NOT set 0, the function of taos_free_result() will send message to server by calling tscProcessSql() + * If qhandle is NOT set 0, the function of taos_free_result() will send message to server by calling tscBuildAndSendRequest() * to free connection, which may cause segment fault, when the parse phrase is not even successfully executed. */ pRes->qId = 0; @@ -1061,7 +1061,7 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) { tscDoQuery(pSql); - tscDebug("%p load multi table meta result:%d %s pObj:%p", pSql, pRes->code, taos_errstr(pSql), pObj); + tscDebug("0x%"PRIx64" load multi-table meta result:%d %s pObj:%p", pSql->self, pRes->code, taos_errstr(pSql), pObj); if ((code = pRes->code) != TSDB_CODE_SUCCESS) { tscFreeSqlObj(pSql); } diff --git a/src/client/src/tscStream.c b/src/client/src/tscStream.c index 7699e6f459..2551662d93 100644 --- a/src/client/src/tscStream.c +++ b/src/client/src/tscStream.c @@ -37,8 +37,8 @@ static int64_t getDelayValueAfterTimewindowClosed(SSqlStream* pStream, int64_t l static bool isProjectStream(SQueryInfo* pQueryInfo) { for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId != TSDB_FUNC_PRJ) { + SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId != TSDB_FUNC_PRJ) { return false; } } @@ -70,7 +70,7 @@ static void setRetryInfo(SSqlStream* pStream, int32_t code) { pSql->res.code = code; int64_t retryDelayTime = tscGetRetryDelayTime(pStream, pStream->interval.sliding, pStream->precision); - tscDebug("%p stream:%p, get table Meta failed, retry in %" PRId64 "ms", pSql, pStream, retryDelayTime); + tscDebug("0x%"PRIx64" stream:%p, get table Meta failed, retry in %" PRId64 "ms", pSql->self, pStream, retryDelayTime); tscSetRetryTimer(pStream, pSql, retryDelayTime); } @@ -89,7 +89,7 @@ static void doLaunchQuery(void* param, TAOS_RES* tres, int32_t code) { return; } - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); code = tscGetTableMeta(pSql, pTableMetaInfo); @@ -101,14 +101,23 @@ static void doLaunchQuery(void* param, TAOS_RES* tres, int32_t code) { return; } + if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo) && (pTableMetaInfo->pVgroupTables == NULL) && (pTableMetaInfo->vgroupList == NULL || pTableMetaInfo->vgroupList->numOfVgroups <= 0)) { + tscDebug("%p empty vgroup list", pSql); + pTableMetaInfo->vgroupList = tscVgroupInfoClear(pTableMetaInfo->vgroupList); + code = TSDB_CODE_TSC_APP_ERROR; + } + // failed to get table Meta or vgroup list, retry in 10sec. if (code == TSDB_CODE_SUCCESS) { tscTansformFuncForSTableQuery(pQueryInfo); - tscDebug("%p stream:%p, start stream query on:%s", pSql, pStream, tNameGetTableName(&pTableMetaInfo->name)); + tscDebug("0x%"PRIx64" stream:%p, start stream query on:%s", pSql->self, pStream, tNameGetTableName(&pTableMetaInfo->name)); + + pQueryInfo->command = TSDB_SQL_SELECT; + pSql->cmd.active = pQueryInfo; pSql->fp = tscProcessStreamQueryCallback; pSql->fetchFp = tscProcessStreamQueryCallback; - tscDoQuery(pSql); + executeQuery(pSql, pQueryInfo); tscIncStreamExecutionCount(pStream); } else { setRetryInfo(pStream, code); @@ -130,8 +139,8 @@ static void tscProcessStreamTimer(void *handle, void *tmrId) { pStream->numOfRes = 0; // reset the numOfRes. SSqlObj *pSql = pStream->pSql; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); - tscDebug("%p add into timer", pSql); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); + tscDebug("0x%"PRIx64" add into timer", pSql->self); if (pStream->isProject) { /* @@ -208,7 +217,7 @@ static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOf static void tscStreamFillTimeGap(SSqlStream* pStream, TSKEY ts) { #if 0 SSqlObj * pSql = pStream->pSql; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); if (pQueryInfo->fillType != TSDB_FILL_SET_VALUE && pQueryInfo->fillType != TSDB_FILL_NULL) { return; @@ -237,7 +246,7 @@ static void tscStreamFillTimeGap(SSqlStream* pStream, TSKEY ts) { } if (rowNum > 0) { - tscDebug("%p stream:%p %d rows padded", pSql, pStream, rowNum); + tscDebug("0x%"PRIx64" stream:%p %d rows padded", pSql, pStream, rowNum); } pRes->numOfRows = 0; @@ -263,7 +272,7 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf for(int32_t i = 0; i < numOfRows; ++i) { TAOS_ROW row = taos_fetch_row(res); if (row != NULL) { - tscDebug("%p stream:%p fetch result", pSql, pStream); + tscDebug("0x%"PRIx64" stream:%p fetch result", pSql->self, pStream); tscStreamFillTimeGap(pStream, *(TSKEY*)row[0]); pStream->stime = *(TSKEY *)row[0]; // user callback function @@ -293,7 +302,7 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf pStream->stime += 1; } - tscDebug("%p stream:%p, query on:%s, fetch result completed, fetched rows:%" PRId64, pSql, pStream, tNameGetTableName(&pTableMetaInfo->name), + tscDebug("0x%"PRIx64" stream:%p, query on:%s, fetch result completed, fetched rows:%" PRId64, pSql->self, pStream, tNameGetTableName(&pTableMetaInfo->name), pStream->numOfRes); tfree(pTableMetaInfo->pTableMeta); @@ -318,8 +327,8 @@ static void tscSetRetryTimer(SSqlStream *pStream, SSqlObj *pSql, int64_t timer) /* * current time window will be closed, since it too early to exceed the maxRetentWindow value */ - tscDebug("%p stream:%p, etime:%" PRId64 " is too old, exceeds the max retention time window:%" PRId64 ", stop the stream", - pStream->pSql, pStream, pStream->stime, pStream->etime); + tscDebug("0x%"PRIx64" stream:%p, etime:%" PRId64 " is too old, exceeds the max retention time window:%" PRId64 ", stop the stream", + pStream->pSql->self, pStream, pStream->stime, pStream->etime); // TODO : How to terminate stream here if (pStream->callback) { // Callback function from upper level @@ -329,10 +338,10 @@ static void tscSetRetryTimer(SSqlStream *pStream, SSqlObj *pSql, int64_t timer) return; } - tscDebug("%p stream:%p, next start at %" PRId64 ", in %" PRId64 "ms. delay:%" PRId64 "ms qrange %" PRId64 "-%" PRId64, pStream->pSql, pStream, + tscDebug("0x%"PRIx64" stream:%p, next start at %" PRId64 ", in %" PRId64 "ms. delay:%" PRId64 "ms qrange %" PRId64 "-%" PRId64, pStream->pSql->self, pStream, now + timer, timer, delay, pStream->stime, etime); } else { - tscDebug("%p stream:%p, next start at %" PRId64 ", in %" PRId64 "ms. delay:%" PRId64 "ms qrange %" PRId64 "-%" PRId64, pStream->pSql, pStream, + tscDebug("0x%"PRIx64" stream:%p, next start at %" PRId64 ", in %" PRId64 "ms. delay:%" PRId64 "ms qrange %" PRId64 "-%" PRId64, pStream->pSql->self, pStream, pStream->stime, timer, delay, pStream->stime - pStream->interval.interval, pStream->stime - 1); } @@ -378,8 +387,8 @@ static void tscSetNextLaunchTimer(SSqlStream *pStream, SSqlObj *pSql) { */ timer = pStream->interval.sliding; if (pStream->stime > pStream->etime) { - tscDebug("%p stream:%p, stime:%" PRId64 " is larger than end time: %" PRId64 ", stop the stream", pStream->pSql, pStream, - pStream->stime, pStream->etime); + tscDebug("0x%"PRIx64" stream:%p, stime:%" PRId64 " is larger than end time: %" PRId64 ", stop the stream", + pStream->pSql->self, pStream, pStream->stime, pStream->etime); // TODO : How to terminate stream here if (pStream->callback) { // Callback function from upper level @@ -392,7 +401,7 @@ static void tscSetNextLaunchTimer(SSqlStream *pStream, SSqlObj *pSql) { int64_t stime = taosTimeTruncate(pStream->stime - 1, &pStream->interval, pStream->precision); //int64_t stime = taosGetIntervalStartTimestamp(pStream->stime - 1, pStream->interval.interval, pStream->interval.interval, pStream->interval.intervalUnit, pStream->precision); if (stime >= pStream->etime) { - tscDebug("%p stream:%p, stime:%" PRId64 " is larger than end time: %" PRId64 ", stop the stream", pStream->pSql, pStream, + tscDebug("0x%"PRIx64" stream:%p, stime:%" PRId64 " is larger than end time: %" PRId64 ", stop the stream", pStream->pSql->self, pStream, pStream->stime, pStream->etime); // TODO : How to terminate stream here if (pStream->callback) { @@ -402,10 +411,12 @@ static void tscSetNextLaunchTimer(SSqlStream *pStream, SSqlObj *pSql) { taos_close_stream(pStream); return; } - - timer = pStream->stime - taosGetTimestamp(pStream->precision); - if (timer < 0) { - timer = 0; + + if (pStream->stime > 0) { + timer = pStream->stime - taosGetTimestamp(pStream->precision); + if (timer < 0) { + timer = 0; + } } } @@ -422,7 +433,7 @@ static int32_t tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) { int64_t minIntervalTime = (pStream->precision == TSDB_TIME_PRECISION_MICRO) ? tsMinIntervalTime * 1000L : tsMinIntervalTime; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); if (!pStream->isProject && pQueryInfo->interval.interval == 0) { sprintf(pSql->cmd.payload, "the interval value is 0"); @@ -472,24 +483,27 @@ static int32_t tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) { } static int64_t tscGetStreamStartTimestamp(SSqlObj *pSql, SSqlStream *pStream, int64_t stime) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); if (pStream->isProject) { // no data in table, flush all data till now to destination meter, 10sec delay pStream->interval.interval = tsProjectExecInterval; pStream->interval.sliding = tsProjectExecInterval; - if (stime != 0) { // first projection start from the latest event timestamp + if (stime != INT64_MIN) { // first projection start from the latest event timestamp assert(stime >= pQueryInfo->window.skey); stime += 1; // exclude the last records from table } else { stime = pQueryInfo->window.skey; } } else { // timewindow based aggregation stream - if (stime == 0) { // no data in meter till now + if (stime == INT64_MIN) { // no data in meter till now if (pQueryInfo->window.skey != INT64_MIN) { stime = pQueryInfo->window.skey; + } else { + return stime; } + stime = taosTimeTruncate(stime, &pStream->interval, pStream->precision); } else { int64_t newStime = taosTimeTruncate(stime, &pStream->interval, pStream->precision); @@ -531,7 +545,7 @@ static void tscCreateStream(void *param, TAOS_RES *res, int code) { return; } - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); @@ -558,7 +572,7 @@ static void tscCreateStream(void *param, TAOS_RES *res, int code) { taosTmrReset(tscProcessStreamTimer, (int32_t)starttime, pStream, tscTmr, &pStream->pTimer); - tscDebug("%p stream:%p is opened, query on:%s, interval:%" PRId64 ", sliding:%" PRId64 ", first launched in:%" PRId64 ", sql:%s", pSql, + tscDebug("0x%"PRIx64" stream:%p is opened, query on:%s, interval:%" PRId64 ", sliding:%" PRId64 ", first launched in:%" PRId64 ", sql:%s", pSql->self, pStream, tNameGetTableName(&pTableMetaInfo->name), pStream->interval.interval, pStream->interval.sliding, starttime, pSql->sqlstr); } @@ -619,7 +633,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; @@ -645,7 +659,7 @@ void taos_close_stream(TAOS_STREAM *handle) { taosTmrStopA(&(pStream->pTimer)); - tscDebug("%p stream:%p is closed", pSql, pStream); + tscDebug("0x%"PRIx64" stream:%p is closed", pSql->self, pStream); // notify CQ to release the pStream object pStream->fp(pStream->param, NULL, NULL); pStream->pSql = NULL; diff --git a/src/client/src/tscSub.c b/src/client/src/tscSub.c index 1277a436a1..a32cadb907 100644 --- a/src/client/src/tscSub.c +++ b/src/client/src/tscSub.c @@ -284,7 +284,7 @@ static int tscUpdateSubscription(STscObj* pObj, SSub* pSub) { } size_t numOfTables = taosArrayGetSize(tables); - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); SArray* progress = taosArrayInit(numOfTables, sizeof(SSubscriptionProgress)); for( size_t i = 0; i < numOfTables; i++ ) { STidTags* tt = taosArrayGet( tables, i ); @@ -304,7 +304,7 @@ static int tscUpdateSubscription(STscObj* pObj, SSub* pSub) { } taosArrayDestroy(tables); - TSDB_QUERY_SET_TYPE(tscGetQueryInfoDetail(pCmd, 0)->type, TSDB_QUERY_TYPE_MULTITABLE_QUERY); + TSDB_QUERY_SET_TYPE(tscGetQueryInfo(pCmd, 0)->type, TSDB_QUERY_TYPE_MULTITABLE_QUERY); return 1; } @@ -487,11 +487,13 @@ TAOS_RES *taos_consume(TAOS_SUB *tsub) { if (pSql == NULL) { return NULL; } + if (pSub->pSql->self != 0) { taosReleaseRef(tscObjRef, pSub->pSql->self); } else { tscFreeSqlObj(pSub->pSql); } + pSub->pSql = pSql; pSql->pSubscription = pSub; } @@ -502,7 +504,7 @@ TAOS_RES *taos_consume(TAOS_SUB *tsub) { SSqlRes *pRes = &pSql->res; SSqlCmd *pCmd = &pSql->cmd; STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, 0); if (taosArrayGetSize(pSub->progress) > 0) { // fix crash in single table subscription size_t size = taosArrayGetSize(pSub->progress); @@ -555,7 +557,10 @@ TAOS_RES *taos_consume(TAOS_SUB *tsub) { pSql->fp = asyncCallback; pSql->fetchFp = asyncCallback; pSql->param = pSub; - tscDoQuery(pSql); + + pSql->cmd.active = pQueryInfo; + executeQuery(pSql, pQueryInfo); + tsem_wait(&pSub->sem); if (pRes->code != TSDB_CODE_SUCCESS) { diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index 3ae0d0f43a..d0c59525aa 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -25,6 +25,7 @@ #include "tsclient.h" #include "qUdf.h" #include "qUtil.h" +#include "qPlan.h" typedef struct SInsertSupporter { SSqlObj* pSql; @@ -32,7 +33,7 @@ typedef struct SInsertSupporter { } SInsertSupporter; static void freeJoinSubqueryObj(SSqlObj* pSql); -static bool tscHasRemainDataInSubqueryResultSet(SSqlObj *pSql); +//static bool tscHasRemainDataInSubqueryResultSet(SSqlObj *pSql); static int32_t tsCompare(int32_t order, int64_t left, int64_t right) { if (left == right) { @@ -82,14 +83,14 @@ static bool allSubqueryDone(SSqlObj *pParentSql) { SSubqueryState *subState = &pParentSql->subState; //lock in caller - tscDebug("%p total subqueries: %d", pParentSql, subState->numOfSub); + tscDebug("0x%"PRIx64" total subqueries: %d", pParentSql->self, subState->numOfSub); for (int i = 0; i < subState->numOfSub; i++) { if (0 == subState->states[i]) { - tscDebug("%p subquery:%p, index: %d NOT finished, abort query completion check", pParentSql, pParentSql->pSubs[i], i); + tscDebug("0x%"PRIx64" subquery:%p, index: %d NOT finished, abort query completion check", pParentSql->self, pParentSql->pSubs[i], i); done = false; break; } else { - tscDebug("%p subquery:%p, index: %d finished", pParentSql, pParentSql->pSubs[i], i); + tscDebug("0x%"PRIx64" subquery:%p, index: %d finished", pParentSql->self, pParentSql->pSubs[i], i); } } @@ -106,14 +107,14 @@ static bool subAndCheckDone(SSqlObj *pSql, SSqlObj *pParentSql, int idx) { bool done = allSubqueryDone(pParentSql); if (done) { - tscDebug("%p subquery:%p,%d all subs already done", pParentSql, pSql, idx); + tscDebug("0x%"PRIx64" subquery:%p,%d all subs already done", pParentSql->self, pSql, idx); pthread_mutex_unlock(&subState->mutex); return false; } - tscDebug("%p subquery:%p,%d state set to 1", pParentSql, pSql, idx); + tscDebug("0x%"PRIx64" subquery:%p,%d state set to 1", pParentSql->self, pSql, idx); subState->states[idx] = 1; @@ -127,7 +128,7 @@ static bool subAndCheckDone(SSqlObj *pSql, SSqlObj *pParentSql, int idx) { static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex); win->skey = INT64_MAX; win->ekey = INT64_MIN; @@ -143,7 +144,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { int32_t equalNum = 0; int32_t stackidx = 0; SMergeTsCtx* ctx = NULL; - SMergeTsCtx* pctx = NULL; + SMergeTsCtx* pctx = NULL; SMergeTsCtx* mainCtx = NULL; STSElem cur; STSElem prev; @@ -152,25 +153,25 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { for (int32_t i = 0; i < joinNum; ++i) { STSBuf* output = tsBufCreate(true, pQueryInfo->order.order); - SQueryInfo* pSubQueryInfo = tscGetQueryInfoDetail(&pSql->pSubs[i]->cmd, 0); + SQueryInfo* pSubQueryInfo = tscGetQueryInfo(&pSql->pSubs[i]->cmd, 0); pSubQueryInfo->tsBuf = output; - + SJoinSupporter* pSupporter = pSql->pSubs[i]->param; if (pSupporter->pTSBuf == NULL) { - tscDebug("%p at least one ts-comp is empty, 0 for secondary query after ts blocks intersecting", pSql); + tscDebug("0x%"PRIx64" at least one ts-comp is empty, 0 for secondary query after ts blocks intersecting", pSql->self); return 0; } tsBufResetPos(pSupporter->pTSBuf); if (!tsBufNextPos(pSupporter->pTSBuf)) { - tscDebug("%p input1 is empty, 0 for secondary query after ts blocks intersecting", pSql); + tscDebug("0x%"PRIx64" input1 is empty, 0 for secondary query after ts blocks intersecting", pSql->self); return 0; } - tscDebug("%p sub:%p table idx:%d, input group number:%d", pSql, pSql->pSubs[i], i, pSupporter->pTSBuf->numOfGroups); + tscDebug("0x%"PRIx64" sub:%p table idx:%d, input group number:%d", pSql->self, pSql->pSubs[i], i, pSupporter->pTSBuf->numOfGroups); ctxlist[i].p = pSupporter; ctxlist[i].res = output; @@ -202,7 +203,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { mainCtx = pctx; - while (1) { + while (1) { pctx = mainCtx; prev = tsBufGetElem(pctx->p->pTSBuf); @@ -218,9 +219,9 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { int32_t skipped = 0; - for (int32_t i = 1; i < tableNum; ++i) { + for (int32_t i = 1; i < tableNum; ++i) { SMergeTsCtx* tctx = &ctxlist[i]; - + // find the data in supporter2 with the same tag value STSElem e2 = tsBufFindElemStartPosByTag(tctx->p->pTSBuf, &tag); @@ -236,7 +237,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { stackidx = 0; continue; } - + tableMIdx = taosArrayGet(tsCond, ++slot); equalNum = 1; @@ -261,7 +262,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { if (ret == 0) { if (++equalNum < tableNum) { pctx = ctx; - + if (++slot >= tableNum) { slot = 0; } @@ -269,14 +270,14 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { tableMIdx = taosArrayGet(tsCond, slot); continue; } - + assert(stackidx == tableNum); if (pLimit->offset == 0 || pQueryInfo->interval.interval > 0 || QUERY_IS_STABLE_QUERY(pQueryInfo->type)) { if (win->skey > prev.ts) { win->skey = prev.ts; } - + if (win->ekey < prev.ts) { win->ekey = prev.ts; } @@ -284,8 +285,8 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { for (int32_t i = 0; i < stackidx; ++i) { SMergeTsCtx* tctx = ctxStack[i]; prev = tsBufGetElem(tctx->p->pTSBuf); - - tsBufAppend(tctx->res, prev.id, prev.tag, (const char*)&prev.ts, sizeof(prev.ts)); + + tsBufAppend(tctx->res, prev.id, prev.tag, (const char*)&prev.ts, sizeof(prev.ts)); } } else { pLimit->offset -= 1;//offset apply to projection? @@ -293,35 +294,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { for (int32_t i = 0; i < stackidx; ++i) { SMergeTsCtx* tctx = ctxStack[i]; - - if (!tsBufNextPos(tctx->p->pTSBuf) && tctx == mainCtx) { - mergeDone = 1; - } - tctx->numOfInput++; - } - if (mergeDone) { - break; - } - - stackidx = 0; - equalNum = 1; - - ctxStack[stackidx++] = pctx; - } else if (ret > 0) { - if (!tsBufNextPos(ctx->p->pTSBuf) && ctx == mainCtx) { - mergeDone = 1; - break; - } - - ctx->numOfInput++; - stackidx--; - } else { - stackidx--; - - for (int32_t i = 0; i < stackidx; ++i) { - SMergeTsCtx* tctx = ctxStack[i]; - if (!tsBufNextPos(tctx->p->pTSBuf) && tctx == mainCtx) { mergeDone = 1; } @@ -332,9 +305,37 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { break; } - stackidx = 0; + stackidx = 0; equalNum = 1; - + + ctxStack[stackidx++] = pctx; + } else if (ret > 0) { + if (!tsBufNextPos(ctx->p->pTSBuf) && ctx == mainCtx) { + mergeDone = 1; + break; + } + + ctx->numOfInput++; + stackidx--; + } else { + stackidx--; + + for (int32_t i = 0; i < stackidx; ++i) { + SMergeTsCtx* tctx = ctxStack[i]; + + if (!tsBufNextPos(tctx->p->pTSBuf) && tctx == mainCtx) { + mergeDone = 1; + } + tctx->numOfInput++; + } + + if (mergeDone) { + break; + } + + stackidx = 0; + equalNum = 1; + ctxStack[stackidx++] = pctx; } @@ -346,7 +347,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { slot = 0; stackidx = 0; - + skipRemainValue(mainCtx->p->pTSBuf, &tag); } @@ -368,7 +369,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { for (int32_t i = 0; i < joinNum; ++i) { tsBufFlush(ctxlist[i].res); - + tsBufDestroy(ctxlist[i].p->pTSBuf); ctxlist[i].p->pTSBuf = NULL; } @@ -376,11 +377,11 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, STimeWindow * win) { TSKEY et = taosGetTimestampUs(); for (int32_t i = 0; i < joinNum; ++i) { - tscDebug("%p sub:%p tblidx:%d, input:%" PRId64 ", final:%" PRId64 " in %d vnodes for secondary query after ts blocks " + tscDebug("0x%"PRIx64" sub:%p tblidx:%d, input:%" PRId64 ", final:%" PRId64 " in %d vnodes for secondary query after ts blocks " "intersecting, skey:%" PRId64 ", ekey:%" PRId64 ", numOfVnode:%d, elapsed time:%" PRId64 " us", - pSql, pSql->pSubs[i], i, ctxlist[i].numOfInput, ctxlist[i].res->numOfTotal, ctxlist[i].res->numOfGroups, win->skey, win->ekey, + pSql->self, pSql->pSubs[i], i, ctxlist[i].numOfInput, ctxlist[i].res->numOfTotal, ctxlist[i].res->numOfGroups, win->skey, win->ekey, tsBufGetNumOfGroup(ctxlist[i].res), et - st); - } + } return ctxlist[0].res->numOfTotal; } @@ -396,7 +397,7 @@ SJoinSupporter* tscCreateJoinSupporter(SSqlObj* pSql, int32_t index) { pSupporter->pObj = pSql; pSupporter->subqueryIndex = index; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex); memcpy(&pSupporter->interval, &pQueryInfo->interval, sizeof(pSupporter->interval)); pSupporter->limit = pQueryInfo->limit; @@ -451,25 +452,6 @@ static void tscDestroyJoinSupporter(SJoinSupporter* pSupporter) { free(pSupporter); } -/* - * need the secondary query process - * In case of count(ts)/count(*)/spread(ts) query, that are only applied to - * primary timestamp column , the secondary query is not necessary - * - */ -static UNUSED_FUNC bool needSecondaryQuery(SQueryInfo* pQueryInfo) { - size_t numOfCols = taosArrayGetSize(pQueryInfo->colList); - - for (int32_t i = 0; i < numOfCols; ++i) { - SColumn* base = taosArrayGet(pQueryInfo->colList, i); - if (base->colIndex.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) { - return true; - } - } - - return false; -} - static void filterVgroupTables(SQueryInfo* pQueryInfo, SArray* pVgroupTables) { int32_t num = 0; int32_t* list = NULL; @@ -550,7 +532,7 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { assert(numOfSub > 0); // scan all subquery, if one sub query has only ts, ignore it - tscDebug("%p start to launch secondary subqueries, %d out of %d needs to query", pSql, numOfSub, pSql->subState.numOfSub); + tscDebug("0x%"PRIx64" start to launch secondary subqueries, %d out of %d needs to query", pSql->self, numOfSub, pSql->subState.numOfSub); bool success = true; @@ -561,7 +543,7 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { pSupporter = pPrevSub->param; if (taosArrayGetSize(pSupporter->exprList) == 0) { - tscDebug("%p subIndex: %d, no need to launch query, ignore it", pSql, i); + tscDebug("0x%"PRIx64" subIndex: %d, no need to launch query, ignore it", pSql->self, i); tscDestroyJoinSupporter(pSupporter); taos_free_result(pPrevSub); @@ -570,7 +552,7 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { continue; } - SQueryInfo *pSubQueryInfo = tscGetQueryInfoDetail(&pPrevSub->cmd, 0); + SQueryInfo *pSubQueryInfo = tscGetQueryInfo(&pPrevSub->cmd, 0); STSBuf *pTsBuf = pSubQueryInfo->tsBuf; pSubQueryInfo->tsBuf = NULL; @@ -584,12 +566,11 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { success = false; break; } - tscClearSubqueryInfo(&pNew->cmd); pSql->pSubs[i] = pNew; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pNew->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pNew->cmd, 0); pQueryInfo->tsBuf = pTsBuf; // transfer the ownership of timestamp comp-z data to the new created object // set the second stage sub query for join process @@ -598,10 +579,11 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { tscTagCondCopy(&pQueryInfo->tagCond, &pSupporter->tagCond); - pQueryInfo->colList = pSupporter->colList; - pQueryInfo->exprList = pSupporter->exprList; - pQueryInfo->fieldsInfo = pSupporter->fieldsInfo; + pQueryInfo->colList = pSupporter->colList; + pQueryInfo->exprList = pSupporter->exprList; + pQueryInfo->fieldsInfo = pSupporter->fieldsInfo; pQueryInfo->groupbyExpr = pSupporter->groupInfo; + pQueryInfo->pUpstream = taosArrayInit(4, sizeof(POINTER_BYTES)); assert(pNew->subState.numOfSub == 0 && pNew->cmd.numOfClause == 1 && pQueryInfo->numOfTables == 1); @@ -621,22 +603,22 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { * during the timestamp intersection. */ pSupporter->limit = pQueryInfo->limit; - pQueryInfo->limit = pSupporter->limit; +// pQueryInfo->limit = pSupporter->limit; SColumnIndex index = {.tableIndex = 0, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX}; SSchema* s = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, 0); - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, 0); - int16_t funcId = pExpr->functionId; + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, 0); + int16_t funcId = pExpr->base.functionId; // add the invisible timestamp column - if ((pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) || + if ((pExpr->base.colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) || (funcId != TSDB_FUNC_TS && funcId != TSDB_FUNC_TS_DUMMY && funcId != TSDB_FUNC_PRJ)) { int16_t functionId = tscIsProjectionQuery(&pNew->cmd, pQueryInfo)? TSDB_FUNC_PRJ : TSDB_FUNC_TS; tscAddFuncInSelectClause(pQueryInfo, 0, functionId, &index, s, TSDB_COL_NORMAL); - tscPrintSelectClause(pNew, 0); + tscPrintSelNodeList(pNew, 0); tscFieldInfoUpdateOffset(pQueryInfo); pExpr = tscSqlExprGet(pQueryInfo, 0); @@ -648,8 +630,8 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { int16_t colId = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->id.uid); // set the tag column id for executor to extract correct tag value - pExpr->param[0] = (tVariant) {.i64 = colId, .nType = TSDB_DATA_TYPE_BIGINT, .nLen = sizeof(int64_t)}; - pExpr->numOfParams = 1; + pExpr->base.param[0] = (tVariant) {.i64 = colId, .nType = TSDB_DATA_TYPE_BIGINT, .nLen = sizeof(int64_t)}; + pExpr->base.numOfParams = 1; } if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { @@ -666,8 +648,8 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { subquerySetState(pPrevSub, &pSql->subState, i, 0); size_t numOfCols = taosArrayGetSize(pQueryInfo->colList); - tscDebug("%p subquery:%p tableIndex:%d, vgroupIndex:%d, type:%d, exprInfo:%" PRIzu ", colList:%" PRIzu ", fieldsInfo:%d, name:%s", - pSql, pNew, 0, pTableMetaInfo->vgroupIndex, pQueryInfo->type, taosArrayGetSize(pQueryInfo->exprList), + tscDebug("0x%"PRIx64" subquery:%p tableIndex:%d, vgroupIndex:%d, type:%d, exprInfo:%" PRIzu ", colList:%" PRIzu ", fieldsInfo:%d, name:%s", + pSql->self, pNew, 0, pTableMetaInfo->vgroupIndex, pQueryInfo->type, taosArrayGetSize(pQueryInfo->exprList), numOfCols, pQueryInfo->fieldsInfo.numOfOutput, tNameGetTableName(&pTableMetaInfo->name)); } @@ -686,7 +668,8 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { continue; } - tscDoQuery(pSql->pSubs[i]); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->pSubs[i]->cmd, 0); + executeQuery(pSql->pSubs[i], pQueryInfo); } return TSDB_CODE_SUCCESS; @@ -793,7 +776,7 @@ void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArr if (taosArrayGetSize(result) > 0) { SVgroupTableInfo* prevGroup = taosArrayGet(result, taosArrayGetSize(result) - 1); - tscDebug("%p vgId:%d, tables:%"PRIzu, pSql, prevGroup->vgInfo.vgId, taosArrayGetSize(prevGroup->itemList)); + tscDebug("0x%"PRIx64" vgId:%d, tables:%"PRIzu, pSql->self, prevGroup->vgInfo.vgId, taosArrayGetSize(prevGroup->itemList)); } taosArrayPush(result, &info); @@ -815,7 +798,7 @@ void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArr pTableMetaInfo->pVgroupTables = result; SVgroupTableInfo* g = taosArrayGet(result, taosArrayGetSize(result) - 1); - tscDebug("%p vgId:%d, tables:%"PRIzu, pSql, g->vgInfo.vgId, taosArrayGetSize(g->itemList)); + tscDebug("0x%"PRIx64" vgId:%d, tables:%"PRIzu, pSql->self, g->vgInfo.vgId, taosArrayGetSize(g->itemList)); } } @@ -824,7 +807,7 @@ static void issueTsCompQuery(SSqlObj* pSql, SJoinSupporter* pSupporter, SSqlObj* tscClearSubqueryInfo(pCmd); tscFreeSqlResult(pSql); - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, 0); assert(pQueryInfo->numOfTables == 1); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); @@ -843,10 +826,12 @@ static void issueTsCompQuery(SSqlObj* pSql, SJoinSupporter* pSupporter, SSqlObj* // set the tags value for ts_comp function if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, 0); + SExprInfo *pExpr = tscSqlExprGet(pQueryInfo, 0); int16_t tagColId = tscGetJoinTagColIdByUid(&pSupporter->tagCond, pTableMetaInfo->pTableMeta->id.uid); - pExpr->param->i64 = tagColId; - pExpr->numOfParams = 1; + pExpr->base.param[0].i64 = tagColId; + pExpr->base.param[0].nLen = sizeof(int64_t); + pExpr->base.param[0].nType = TSDB_DATA_TYPE_BIGINT; + pExpr->base.numOfParams = 1; } // add the filter tag column @@ -856,7 +841,7 @@ static void issueTsCompQuery(SSqlObj* pSql, SJoinSupporter* pSupporter, SSqlObj* for (int32_t i = 0; i < s; ++i) { SColumn *pCol = taosArrayGetP(pSupporter->colList, i); - if (pCol->numOfFilters > 0) { // copy to the pNew->cmd.colList if it is filtered. + if (pCol->info.flist.numOfFilters > 0) { // copy to the pNew->cmd.colList if it is filtered. SColumn *p = tscColumnClone(pCol); taosArrayPush(pQueryInfo->colList, &p); } @@ -871,7 +856,7 @@ static void issueTsCompQuery(SSqlObj* pSql, SJoinSupporter* pSupporter, SSqlObj* pParent, pSql, 0, pTableMetaInfo->vgroupIndex, pTableMetaInfo->vgroupList->numOfVgroups, pQueryInfo->type, tscSqlExprNumOfExprs(pQueryInfo), numOfCols, pQueryInfo->fieldsInfo.numOfOutput, tNameGetTableName(&pTableMetaInfo->name)); - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); } static bool checkForDuplicateTagVal(SSchema* pColSchema, SJoinSupporter* p1, SSqlObj* pPSqlObj) { @@ -904,19 +889,19 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar SSchema* pColSchema = tscGetColumnSchemaById(pTableMetaInfo->pTableMeta, tagColId); - tscDebug("%p all subquery retrieve complete, do tags match", pParentSql); + tscDebug("0x%"PRIx64" all subquery retrieve complete, do tags match", pParentSql->self); for (int32_t i = 0; i < joinNum; i++) { SJoinSupporter* p = pParentSql->pSubs[i]->param; ctxlist[i].p = p; ctxlist[i].res = taosArrayInit(p->num, size); - + tscDebug("Join %d - num:%d", i, p->num); - + // sort according to the tag valu qsort(p->pIdTagList, p->num, p->tagSize, tagValCompar); - + if (!checkForDuplicateTagVal(pColSchema, p, pParentSql)) { for (int32_t j = 0; j <= i; j++) { taosArrayDestroy(ctxlist[j].res); @@ -969,9 +954,9 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar mergeDone = 0; continue; } - + tableMIdx = taosArrayGet(tagCond, slot); - + pctx = &ctxlist[*tableMIdx]; prev = (STidTags*) varDataVal(pctx->p->pIdTagList + pctx->idx * pctx->p->tagSize); @@ -981,10 +966,10 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar tableMIdx = taosArrayGet(tagCond, ++slot); equalNum = 1; - + while (1) { ctx = &ctxlist[*tableMIdx]; - + cur = (STidTags*) varDataVal(ctx->p->pIdTagList + ctx->idx * ctx->p->tagSize); assert(cur->tid != 0 && prev->tid != 0); @@ -996,7 +981,7 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar if (++equalNum < tableNum) { prev = cur; pctx = ctx; - + if (++slot >= tableNum) { slot = 0; } @@ -1005,11 +990,11 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar continue; } - tscDebug("%p tag matched, vgId:%d, val:%d, tid:%d, uid:%"PRIu64", tid:%d, uid:%"PRIu64, pParentSql, prev->vgId, + tscDebug("0x%"PRIx64" tag matched, vgId:%d, val:%d, tid:%d, uid:%"PRIu64", tid:%d, uid:%"PRIu64, pParentSql->self, prev->vgId, *(int*) prev->tag, prev->tid, prev->uid, cur->tid, cur->uid); assert(stackidx == tableNum); - + for (int32_t i = 0; i < stackidx; ++i) { SMergeCtx* tctx = ctxStack[i]; prev = (STidTags*) varDataVal(tctx->p->pIdTagList + tctx->idx * tctx->p->tagSize); @@ -1019,7 +1004,7 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar for (int32_t i = 0; i < stackidx; ++i) { SMergeCtx* tctx = ctxStack[i]; - + if (++tctx->idx >= tctx->p->num) { mergeDone = 1; break; @@ -1032,19 +1017,19 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar stackidx = 0; equalNum = 1; - + prev = (STidTags*) varDataVal(pctx->p->pIdTagList + pctx->idx * pctx->p->tagSize); ctxStack[stackidx++] = pctx; } else if (ret > 0) { stackidx--; - + if (++ctx->idx >= ctx->p->num) { break; } } else { stackidx--; - + for (int32_t i = 0; i < stackidx; ++i) { SMergeCtx* tctx = ctxStack[i]; if (++tctx->idx >= tctx->p->num) { @@ -1057,9 +1042,9 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar break; } - stackidx = 0; + stackidx = 0; equalNum = 1; - + prev = (STidTags*) varDataVal(pctx->p->pIdTagList + pctx->idx * pctx->p->tagSize); ctxStack[stackidx++] = pctx; } @@ -1075,14 +1060,14 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar // reorganize the tid-tag value according to both the vgroup id and tag values // sort according to the tag value size_t num = taosArrayGetSize(ctxlist[i].res); - + qsort((ctxlist[i].res)->pData, num, size, tidTagsCompar); taosArrayPush(resList, &ctxlist[i].res); - tscDebug("%p tags match complete, result num: %"PRIzu, pParentSql, num); + tscDebug("0x%"PRIx64" tags match complete, result num: %"PRIzu, pParentSql->self, num); } - + return TSDB_CODE_SUCCESS; } @@ -1111,7 +1096,7 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); // todo, the type may not include TSDB_QUERY_TYPE_TAG_FILTER_QUERY assert(TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TAG_FILTER_QUERY)); @@ -1184,22 +1169,22 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow pTableMetaInfo->vgroupIndex += 1; assert(pTableMetaInfo->vgroupIndex < totalVgroups); - tscDebug("%p tid_tag from vgroup index:%d completed, try next vgroup:%d. total vgroups:%d. current numOfRes:%d", - pSql, pTableMetaInfo->vgroupIndex - 1, pTableMetaInfo->vgroupIndex, totalVgroups, pSupporter->num); + tscDebug("0x%"PRIx64" tid_tag from vgroup index:%d completed, try next vgroup:%d. total vgroups:%d. current numOfRes:%d", + pSql->self, pTableMetaInfo->vgroupIndex - 1, pTableMetaInfo->vgroupIndex, totalVgroups, pSupporter->num); pCmd->command = TSDB_SQL_SELECT; tscResetForNextRetrieve(&pSql->res); // set the callback function pSql->fp = tscJoinQueryCallback; - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); return; } // no data exists in next vnode, mark the query completed // only when there is no subquery exits any more, proceeds to get the intersect of the tuple sets. if (!subAndCheckDone(pSql, pParentSql, pSupporter->subqueryIndex)) { - tscDebug("%p tagRetrieve:%p,%d completed, total:%d", pParentSql, tres, pSupporter->subqueryIndex, pParentSql->subState.numOfSub); + tscDebug("0x%"PRIx64" tagRetrieve:%p,%d completed, total:%d", pParentSql->self, tres, pSupporter->subqueryIndex, pParentSql->subState.numOfSub); return; } @@ -1218,7 +1203,8 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow if (emptyTagList(resList, pParentSql->subState.numOfSub)) { // no results,return. assert(pParentSql->fp != tscJoinQueryCallback); - tscDebug("%p tag intersect does not generated qualified tables for join, free all sub SqlObj and quit", pParentSql); + tscDebug("0x%"PRIx64" tag intersect does not generated qualified tables for join, free all sub SqlObj and quit", + pParentSql->self); freeJoinSubqueryObj(pParentSql); // set no result command @@ -1231,16 +1217,16 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow // proceed to for ts_comp query SSqlCmd* pSubCmd = &pParentSql->pSubs[m]->cmd; SArray** s = taosArrayGet(resList, m); - - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pSubCmd, 0); - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); + + SQueryInfo* pQueryInfo1 = tscGetQueryInfo(pSubCmd, 0); + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo1, 0); tscBuildVgroupTableInfo(pParentSql, pTableMetaInfo, *s); - + SSqlObj* psub = pParentSql->pSubs[m]; ((SJoinSupporter*)psub->param)->pVgroupTables = tscVgroupTableInfoDup(pTableMetaInfo->pVgroupTables); - + memset(pParentSql->subState.states, 0, sizeof(pParentSql->subState.states[0]) * pParentSql->subState.numOfSub); - tscDebug("%p reset all sub states to 0", pParentSql); + tscDebug("0x%"PRIx64" reset all sub states to 0", pParentSql->self); issueTsCompQuery(psub, psub->param, pParentSql); } @@ -1266,7 +1252,7 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); assert(!TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_SEC_STAGE)); if (pParentSql->res.code != TSDB_CODE_SUCCESS) { @@ -1333,7 +1319,7 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow } if (pSupporter->pTSBuf == NULL) { - tscDebug("%p create tmp file for ts block:%s, size:%d bytes", pSql, pBuf->path, numOfRows); + tscDebug("0x%"PRIx64" create tmp file for ts block:%s, size:%d bytes", pSql->self, pBuf->path, numOfRows); pSupporter->pTSBuf = pBuf; } else { assert(pQueryInfo->numOfTables == 1); // for subquery, only one @@ -1359,8 +1345,8 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow pTableMetaInfo->vgroupIndex += 1; assert(pTableMetaInfo->vgroupIndex < totalVgroups); - tscDebug("%p results from vgroup index:%d completed, try next vgroup:%d. total vgroups:%d. current numOfRes:%" PRId64, - pSql, pTableMetaInfo->vgroupIndex - 1, pTableMetaInfo->vgroupIndex, totalVgroups, + tscDebug("0x%"PRIx64" results from vgroup index:%d completed, try next vgroup:%d. total vgroups:%d. current numOfRes:%" PRId64, + pSql->self, pTableMetaInfo->vgroupIndex - 1, pTableMetaInfo->vgroupIndex, totalVgroups, pRes->numOfClauseTotal); pCmd->command = TSDB_SQL_SELECT; @@ -1375,7 +1361,7 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow // set the callback function pSql->fp = tscJoinQueryCallback; - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); return; } @@ -1383,12 +1369,12 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow return; } - tscDebug("%p all subquery retrieve ts complete, do ts block intersect", pParentSql); + tscDebug("0x%"PRIx64" all subquery retrieve ts complete, do ts block intersect", pParentSql->self); STimeWindow win = TSWINDOW_INITIALIZER; int64_t num = doTSBlockIntersect(pParentSql, &win); if (num <= 0) { // no result during ts intersect - tscDebug("%p no results generated in ts intersection, free all sub SqlObj and quit", pParentSql); + tscDebug("0x%"PRIx64" no results generated in ts intersection, free all sub SqlObj and quit", pParentSql->self); freeJoinSubqueryObj(pParentSql); // set no result command @@ -1398,7 +1384,7 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow } // launch the query the retrieve actual results from vnode along with the filtered timestamp - SQueryInfo* pPQueryInfo = tscGetQueryInfoDetail(&pParentSql->cmd, pParentSql->cmd.clauseIndex); + SQueryInfo* pPQueryInfo = tscGetQueryInfo(&pParentSql->cmd, pParentSql->cmd.clauseIndex); updateQueryTimeRange(pPQueryInfo, &win); //update the vgroup that involved in real data query @@ -1414,7 +1400,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); if (pParentSql->res.code != TSDB_CODE_SUCCESS) { tscError("%p abort query due to other subquery failure. code:%d, global code:%d", pSql, numOfRows, pParentSql->res.code); @@ -1456,23 +1442,23 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR } if ((++pTableMetaInfo->vgroupIndex) < numOfVgroups) { - tscDebug("%p no result in current vnode anymore, try next vnode, vgIndex:%d", pSql, pTableMetaInfo->vgroupIndex); + tscDebug("0x%"PRIx64" no result in current vnode anymore, try next vnode, vgIndex:%d", pSql->self, pTableMetaInfo->vgroupIndex); pSql->cmd.command = TSDB_SQL_SELECT; pSql->fp = tscJoinQueryCallback; - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); return; } else { - tscDebug("%p no result in current subquery anymore", pSql); + tscDebug("0x%"PRIx64" no result in current subquery anymore", pSql->self); } } if (!subAndCheckDone(pSql, pParentSql, pSupporter->subqueryIndex)) { - tscDebug("%p sub:%p,%d completed, total:%d", pParentSql, tres, pSupporter->subqueryIndex, pState->numOfSub); + tscDebug("0x%"PRIx64" sub:%p,%d completed, total:%d", pParentSql->self, tres, pSupporter->subqueryIndex, pState->numOfSub); return; } - tscDebug("%p all %d secondary subqueries retrieval completed, code:%d", tres, pState->numOfSub, pParentSql->res.code); + tscDebug("0x%"PRIx64" all %d secondary subqueries retrieval completed, code:%d", pSql->self, pState->numOfSub, pParentSql->res.code); if (pParentSql->res.code != TSDB_CODE_SUCCESS) { freeJoinSubqueryObj(pParentSql); @@ -1480,25 +1466,24 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR } // update the records for each subquery in parent sql object. - bool stableQuery = tscIsTwoStageSTableQuery(pCmd, pQueryInfo, 0); for (int32_t i = 0; i < pState->numOfSub; ++i) { if (pParentSql->pSubs[i] == NULL) { - tscDebug("%p %p sub:%d not retrieve data", pParentSql, NULL, i); + tscDebug("0x%"PRIx64" %p sub:%d not retrieve data", pParentSql->self, NULL, i); continue; } SSqlRes* pRes1 = &pParentSql->pSubs[i]->res; if (pRes1->row > 0 && pRes1->numOfRows > 0) { - tscDebug("%p sub:%p index:%d numOfRows:%d total:%"PRId64 " (not retrieve)", pParentSql, pParentSql->pSubs[i], i, + tscDebug("0x%"PRIx64" sub:%p index:%d numOfRows:%d total:%"PRId64 " (not retrieve)", pParentSql->self, pParentSql->pSubs[i], i, pRes1->numOfRows, pRes1->numOfTotal); assert(pRes1->row < pRes1->numOfRows); } else { - if (!stableQuery) { + if (!pQueryInfo->globalMerge) { pRes1->numOfClauseTotal += pRes1->numOfRows; } - tscDebug("%p sub:%p index:%d numOfRows:%d total:%"PRId64, pParentSql, pParentSql->pSubs[i], i, + tscDebug("0x%"PRIx64" sub:%p index:%d numOfRows:%d total:%"PRId64, pParentSql->self, pParentSql->pSubs[i], i, pRes1->numOfRows, pRes1->numOfTotal); } } @@ -1523,8 +1508,7 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { SSqlRes *pRes = &pSub->res; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSub->cmd, 0); - + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSub->cmd, 0); if (!tscHasReachLimitation(pQueryInfo, pRes)) { if (pRes->row >= pRes->numOfRows) { // no data left in current result buffer @@ -1576,7 +1560,7 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { continue; } - SQueryInfo* p = tscGetQueryInfoDetail(&pSub->cmd, 0); + SQueryInfo* p = tscGetQueryInfo(&pSub->cmd, 0); orderedPrjQuery = tscNonOrderedProjectionQueryOnSTable(&pSub->cmd, p, 0); if (orderedPrjQuery) { break; @@ -1600,7 +1584,7 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { continue; } - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSub->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSub->cmd, 0); if (tscNonOrderedProjectionQueryOnSTable(&pSub->cmd, pQueryInfo, 0) && pSub->res.row >= pSub->res.numOfRows && pSub->res.completed) { @@ -1616,15 +1600,15 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { } if ((++pTableMetaInfo->vgroupIndex) < numOfVgroups) { - tscDebug("%p no result in current vnode anymore, try next vnode, vgIndex:%d", pSub, + tscDebug("0x%"PRIx64" no result in current vnode anymore, try next vnode, vgIndex:%d", pSub->self, pTableMetaInfo->vgroupIndex); pSub->cmd.command = TSDB_SQL_SELECT; pSub->fp = tscJoinQueryCallback; - tscProcessSql(pSub); + tscBuildAndSendRequest(pSub, NULL); tryNextVnode = true; } else { - tscDebug("%p no result in current subquery anymore", pSub); + tscDebug("0x%"PRIx64" no result in current subquery anymore", pSub->self); } } } @@ -1647,7 +1631,7 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { // TODO multi-vnode retrieve for projection query with limitation has bugs, since the global limiation is not handled // retrieve data from current vnode. - tscDebug("%p retrieve data from %d subqueries", pSql, numOfFetch); + tscDebug("0x%"PRIx64" retrieve data from %d subqueries", pSql->self, numOfFetch); SJoinSupporter* pSupporter = NULL; for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) { @@ -1675,13 +1659,13 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { pSupporter = (SJoinSupporter*)pSql1->param; // wait for all subqueries completed - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd1, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd1, 0); assert(pRes1->numOfRows >= 0 && pQueryInfo->numOfTables == 1); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); if (pRes1->row >= pRes1->numOfRows) { - tscDebug("%p subquery:%p retrieve data from vnode, subquery:%d, vgroupIndex:%d", pSql, pSql1, + tscDebug("0x%"PRIx64" subquery:%p retrieve data from vnode, subquery:%d, vgroupIndex:%d", pSql->self, pSql1, pSupporter->subqueryIndex, pTableMetaInfo->vgroupIndex); tscResetForNextRetrieve(pRes1); @@ -1691,7 +1675,7 @@ void tscFetchDatablockForSubquery(SSqlObj* pSql) { pCmd1->command = (pCmd1->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH; } - tscProcessSql(pSql1); + tscBuildAndSendRequest(pSql1, NULL); } } } @@ -1701,13 +1685,12 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) { SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; - // the column transfer support struct has been built if (pRes->pColumnIndex != NULL) { return; } - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); int32_t numOfExprs = (int32_t)tscSqlExprNumOfExprs(pQueryInfo); pRes->pColumnIndex = calloc(1, sizeof(SColumnIndex) * numOfExprs); @@ -1717,12 +1700,12 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) { } for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); int32_t tableIndexOfSub = -1; for (int32_t j = 0; j < pQueryInfo->numOfTables; ++j) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, j); - if (pTableMetaInfo->pTableMeta->id.uid == pExpr->uid) { + if (pTableMetaInfo->pTableMeta->id.uid == pExpr->base.uid) { tableIndexOfSub = j; break; } @@ -1731,12 +1714,12 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) { assert(tableIndexOfSub >= 0 && tableIndexOfSub < pQueryInfo->numOfTables); SSqlCmd* pSubCmd = &pSql->pSubs[tableIndexOfSub]->cmd; - SQueryInfo* pSubQueryInfo = tscGetQueryInfoDetail(pSubCmd, 0); + SQueryInfo* pSubQueryInfo = tscGetQueryInfo(pSubCmd, 0); size_t numOfSubExpr = taosArrayGetSize(pSubQueryInfo->exprList); for (int32_t k = 0; k < numOfSubExpr; ++k) { - SSqlExpr* pSubExpr = tscSqlExprGet(pSubQueryInfo, k); - if (pExpr->functionId == pSubExpr->functionId && pExpr->colInfo.colId == pSubExpr->colInfo.colId) { + SExprInfo* pSubExpr = tscSqlExprGet(pSubQueryInfo, k); + if (pExpr->base.functionId == pSubExpr->base.functionId && pExpr->base.colInfo.colId == pSubExpr->base.colInfo.colId) { pRes->pColumnIndex[i] = (SColumnIndex){.tableIndex = tableIndexOfSub, .columnIndex = k}; break; } @@ -1755,7 +1738,7 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) { SSqlObj* pParentSql = pSupporter->pObj; // There is only one subquery and table for each subquery. - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); assert(pQueryInfo->numOfTables == 1 && pSql->cmd.numOfClause == 1); @@ -1792,7 +1775,7 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) { if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TAG_FILTER_QUERY)) { pSql->fp = tidTagRetrieveCallback; pSql->cmd.command = TSDB_SQL_FETCH; - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); return; } @@ -1800,7 +1783,7 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) { if (!TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_SEC_STAGE)) { pSql->fp = tsCompRetrieveCallback; pSql->cmd.command = TSDB_SQL_FETCH; - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); return; } @@ -1821,7 +1804,7 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) { pSql->fp = joinRetrieveFinalResCallback; // continue retrieve data pSql->cmd.command = TSDB_SQL_FETCH; - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); } else { // first retrieve from vnode during the secondary stage sub-query // set the command flag must be after the semaphore been correctly set. if (pParentSql->res.code == TSDB_CODE_SUCCESS) { @@ -1839,7 +1822,7 @@ static SSqlObj *tscCreateSTableSubquery(SSqlObj *pSql, SRetrieveSupport *trsuppo int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter *pSupporter) { SSqlCmd * pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); pSql->res.qId = 0x1; assert(pSql->res.numOfRows == 0); @@ -1862,15 +1845,14 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter addGroupInfoForSubquery(pSql, pNew, 0, tableIndex); // refactor as one method - SQueryInfo *pNewQueryInfo = tscGetQueryInfoDetail(&pNew->cmd, 0); + SQueryInfo *pNewQueryInfo = tscGetQueryInfo(&pNew->cmd, 0); assert(pNewQueryInfo != NULL); // update the table index - size_t num = taosArrayGetSize(pNewQueryInfo->colList); - for (int32_t i = 0; i < num; ++i) { - SColumn* pCol = taosArrayGetP(pNewQueryInfo->colList, i); - pCol->colIndex.tableIndex = 0; - } +// size_t num = taosArrayGetSize(pNewQueryInfo->colList); +// for (int32_t i = 0; i < num; ++i) { +// SColumn* pCol = taosArrayGetP(pNewQueryInfo->colList, i); +// } pSupporter->colList = pNewQueryInfo->colList; pNewQueryInfo->colList = NULL; @@ -1895,6 +1877,7 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter pNewQueryInfo->limit.limit = -1; pNewQueryInfo->limit.offset = 0; + taosArrayDestroy(pNewQueryInfo->pUpstream); pNewQueryInfo->order.orderColId = INT32_MIN; @@ -1941,12 +1924,12 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter tscAddFuncInSelectClause(pNewQueryInfo, 0, TSDB_FUNC_TS_COMP, &colIndex, &colSchema, TSDB_COL_NORMAL); // set the tags value for ts_comp function - SSqlExpr *pExpr = tscSqlExprGet(pNewQueryInfo, 0); + SExprInfo *pExpr = tscSqlExprGet(pNewQueryInfo, 0); if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { int16_t tagColId = tscGetJoinTagColIdByUid(&pSupporter->tagCond, pTableMetaInfo->pTableMeta->id.uid); - pExpr->param->i64 = tagColId; - pExpr->numOfParams = 1; + pExpr->base.param->i64 = tagColId; + pExpr->base.numOfParams = 1; } // add the filter tag column @@ -1956,7 +1939,7 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter for (int32_t i = 0; i < s; ++i) { SColumn *pCol = taosArrayGetP(pSupporter->colList, i); - if (pCol->numOfFilters > 0) { // copy to the pNew->cmd.colList if it is filtered. + if (pCol->info.flist.numOfFilters > 0) { // copy to the pNew->cmd.colList if it is filtered. SColumn *p = tscColumnClone(pCol); taosArrayPush(pNewQueryInfo->colList, &p); } @@ -1973,7 +1956,7 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter } } else { assert(0); - SQueryInfo *pNewQueryInfo = tscGetQueryInfoDetail(&pNew->cmd, 0); + SQueryInfo *pNewQueryInfo = tscGetQueryInfo(&pNew->cmd, 0); pNewQueryInfo->type |= TSDB_QUERY_TYPE_SUBQUERY; } @@ -1984,7 +1967,7 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) { SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); assert((pQueryInfo->type & TSDB_QUERY_TYPE_SUBQUERY) == 0); int32_t code = TSDB_CODE_SUCCESS; @@ -2001,15 +1984,11 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) { } memset(pSql->subState.states, 0, sizeof(*pSql->subState.states) * pSql->subState.numOfSub); - tscDebug("%p reset all sub states to 0", pSql); + tscDebug("0x%"PRIx64" reset all sub states to 0", pSql->self); - bool hasEmptySub = false; - - tscDebug("%p start subquery, total:%d", pSql, pQueryInfo->numOfTables); + tscDebug("0x%"PRIx64" start subquery, total:%d", pSql->self, pQueryInfo->numOfTables); for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { - SJoinSupporter *pSupporter = tscCreateJoinSupporter(pSql, i); - if (pSupporter == NULL) { // failed to create support struct, abort current query tscError("%p tableIndex:%d, failed to allocate join support object, abort further query", pSql, i); code = TSDB_CODE_TSC_OUT_OF_MEMORY; @@ -2025,14 +2004,13 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) { SSqlObj* pSub = pSql->pSubs[i]; STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSub->cmd, 0, 0); if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo) && (pTableMetaInfo->vgroupList->numOfVgroups == 0)) { - hasEmptySub = true; + pSql->cmd.command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; break; } } - if (hasEmptySub) { // at least one subquery is empty, do nothing and return + if (pSql->cmd.command == TSDB_SQL_RETRIEVE_EMPTY_RESULT) { // at least one subquery is empty, do nothing and return freeJoinSubqueryObj(pSql); - pSql->cmd.command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; (*pSql->fp)(pSql->param, pSql, 0); } else { int fail = 0; @@ -2043,7 +2021,7 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) { continue; } - if ((code = tscProcessSql(pSub)) != TSDB_CODE_SUCCESS) { + if ((code = tscBuildAndSendRequest(pSub, NULL)) != TSDB_CODE_SUCCESS) { pRes->code = code; (*pSub->fp)(pSub->param, pSub, 0); fail = 1; @@ -2112,12 +2090,12 @@ typedef struct SFirstRoundQuerySup { void doAppendData(SInterResult* pInterResult, TAOS_ROW row, int32_t numOfCols, SQueryInfo* pQueryInfo) { TSKEY key = INT64_MIN; for(int32_t i = 0; i < numOfCols; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (TSDB_COL_IS_TAG(pExpr->colInfo.flag) || pExpr->functionId == TSDB_FUNC_PRJ) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (TSDB_COL_IS_TAG(pExpr->base.colInfo.flag) || pExpr->base.functionId == TSDB_FUNC_PRJ) { continue; } - if (pExpr->colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { + if (pExpr->base.colInfo.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { key = *(TSKEY*) row[i]; continue; } @@ -2129,7 +2107,7 @@ void doAppendData(SInterResult* pInterResult, TAOS_ROW row, int32_t numOfCols, S SET_DOUBLE_NULL(&v); } - int32_t id = pExpr->colInfo.colId; + int32_t id = pExpr->base.colInfo.colId; int32_t numOfQueriedCols = (int32_t) taosArrayGetSize(pInterResult->pResult); SArray* p = NULL; @@ -2173,7 +2151,7 @@ void tscFirstRoundRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) { SFirstRoundQuerySup* pSup = param; SSqlObj* pParent = pSup->pParent; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); int32_t code = taos_errno(pSql); if (code != TSDB_CODE_SUCCESS) { @@ -2205,16 +2183,16 @@ void tscFirstRoundRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) { int32_t offset = 0; for (int32_t i = 0; i < numOfCols && offset < pSup->tagLen; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); // tag or group by column - if (TSDB_COL_IS_TAG(pExpr->colInfo.flag) || pExpr->functionId == TSDB_FUNC_PRJ) { + if (TSDB_COL_IS_TAG(pExpr->base.colInfo.flag) || pExpr->base.functionId == TSDB_FUNC_PRJ) { if (row[i] == NULL) { - setNull(p + offset, pExpr->resType, pExpr->resBytes); + setNull(p + offset, pExpr->base.resType, pExpr->base.resBytes); } else { memcpy(p + offset, row[i], length[i]); } - offset += pExpr->resBytes; + offset += pExpr->base.resBytes; } } @@ -2249,14 +2227,14 @@ void tscFirstRoundRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) { } } - if (!pRes->completed) { + if (!pRes->completed && numOfRows > 0) { taos_fetch_rows_a(tres, tscFirstRoundRetrieveCallback, param); return; } // set the parameters for the second round query process SSqlCmd *pPCmd = &pParent->cmd; - SQueryInfo *pQueryInfo1 = tscGetQueryInfoDetail(pPCmd, 0); + SQueryInfo *pQueryInfo1 = tscGetQueryInfo(pPCmd, 0); int32_t resRows = pSup->numOfRows; if (pSup->numOfRows > 0) { @@ -2283,7 +2261,7 @@ void tscFirstRoundRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) { } pQueryInfo1->round = 1; - tscDoQuery(pParent); + executeQuery(pParent, pQueryInfo1); } void tscFirstRoundCallback(void* param, TAOS_RES* tres, int code) { @@ -2306,7 +2284,7 @@ void tscFirstRoundCallback(void* param, TAOS_RES* tres, int code) { } int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo* pTableMetaInfo1 = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0); SFirstRoundQuerySup *pSup = calloc(1, sizeof(SFirstRoundQuerySup)); @@ -2322,7 +2300,7 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { tscClearSubqueryInfo(pCmd); tscFreeSqlResult(pSql); - SQueryInfo* pNewQueryInfo = tscGetQueryInfoDetail(pCmd, 0); + SQueryInfo* pNewQueryInfo = tscGetQueryInfo(pCmd, 0); assert(pQueryInfo->numOfTables == 1); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pNewQueryInfo, 0); @@ -2343,6 +2321,8 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { } pNewQueryInfo->interval = pQueryInfo->interval; + pNewQueryInfo->globalMerge = pQueryInfo->globalMerge; + assert(pNewQueryInfo->globalMerge); pCmd->command = TSDB_SQL_SELECT; pNew->fp = tscFirstRoundCallback; @@ -2351,62 +2331,60 @@ int32_t tscHandleFirstRoundStableQuery(SSqlObj *pSql) { int32_t index = 0; for(int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_TS && pQueryInfo->interval.interval > 0) { - taosArrayPush(pSup->pColsInfo, &pExpr->resColId); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId == TSDB_FUNC_TS && pQueryInfo->interval.interval > 0) { + taosArrayPush(pSup->pColsInfo, &pExpr->base.resColId); SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX}; - SSchema* schema = tscGetColumnSchemaById(pTableMetaInfo1->pTableMeta, pExpr->colInfo.colId); + SSchema* schema = tscGetColumnSchemaById(pTableMetaInfo1->pTableMeta, pExpr->base.colInfo.colId); - SSqlExpr* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_TS, &colIndex, schema, TSDB_COL_NORMAL); - p->resColId = pExpr->resColId; // update the result column id - } else if (pExpr->functionId == TSDB_FUNC_STDDEV_DST) { - taosArrayPush(pSup->pColsInfo, &pExpr->resColId); + SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_TS, &colIndex, schema, TSDB_COL_NORMAL); + p->base.resColId = pExpr->base.resColId; // update the result column id + } else if (pExpr->base.functionId == TSDB_FUNC_STDDEV_DST) { + taosArrayPush(pSup->pColsInfo, &pExpr->base.resColId); - SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = pExpr->colInfo.colIndex}; + SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = pExpr->base.colInfo.colIndex}; SSchema schema = {.type = TSDB_DATA_TYPE_DOUBLE, .bytes = sizeof(double)}; - tstrncpy(schema.name, pExpr->aliasName, tListLen(schema.name)); + tstrncpy(schema.name, pExpr->base.aliasName, tListLen(schema.name)); - SSqlExpr* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_AVG, &colIndex, &schema, TSDB_COL_NORMAL); - p->resColId = pExpr->resColId; // update the result column id - } else if (pExpr->functionId == TSDB_FUNC_TAG) { - pSup->tagLen += pExpr->resBytes; - SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = pExpr->colInfo.colIndex}; + SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_AVG, &colIndex, &schema, TSDB_COL_NORMAL); + p->base.resColId = pExpr->base.resColId; // update the result column id + } else if (pExpr->base.functionId == TSDB_FUNC_TAG) { + pSup->tagLen += pExpr->base.resBytes; + SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = pExpr->base.colInfo.colIndex}; SSchema* schema = NULL; - if (pExpr->colInfo.colId != TSDB_TBNAME_COLUMN_INDEX) { - schema = tscGetColumnSchemaById(pTableMetaInfo1->pTableMeta, pExpr->colInfo.colId); + if (pExpr->base.colInfo.colId != TSDB_TBNAME_COLUMN_INDEX) { + schema = tscGetColumnSchemaById(pTableMetaInfo1->pTableMeta, pExpr->base.colInfo.colId); } else { schema = tGetTbnameColumnSchema(); } - SSqlExpr* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_TAG, &colIndex, schema, TSDB_COL_TAG); - p->resColId = pExpr->resColId; - } else if (pExpr->functionId == TSDB_FUNC_PRJ) { + SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_TAG, &colIndex, schema, TSDB_COL_TAG); + p->base.resColId = pExpr->base.resColId; + } else if (pExpr->base.functionId == TSDB_FUNC_PRJ) { int32_t num = (int32_t) taosArrayGetSize(pNewQueryInfo->groupbyExpr.columnInfo); for(int32_t k = 0; k < num; ++k) { SColIndex* pIndex = taosArrayGet(pNewQueryInfo->groupbyExpr.columnInfo, k); - if (pExpr->colInfo.colId == pIndex->colId) { - pSup->tagLen += pExpr->resBytes; - taosArrayPush(pSup->pColsInfo, &pExpr->resColId); + if (pExpr->base.colInfo.colId == pIndex->colId) { + pSup->tagLen += pExpr->base.resBytes; + taosArrayPush(pSup->pColsInfo, &pExpr->base.resColId); SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = pIndex->colIndex}; - SSchema* schema = tscGetColumnSchemaById(pTableMetaInfo1->pTableMeta, pExpr->colInfo.colId); + SSchema* schema = tscGetColumnSchemaById(pTableMetaInfo1->pTableMeta, pExpr->base.colInfo.colId); //doLimitOutputNormalColOfGroupby - SSqlExpr* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_PRJ, &colIndex, schema, TSDB_COL_NORMAL); - p->numOfParams = 1; - p->param[0].i64 = 1; - p->param[0].nType = TSDB_DATA_TYPE_INT; - p->resColId = pExpr->resColId; // update the result column id + SExprInfo* p = tscAddFuncInSelectClause(pNewQueryInfo, index++, TSDB_FUNC_PRJ, &colIndex, schema, TSDB_COL_NORMAL); + p->base.numOfParams = 1; + p->base.param[0].i64 = 1; + p->base.param[0].nType = TSDB_DATA_TYPE_INT; + p->base.resColId = pExpr->base.resColId; // update the result column id } } } } - SColumnIndex columnIndex = {.tableIndex = 0, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX}; - tscInsertPrimaryTsSourceColumn(pNewQueryInfo, &columnIndex); - + tscInsertPrimaryTsSourceColumn(pNewQueryInfo, pTableMetaInfo->pTableMeta->id.uid); tscTansformFuncForSTableQuery(pNewQueryInfo); tscDebug( @@ -2445,7 +2423,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { const uint32_t nBufferSize = (1u << 16u); // 64KB - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetActiveQueryInfo(pCmd); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); SSubqueryState *pState = &pSql->subState; @@ -2466,7 +2444,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { return ret; } - tscDebug("%p retrieved query data from %d vnode(s)", pSql, pState->numOfSub); + tscDebug("0x%"PRIx64" retrieved query data from %d vnode(s)", pSql->self, pState->numOfSub); pSql->pSubs = calloc(pState->numOfSub, POINTER_BYTES); if (pSql->pSubs == NULL) { tfree(pSql->pSubs); @@ -2490,7 +2468,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { } memset(pState->states, 0, sizeof(*pState->states) * pState->numOfSub); - tscDebug("%p reset all sub states to 0", pSql); + tscDebug("0x%"PRIx64" reset all sub states to 0", pSql->self); pRes->code = TSDB_CODE_SUCCESS; @@ -2527,12 +2505,12 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { // todo handle multi-vnode situation if (pQueryInfo->tsBuf) { - SQueryInfo *pNewQueryInfo = tscGetQueryInfoDetail(&pNew->cmd, 0); + SQueryInfo *pNewQueryInfo = tscGetQueryInfo(&pNew->cmd, 0); pNewQueryInfo->tsBuf = tsBufClone(pQueryInfo->tsBuf); assert(pNewQueryInfo->tsBuf != NULL); } - tscDebug("%p sub:%p create subquery success. orderOfSub:%d", pSql, pNew, trs->subqueryIndex); + tscDebug("0x%"PRIx64" sub:%p create subquery success. orderOfSub:%d", pSql->self, pNew, trs->subqueryIndex); } if (i < pState->numOfSub) { @@ -2554,8 +2532,8 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { SSqlObj* pSub = pSql->pSubs[j]; SRetrieveSupport* pSupport = pSub->param; - tscDebug("%p sub:%p launch subquery, orderOfSub:%d.", pSql, pSub, pSupport->subqueryIndex); - tscProcessSql(pSub); + tscDebug("0x%"PRIx64" sub:%p launch subquery, orderOfSub:%d.", pSql->self, pSub, pSupport->subqueryIndex); + tscBuildAndSendRequest(pSub, NULL); } return TSDB_CODE_SUCCESS; @@ -2566,11 +2544,11 @@ static void tscFreeRetrieveSup(SSqlObj *pSql) { void* p = atomic_val_compare_exchange_ptr(&pSql->param, trsupport, 0); if (p == NULL) { - tscDebug("%p retrieve supp already released", pSql); + tscDebug("0x%"PRIx64" retrieve supp already released", pSql->self); return; } - tscDebug("%p start to free subquery supp obj:%p", pSql, trsupport); + tscDebug("0x%"PRIx64" start to free subquery supp obj:%p", pSql->self, trsupport); tfree(trsupport->localBuffer); tfree(trsupport); } @@ -2635,7 +2613,7 @@ static int32_t tscReissueSubquery(SRetrieveSupport *oriTrs, SSqlObj *pSql, int32 return pParentSql->res.code; } - int32_t ret = tscProcessSql(pNew); + int32_t ret = tscBuildAndSendRequest(pNew, NULL); *sent = 1; @@ -2674,12 +2652,12 @@ void tscHandleSubqueryError(SRetrieveSupport *trsupport, SSqlObj *pSql, int numO */ pSql->res.numOfRows = 0; trsupport->numOfRetry = MAX_NUM_OF_SUBQUERY_RETRY; // disable retry efforts - tscDebug("%p query is cancelled, sub:%p, orderOfSub:%d abort retrieve, code:%s", pParentSql, pSql, + tscDebug("0x%"PRIx64" query is cancelled, sub:%p, orderOfSub:%d abort retrieve, code:%s", pParentSql->self, pSql, subqueryIndex, tstrerror(pParentSql->res.code)); } if (numOfRows >= 0) { // current query is successful, but other sub query failed, still abort current query. - tscDebug("%p sub:%p retrieve numOfRows:%d,orderOfSub:%d", pParentSql, pSql, numOfRows, subqueryIndex); + tscDebug("0x%"PRIx64" sub:0x%"PRIx64" retrieve numOfRows:%d,orderOfSub:%d", pParentSql->self, pSql->self, numOfRows, subqueryIndex); tscError("%p sub:%p abort further retrieval due to other queries failure,orderOfSub:%d,code:%s", pParentSql, pSql, subqueryIndex, tstrerror(pParentSql->res.code)); } else { @@ -2698,7 +2676,7 @@ void tscHandleSubqueryError(SRetrieveSupport *trsupport, SSqlObj *pSql, int numO } if (!subAndCheckDone(pSql, pParentSql, subqueryIndex)) { - tscDebug("%p sub:%p,%d freed, not finished, total:%d", pParentSql, pSql, trsupport->subqueryIndex, pState->numOfSub); + tscDebug("0x%"PRIx64" sub:%p,%d freed, not finished, total:%d", pParentSql->self, pSql, trsupport->subqueryIndex, pState->numOfSub); tscFreeRetrieveSup(pSql); return; @@ -2715,7 +2693,7 @@ void tscHandleSubqueryError(SRetrieveSupport *trsupport, SSqlObj *pSql, int numO tscFreeRetrieveSup(pSql); // in case of second stage join subquery, invoke its callback function instead of regular QueueAsyncRes - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pParentSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pParentSql->cmd, 0); if (!TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_SEC_STAGE)) { (*pParentSql->fp)(pParentSql->param, pParentSql, pParentSql->res.code); @@ -2732,14 +2710,14 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p tOrderDescriptor *pDesc = trsupport->pOrderDescriptor; SSubqueryState* pState = &pParentSql->subState; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[0]; // data in from current vnode is stored in cache and disk uint32_t numOfRowsFromSubquery = (uint32_t)(trsupport->pExtMemBuffer[idx]->numOfTotalElems + trsupport->localBuffer->num); SVgroupsInfo* vgroupsInfo = pTableMetaInfo->vgroupList; - tscDebug("%p sub:%p all data retrieved from ep:%s, vgId:%d, numOfRows:%d, orderOfSub:%d", pParentSql, pSql, + tscDebug("0x%"PRIx64" sub:%p all data retrieved from ep:%s, vgId:%d, numOfRows:%d, orderOfSub:%d", pParentSql->self, pSql, vgroupsInfo->vgroups[0].epAddr[0].fqdn, vgroupsInfo->vgroups[0].vgId, numOfRowsFromSubquery, idx); tColModelCompact(pDesc->pColumnModel, trsupport->localBuffer, pDesc->pColumnModel->capacity); @@ -2768,7 +2746,7 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p } if (!subAndCheckDone(pSql, pParentSql, idx)) { - tscDebug("%p sub:%p orderOfSub:%d freed, not finished", pParentSql, pSql, trsupport->subqueryIndex); + tscDebug("0x%"PRIx64" sub:%p orderOfSub:%d freed, not finished", pParentSql->self, pSql, trsupport->subqueryIndex); tscFreeRetrieveSup(pSql); return; @@ -2777,14 +2755,14 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p // all sub-queries are returned, start to local merge process pDesc->pColumnModel->capacity = trsupport->pExtMemBuffer[idx]->numOfElemsPerPage; - tscDebug("%p retrieve from %d vnodes completed.final NumOfRows:%" PRId64 ",start to build loser tree", pParentSql, - pState->numOfSub, pState->numOfRetrievedRows); + tscDebug("0x%"PRIx64" retrieve from %d vnodes completed.final NumOfRows:%" PRId64 ",start to build loser tree", + pParentSql->self, pState->numOfSub, pState->numOfRetrievedRows); - SQueryInfo *pPQueryInfo = tscGetQueryInfoDetail(&pParentSql->cmd, 0); + SQueryInfo *pPQueryInfo = tscGetQueryInfo(&pParentSql->cmd, 0); tscClearInterpInfo(pPQueryInfo); tscCreateLocalMerger(trsupport->pExtMemBuffer, pState->numOfSub, pDesc, trsupport->pFinalColModel, trsupport->pFFColModel, pParentSql); - tscDebug("%p build loser tree completed", pParentSql); + tscDebug("0x%"PRIx64" build loser tree completed", pParentSql->self); pParentSql->res.precision = pSql->res.precision; pParentSql->res.numOfRows = 0; @@ -2792,24 +2770,27 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p tscFreeRetrieveSup(pSql); - size_t size = tscSqlExprNumOfExprs(pQueryInfo); - for (int32_t j = 0; j < size; ++j) { - SQLFunctionCtx *pCtx = &pParentSql->res.pLocalMerger->pCtx[j]; + // set the command flag must be after the semaphore been correctly set. + if (pParentSql->cmd.command != TSDB_SQL_RETRIEVE_EMPTY_RESULT) { + pParentSql->cmd.command = TSDB_SQL_RETRIEVE_LOCALMERGE; - int32_t functionId = pCtx->functionId; - - if (functionId < 0) { - SUdfInfo* pUdfInfo = taosArrayGet(pParentSql->cmd.pUdfInfo, -1 * functionId - 1); - int32_t code = initUdfInfo(pUdfInfo); - if (code != TSDB_CODE_SUCCESS) { - pParentSql->res.code = code; - tscAsyncResultOnError(pParentSql); + size_t size = tscSqlExprNumOfExprs(pQueryInfo); + for (int32_t j = 0; j < size; ++j) { + SQLFunctionCtx *pCtx = &pParentSql->res.pLocalMerger->pCtx[j]; + + int32_t functionId = pCtx->functionId; + + if (functionId < 0) { + SUdfInfo* pUdfInfo = taosArrayGet(pParentSql->cmd.pUdfInfo, -1 * functionId - 1); + code = initUdfInfo(pUdfInfo); + if (code != TSDB_CODE_SUCCESS) { + pParentSql->res.code = code; + tscAsyncResultOnError(pParentSql); + } } } } - // set the command flag must be after the semaphore been correctly set. - pParentSql->cmd.command = TSDB_SQL_RETRIEVE_LOCALMERGE; if (pParentSql->res.code == TSDB_CODE_SUCCESS) { (*pParentSql->fp)(pParentSql->param, pParentSql, 0); } else { @@ -2824,7 +2805,7 @@ static void tscRetrieveFromDnodeCallBack(void *param, TAOS_RES *tres, int numOfR // this query has been freed already SRetrieveSupport *trsupport = (SRetrieveSupport *)param; if (pSql->param == NULL || param == NULL) { - tscDebug("%p already freed in dnodecallback", pSql); + tscDebug("0x%"PRIx64" already freed in dnodecallback", pSql->self); return; } @@ -2839,8 +2820,8 @@ static void tscRetrieveFromDnodeCallBack(void *param, TAOS_RES *tres, int numOfR if (pParentSql->res.code != TSDB_CODE_SUCCESS) { trsupport->numOfRetry = MAX_NUM_OF_SUBQUERY_RETRY; - tscDebug("%p query cancelled/failed, sub:%p, vgId:%d, orderOfSub:%d, code:%s, global code:%s", - pParentSql, pSql, pVgroup->vgId, trsupport->subqueryIndex, tstrerror(numOfRows), tstrerror(pParentSql->res.code)); + tscDebug("0x%"PRIx64" query cancelled/failed, sub:%p, vgId:%d, orderOfSub:%d, code:%s, global code:%s", + pParentSql->self, pSql, pVgroup->vgId, trsupport->subqueryIndex, tstrerror(numOfRows), tstrerror(pParentSql->res.code)); tscHandleSubqueryError(param, tres, numOfRows); return; @@ -2863,7 +2844,7 @@ static void tscRetrieveFromDnodeCallBack(void *param, TAOS_RES *tres, int numOfR return; } } else { - tscDebug("%p sub:%p reach the max retry times, set global code:%s", pParentSql, pSql, tstrerror(numOfRows)); + tscDebug("0x%"PRIx64" sub:%p reach the max retry times, set global code:%s", pParentSql->self, pSql, tstrerror(numOfRows)); atomic_val_compare_exchange_32(&pParentSql->res.code, TSDB_CODE_SUCCESS, numOfRows); // set global code and abort } @@ -2872,14 +2853,14 @@ static void tscRetrieveFromDnodeCallBack(void *param, TAOS_RES *tres, int numOfR } SSqlRes * pRes = &pSql->res; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); if (numOfRows > 0) { assert(pRes->numOfRows == numOfRows); int64_t num = atomic_add_fetch_64(&pState->numOfRetrievedRows, numOfRows); - tscDebug("%p sub:%p retrieve numOfRows:%d totalNumOfRows:%" PRIu64 " from ep:%s, orderOfSub:%d", pParentSql, pSql, - pRes->numOfRows, pState->numOfRetrievedRows, pSql->epSet.fqdn[pSql->epSet.inUse], idx); + tscDebug("0x%"PRIx64" sub:%p retrieve numOfRows:%d totalNumOfRows:%" PRIu64 " from ep:%s, orderOfSub:%d", + pParentSql->self, pSql, pRes->numOfRows, pState->numOfRetrievedRows, pSql->epSet.fqdn[pSql->epSet.inUse], idx); SSqlCmd* pCmd = &pSql->cmd; if (num > tsMaxNumOfOrderedResults && tscIsProjectionQueryOnSTable(pCmd, pQueryInfo, 0)) { @@ -2925,8 +2906,9 @@ static SSqlObj *tscCreateSTableSubquery(SSqlObj *pSql, SRetrieveSupport *trsuppo SSqlObj *pNew = createSubqueryObj(pSql, table_index, tscRetrieveDataRes, trsupport, TSDB_SQL_SELECT, prevSqlObj); if (pNew != NULL) { // the sub query of two-stage super table query - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pNew->cmd, 0); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pNew->cmd, 0); + pNew->cmd.active = pQueryInfo; pQueryInfo->type |= TSDB_QUERY_TYPE_STABLE_SUBQUERY; // clear the limit/offset info, since it should not be sent to vnode to be executed. @@ -2959,7 +2941,7 @@ void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) { SSqlObj* pParentSql = trsupport->pParentSql; SSqlObj* pSql = (SSqlObj *) tres; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, 0); assert(pSql->cmd.numOfClause == 1 && pQueryInfo->numOfTables == 1); STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0); @@ -3003,8 +2985,8 @@ void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) { return; } - tscDebug("%p sub:%p query complete, ep:%s, vgId:%d, orderOfSub:%d, retrieve data", trsupport->pParentSql, pSql, - pVgroup->epAddr[pSql->epSet.inUse].fqdn, pVgroup->vgId, trsupport->subqueryIndex); + tscDebug("0x%"PRIx64" sub:0x%"PRIx64" query complete, ep:%s, vgId:%d, orderOfSub:%d, retrieve data", trsupport->pParentSql->self, + pSql->self, 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); @@ -3067,7 +3049,7 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) } if (!subAndCheckDone(tres, pParentObj, pSupporter->index)) { - tscDebug("%p insert:%p,%d completed, total:%d", pParentObj, tres, pSupporter->index, pParentObj->subState.numOfSub); + tscDebug("0x%"PRIx64" insert:%p,%d completed, total:%d", pParentObj->self, tres, pSupporter->index, pParentObj->subState.numOfSub); return; } @@ -3077,7 +3059,7 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) doFreeInsertSupporter(pParentObj); if (pParentObj->res.code == TSDB_CODE_SUCCESS) { - tscDebug("%p Async insertion completed, total inserted:%d", pParentObj, pParentObj->res.numOfRows); + tscDebug("0x%"PRIx64" Async insertion completed, total inserted:%d", pParentObj->self, pParentObj->res.numOfRows); // todo remove this parameter in async callback function definition. // all data has been sent to vnode, call user function @@ -3097,20 +3079,20 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) // clean up tableMeta in cache tscFreeQueryInfo(&pSql->cmd, false); - SQueryInfo* pQueryInfo = tscGetQueryInfoDetailSafely(&pSql->cmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfoS(&pSql->cmd, 0); STableMetaInfo* pMasterTableMetaInfo = tscGetTableMetaInfoFromCmd(&pParentObj->cmd, pSql->cmd.clauseIndex, 0); tscAddTableMetaInfo(pQueryInfo, &pMasterTableMetaInfo->name, NULL, NULL, NULL, NULL); subquerySetState(pSql, &pParentObj->subState, i, 0); - tscDebug("%p, failed sub:%d, %p", pParentObj, i, pSql); + tscDebug("0x%"PRIx64", failed sub:%d, %p", pParentObj->self, i, pSql); } } tscError("%p Async insertion completed, total inserted:%d rows, numOfFailed:%d, numOfTotal:%d", pParentObj, pParentObj->res.numOfRows, numOfFailed, numOfSub); - tscDebug("%p cleanup %d tableMeta in hashTable", pParentObj, pParentObj->cmd.numOfTables); + tscDebug("0x%"PRIx64" cleanup %d tableMeta in hashTable", pParentObj->self, pParentObj->cmd.numOfTables); for(int32_t i = 0; i < pParentObj->cmd.numOfTables; ++i) { char name[TSDB_TABLE_FNAME_LEN] = {0}; tNameExtractFullName(pParentObj->cmd.pTableNameList[i], name); @@ -3124,7 +3106,7 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) // in case of insert, redo parsing the sql string and build new submit data block for two reasons: // 1. the table Id(tid & uid) may have been update, the submit block needs to be updated accordingly. // 2. vnode may need the schema information along with submit block to update its local table schema. - tscDebug("%p re-parse sql to generate submit data, retry:%d", pParentObj, pParentObj->retry); + tscDebug("0x%"PRIx64" re-parse sql to generate submit data, retry:%d", pParentObj->self, pParentObj->retry); pParentObj->retry++; int32_t code = tsParseSql(pParentObj, true); @@ -3136,7 +3118,7 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) return; } - tscDoQuery(pParentObj); + tscHandleMultivnodeInsert(pParentObj); } } @@ -3160,7 +3142,7 @@ int32_t tscHandleInsertRetry(SSqlObj* pParent, SSqlObj* pSql) { return code; // here the pSql may have been released already. } - return tscProcessSql(pSql); + return tscBuildAndSendRequest(pSql, NULL); } int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) { @@ -3176,7 +3158,7 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) { pSup->pSql = pSql; pSub->param = pSup; - tscDebug("%p sub:%p launch sub insert, orderOfSub:%d", pSql, pSub, i); + tscDebug("0x%"PRIx64" sub:%p launch sub insert, orderOfSub:%d", pSql->self, pSub, i); if (pSub->res.code != TSDB_CODE_SUCCESS) { tscHandleInsertRetry(pSql, pSub); } @@ -3204,14 +3186,14 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) { } memset(pSql->subState.states, 0, sizeof(*pSql->subState.states) * pSql->subState.numOfSub); - tscDebug("%p reset all sub states to 0", pSql); + tscDebug("0x%"PRIx64" reset all sub states to 0", pSql->self); pSql->pSubs = calloc(pSql->subState.numOfSub, POINTER_BYTES); if (pSql->pSubs == NULL) { goto _error; } - tscDebug("%p submit data to %d vnode(s)", pSql, pSql->subState.numOfSub); + tscDebug("0x%"PRIx64" submit data to %d vnode(s)", pSql->self, pSql->subState.numOfSub); while(numOfSub < pSql->subState.numOfSub) { SInsertSupporter* pSupporter = calloc(1, sizeof(SInsertSupporter)); @@ -3238,10 +3220,10 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) { STableDataBlocks* pTableDataBlock = taosArrayGetP(pCmd->pDataBlocks, numOfSub); pRes->code = tscCopyDataBlockToPayload(pNew, pTableDataBlock); if (pRes->code == TSDB_CODE_SUCCESS) { - tscDebug("%p sub:%p create subObj success. orderOfSub:%d", pSql, pNew, numOfSub); + tscDebug("0x%"PRIx64" sub:%p create subObj success. orderOfSub:%d", pSql->self, pNew, numOfSub); numOfSub++; } else { - tscDebug("%p prepare submit data block failed in async insertion, vnodeIdx:%d, total:%d, code:%s", pSql, numOfSub, + tscDebug("0x%"PRIx64" prepare submit data block failed in async insertion, vnodeIdx:%d, total:%d, code:%s", pSql->self, numOfSub, pSql->subState.numOfSub, tstrerror(pRes->code)); goto _error; } @@ -3258,8 +3240,8 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) { // use the local variable for (int32_t j = 0; j < numOfSub; ++j) { SSqlObj *pSub = pSql->pSubs[j]; - tscDebug("%p sub:%p launch sub insert, orderOfSub:%d", pSql, pSub, j); - tscProcessSql(pSub); + tscDebug("0x%"PRIx64" sub:%p launch sub insert, orderOfSub:%d", pSql->self, pSub, j); + tscBuildAndSendRequest(pSub, NULL); } return TSDB_CODE_SUCCESS; @@ -3269,21 +3251,23 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) { } static char* getResultBlockPosition(SSqlCmd* pCmd, SSqlRes* pRes, int32_t columnIndex, int16_t* bytes) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); SInternalField* pInfo = (SInternalField*) TARRAY_GET_ELEM(pQueryInfo->fieldsInfo.internalField, columnIndex); - assert(pInfo->pSqlExpr != NULL); + assert(pInfo->pExpr->pExpr == NULL); - *bytes = pInfo->pSqlExpr->resBytes; - char* pData = pRes->data + pInfo->pSqlExpr->offset * pRes->numOfRows + pRes->row * (*bytes); - - return pData; + *bytes = pInfo->pExpr->base.resBytes; + if (pRes->data != NULL) { + return pRes->data + pInfo->pExpr->base.offset * pRes->numOfRows + pRes->row * (*bytes); + } else { + return ((char*)pRes->urow[columnIndex]) + pRes->row * (*bytes); + } } static void doBuildResFromSubqueries(SSqlObj* pSql) { SSqlRes* pRes = &pSql->res; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex); int32_t numOfRes = INT32_MAX; for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) { @@ -3301,6 +3285,7 @@ static void doBuildResFromSubqueries(SSqlObj* pSql) { return; } + tscRestoreFuncForSTableQuery(pQueryInfo); int32_t rowSize = tscGetResRowLength(pQueryInfo->exprList); assert(numOfRes * rowSize > 0); @@ -3320,6 +3305,19 @@ static void doBuildResFromSubqueries(SSqlObj* pSql) { int16_t bytes = 0; + tscRestoreFuncForSTableQuery(pQueryInfo); + tscFieldInfoUpdateOffset(pQueryInfo); + for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) { + SSqlObj* pSub = pSql->pSubs[i]; + if (pSub == NULL) { + continue; + } + + SQueryInfo* pSubQueryInfo = pSub->cmd.pQueryInfo[0]; + tscRestoreFuncForSTableQuery(pSubQueryInfo); + tscFieldInfoUpdateOffset(pSubQueryInfo); + } + size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); for(int32_t i = 0; i < numOfExprs; ++i) { SColumnIndex* pIndex = &pRes->pColumnIndex[i]; @@ -3366,7 +3364,7 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) { } if (pRes->tsrow == NULL) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(&pSql->cmd, pSql->cmd.clauseIndex); pRes->numOfCols = (int16_t) tscSqlExprNumOfExprs(pQueryInfo); pRes->tsrow = calloc(pRes->numOfCols, POINTER_BYTES); @@ -3396,18 +3394,18 @@ char *getArithmeticInputSrc(void *param, const char *name, int32_t colId) { SArithmeticSupport *pSupport = (SArithmeticSupport *) param; int32_t index = -1; - SSqlExpr* pExpr = NULL; + SExprInfo* pExpr = NULL; for (int32_t i = 0; i < pSupport->numOfCols; ++i) { pExpr = taosArrayGetP(pSupport->exprList, i); - if (strncmp(name, pExpr->aliasName, sizeof(pExpr->aliasName) - 1) == 0) { + if (strncmp(name, pExpr->base.aliasName, sizeof(pExpr->base.aliasName) - 1) == 0) { index = i; break; } } assert(index >= 0 && index < pSupport->numOfCols); - return pSupport->data[index] + pSupport->offset * pExpr->resBytes; + return pSupport->data[index] + pSupport->offset * pExpr->base.resBytes; } TAOS_ROW doSetResultRowData(SSqlObj *pSql) { @@ -3420,78 +3418,200 @@ TAOS_ROW doSetResultRowData(SSqlObj *pSql) { return pRes->tsrow; } - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); size_t size = tscNumOfFields(pQueryInfo); + + int32_t j = 0; for (int i = 0; i < size; ++i) { SInternalField* pInfo = (SInternalField*)TARRAY_GET_ELEM(pQueryInfo->fieldsInfo.internalField, i); + if (!pInfo->visible) { + continue; + } int32_t type = pInfo->field.type; int32_t bytes = pInfo->field.bytes; if (type != TSDB_DATA_TYPE_BINARY && type != TSDB_DATA_TYPE_NCHAR) { - pRes->tsrow[i] = isNull(pRes->urow[i], type) ? NULL : pRes->urow[i]; + pRes->tsrow[j] = isNull(pRes->urow[i], type) ? NULL : pRes->urow[i]; } else { - pRes->tsrow[i] = isNull(pRes->urow[i], type) ? NULL : varDataVal(pRes->urow[i]); - pRes->length[i] = varDataLen(pRes->urow[i]); + pRes->tsrow[j] = isNull(pRes->urow[i], type) ? NULL : varDataVal(pRes->urow[i]); + pRes->length[j] = varDataLen(pRes->urow[i]); } ((char**) pRes->urow)[i] += bytes; + j += 1; } pRes->row++; // index increase one-step return pRes->tsrow; } -static UNUSED_FUNC bool tscHasRemainDataInSubqueryResultSet(SSqlObj *pSql) { - bool hasData = true; - SSqlCmd *pCmd = &pSql->cmd; - - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - if (tscNonOrderedProjectionQueryOnSTable(pCmd, pQueryInfo, 0)) { - bool allSubqueryExhausted = true; - - for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) { - if (pSql->pSubs[i] == NULL) { - continue; - } - - SSqlRes *pRes1 = &pSql->pSubs[i]->res; - SSqlCmd *pCmd1 = &pSql->pSubs[i]->cmd; - - SQueryInfo *pQueryInfo1 = tscGetQueryInfoDetail(pCmd1, pCmd1->clauseIndex); - assert(pQueryInfo1->numOfTables == 1); - - STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo1, 0); - - /* - * if the global limitation is not reached, and current result has not exhausted, or next more vnodes are - * available, goes on - */ - if (pTableMetaInfo->vgroupIndex < pTableMetaInfo->vgroupList->numOfVgroups && pRes1->row < pRes1->numOfRows && - (!tscHasReachLimitation(pQueryInfo1, pRes1))) { - allSubqueryExhausted = false; - break; - } - } - - hasData = !allSubqueryExhausted; - } else { // otherwise, in case inner join, if any subquery exhausted, query completed. - for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) { - if (pSql->pSubs[i] == 0) { - continue; - } - - SSqlRes * pRes1 = &pSql->pSubs[i]->res; - SQueryInfo *pQueryInfo1 = tscGetQueryInfoDetail(&pSql->pSubs[i]->cmd, 0); - - if ((pRes1->row >= pRes1->numOfRows && tscHasReachLimitation(pQueryInfo1, pRes1) && - tscIsProjectionQuery(&pSql->pSubs[i]->cmd, pQueryInfo1)) || (pRes1->numOfRows == 0)) { - hasData = false; - break; - } +//static UNUSED_FUNC bool tscHasRemainDataInSubqueryResultSet(SSqlObj *pSql) { +// bool hasData = true; +// SSqlCmd *pCmd = &pSql->cmd; +// +// SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); +// if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) { +// bool allSubqueryExhausted = true; +// +// for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) { +// if (pSql->pSubs[i] == NULL) { +// continue; +// } +// +// SSqlRes *pRes1 = &pSql->pSubs[i]->res; +// SSqlCmd *pCmd1 = &pSql->pSubs[i]->cmd; +// +// SQueryInfo *pQueryInfo1 = tscGetQueryInfo(pCmd1, pCmd1->clauseIndex); +// assert(pQueryInfo1->numOfTables == 1); +// +// STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo1, 0); +// +// /* +// * if the global limitation is not reached, and current result has not exhausted, or next more vnodes are +// * available, goes on +// */ +// if (pTableMetaInfo->vgroupIndex < pTableMetaInfo->vgroupList->numOfVgroups && pRes1->row < pRes1->numOfRows && +// (!tscHasReachLimitation(pQueryInfo1, pRes1))) { +// allSubqueryExhausted = false; +// break; +// } +// } +// +// hasData = !allSubqueryExhausted; +// } else { // otherwise, in case inner join, if any subquery exhausted, query completed. +// for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) { +// if (pSql->pSubs[i] == 0) { +// continue; +// } +// +// SSqlRes * pRes1 = &pSql->pSubs[i]->res; +// SQueryInfo *pQueryInfo1 = tscGetQueryInfo(&pSql->pSubs[i]->cmd, 0); +// +// if ((pRes1->row >= pRes1->numOfRows && tscHasReachLimitation(pQueryInfo1, pRes1) && +// tscIsProjectionQuery(pQueryInfo1)) || +// (pRes1->numOfRows == 0)) { +// hasData = false; +// break; +// } +// } +// } +// +// return hasData; +//} + +void* createQueryInfoFromQueryNode(SQueryInfo* pQueryInfo, SExprInfo* pExprs, STableGroupInfo* pTableGroupInfo, + SOperatorInfo* pSourceOperator, char* sql, void* merger, int32_t stage) { + assert(pQueryInfo != NULL); + int16_t numOfOutput = pQueryInfo->fieldsInfo.numOfOutput; + + SQInfo *pQInfo = (SQInfo *)calloc(1, sizeof(SQInfo)); + if (pQInfo == NULL) { + goto _cleanup; + } + + // to make sure third party won't overwrite this structure + pQInfo->signature = pQInfo; + + SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv; + SQueryAttr *pQueryAttr = &pQInfo->query; + + pRuntimeEnv->pQueryAttr = pQueryAttr; + tscCreateQueryFromQueryInfo(pQueryInfo, pQueryAttr, NULL); + + pQueryAttr->tableGroupInfo = *pTableGroupInfo; + + // calculate the result row size + for (int16_t col = 0; col < numOfOutput; ++col) { + assert(pExprs[col].base.resBytes > 0); + pQueryAttr->resultRowSize += pExprs[col].base.resBytes; + + // keep the tag length + if (TSDB_COL_IS_TAG(pExprs[col].base.colInfo.flag)) { + pQueryAttr->tagLen += pExprs[col].base.resBytes; } } - - return hasData; + + size_t numOfGroups = 0; + if (pTableGroupInfo->pGroupList != NULL) { + numOfGroups = taosArrayGetSize(pTableGroupInfo->pGroupList); + STableGroupInfo* pTableqinfo = &pQInfo->runtimeEnv.tableqinfoGroupInfo; + + pTableqinfo->pGroupList = taosArrayInit(numOfGroups, POINTER_BYTES); + pTableqinfo->numOfTables = pTableGroupInfo->numOfTables; + pTableqinfo->map = taosHashInit(pTableGroupInfo->numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK); + } + + pQInfo->pBuf = calloc(pTableGroupInfo->numOfTables, sizeof(STableQueryInfo)); + if (pQInfo->pBuf == NULL) { + goto _cleanup; + } + + pQInfo->dataReady = QUERY_RESULT_NOT_READY; + pQInfo->rspContext = NULL; + pQInfo->sql = sql; + + pthread_mutex_init(&pQInfo->lock, NULL); + tsem_init(&pQInfo->ready, 0, 0); + + int32_t index = 0; + for(int32_t i = 0; i < numOfGroups; ++i) { + SArray* pa = taosArrayGetP(pQueryAttr->tableGroupInfo.pGroupList, i); + + size_t s = taosArrayGetSize(pa); + SArray* p1 = taosArrayInit(s, POINTER_BYTES); + if (p1 == NULL) { + goto _cleanup; + } + + taosArrayPush(pRuntimeEnv->tableqinfoGroupInfo.pGroupList, &p1); + + STimeWindow window = pQueryAttr->window; + for(int32_t j = 0; j < s; ++j) { + STableKeyInfo* info = taosArrayGet(pa, j); + window.skey = info->lastKey; + + void* buf = (char*) pQInfo->pBuf + index * sizeof(STableQueryInfo); + STableQueryInfo* item = createTableQueryInfo(pQueryAttr, info->pTable, pQueryAttr->groupbyColumn, window, buf); + if (item == NULL) { + goto _cleanup; + } + + item->groupIndex = i; + taosArrayPush(p1, &item); + + STableId id = {.tid = 0, .uid = 0}; + taosHashPut(pRuntimeEnv->tableqinfoGroupInfo.map, &id.tid, sizeof(id.tid), &item, POINTER_BYTES); + index += 1; + } + } + + for (int32_t i = 0; i < numOfOutput; ++i) { + SExprInfo* pExprInfo = &pExprs[i]; + if (pExprInfo->pExpr != NULL) { + tExprTreeDestroy(pExprInfo->pExpr, NULL); + pExprInfo->pExpr = NULL; + } + } + + tfree(pExprs); + + SArray* pa = NULL; + if (stage == MASTER_SCAN) { + pa = createExecOperatorPlan(pQueryAttr); + } else { + pa = createGlobalMergePlan(pQueryAttr); + } + + STsBufInfo bufInfo = {0}; + SQueryParam param = {.pOperator = pa}; + /*int32_t code = */initQInfo(&bufInfo, NULL, pSourceOperator, pQInfo, ¶m, NULL, 0, merger); + taosArrayDestroy(pa); + + return pQInfo; + + _cleanup: + freeQInfo(pQInfo); + return NULL; } diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index a034de1714..7e0aad3b44 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -81,11 +81,11 @@ bool tscQueryTags(SQueryInfo* pQueryInfo) { int32_t numOfCols = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfCols; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - int32_t functId = pExpr->functionId; + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + int32_t functId = pExpr->base.functionId; // "select count(tbname)" query - if (functId == TSDB_FUNC_COUNT && pExpr->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) { + if (functId == TSDB_FUNC_COUNT && pExpr->base.colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) { continue; } @@ -101,10 +101,9 @@ bool tscQueryBlockInfo(SQueryInfo* pQueryInfo) { int32_t numOfCols = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfCols; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - int32_t functId = pExpr->functionId; + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + int32_t functId = pExpr->base.functionId; - // "select count(tbname)" query if (functId == TSDB_FUNC_BLKINFO) { return true; } @@ -154,17 +153,17 @@ bool tscIsProjectionQueryOnSTable(SSqlCmd *pCmd, SQueryInfo* pQueryInfo, int32_t } for (int32_t i = 0; i < numOfExprs; ++i) { - int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId; + int32_t functionId = tscSqlExprGet(pQueryInfo, i)->base.functionId; if (functionId < 0) { SUdfInfo* pUdfInfo = taosArrayGet(pCmd->pUdfInfo, -1 * functionId - 1); if (pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE) { return false; } - + continue; } - + if (functionId != TSDB_FUNC_PRJ && functionId != TSDB_FUNC_TAGPRJ && functionId != TSDB_FUNC_TAG && @@ -202,14 +201,14 @@ bool tscIsProjectionQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId; + int32_t functionId = tscSqlExprGet(pQueryInfo, i)->base.functionId; if (functionId < 0) { SUdfInfo* pUdfInfo = taosArrayGet(pCmd->pUdfInfo, -1 * functionId - 1); if (pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE) { return false; } - + continue; } @@ -225,11 +224,11 @@ bool tscIsProjectionQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo) { size_t size = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); assert(pExpr != NULL); - int32_t functionId = pExpr->functionId; - if (functionId == TSDB_FUNC_TAG) { + int32_t functionId = pExpr->base.functionId; + if (functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS) { continue; } @@ -244,8 +243,8 @@ bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo) { bool tscIsSecondStageQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { size_t numOfOutput = tscNumOfFields(pQueryInfo); for(int32_t i = 0; i < numOfOutput; ++i) { - SExprInfo* pExprInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i)->pArithExprInfo; - if (pExprInfo != NULL) { + SExprInfo* pExprInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i)->pExpr; + if (pExprInfo->pExpr != NULL) { return true; } } @@ -272,16 +271,103 @@ bool tscGroupbyColumn(SQueryInfo* pQueryInfo) { return false; } +bool tscIsTopBotQuery(SQueryInfo* pQueryInfo) { + size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + + for (int32_t i = 0; i < numOfExprs; ++i) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr == NULL) { + continue; + } + + if (pExpr->base.functionId == TSDB_FUNC_TS) { + continue; + } + + if (pExpr->base.functionId == TSDB_FUNC_TOP || pExpr->base.functionId == TSDB_FUNC_BOTTOM) { + return true; + } + } + + return false; +} + +bool isTsCompQuery(SQueryInfo* pQueryInfo) { + size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + SExprInfo* pExpr1 = tscSqlExprGet(pQueryInfo, 0); + if (numOfExprs != 1) { + return false; + } + + return pExpr1->base.functionId == TSDB_FUNC_TS_COMP; +} + +bool hasTagValOutput(SQueryInfo* pQueryInfo) { + size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + SExprInfo* pExpr1 = tscSqlExprGet(pQueryInfo, 0); + + if (numOfExprs == 1 && pExpr1->base.functionId == TSDB_FUNC_TS_COMP) { + return true; + } + + for (int32_t i = 0; i < numOfExprs; ++i) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr == NULL) { + continue; + } + + // ts_comp column required the tag value for join filter + if (TSDB_COL_IS_TAG(pExpr->base.colInfo.flag)) { + return true; + } + } + + return false; +} + +bool timeWindowInterpoRequired(SQueryInfo *pQueryInfo) { + size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + for (int32_t i = 0; i < numOfExprs; ++i) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr == NULL) { + continue; + } + + int32_t functionId = pExpr->base.functionId; + if (functionId == TSDB_FUNC_TWA || functionId == TSDB_FUNC_INTERP) { + return true; + } + } + + return false; +} + +bool isStabledev(SQueryInfo* pQueryInfo) { + size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + for (int32_t i = 0; i < numOfExprs; ++i) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr == NULL) { + continue; + } + + int32_t functionId = pExpr->base.functionId; + if (functionId == TSDB_FUNC_STDDEV_DST) { + return true; + } + } + + return false; +} + bool tscIsTWAQuery(SQueryInfo* pQueryInfo) { size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); if (pExpr == NULL) { continue; } - int32_t functionId = pExpr->functionId; - if (functionId == TSDB_FUNC_TWA) { + if (pExpr->base.functionId == TSDB_FUNC_TWA) { return true; } } @@ -289,16 +375,58 @@ bool tscIsTWAQuery(SQueryInfo* pQueryInfo) { return false; } -bool tscIsTopbotQuery(SQueryInfo* pQueryInfo) { +bool tscNeedReverseScan(SQueryInfo* pQueryInfo) { size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); if (pExpr == NULL) { continue; } - int32_t functionId = pExpr->functionId; - if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) { + int32_t functionId = pExpr->base.functionId; + if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_TAG) { + continue; + } + + if ((functionId == TSDB_FUNC_FIRST || functionId == TSDB_FUNC_FIRST_DST) && pQueryInfo->order.order == TSDB_ORDER_DESC) { + return true; + } + + if (functionId == TSDB_FUNC_LAST || functionId == TSDB_FUNC_LAST_DST) { + // the scan order to acquire the last result of the specified column + int32_t order = (int32_t)pExpr->base.param[0].i64; + if (order != pQueryInfo->order.order) { + return true; + } + } + } + + return false; +} + +bool isSimpleAggregate(SQueryInfo* pQueryInfo) { + if (pQueryInfo->interval.interval > 0) { + return false; + } + + // Note:top/bottom query is fixed output query + if (tscIsTopBotQuery(pQueryInfo) || tscGroupbyColumn(pQueryInfo) || isTsCompQuery(pQueryInfo)) { + return true; + } + + size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); + for (int32_t i = 0; i < numOfExprs; ++i) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr == NULL) { + continue; + } + + int32_t functionId = pExpr->base.functionId; + if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY) { + continue; + } + + if (!IS_MULTIOUTPUT(aAggs[functionId].status)) { return true; } } @@ -306,24 +434,12 @@ bool tscIsTopbotQuery(SQueryInfo* pQueryInfo) { return false; } -int32_t tscGetTopbotQueryParam(SQueryInfo* pQueryInfo) { +bool isBlockDistQuery(SQueryInfo* pQueryInfo) { size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); - for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr == NULL) { - continue; - } - - int32_t functionId = pExpr->functionId; - if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) { - return (int32_t) pExpr->param[0].i64; - } - } - - return 0; + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, 0); + return (numOfExprs == 1 && pExpr->base.colInfo.colId == TSDB_BLOCK_DIST_COLUMN_INDEX); } - void tscClearInterpInfo(SQueryInfo* pQueryInfo) { if (!tscIsPointInterpQuery(pQueryInfo)) { return; @@ -371,23 +487,23 @@ void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo) { offset += pInfo->field.bytes; // generated the user-defined column result - if (pInfo->pSqlExpr != NULL && TSDB_COL_IS_UD_COL(pInfo->pSqlExpr->colInfo.flag)) { - if (pInfo->pSqlExpr->param[1].nType == TSDB_DATA_TYPE_NULL) { + if (pInfo->pExpr->pExpr == NULL && TSDB_COL_IS_UD_COL(pInfo->pExpr->base.colInfo.flag)) { + if (pInfo->pExpr->base.param[1].nType == TSDB_DATA_TYPE_NULL) { setNullN(pRes->urow[i], pInfo->field.type, pInfo->field.bytes, (int32_t) pRes->numOfRows); } else { if (pInfo->field.type == TSDB_DATA_TYPE_NCHAR || pInfo->field.type == TSDB_DATA_TYPE_BINARY) { - assert(pInfo->pSqlExpr->param[1].nLen <= pInfo->field.bytes); + assert(pInfo->pExpr->base.param[1].nLen <= pInfo->field.bytes); for (int32_t k = 0; k < pRes->numOfRows; ++k) { char* p = ((char**)pRes->urow)[i] + k * pInfo->field.bytes; - memcpy(varDataVal(p), pInfo->pSqlExpr->param[1].pz, pInfo->pSqlExpr->param[1].nLen); - varDataSetLen(p, pInfo->pSqlExpr->param[1].nLen); + memcpy(varDataVal(p), pInfo->pExpr->base.param[1].pz, pInfo->pExpr->base.param[1].nLen); + varDataSetLen(p, pInfo->pExpr->base.param[1].nLen); } } else { for (int32_t k = 0; k < pRes->numOfRows; ++k) { char* p = ((char**)pRes->urow)[i] + k * pInfo->field.bytes; - memcpy(p, &pInfo->pSqlExpr->param[1].i64, pInfo->field.bytes); + memcpy(p, &pInfo->pExpr->base.param[1].i64, pInfo->field.bytes); } } } @@ -424,6 +540,216 @@ void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo) { } } +void tscSetResRawPtrRv(SSqlRes* pRes, SQueryInfo* pQueryInfo, SSDataBlock* pBlock) { + assert(pRes->numOfCols > 0); + + for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { + SInternalField* pInfo = (SInternalField*)TARRAY_GET_ELEM(pQueryInfo->fieldsInfo.internalField, i); + + SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, i); + + pRes->urow[i] = pColData->pData; + pRes->length[i] = pInfo->field.bytes; + + // generated the user-defined column result + if (pInfo->pExpr->pExpr == NULL && TSDB_COL_IS_UD_COL(pInfo->pExpr->base.colInfo.flag)) { + if (pInfo->pExpr->base.param[1].nType == TSDB_DATA_TYPE_NULL) { + setNullN(pRes->urow[i], pInfo->field.type, pInfo->field.bytes, (int32_t) pRes->numOfRows); + } else { + if (pInfo->field.type == TSDB_DATA_TYPE_NCHAR || pInfo->field.type == TSDB_DATA_TYPE_BINARY) { + assert(pInfo->pExpr->base.param[1].nLen <= pInfo->field.bytes); + + for (int32_t k = 0; k < pRes->numOfRows; ++k) { + char* p = ((char**)pRes->urow)[i] + k * pInfo->field.bytes; + + memcpy(varDataVal(p), pInfo->pExpr->base.param[1].pz, pInfo->pExpr->base.param[1].nLen); + varDataSetLen(p, pInfo->pExpr->base.param[1].nLen); + } + } else { + for (int32_t k = 0; k < pRes->numOfRows; ++k) { + char* p = ((char**)pRes->urow)[i] + k * pInfo->field.bytes; + memcpy(p, &pInfo->pExpr->base.param[1].i64, pInfo->field.bytes); + } + } + } + + } else if (pInfo->field.type == TSDB_DATA_TYPE_NCHAR) { + // convert unicode to native code in a temporary buffer extra one byte for terminated symbol + pRes->buffer[i] = realloc(pRes->buffer[i], pInfo->field.bytes * pRes->numOfRows); + + // string terminated char for binary data + memset(pRes->buffer[i], 0, pInfo->field.bytes * pRes->numOfRows); + + char* p = pRes->urow[i]; + for (int32_t k = 0; k < pRes->numOfRows; ++k) { + char* dst = pRes->buffer[i] + k * pInfo->field.bytes; + + if (isNull(p, TSDB_DATA_TYPE_NCHAR)) { + memcpy(dst, p, varDataTLen(p)); + } else if (varDataLen(p) > 0) { + int32_t length = taosUcs4ToMbs(varDataVal(p), varDataLen(p), varDataVal(dst)); + varDataSetLen(dst, length); + + if (length == 0) { + tscError("charset:%s to %s. val:%s convert failed.", DEFAULT_UNICODE_ENCODEC, tsCharset, (char*)p); + } + } else { + varDataSetLen(dst, 0); + } + + p += pInfo->field.bytes; + } + + memcpy(pRes->urow[i], pRes->buffer[i], pInfo->field.bytes * pRes->numOfRows); + } + } +} + +static SColumnInfo* extractColumnInfoFromResult(STableMeta* pTableMeta, SArray* pTableCols) { + int32_t numOfCols = (int32_t) taosArrayGetSize(pTableCols); + SColumnInfo* pColInfo = calloc(numOfCols, sizeof(SColumnInfo)); + + SSchema *pSchema = pTableMeta->schema; + for(int32_t i = 0; i < numOfCols; ++i) { + SColumn* pCol = taosArrayGetP(pTableCols, i); + int32_t index = pCol->columnIndex; + + pColInfo[i].type = pSchema[index].type; + pColInfo[i].bytes = pSchema[index].bytes; + pColInfo[i].colId = pSchema[index].colId; + } + + return pColInfo; +} + +typedef struct SDummyInputInfo { + SSDataBlock *block; + SSqlRes *pRes; // refactor: remove it +} SDummyInputInfo; + +SSDataBlock* doGetDataBlock(void* param, bool* newgroup) { + SOperatorInfo *pOperator = (SOperatorInfo*) param; + + SDummyInputInfo *pInput = pOperator->info; + char* pData = pInput->pRes->data; + + SSDataBlock* pBlock = pInput->block; + pBlock->info.rows = pInput->pRes->numOfRows; + if (pBlock->info.rows == 0) { + return NULL; + } + + //TODO refactor + int32_t offset = 0; + for(int32_t i = 0; i < pBlock->info.numOfCols; ++i) { + SColumnInfoData* pColData = taosArrayGet(pBlock->pDataBlock, i); + if (pData != NULL) { + pColData->pData = pData + offset * pBlock->info.rows; + } else { + pColData->pData = pInput->pRes->urow[i]; + } + + offset += pColData->info.bytes; + } + + pInput->pRes->numOfRows = 0; + *newgroup = false; + return pBlock; +} + +static void destroyDummyInputOperator(void* param, int32_t numOfOutput) { + SDummyInputInfo* pInfo = (SDummyInputInfo*) param; + + // tricky + for(int32_t i = 0; i < numOfOutput; ++i) { + SColumnInfoData* pColInfoData = taosArrayGet(pInfo->block->pDataBlock, i); + pColInfoData->pData = NULL; + } + + pInfo->block = destroyOutputBuf(pInfo->block); + pInfo->pRes = NULL; +} + +// todo this operator servers as the adapter for Operator tree and SqlRes result, remove it later +SOperatorInfo* createDummyInputOperator(char* pResult, SSchema* pSchema, int32_t numOfCols) { + assert(numOfCols > 0); + SDummyInputInfo* pInfo = calloc(1, sizeof(SDummyInputInfo)); + + pInfo->pRes = (SSqlRes*) pResult; + + pInfo->block = calloc(numOfCols, sizeof(SSDataBlock)); + pInfo->block->info.numOfCols = numOfCols; + + pInfo->block->pDataBlock = taosArrayInit(numOfCols, sizeof(SColumnInfoData)); + for(int32_t i = 0; i < numOfCols; ++i) { + SColumnInfoData colData = {{0}}; + colData.info.bytes = pSchema[i].bytes; + colData.info.type = pSchema[i].type; + colData.info.colId = pSchema[i].colId; + + taosArrayPush(pInfo->block->pDataBlock, &colData); + } + + SOperatorInfo* pOptr = calloc(1, sizeof(SOperatorInfo)); + pOptr->name = "DummyInputOperator"; + pOptr->operatorType = OP_DummyInput; + pOptr->numOfOutput = numOfCols; + pOptr->blockingOptr = false; + pOptr->info = pInfo; + pOptr->exec = doGetDataBlock; + pOptr->cleanup = destroyDummyInputOperator; + return pOptr; +} + +void convertQueryResult(SSqlRes* pRes, SQueryInfo* pQueryInfo) { + // set the correct result + SSDataBlock* p = pQueryInfo->pQInfo->runtimeEnv.outputBuf; + pRes->numOfRows = (p != NULL)? p->info.rows: 0; + + if (pRes->code == TSDB_CODE_SUCCESS && pRes->numOfRows > 0) { + tscCreateResPointerInfo(pRes, pQueryInfo); + tscSetResRawPtrRv(pRes, pQueryInfo, p); + } + + pRes->row = 0; + pRes->completed = (pRes->numOfRows == 0); +} + +void handleDownstreamOperator(SSqlRes* pRes, SQueryInfo* pQueryInfo) { + if (pQueryInfo->pDownstream != NULL) { + // handle the following query process + SQueryInfo *px = pQueryInfo->pDownstream; + SColumnInfo* pColumnInfo = extractColumnInfoFromResult(px->pTableMetaInfo[0]->pTableMeta, px->colList); + int32_t numOfOutput = (int32_t) tscSqlExprNumOfExprs(px); + + int32_t numOfCols = (int32_t) taosArrayGetSize(px->colList); + SQueriedTableInfo info = {.colList = pColumnInfo, .numOfCols = numOfCols,}; + SSchema* pSchema = tscGetTableSchema(px->pTableMetaInfo[0]->pTableMeta); + + STableGroupInfo tableGroupInfo = {.numOfTables = 1, .pGroupList = taosArrayInit(1, POINTER_BYTES),}; + tableGroupInfo.map = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK); + + STableKeyInfo tableKeyInfo = {.pTable = NULL, .lastKey = INT64_MIN}; + + SArray* group = taosArrayInit(1, sizeof(STableKeyInfo)); + taosArrayPush(group, &tableKeyInfo); + + taosArrayPush(tableGroupInfo.pGroupList, &group); + + SOperatorInfo* pSourceOptr = createDummyInputOperator((char*)pRes, pSchema, numOfCols); + + SExprInfo *exprInfo = NULL; + /*int32_t code = */createQueryFunc(&info, numOfOutput, &exprInfo, px->exprList->pData, NULL, px->type, NULL, NULL); + px->pQInfo = createQueryInfoFromQueryNode(px, exprInfo, &tableGroupInfo, pSourceOptr, NULL, NULL, MASTER_SCAN); + + uint64_t qId = 0; + qTableQuery(px->pQInfo, &qId); + convertQueryResult(pRes, px); + + tfree(pColumnInfo); + } +} + static void tscDestroyResPointerInfo(SSqlRes* pRes) { if (pRes->buffer != NULL) { // free all buffers containing the multibyte string for (int i = 0; i < pRes->numOfCols; i++) { @@ -449,7 +775,7 @@ static void tscDestroyResPointerInfo(SSqlRes* pRes) { } tfree(pRes->final); - + pRes->data = NULL; // pRes->data points to the buffer of pRsp, no need to free } @@ -459,10 +785,29 @@ void tscFreeQueryInfo(SSqlCmd* pCmd, bool removeMeta) { } for (int32_t i = 0; i < pCmd->numOfClause; ++i) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, i); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, i); + + // recursive call it + if (taosArrayGetSize(pQueryInfo->pUpstream) > 0) { + SQueryInfo* pUp = taosArrayGetP(pQueryInfo->pUpstream, 0); + freeQueryInfoImpl(pUp); + clearAllTableMetaInfo(pUp, removeMeta); + if (pUp->pQInfo != NULL) { + qDestroyQueryInfo(pUp->pQInfo); + pUp->pQInfo = NULL; + } + + tfree(pUp); + } freeQueryInfoImpl(pQueryInfo); clearAllTableMetaInfo(pQueryInfo, removeMeta); + + if (pQueryInfo->pQInfo != NULL) { + qDestroyQueryInfo(pQueryInfo->pQInfo); + pQueryInfo->pQInfo = NULL; + } + tfree(pQueryInfo); } @@ -519,10 +864,10 @@ void tscFreeSubobj(SSqlObj* pSql) { return; } - tscDebug("%p start to free sub SqlObj, numOfSub:%d", pSql, pSql->subState.numOfSub); + tscDebug("0x%"PRIx64" start to free sub SqlObj, numOfSub:%d", pSql->self, pSql->subState.numOfSub); for(int32_t i = 0; i < pSql->subState.numOfSub; ++i) { - tscDebug("%p free sub SqlObj:%p, index:%d", pSql, pSql->pSubs[i], i); + tscDebug("0x%"PRIx64" free sub SqlObj:%p, index:%d", pSql->self, pSql->pSubs[i], i); taos_free_result(pSql->pSubs[i]); pSql->pSubs[i] = NULL; } @@ -553,7 +898,7 @@ void tscFreeRegisteredSqlObj(void *pSql) { int32_t num = atomic_sub_fetch_32(&pTscObj->numOfObj, 1); int32_t total = atomic_sub_fetch_32(&tscNumOfObj, 1); - tscDebug("%p free SqlObj, total in tscObj:%d, total:%d", pSql, num, total); + tscDebug("0x%"PRIx64" free SqlObj, total in tscObj:%d, total:%d", p->self, num, total); tscFreeSqlObj(p); taosReleaseRef(tscRefId, pTscObj->rid); @@ -576,7 +921,7 @@ void tscFreeSqlObj(SSqlObj* pSql) { return; } - tscDebug("%p start to free sqlObj", pSql); + tscDebug("0x%"PRIx64" start to free sqlObj", pSql->self); pSql->res.code = TSDB_CODE_TSC_QUERY_CANCELLED; @@ -692,17 +1037,17 @@ void freeUdfInfo(SUdfInfo* pUdfInfo) { if (pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY]) { (*(udfDestroyFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY])(&pUdfInfo->init); } - + tfree(pUdfInfo->name); if (pUdfInfo->path) { unlink(pUdfInfo->path); } - + tfree(pUdfInfo->path); tfree(pUdfInfo->content); - + taosCloseDll(pUdfInfo->handle); } @@ -783,6 +1128,10 @@ int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock) { return TSDB_CODE_SUCCESS; } +SQueryInfo* tscGetActiveQueryInfo(SSqlCmd* pCmd) { + return pCmd->active; +} + /** * create the in-memory buffer for each table to keep the submitted data block * @param initialSize @@ -1009,7 +1358,7 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, bool freeBlockMap) { tscSortRemoveDataBlockDupRows(pOneTableBlock); char* ekey = (char*)pBlocks->data + pOneTableBlock->rowSize*(pBlocks->numOfRows-1); - tscDebug("%p name:%s, name:%d rows:%d sversion:%d skey:%" PRId64 ", ekey:%" PRId64, pSql, tNameGetTableName(&pOneTableBlock->tableName), + tscDebug("0x%"PRIx64" name:%s, name:%d rows:%d sversion:%d skey:%" PRId64 ", ekey:%" PRId64, pSql->self, tNameGetTableName(&pOneTableBlock->tableName), pBlocks->tid, pBlocks->numOfRows, pBlocks->sversion, GET_INT64_VAL(pBlocks->data), GET_INT64_VAL(ekey)); int32_t len = pBlocks->numOfRows * (pOneTableBlock->rowSize + expandSize) + sizeof(STColumn) * tscGetNumOfColumns(pOneTableBlock->pTableMeta); @@ -1107,12 +1456,7 @@ SInternalField* tscFieldInfoAppend(SFieldInfo* pFieldInfo, TAOS_FIELD* pField) { assert(pFieldInfo != NULL); pFieldInfo->numOfOutput++; - struct SInternalField info = { - .pSqlExpr = NULL, - .pArithExprInfo = NULL, - .visible = true, - .pFieldFilters = NULL, - }; + struct SInternalField info = { .pExpr = NULL, .visible = true }; info.field = *pField; return taosArrayPush(pFieldInfo->internalField, &info); @@ -1120,12 +1464,7 @@ SInternalField* tscFieldInfoAppend(SFieldInfo* pFieldInfo, TAOS_FIELD* pField) { SInternalField* tscFieldInfoInsert(SFieldInfo* pFieldInfo, int32_t index, TAOS_FIELD* field) { pFieldInfo->numOfOutput++; - struct SInternalField info = { - .pSqlExpr = NULL, - .pArithExprInfo = NULL, - .visible = true, - .pFieldFilters = NULL, - }; + struct SInternalField info = { .pExpr = NULL, .visible = true }; info.field = *field; return taosArrayInsert(pFieldInfo->internalField, index, &info); @@ -1134,14 +1473,14 @@ SInternalField* tscFieldInfoInsert(SFieldInfo* pFieldInfo, int32_t index, TAOS_F void tscFieldInfoUpdateOffset(SQueryInfo* pQueryInfo) { size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); - SSqlExpr* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); - pExpr->offset = 0; + SExprInfo* pExpr = taosArrayGetP(pQueryInfo->exprList, 0); + pExpr->base.offset = 0; for (int32_t i = 1; i < numOfExprs; ++i) { - SSqlExpr* prev = taosArrayGetP(pQueryInfo->exprList, i - 1); - SSqlExpr* p = taosArrayGetP(pQueryInfo->exprList, i); + SExprInfo* prev = taosArrayGetP(pQueryInfo->exprList, i - 1); + SExprInfo* p = taosArrayGetP(pQueryInfo->exprList, i); - p->offset = prev->offset + prev->resBytes; + p->base.offset = prev->base.offset + prev->base.resBytes; } } @@ -1157,9 +1496,9 @@ TAOS_FIELD* tscFieldInfoGetField(SFieldInfo* pFieldInfo, int32_t index) { int16_t tscFieldInfoGetOffset(SQueryInfo* pQueryInfo, int32_t index) { SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, index); - assert(pInfo != NULL && pInfo->pSqlExpr != NULL); + assert(pInfo != NULL && pInfo->pExpr->pExpr == NULL); - return pInfo->pSqlExpr->offset; + return pInfo->pExpr->base.offset; } int32_t tscFieldInfoCompare(const SFieldInfo* pFieldInfo1, const SFieldInfo* pFieldInfo2) { @@ -1191,141 +1530,162 @@ int32_t tscGetResRowLength(SArray* pExprList) { int32_t size = 0; for(int32_t i = 0; i < num; ++i) { - SSqlExpr* pExpr = taosArrayGetP(pExprList, i); - size += pExpr->resBytes; + SExprInfo* pExpr = taosArrayGetP(pExprList, i); + size += pExpr->base.resBytes; } 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); +static void destroyFilterInfo(SColumnFilterList* pFilterList) { + for(int32_t i = 0; i < pFilterList->numOfFilters; ++i) { + if (pFilterList->filterInfo[i].filterstr) { + tfree(pFilterList->filterInfo[i].pz); } } - - tfree(pFilterInfo); + + tfree(pFilterList->filterInfo); + pFilterList->numOfFilters = 0; } -static void tscColumnDestroy(SColumn* pCol) { - destroyFilterInfo(pCol->filterInfo, pCol->numOfFilters); - free(pCol); -} +void* sqlExprDestroy(SExprInfo* pExpr) { + if (pExpr == NULL) { + return NULL; + } + SSqlExpr* p = &pExpr->base; + for(int32_t i = 0; i < tListLen(p->param); ++i) { + tVariantDestroy(&p->param[i]); + } + + if (p->flist.numOfFilters > 0) { + tfree(p->flist.filterInfo); + } + + if (pExpr->pExpr != NULL) { + tExprTreeDestroy(pExpr->pExpr, NULL); + } + + tfree(pExpr); + return NULL; +} void tscFieldInfoClear(SFieldInfo* pFieldInfo) { if (pFieldInfo == NULL) { return; } - for(int32_t i = 0; i < pFieldInfo->numOfOutput; ++i) { - SInternalField* pInfo = taosArrayGet(pFieldInfo->internalField, i); - - if (pInfo->pArithExprInfo != NULL) { - tExprTreeDestroy(pInfo->pArithExprInfo->pExpr, NULL); - - SSqlFuncMsg* pFuncMsg = &pInfo->pArithExprInfo->base; - for(int32_t j = 0; j < pFuncMsg->numOfParams; ++j) { - if (pFuncMsg->arg[j].argType == TSDB_DATA_TYPE_BINARY) { - tfree(pFuncMsg->arg[j].argValue.pz); - } + if (pFieldInfo->internalField != NULL) { + size_t num = taosArrayGetSize(pFieldInfo->internalField); + for (int32_t i = 0; i < num; ++i) { + SInternalField* pfield = taosArrayGet(pFieldInfo->internalField, i); + if (pfield->pExpr != NULL && pfield->pExpr->pExpr != NULL) { + sqlExprDestroy(pfield->pExpr); } - - 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)); } -static SSqlExpr* doCreateSqlExpr(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type, - int16_t size, int16_t resColId, int16_t interSize, int32_t colType) { +static SExprInfo* doCreateSqlExpr(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type, + int16_t size, int16_t resColId, int16_t interSize, int32_t colType) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, pColIndex->tableIndex); - SSqlExpr* pExpr = calloc(1, sizeof(SSqlExpr)); + SExprInfo* pExpr = calloc(1, sizeof(SExprInfo)); if (pExpr == NULL) { return NULL; } - pExpr->functionId = functionId; + SSqlExpr* p = &pExpr->base; + p->functionId = functionId; // set the correct columnIndex index if (pColIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX) { - pExpr->colInfo.colId = TSDB_TBNAME_COLUMN_INDEX; + SSchema* s = tGetTbnameColumnSchema(); + p->colInfo.colId = TSDB_TBNAME_COLUMN_INDEX; + p->colBytes = s->bytes; + p->colType = s->type; } else if (pColIndex->columnIndex == TSDB_BLOCK_DIST_COLUMN_INDEX) { - pExpr->colInfo.colId = TSDB_BLOCK_DIST_COLUMN_INDEX; + SSchema s = tGetBlockDistColumnSchema(); + + p->colInfo.colId = TSDB_BLOCK_DIST_COLUMN_INDEX; + p->colBytes = s.bytes; + p->colType = s.type; } else if (pColIndex->columnIndex <= TSDB_UD_COLUMN_INDEX) { - pExpr->colInfo.colId = pColIndex->columnIndex; + p->colInfo.colId = pColIndex->columnIndex; + p->colBytes = size; + p->colType = type; } else { if (TSDB_COL_IS_TAG(colType)) { SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); - pExpr->colInfo.colId = pSchema[pColIndex->columnIndex].colId; - tstrncpy(pExpr->colInfo.name, pSchema[pColIndex->columnIndex].name, sizeof(pExpr->colInfo.name)); + p->colInfo.colId = pSchema[pColIndex->columnIndex].colId; + p->colBytes = pSchema[pColIndex->columnIndex].bytes; + p->colType = pSchema[pColIndex->columnIndex].type; + tstrncpy(p->colInfo.name, pSchema[pColIndex->columnIndex].name, sizeof(p->colInfo.name)); } else if (pTableMetaInfo->pTableMeta != NULL) { // in handling select database/version/server_status(), the pTableMeta is NULL SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pColIndex->columnIndex); - pExpr->colInfo.colId = pSchema->colId; - tstrncpy(pExpr->colInfo.name, pSchema->name, sizeof(pExpr->colInfo.name)); + p->colInfo.colId = pSchema->colId; + p->colBytes = pSchema->bytes; + p->colType = pSchema->type; + tstrncpy(p->colInfo.name, pSchema->name, sizeof(p->colInfo.name)); } } - pExpr->colInfo.flag = colType; - pExpr->colInfo.colIndex = pColIndex->columnIndex; + p->colInfo.flag = colType; + p->colInfo.colIndex = pColIndex->columnIndex; - pExpr->resType = type; - pExpr->resBytes = size; - pExpr->resColId = resColId; - pExpr->interBytes = interSize; + p->resType = type; + p->resBytes = size; + p->resColId = resColId; + p->interBytes = interSize; if (pTableMetaInfo->pTableMeta) { - pExpr->uid = pTableMetaInfo->pTableMeta->id.uid; + p->uid = pTableMetaInfo->pTableMeta->id.uid; } return pExpr; } -SSqlExpr* tscSqlExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type, +SExprInfo* tscSqlExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type, int16_t size, int16_t resColId, int16_t interSize, bool isTagCol) { int32_t num = (int32_t)taosArrayGetSize(pQueryInfo->exprList); if (index == num) { return tscSqlExprAppend(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol); } - SSqlExpr* pExpr = doCreateSqlExpr(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol); + SExprInfo* pExpr = doCreateSqlExpr(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol); taosArrayInsert(pQueryInfo->exprList, index, &pExpr); return pExpr; } -SSqlExpr* tscSqlExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type, +SExprInfo* tscSqlExprAppend(SQueryInfo* pQueryInfo, int16_t functionId, SColumnIndex* pColIndex, int16_t type, int16_t size, int16_t resColId, int16_t interSize, bool isTagCol) { - SSqlExpr* pExpr = doCreateSqlExpr(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol); + SExprInfo* pExpr = doCreateSqlExpr(pQueryInfo, functionId, pColIndex, type, size, resColId, interSize, isTagCol); taosArrayPush(pQueryInfo->exprList, &pExpr); return pExpr; } -SSqlExpr* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, +SExprInfo* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functionId, int16_t srcColumnIndex, int16_t type, int16_t size) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, index); + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, index); if (pExpr == NULL) { return NULL; } - pExpr->functionId = functionId; + SSqlExpr* pse = &pExpr->base; + pse->functionId = functionId; - pExpr->colInfo.colIndex = srcColumnIndex; - pExpr->colInfo.colId = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, srcColumnIndex)->colId; + pse->colInfo.colIndex = srcColumnIndex; + pse->colInfo.colId = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, srcColumnIndex)->colId; - pExpr->resType = type; - pExpr->resBytes = size; + pse->resType = type; + pse->resBytes = size; return pExpr; } @@ -1337,8 +1697,8 @@ bool tscMultiRoundQuery(SQueryInfo* pQueryInfo, int32_t index) { int32_t numOfExprs = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); for(int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - if (pExpr->functionId == TSDB_FUNC_STDDEV_DST) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + if (pExpr->base.functionId == TSDB_FUNC_STDDEV_DST) { return true; } } @@ -1361,32 +1721,18 @@ void addExprParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes) assert(pExpr->numOfParams <= 3); } -SSqlExpr* tscSqlExprGet(SQueryInfo* pQueryInfo, int32_t index) { +SExprInfo* tscSqlExprGet(SQueryInfo* pQueryInfo, int32_t index) { return taosArrayGetP(pQueryInfo->exprList, index); } -void* sqlExprDestroy(SSqlExpr* pExpr) { - if (pExpr == NULL) { - return NULL; - } - - for(int32_t i = 0; i < tListLen(pExpr->param); ++i) { - tVariantDestroy(&pExpr->param[i]); - } - - tfree(pExpr); - - return NULL; -} - /* - * NOTE: Does not release SSqlExprInfo here. + * NOTE: Does not release SExprInfo here. */ void tscSqlExprInfoDestroy(SArray* pExprInfo) { size_t size = taosArrayGetSize(pExprInfo); for(int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = taosArrayGetP(pExprInfo, i); + SExprInfo* pExpr = taosArrayGetP(pExprInfo, i); sqlExprDestroy(pExpr); } @@ -1398,46 +1744,36 @@ int32_t tscSqlExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deepco size_t size = taosArrayGetSize(src); for (int32_t i = 0; i < size; ++i) { - SSqlExpr* pExpr = taosArrayGetP(src, i); + SExprInfo* pExpr = taosArrayGetP(src, i); - if (pExpr->uid == uid) { - + if (pExpr->base.uid == uid) { if (deepcopy) { - SSqlExpr* p1 = calloc(1, sizeof(SSqlExpr)); - if (p1 == NULL) { - return -1; - } + SExprInfo* p1 = calloc(1, sizeof(SExprInfo)); + tscSqlExprAssign(p1, pExpr); - *p1 = *pExpr; - memset(p1->param, 0, sizeof(tVariant) * tListLen(p1->param)); - - for (int32_t j = 0; j < pExpr->numOfParams; ++j) { - tVariantAssign(&p1->param[j], &pExpr->param[j]); - } - taosArrayPush(dst, &p1); } else { taosArrayPush(dst, &pExpr); } + } } return 0; } -bool tscColumnExists(SArray* pColumnList, SColumnIndex* pColIndex) { +bool tscColumnExists(SArray* pColumnList, int32_t columnIndex, uint64_t uid) { // ignore the tbname columnIndex to be inserted into source list - if (pColIndex->columnIndex < 0) { + if (columnIndex < 0) { return false; } - + size_t numOfCols = taosArrayGetSize(pColumnList); - int16_t col = pColIndex->columnIndex; int32_t i = 0; while (i < numOfCols) { SColumn* pCol = taosArrayGetP(pColumnList, i); - if ((pCol->colIndex.columnIndex != col) || (pCol->colIndex.tableIndex != pColIndex->tableIndex)) { + if ((pCol->columnIndex != columnIndex) || (pCol->tableUid != uid)) { ++i; continue; } else { @@ -1452,22 +1788,38 @@ bool tscColumnExists(SArray* pColumnList, SColumnIndex* pColIndex) { return true; } +void tscSqlExprAssign(SExprInfo* dst, const SExprInfo* src) { + assert(dst != NULL && src != NULL); -SColumn* tscColumnListInsert(SArray* pColumnList, SColumnIndex* pColIndex) { + *dst = *src; + + if (src->base.flist.numOfFilters > 0) { + dst->base.flist.filterInfo = calloc(src->base.flist.numOfFilters, sizeof(SColumnFilterInfo)); + memcpy(dst->base.flist.filterInfo, src->base.flist.filterInfo, sizeof(SColumnFilterInfo) * src->base.flist.numOfFilters); + } + + dst->pExpr = exprdup(src->pExpr); + + memset(dst->base.param, 0, sizeof(tVariant) * tListLen(dst->base.param)); + for (int32_t j = 0; j < src->base.numOfParams; ++j) { + tVariantAssign(&dst->base.param[j], &src->base.param[j]); + } +} + +SColumn* tscColumnListInsert(SArray* pColumnList, int32_t columnIndex, uint64_t uid, SSchema* pSchema) { // ignore the tbname columnIndex to be inserted into source list - if (pColIndex->columnIndex < 0) { + if (columnIndex < 0) { return NULL; } size_t numOfCols = taosArrayGetSize(pColumnList); - int16_t col = pColIndex->columnIndex; int32_t i = 0; while (i < numOfCols) { SColumn* pCol = taosArrayGetP(pColumnList, i); - if (pCol->colIndex.columnIndex < col) { + if (pCol->columnIndex < columnIndex) { i++; - } else if (pCol->colIndex.tableIndex < pColIndex->tableIndex) { + } else if (pCol->tableUid < uid) { i++; } else { break; @@ -1480,18 +1832,28 @@ SColumn* tscColumnListInsert(SArray* pColumnList, SColumnIndex* pColIndex) { return NULL; } - b->colIndex = *pColIndex; + b->columnIndex = columnIndex; + b->tableUid = uid; + b->info.colId = pSchema->colId; + b->info.bytes = pSchema->bytes; + b->info.type = pSchema->type; + taosArrayInsert(pColumnList, i, &b); } else { SColumn* pCol = taosArrayGetP(pColumnList, i); - if (i < numOfCols && (pCol->colIndex.columnIndex > col || pCol->colIndex.tableIndex != pColIndex->tableIndex)) { + if (i < numOfCols && (pCol->columnIndex > columnIndex || pCol->tableUid != uid)) { SColumn* b = calloc(1, sizeof(SColumn)); if (b == NULL) { return NULL; } - b->colIndex = *pColIndex; + b->columnIndex = columnIndex; + b->tableUid = uid; + b->info.colId = pSchema->colId; + b->info.bytes = pSchema->bytes; + b->info.type = pSchema->type; + taosArrayInsert(pColumnList, i, &b); } } @@ -1509,22 +1871,29 @@ SColumn* tscColumnClone(const SColumn* src) { return NULL; } - dst->colIndex = src->colIndex; - dst->numOfFilters = src->numOfFilters; - dst->filterInfo = tFilterInfoDup(src->filterInfo, src->numOfFilters); - + dst->columnIndex = src->columnIndex; + dst->tableUid = src->tableUid; + dst->info.flist.numOfFilters = src->info.flist.numOfFilters; + dst->info.flist.filterInfo = tFilterInfoDup(src->info.flist.filterInfo, src->info.flist.numOfFilters); + dst->info.type = src->info.type; + dst->info.colId = src->info.colId; + dst->info.bytes = src->info.bytes; return dst; } +static void tscColumnDestroy(SColumn* pCol) { + destroyFilterInfo(&pCol->info.flist); + free(pCol); +} -void tscColumnListCopy(SArray* dst, const SArray* src, int16_t tableIndex) { +void tscColumnListCopy(SArray* dst, const SArray* src, uint64_t tableUid) { assert(src != NULL && dst != NULL); size_t num = taosArrayGetSize(src); for (int32_t i = 0; i < num; ++i) { SColumn* pCol = taosArrayGetP(src, i); - if (pCol->colIndex.tableIndex == tableIndex || tableIndex < 0) { + if (pCol->tableUid == tableUid) { SColumn* p = tscColumnClone(pCol); taosArrayPush(dst, &p); } @@ -1746,7 +2115,7 @@ int32_t tscTagCondCopy(STagCond* dest, const STagCond* src) { dest->tbnameCond.len = src->tbnameCond.len; dest->joinInfo.hasJoin = src->joinInfo.hasJoin; - + for (int32_t i = 0; i < TSDB_MAX_JOIN_TABLE_NUM; ++i) { if (src->joinInfo.joinTables[i]) { dest->joinInfo.joinTables[i] = calloc(1, sizeof(SJoinNode)); @@ -1763,7 +2132,7 @@ int32_t tscTagCondCopy(STagCond* dest, const STagCond* src) { } } - + dest->relType = src->relType; if (src->pCond == NULL) { @@ -1835,16 +2204,16 @@ void tscGetSrcColumnInfo(SSrcColumnInfo* pColInfo, SQueryInfo* pQueryInfo) { size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i); - pColInfo[i].functionId = pExpr->functionId; + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + pColInfo[i].functionId = pExpr->base.functionId; - if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) { + if (TSDB_COL_IS_TAG(pExpr->base.colInfo.flag)) { SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); - int16_t index = pExpr->colInfo.colIndex; + int16_t index = pExpr->base.colInfo.colIndex; pColInfo[i].type = (index != -1) ? pTagSchema[index].type : TSDB_DATA_TYPE_BINARY; } else { - pColInfo[i].type = pSchema[pExpr->colInfo.colIndex].type; + pColInfo[i].type = pSchema[pExpr->base.colInfo.colIndex].type; } } } @@ -1894,7 +2263,7 @@ STableMetaInfo* tscGetTableMetaInfoFromCmd(SSqlCmd* pCmd, int32_t clauseIndex, i assert(clauseIndex >= 0 && clauseIndex < pCmd->numOfClause); - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, clauseIndex); return tscGetMetaInfo(pQueryInfo, tableIndex); } @@ -1911,17 +2280,17 @@ STableMetaInfo* tscGetMetaInfo(SQueryInfo* pQueryInfo, int32_t tableIndex) { return pQueryInfo->pTableMetaInfo[tableIndex]; } -SQueryInfo* tscGetQueryInfoDetailSafely(SSqlCmd* pCmd, int32_t subClauseIndex) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, subClauseIndex); +SQueryInfo* tscGetQueryInfoS(SSqlCmd* pCmd, int32_t subClauseIndex) { + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, subClauseIndex); int32_t ret = TSDB_CODE_SUCCESS; while ((pQueryInfo) == NULL) { - if ((ret = tscAddSubqueryInfo(pCmd)) != TSDB_CODE_SUCCESS) { + if ((ret = tscAddQueryInfo(pCmd)) != TSDB_CODE_SUCCESS) { terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; return NULL; } - pQueryInfo = tscGetQueryInfoDetail(pCmd, subClauseIndex); + pQueryInfo = tscGetQueryInfo(pCmd, subClauseIndex); } return pQueryInfo; @@ -1950,18 +2319,20 @@ void tscInitQueryInfo(SQueryInfo* pQueryInfo) { pQueryInfo->fieldsInfo.internalField = taosArrayInit(4, sizeof(SInternalField)); assert(pQueryInfo->exprList == NULL); - pQueryInfo->exprList = taosArrayInit(4, POINTER_BYTES); - pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES); - pQueryInfo->udColumnId = TSDB_UD_COLUMN_INDEX; - pQueryInfo->resColumnId = -1000; - pQueryInfo->limit.limit = -1; - pQueryInfo->limit.offset = 0; - pQueryInfo->slimit.limit = -1; - pQueryInfo->slimit.offset = 0; + pQueryInfo->exprList = taosArrayInit(4, POINTER_BYTES); + pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES); + pQueryInfo->udColumnId = TSDB_UD_COLUMN_INDEX; + pQueryInfo->resColumnId = TSDB_RES_COL_ID; + pQueryInfo->limit.limit = -1; + pQueryInfo->limit.offset = 0; + + pQueryInfo->slimit.limit = -1; + pQueryInfo->slimit.offset = 0; + pQueryInfo->pUpstream = taosArrayInit(4, POINTER_BYTES); } -int32_t tscAddSubqueryInfo(SSqlCmd* pCmd) { +int32_t tscAddQueryInfo(SSqlCmd* pCmd) { assert(pCmd != NULL); // todo refactor: remove this structure @@ -2007,11 +2378,14 @@ static void freeQueryInfoImpl(SQueryInfo* pQueryInfo) { tfree(pQueryInfo->fillVal); tfree(pQueryInfo->buf); + + taosArrayDestroy(pQueryInfo->pUpstream); + pQueryInfo->pUpstream = NULL; } void tscClearSubqueryInfo(SSqlCmd* pCmd) { for (int32_t i = 0; i < pCmd->numOfClause; ++i) { - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, i); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, i); freeQueryInfoImpl(pQueryInfo); } } @@ -2086,7 +2460,7 @@ void clearAllTableMetaInfo(SQueryInfo* pQueryInfo, bool removeMeta) { for(int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i); - if (removeMeta) { + if (removeMeta) { char name[TSDB_TABLE_FNAME_LEN] = {0}; tNameExtractFullName(&pTableMetaInfo->name, name); @@ -2135,7 +2509,7 @@ STableMetaInfo* tscAddTableMetaInfo(SQueryInfo* pQueryInfo, SName* name, STableM } if (pTagCols != NULL) { - tscColumnListCopy(pTableMetaInfo->tagColList, pTagCols, -1); + tscColumnListCopy(pTableMetaInfo->tagColList, pTagCols, pTableMetaInfo->pTableMeta->id.uid); } pTableMetaInfo->pVgroupTables = tscVgroupTableInfoDup(pVgroupTables); @@ -2175,7 +2549,7 @@ void registerSqlObj(SSqlObj* pSql) { int32_t num = atomic_add_fetch_32(&pSql->pTscObj->numOfObj, 1); int32_t total = atomic_add_fetch_32(&tscNumOfObj, 1); - tscDebug("%p new SqlObj from %p, total in tscObj:%d, total:%d", pSql, pSql->pTscObj, num, total); + tscDebug("0x%"PRIx64" new SqlObj from %p, total in tscObj:%d, total:%d", pSql->self, pSql->pTscObj, num, total); } SSqlObj* createSimpleSubObj(SSqlObj* pSql, __async_cb_func_t fp, void* param, int32_t cmd) { @@ -2200,7 +2574,7 @@ SSqlObj* createSimpleSubObj(SSqlObj* pSql, __async_cb_func_t fp, void* param, in return NULL; } - if (tscAddSubqueryInfo(pCmd) != TSDB_CODE_SUCCESS) { + if (tscAddQueryInfo(pCmd) != TSDB_CODE_SUCCESS) { #ifdef __APPLE__ // to satisfy later tsem_destroy in taos_free_result tsem_init(&pNew->rspSem, 0, 0); @@ -2215,7 +2589,7 @@ SSqlObj* createSimpleSubObj(SSqlObj* pSql, __async_cb_func_t fp, void* param, in pNew->sqlstr = NULL; pNew->maxRetry = TSDB_MAX_REPLICA; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetailSafely(pCmd, 0); + SQueryInfo* pQueryInfo = tscGetQueryInfoS(pCmd, 0); assert(pSql->cmd.clauseIndex == 0); STableMetaInfo* pMasterTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, pSql->cmd.clauseIndex, 0); @@ -2233,13 +2607,12 @@ static void doSetSqlExprAndResultFieldInfo(SQueryInfo* pNewQueryInfo, int64_t ui } // set the field info in pNewQueryInfo object according to sqlExpr information - size_t numOfExprs = tscSqlExprNumOfExprs(pNewQueryInfo); - for (int32_t i = 0; i < numOfExprs; ++i) { - SSqlExpr* pExpr = tscSqlExprGet(pNewQueryInfo, i); + for (int32_t i = 0; i < numOfOutput; ++i) { + SExprInfo* pExpr = tscSqlExprGet(pNewQueryInfo, i); - TAOS_FIELD f = tscCreateField((int8_t) pExpr->resType, pExpr->aliasName, pExpr->resBytes); + TAOS_FIELD f = tscCreateField((int8_t) pExpr->base.resType, pExpr->base.aliasName, pExpr->base.resBytes); SInternalField* pInfo1 = tscFieldInfoAppend(&pNewQueryInfo->fieldsInfo, &f); - pInfo1->pSqlExpr = pExpr; + pInfo1->pExpr = pExpr; } // update the pSqlExpr pointer in SInternalField according the field name @@ -2248,12 +2621,12 @@ static void doSetSqlExprAndResultFieldInfo(SQueryInfo* pNewQueryInfo, int64_t ui TAOS_FIELD* field = tscFieldInfoGetField(&pNewQueryInfo->fieldsInfo, f); bool matched = false; - for (int32_t k1 = 0; k1 < numOfExprs; ++k1) { - SSqlExpr* pExpr1 = tscSqlExprGet(pNewQueryInfo, k1); + for (int32_t k1 = 0; k1 < numOfOutput; ++k1) { + SExprInfo* pExpr1 = tscSqlExprGet(pNewQueryInfo, k1); - if (strcmp(field->name, pExpr1->aliasName) == 0) { // establish link according to the result field name + if (strcmp(field->name, pExpr1->base.aliasName) == 0) { // establish link according to the result field name SInternalField* pInfo = tscFieldInfoGetInternalField(&pNewQueryInfo->fieldsInfo, f); - pInfo->pSqlExpr = pExpr1; + pInfo->pExpr = pExpr1; matched = true; break; @@ -2276,8 +2649,9 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; return NULL; } - - STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, tableIndex); + + SQueryInfo* pQueryInfo = tscGetActiveQueryInfo(pCmd); + STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[tableIndex]; pNew->pTscObj = pSql->pTscObj; pNew->signature = pNew; @@ -2287,12 +2661,12 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t memcpy(pnCmd, pCmd, sizeof(SSqlCmd)); pnCmd->subCmd = true; - + pnCmd->command = cmd; pnCmd->payload = NULL; pnCmd->allocSize = 0; - pnCmd->pQueryInfo = NULL; + pnCmd->pQueryInfo = NULL; pnCmd->numOfClause = 0; pnCmd->clauseIndex = 0; pnCmd->pDataBlocks = NULL; @@ -2304,19 +2678,20 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t pnCmd->tagData.data = NULL; pnCmd->tagData.dataLen = 0; - if (pCmd->pUdfInfo) { - pnCmd->pUdfInfo = taosArrayDup(pCmd->pUdfInfo); - } - - if (tscAddSubqueryInfo(pnCmd) != TSDB_CODE_SUCCESS) { + if (tscAddQueryInfo(pnCmd) != TSDB_CODE_SUCCESS) { terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; goto _error; } - SQueryInfo* pNewQueryInfo = tscGetQueryInfoDetail(pnCmd, 0); - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + if (pCmd->pUdfInfo) { + pnCmd->pUdfInfo = taosArrayDup(pCmd->pUdfInfo); + } + + SQueryInfo* pNewQueryInfo = tscGetQueryInfo(pnCmd, 0); pNewQueryInfo->command = pQueryInfo->command; + pnCmd->active = pNewQueryInfo; + memcpy(&pNewQueryInfo->interval, &pQueryInfo->interval, sizeof(pNewQueryInfo->interval)); pNewQueryInfo->type = pQueryInfo->type; pNewQueryInfo->window = pQueryInfo->window; @@ -2331,6 +2706,8 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t pNewQueryInfo->numOfTables = 0; pNewQueryInfo->pTableMetaInfo = NULL; pNewQueryInfo->bufLen = pQueryInfo->bufLen; + pNewQueryInfo->globalMerge = false; + pNewQueryInfo->arithmCalOnAgg = false; pNewQueryInfo->buf = malloc(pQueryInfo->bufLen); if (pNewQueryInfo->buf == NULL) { @@ -2371,18 +2748,18 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; goto _error; } - - tscColumnListCopy(pNewQueryInfo->colList, pQueryInfo->colList, (int16_t)tableIndex); + + uint64_t uid = pTableMetaInfo->pTableMeta->id.uid; + tscColumnListCopy(pNewQueryInfo->colList, pQueryInfo->colList, uid); // set the correct query type if (pPrevSql != NULL) { - SQueryInfo* pPrevQueryInfo = tscGetQueryInfoDetail(&pPrevSql->cmd, pPrevSql->cmd.clauseIndex); + SQueryInfo* pPrevQueryInfo = tscGetQueryInfo(&pPrevSql->cmd, pPrevSql->cmd.clauseIndex); pNewQueryInfo->type = pPrevQueryInfo->type; } else { TSDB_QUERY_SET_TYPE(pNewQueryInfo->type, TSDB_QUERY_TYPE_SUBQUERY);// it must be the subquery } - uint64_t uid = pTableMetaInfo->pTableMeta->id.uid; if (tscSqlExprCopy(pNewQueryInfo->exprList, pQueryInfo->exprList, uid, true) != 0) { terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; goto _error; @@ -2446,9 +2823,9 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t size, pNewQueryInfo->fieldsInfo.numOfOutput, tNameGetTableName(&pFinalInfo->name), pNewQueryInfo->window.skey, pNewQueryInfo->window.ekey, pNewQueryInfo->order.order, pNewQueryInfo->limit.limit); - tscPrintSelectClause(pNew, 0); + tscPrintSelNodeList(pNew, 0); } else { - tscDebug("%p new sub insertion: %p, vnodeIdx:%d", pSql, pNew, pTableMetaInfo->vgroupIndex); + tscDebug("0x%"PRIx64" new sub insertion: %p, vnodeIdx:%d", pSql->self, pNew, pTableMetaInfo->vgroupIndex); } registerSqlObj(pNew); @@ -2459,7 +2836,54 @@ _error: return NULL; } +void doExecuteQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo) { + uint16_t type = pQueryInfo->type; + if (QUERY_IS_JOIN_QUERY(type) && !TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_SUBQUERY)) { + tscHandleMasterJoinQuery(pSql); + } else if (tscMultiRoundQuery(pQueryInfo, 0) && pQueryInfo->round == 0) { + tscHandleFirstRoundStableQuery(pSql); // todo lock? + } else if (pQueryInfo->globalMerge) { // super table query + tscLockByThread(&pSql->squeryLock); + tscHandleMasterSTableQuery(pSql); + tscUnlockByThread(&pSql->squeryLock); + } else if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT)) { + tscHandleMultivnodeInsert(pSql); + } else if (pSql->cmd.command > TSDB_SQL_LOCAL) { + tscProcessLocalCmd(pSql); + } else { // send request to server directly + tscBuildAndSendRequest(pSql, pQueryInfo); + } +} + +// do execute the query according to the query execution plan +void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo) { + if (pSql->cmd.command == TSDB_SQL_RETRIEVE_EMPTY_RESULT) { + (*pSql->fp)(pSql->param, pSql, 0); + return; + } + + if (pSql->cmd.command == TSDB_SQL_SELECT) { + tscAddIntoSqlList(pSql); + } + + if (taosArrayGetSize(pQueryInfo->pUpstream) > 0) { // nest query. do execute it firstly + SQueryInfo* pq = taosArrayGetP(pQueryInfo->pUpstream, 0); + + pSql->cmd.active = pq; + pSql->cmd.command = TSDB_SQL_SELECT; + + executeQuery(pSql, pq); + + // merge nest query result and generate final results + return; + } + + pSql->cmd.active = pQueryInfo; + doExecuteQuery(pSql, pQueryInfo); +} + /** + * todo remove it * To decide if current is a two-stage super table query, join query, or insert. And invoke different * procedure accordingly * @param pSql @@ -2482,27 +2906,22 @@ void tscDoQuery(SSqlObj* pSql) { if (pCmd->dataSourceType == DATA_FROM_DATA_FILE) { tscImportDataFromFile(pSql); } else { - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); uint16_t type = pQueryInfo->type; - - if (TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_INSERT)) { // multi-vnodes insertion - tscHandleMultivnodeInsert(pSql); - return; - } - + if (QUERY_IS_JOIN_QUERY(type)) { if (!TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_SUBQUERY)) { tscHandleMasterJoinQuery(pSql); } else { // for first stage sub query, iterate all vnodes to get all timestamp if (!TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_JOIN_SEC_STAGE)) { - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); } else { // secondary stage join query. - if (tscIsTwoStageSTableQuery(pCmd, pQueryInfo, 0)) { // super table query + if (pQueryInfo->globalMerge) { // super table query tscLockByThread(&pSql->squeryLock); tscHandleMasterSTableQuery(pSql); tscUnlockByThread(&pSql->squeryLock); } else { - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); } } } @@ -2511,14 +2930,15 @@ void tscDoQuery(SSqlObj* pSql) { } else if (tscMultiRoundQuery(pQueryInfo, 0) && pQueryInfo->round == 0) { tscHandleFirstRoundStableQuery(pSql); // todo lock? return; - } else if (tscIsTwoStageSTableQuery(pCmd, pQueryInfo, 0)) { // super table query + } else if (pQueryInfo->globalMerge) { // super table query tscLockByThread(&pSql->squeryLock); tscHandleMasterSTableQuery(pSql); tscUnlockByThread(&pSql->squeryLock); return; } - - tscProcessSql(pSql); + + pCmd->active = pQueryInfo; + tscBuildAndSendRequest(pSql, NULL); } } @@ -2578,7 +2998,7 @@ bool tscIsQueryWithLimit(SSqlObj* pSql) { SSqlCmd* pCmd = &pSql->cmd; for (int32_t i = 0; i < pCmd->numOfClause; ++i) { - SQueryInfo* pqi = tscGetQueryInfoDetailSafely(pCmd, i); + SQueryInfo* pqi = tscGetQueryInfoS(pCmd, i); if (pqi == NULL) { continue; } @@ -2663,7 +3083,7 @@ bool hasMoreVnodesToTry(SSqlObj* pSql) { } assert(pRes->completed); - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); // for normal table, no need to try any more if results are all retrieved from one vnode @@ -2688,7 +3108,7 @@ void tscTryQueryNextVnode(SSqlObj* pSql, __async_cb_func_t fp) { SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); /* * no result returned from the current virtual node anymore, try the next vnode if exists @@ -2699,7 +3119,7 @@ void tscTryQueryNextVnode(SSqlObj* pSql, __async_cb_func_t fp) { int32_t totalVgroups = pTableMetaInfo->vgroupList->numOfVgroups; if (++pTableMetaInfo->vgroupIndex < totalVgroups) { - tscDebug("%p results from vgroup index:%d completed, try next:%d. total vgroups:%d. current numOfRes:%" PRId64, pSql, + tscDebug("0x%"PRIx64" results from vgroup index:%d completed, try next:%d. total vgroups:%d. current numOfRes:%" PRId64, pSql->self, pTableMetaInfo->vgroupIndex - 1, pTableMetaInfo->vgroupIndex, totalVgroups, pRes->numOfClauseTotal); /* @@ -2718,8 +3138,8 @@ void tscTryQueryNextVnode(SSqlObj* pSql, __async_cb_func_t fp) { pQueryInfo->limit.offset = pRes->offset; assert((pRes->offset >= 0 && pRes->numOfRows == 0) || (pRes->offset == 0 && pRes->numOfRows >= 0)); - tscDebug("%p new query to next vgroup, index:%d, limit:%" PRId64 ", offset:%" PRId64 ", glimit:%" PRId64, - pSql, pTableMetaInfo->vgroupIndex, pQueryInfo->limit.limit, pQueryInfo->limit.offset, pQueryInfo->clauseLimit); + tscDebug("0x%"PRIx64" new query to next vgroup, index:%d, limit:%" PRId64 ", offset:%" PRId64 ", glimit:%" PRId64, + pSql->self, pTableMetaInfo->vgroupIndex, pQueryInfo->limit.limit, pQueryInfo->limit.offset, pQueryInfo->clauseLimit); /* * For project query with super table join, the numOfSub is equalled to the number of all subqueries. @@ -2734,9 +3154,9 @@ void tscTryQueryNextVnode(SSqlObj* pSql, __async_cb_func_t fp) { // set the callback function pSql->fp = fp; - tscProcessSql(pSql); + tscBuildAndSendRequest(pSql, NULL); } else { - tscDebug("%p try all %d vnodes, query complete. current numOfRes:%" PRId64, pSql, totalVgroups, pRes->numOfClauseTotal); + tscDebug("0x%"PRIx64" try all %d vnodes, query complete. current numOfRes:%" PRId64, pSql->self, totalVgroups, pRes->numOfClauseTotal); } } @@ -2748,7 +3168,7 @@ void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp) { assert(pCmd->clauseIndex < pCmd->numOfClause - 1); pCmd->clauseIndex++; - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd, pCmd->clauseIndex); pSql->cmd.command = pQueryInfo->command; @@ -2762,11 +3182,11 @@ void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp) { pSql->subState.numOfSub = 0; pSql->fp = fp; - tscDebug("%p try data in the next subclause:%d, total subclause:%d", pSql, pCmd->clauseIndex, pCmd->numOfClause); + tscDebug("0x%"PRIx64" try data in the next subclause:%d, total subclause:%d", pSql->self, pCmd->clauseIndex, pCmd->numOfClause); if (pCmd->command > TSDB_SQL_LOCAL) { tscProcessLocalCmd(pSql); } else { - tscDoQuery(pSql); + executeQuery(pSql, pQueryInfo); } } @@ -3025,4 +3445,288 @@ STableMeta* tscTableMetaDup(STableMeta* pTableMeta) { return p; } +static int32_t createSecondaryExpr(SQueryAttr* pQueryAttr, SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo) { + if (!pQueryInfo->arithmCalOnAgg) { + return TSDB_CODE_SUCCESS; + } + pQueryAttr->numOfExpr2 = tscNumOfFields(pQueryInfo); + pQueryAttr->pExpr2 = calloc(pQueryAttr->numOfExpr2, sizeof(SExprInfo)); + if (pQueryAttr->pExpr2 == NULL) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + + for (int32_t i = 0; i < pQueryAttr->numOfExpr2; ++i) { + SInternalField* pField = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i); + SExprInfo* pExpr = pField->pExpr; + + SSqlExpr *pse = &pQueryAttr->pExpr2[i].base; + pse->uid = pTableMetaInfo->pTableMeta->id.uid; + pse->resColId = pExpr->base.resColId; + + if (pExpr->base.functionId != TSDB_FUNC_ARITHM) { // this should be switched to projection query + pse->numOfParams = 0; // no params for projection query + pse->functionId = TSDB_FUNC_PRJ; + pse->colInfo.colId = pExpr->base.resColId; + + for (int32_t j = 0; j < pQueryAttr->numOfOutput; ++j) { + if (pQueryAttr->pExpr1[j].base.resColId == pse->colInfo.colId) { + pse->colInfo.colIndex = j; + } + } + + pse->colInfo.flag = TSDB_COL_NORMAL; + pse->resType = pExpr->base.resType; + pse->resBytes = pExpr->base.resBytes; + + // TODO restore refactor + int32_t functionId = pExpr->base.functionId; + if (pExpr->base.functionId == TSDB_FUNC_FIRST_DST) { + functionId = TSDB_FUNC_FIRST; + } else if (pExpr->base.functionId == TSDB_FUNC_LAST_DST) { + functionId = TSDB_FUNC_LAST; + } else if (pExpr->base.functionId == TSDB_FUNC_STDDEV_DST) { + functionId = TSDB_FUNC_STDDEV; + } + + int32_t inter = 0; + getResultDataInfo(pExpr->base.colType, pExpr->base.colBytes, functionId, 0, &pse->resType, + &pse->resBytes, &inter, 0, false, NULL); + pse->colType = pse->resType; + pse->colBytes = pse->resBytes; + + } else { // arithmetic expression + pse->colInfo.colId = pExpr->base.colInfo.colId; + pse->colType = pExpr->base.colType; + pse->colBytes = pExpr->base.colBytes; + pse->resBytes = sizeof(double); + pse->resType = TSDB_DATA_TYPE_DOUBLE; + + pse->functionId = pExpr->base.functionId; + pse->numOfParams = pExpr->base.numOfParams; + + for (int32_t j = 0; j < pExpr->base.numOfParams; ++j) { + tVariantAssign(&pse->param[j], &pExpr->base.param[j]); + buildArithmeticExprFromMsg(&pQueryAttr->pExpr2[i], NULL); + } + } + } + + return TSDB_CODE_SUCCESS; +} + +static int32_t createGlobalAggregateExpr(SQueryAttr* pQueryAttr, SQueryInfo* pQueryInfo) { + assert(pQueryInfo->globalMerge); + + pQueryAttr->numOfExpr3 = (int32_t) tscSqlExprNumOfExprs(pQueryInfo); + pQueryAttr->pExpr3 = calloc(pQueryAttr->numOfExpr3, sizeof(SExprInfo)); + if (pQueryAttr->pExpr3 == NULL) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + + for (int32_t i = 0; i < pQueryAttr->numOfExpr3; ++i) { + SExprInfo* pExpr = &pQueryAttr->pExpr1[i]; + SSqlExpr* pse = &pQueryAttr->pExpr3[i].base; + + tscSqlExprAssign(&pQueryAttr->pExpr3[i], pExpr); + pse->colInfo.colId = pExpr->base.resColId; + pse->colInfo.colIndex = i; + + pse->colType = pExpr->base.resType; + pse->colBytes = pExpr->base.resBytes; + } + + { + for (int32_t i = 0; i < pQueryAttr->numOfExpr3; ++i) { + SExprInfo* pExpr = &pQueryAttr->pExpr1[i]; + SSqlExpr* pse = &pQueryAttr->pExpr3[i].base; + + // the final result size and type in the same as query on single table. + // so here, set the flag to be false; + int32_t inter = 0; + + int32_t functionId = pExpr->base.functionId; + if (functionId >= TSDB_FUNC_TS && functionId <= TSDB_FUNC_DIFF) { + continue; + } + + if (functionId == TSDB_FUNC_FIRST_DST) { + functionId = TSDB_FUNC_FIRST; + } else if (functionId == TSDB_FUNC_LAST_DST) { + functionId = TSDB_FUNC_LAST; + } else if (functionId == TSDB_FUNC_STDDEV_DST) { + functionId = TSDB_FUNC_STDDEV; + } + + getResultDataInfo(pExpr->base.colType, pExpr->base.colBytes, functionId, 0, &pse->resType, &pse->resBytes, &inter, + 0, false, NULL); + } + } + + return TSDB_CODE_SUCCESS; +} + +static int32_t createTagColumnInfo(SQueryAttr* pQueryAttr, SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo) { + if (pTableMetaInfo->tagColList == NULL) { + return TSDB_CODE_SUCCESS; + } + + pQueryAttr->numOfTags = (int16_t)taosArrayGetSize(pTableMetaInfo->tagColList); + if (pQueryAttr->numOfTags == 0) { + return TSDB_CODE_SUCCESS; + } + + STableMeta* pTableMeta = pQueryInfo->pTableMetaInfo[0]->pTableMeta; + + int32_t numOfTagColumns = tscGetNumOfTags(pTableMeta); + + pQueryAttr->tagColList = calloc(pQueryAttr->numOfTags, sizeof(SColumnInfo)); + if (pQueryAttr->tagColList == NULL) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } + + SSchema* pSchema = tscGetTableTagSchema(pTableMeta); + for (int32_t i = 0; i < pQueryAttr->numOfTags; ++i) { + SColumn* pCol = taosArrayGetP(pTableMetaInfo->tagColList, i); + SSchema* pColSchema = &pSchema[pCol->columnIndex]; + + if ((pCol->columnIndex >= numOfTagColumns || pCol->columnIndex < TSDB_TBNAME_COLUMN_INDEX) || + (!isValidDataType(pColSchema->type))) { + return TSDB_CODE_TSC_INVALID_SQL; + } + + SColumnInfo* pTagCol = &pQueryAttr->tagColList[i]; + + pTagCol->colId = pColSchema->colId; + pTagCol->bytes = pColSchema->bytes; + pTagCol->type = pColSchema->type; + pTagCol->flist.numOfFilters = 0; + } + + return TSDB_CODE_SUCCESS; +} + +int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAttr, void* addr) { + memset(pQueryAttr, 0, sizeof(SQueryAttr)); + + int16_t numOfCols = (int16_t) taosArrayGetSize(pQueryInfo->colList); + int16_t numOfOutput = (int16_t) tscSqlExprNumOfExprs(pQueryInfo); + + pQueryAttr->topBotQuery = tscIsTopBotQuery(pQueryInfo); + pQueryAttr->hasTagResults = hasTagValOutput(pQueryInfo); + pQueryAttr->stabledev = isStabledev(pQueryInfo); + pQueryAttr->tsCompQuery = isTsCompQuery(pQueryInfo); + pQueryAttr->simpleAgg = isSimpleAggregate(pQueryInfo); + pQueryAttr->needReverseScan = tscNeedReverseScan(pQueryInfo); + pQueryAttr->stableQuery = QUERY_IS_STABLE_QUERY(pQueryInfo->type); + pQueryAttr->groupbyColumn = tscGroupbyColumn(pQueryInfo); + pQueryAttr->queryBlockDist = isBlockDistQuery(pQueryInfo); + pQueryAttr->pointInterpQuery = tscIsPointInterpQuery(pQueryInfo); + pQueryAttr->timeWindowInterpo = timeWindowInterpoRequired(pQueryInfo); + pQueryAttr->distinctTag = pQueryInfo->distinctTag; + + pQueryAttr->numOfCols = numOfCols; + pQueryAttr->numOfOutput = numOfOutput; + pQueryAttr->limit = pQueryInfo->limit; + pQueryAttr->slimit = pQueryInfo->slimit; + pQueryAttr->order = pQueryInfo->order; + pQueryAttr->fillType = pQueryInfo->fillType; + pQueryAttr->groupbyColumn = tscGroupbyColumn(pQueryInfo); + pQueryAttr->havingNum = pQueryInfo->havingFieldNum; + + if (pQueryInfo->order.order == TSDB_ORDER_ASC) { // TODO refactor + pQueryAttr->window = pQueryInfo->window; + } else { + pQueryAttr->window.skey = pQueryInfo->window.ekey; + pQueryAttr->window.ekey = pQueryInfo->window.skey; + } + + memcpy(&pQueryAttr->interval, &pQueryInfo->interval, sizeof(pQueryAttr->interval)); + + STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[0]; + + pQueryAttr->pGroupbyExpr = calloc(1, sizeof(SSqlGroupbyExpr)); + *(pQueryAttr->pGroupbyExpr) = pQueryInfo->groupbyExpr; + + if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) { + pQueryAttr->pGroupbyExpr->columnInfo = taosArrayDup(pQueryInfo->groupbyExpr.columnInfo); + } else { + assert(pQueryInfo->groupbyExpr.columnInfo == NULL); + } + + pQueryAttr->pExpr1 = calloc(pQueryAttr->numOfOutput, sizeof(SExprInfo)); + for(int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { + SExprInfo* pExpr = tscSqlExprGet(pQueryInfo, i); + tscSqlExprAssign(&pQueryAttr->pExpr1[i], pExpr); + + if (pQueryAttr->pExpr1[i].base.functionId == TSDB_FUNC_ARITHM) { + for (int32_t j = 0; j < pQueryAttr->pExpr1[i].base.numOfParams; ++j) { + buildArithmeticExprFromMsg(&pQueryAttr->pExpr1[i], NULL); + } + } + } + + pQueryAttr->tableCols = calloc(numOfCols, sizeof(SColumnInfo)); + for(int32_t i = 0; i < numOfCols; ++i) { + SColumn* pCol = taosArrayGetP(pQueryInfo->colList, i); + if (!isValidDataType(pCol->info.type) || pCol->info.type == TSDB_DATA_TYPE_NULL) { + assert(0); + } + + pQueryAttr->tableCols[i] = pCol->info; + pQueryAttr->tableCols[i].flist.filterInfo = tFilterInfoDup(pCol->info.flist.filterInfo, pQueryAttr->tableCols[i].flist.numOfFilters); + } + + // global aggregate query + if (pQueryAttr->stableQuery && (pQueryAttr->simpleAgg || pQueryAttr->interval.interval > 0) && pQueryInfo->globalMerge) { + createGlobalAggregateExpr(pQueryAttr, pQueryInfo); + } + + // for simple table, not for super table + int32_t code = createSecondaryExpr(pQueryAttr, pQueryInfo, pTableMetaInfo); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + + // tag column info + code = createTagColumnInfo(pQueryAttr, pQueryInfo, pTableMetaInfo); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + + if (pQueryAttr->fillType != TSDB_FILL_NONE) { + pQueryAttr->fillVal = calloc(pQueryAttr->numOfOutput, sizeof(int64_t)); + memcpy(pQueryAttr->fillVal, pQueryInfo->fillVal, pQueryAttr->numOfOutput * sizeof(int64_t)); + } + + pQueryAttr->srcRowSize = 0; + pQueryAttr->maxTableColumnWidth = 0; + for (int16_t i = 0; i < numOfCols; ++i) { + pQueryAttr->srcRowSize += pQueryAttr->tableCols[i].bytes; + if (pQueryAttr->maxTableColumnWidth < pQueryAttr->tableCols[i].bytes) { + pQueryAttr->maxTableColumnWidth = pQueryAttr->tableCols[i].bytes; + } + } + + pQueryAttr->interBufSize = getOutputInterResultBufSize(pQueryAttr); + + if (pQueryAttr->numOfCols <= 0 && !tscQueryTags(pQueryInfo) && !pQueryAttr->queryBlockDist) { + tscError("%p illegal value of numOfCols in query msg: %" PRIu64 ", table cols:%d", addr, + (uint64_t)pQueryAttr->numOfCols, numOfCols); + + return TSDB_CODE_TSC_INVALID_SQL; + } + + if (pQueryAttr->interval.interval < 0) { + tscError("%p illegal value of aggregation time interval in query msg: %" PRId64, addr, + (int64_t)pQueryInfo->interval.interval); + return TSDB_CODE_TSC_INVALID_SQL; + } + + if (pQueryAttr->pGroupbyExpr->numOfGroupCols < 0) { + tscError("%p illegal value of numOfGroupCols in query msg: %d", addr, pQueryInfo->groupbyExpr.numOfGroupCols); + return TSDB_CODE_TSC_INVALID_SQL; + } + + return TSDB_CODE_SUCCESS; +} diff --git a/src/common/inc/texpr.h b/src/common/inc/texpr.h index acfbffc01e..a0854ce81b 100644 --- a/src/common/inc/texpr.h +++ b/src/common/inc/texpr.h @@ -13,8 +13,8 @@ * along with this program. If not, see . */ -#ifndef TDENGINE_TAST_H -#define TDENGINE_TAST_H +#ifndef TDENGINE_TEXPR_H +#define TDENGINE_TEXPR_H #ifdef __cplusplus extern "C" { @@ -62,32 +62,32 @@ typedef struct tExprNode { uint8_t nodeType; union { struct { - uint8_t optr; // filter operator - uint8_t hasPK; // 0: do not contain primary filter, 1: contain - void * info; // support filter operation on this expression only available for leaf node - + uint8_t optr; // filter operator + uint8_t hasPK; // 0: do not contain primary filter, 1: contain + void *info; // support filter operation on this expression only available for leaf node struct tExprNode *pLeft; // left child pointer struct tExprNode *pRight; // right child pointer } _node; - struct SSchema *pSchema; - tVariant * pVal; + + struct SSchema *pSchema; + tVariant *pVal; }; } tExprNode; typedef struct SExprTraverseSupp { __result_filter_fn_t nodeFilterFn; __do_filter_suppl_fn_t setupInfoFn; - void * pExtInfo; + void *pExtInfo; } SExprTraverseSupp; void tExprTreeDestroy(tExprNode *pNode, void (*fp)(void *)); +void exprTreeToBinary(SBufferWriter* bw, tExprNode* pExprTree); tExprNode* exprTreeFromBinary(const void* data, size_t size); tExprNode* exprTreeFromTableName(const char* tbnameCond); +tExprNode* exprdup(tExprNode* pTree); -void exprTreeToBinary(SBufferWriter* bw, tExprNode* pExprTree); - -bool exprTreeApplayFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param); +bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param); typedef void (*_arithmetic_operator_fn_t)(void *left, int32_t numLeft, int32_t leftType, void *right, int32_t numRight, int32_t rightType, void *output, int32_t order); @@ -99,4 +99,4 @@ void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, } #endif -#endif // TDENGINE_TAST_H +#endif // TDENGINE_TEXPR_H diff --git a/src/common/inc/tname.h b/src/common/inc/tname.h index 465b298973..f37a4d9a36 100644 --- a/src/common/inc/tname.h +++ b/src/common/inc/tname.h @@ -41,6 +41,35 @@ typedef struct SResPair { double avg; } SResPair; +// the structure for sql function in select clause +typedef struct SSqlExpr { + char aliasName[TSDB_COL_NAME_LEN]; // as aliasName + SColIndex colInfo; + + uint64_t uid; // refactor use the pointer + + int16_t functionId; // function id in aAgg array + + int16_t resType; // return value type + int16_t resBytes; // length of return value + int32_t interBytes; // inter result buffer size + + int16_t colType; // table column type + int16_t colBytes; // table column bytes + + int16_t numOfParams; // argument value of each function + 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 + + SColumnFilterList flist; +} SSqlExpr; + +typedef struct SExprInfo { + SSqlExpr base; + struct tExprNode *pExpr; +} SExprInfo; + #define TSDB_DB_NAME_T 1 #define TSDB_TABLE_NAME_T 2 diff --git a/src/common/src/texpr.c b/src/common/src/texpr.c index 1008c4cf8f..4334a0de26 100644 --- a/src/common/src/texpr.c +++ b/src/common/src/texpr.c @@ -15,6 +15,7 @@ #include "os.h" +#include "texpr.h" #include "exception.h" #include "taosdef.h" #include "taosmsg.h" @@ -145,25 +146,25 @@ static void doExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) { *pExpr = NULL; } -bool exprTreeApplayFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param) { +bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param) { tExprNode *pLeft = pExpr->_node.pLeft; tExprNode *pRight = pExpr->_node.pRight; //non-leaf nodes, recursively traverse the expression tree in the post-root order if (pLeft->nodeType == TSQL_NODE_EXPR && pRight->nodeType == TSQL_NODE_EXPR) { if (pExpr->_node.optr == TSDB_RELATION_OR) { // or - if (exprTreeApplayFilter(pLeft, pItem, param)) { + if (exprTreeApplyFilter(pLeft, pItem, param)) { return true; } // left child does not satisfy the query condition, try right child - return exprTreeApplayFilter(pRight, pItem, param); + return exprTreeApplyFilter(pRight, pItem, param); } else { // and - if (!exprTreeApplayFilter(pLeft, pItem, param)) { + if (!exprTreeApplyFilter(pLeft, pItem, param)) { return false; } - return exprTreeApplayFilter(pRight, pItem, param); + return exprTreeApplyFilter(pRight, pItem, param); } } @@ -463,3 +464,28 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) { CLEANUP_EXECUTE_TO(anchor, false); return expr; } + +tExprNode* exprdup(tExprNode* pTree) { + if (pTree == NULL) { + return NULL; + } + + tExprNode* pNode = calloc(1, sizeof(tExprNode)); + if (pTree->nodeType == TSQL_NODE_EXPR) { + tExprNode* pLeft = exprdup(pTree->_node.pLeft); + tExprNode* pRight = exprdup(pTree->_node.pRight); + + pNode->nodeType = TSQL_NODE_EXPR; + pNode->_node.pLeft = pLeft; + pNode->_node.pRight = pRight; + } else if (pTree->nodeType == TSQL_NODE_VALUE) { + pNode->pVal = calloc(1, sizeof(tVariant)); + tVariantAssign(pNode->pVal, pTree->pVal); + } else if (pTree->nodeType == TSQL_NODE_COL) { + pNode->pSchema = calloc(1, sizeof(SSchema)); + *pNode->pSchema = *pTree->pSchema; + } + + return pNode; +} + diff --git a/src/common/src/tname.c b/src/common/src/tname.c index 787aa1e95b..f1ddc60637 100644 --- a/src/common/src/tname.c +++ b/src/common/src/tname.c @@ -68,6 +68,7 @@ bool tscValidateTableNameLength(size_t len) { return len < TSDB_TABLE_NAME_LEN; } +// TODO refactor SColumnFilterInfo* tFilterInfoDup(const SColumnFilterInfo* src, int32_t numOfFilters) { if (numOfFilters == 0) { assert(src == NULL); diff --git a/src/common/src/tvariant.c b/src/common/src/tvariant.c index 7009c4d5c3..c872d8731b 100644 --- a/src/common/src/tvariant.c +++ b/src/common/src/tvariant.c @@ -48,8 +48,19 @@ void tVariantCreate(tVariant *pVar, SStrToken *token) { case TSDB_DATA_TYPE_INT:{ ret = tStrToInteger(token->z, token->type, token->n, &pVar->i64, true); if (ret != 0) { - pVar->nType = -1; // -1 means error type - return; + SStrToken t = {0}; + tSQLGetToken(token->z, &t.type); + if (t.type == TK_MINUS) { // it is a signed number which is greater than INT64_MAX or less than INT64_MIN + pVar->nType = -1; // -1 means error type + return; + } + + // data overflow, try unsigned parse the input number + ret = tStrToInteger(token->z, token->type, token->n, &pVar->i64, false); + if (ret != 0) { + pVar->nType = -1; // -1 means error type + return; + } } break; @@ -525,6 +536,8 @@ static FORCE_INLINE int32_t convertToInteger(tVariant *pVariant, int64_t *result } bool code = false; + + uint64_t ui = 0; switch(type) { case TSDB_DATA_TYPE_TINYINT: code = IS_VALID_TINYINT(*result); break; @@ -535,13 +548,17 @@ static FORCE_INLINE int32_t convertToInteger(tVariant *pVariant, int64_t *result case TSDB_DATA_TYPE_BIGINT: code = IS_VALID_BIGINT(*result); break; case TSDB_DATA_TYPE_UTINYINT: - code = IS_VALID_UTINYINT(*result); break; + ui = *result; + code = IS_VALID_UTINYINT(ui); break; case TSDB_DATA_TYPE_USMALLINT: - code = IS_VALID_USMALLINT(*result); break; + ui = *result; + code = IS_VALID_USMALLINT(ui); break; case TSDB_DATA_TYPE_UINT: - code = IS_VALID_UINT(*result); break; + ui = *result; + code = IS_VALID_UINT(ui); break; case TSDB_DATA_TYPE_UBIGINT: - code = IS_VALID_UBIGINT(*result); break; + ui = *result; + code = IS_VALID_UBIGINT(ui); break; } return code? 0:-1; diff --git a/src/connector/C#/TDengineDriver.cs b/src/connector/C#/TDengineDriver.cs index 205269501d..2c150341f6 100644 --- a/src/connector/C#/TDengineDriver.cs +++ b/src/connector/C#/TDengineDriver.cs @@ -31,7 +31,11 @@ namespace TDengineDriver TSDB_DATA_TYPE_DOUBLE = 7, // 8 bytes TSDB_DATA_TYPE_BINARY = 8, // string TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes - TSDB_DATA_TYPE_NCHAR = 10 // unicode string + TSDB_DATA_TYPE_NCHAR = 10, // unicode string + TSDB_DATA_TYPE_UTINYINT = 11,// 1 byte + TSDB_DATA_TYPE_USMALLINT= 12,// 2 bytes + TSDB_DATA_TYPE_UINT = 13, // 4 bytes + TSDB_DATA_TYPE_UBIGINT= 14 // 8 bytes } enum TDengineInitOption @@ -53,15 +57,23 @@ namespace TDengineDriver switch ((TDengineDataType)type) { case TDengineDataType.TSDB_DATA_TYPE_BOOL: - return "BOOLEAN"; + return "BOOL"; case TDengineDataType.TSDB_DATA_TYPE_TINYINT: - return "BYTE"; + return "TINYINT"; case TDengineDataType.TSDB_DATA_TYPE_SMALLINT: - return "SHORT"; + return "SMALLINT"; case TDengineDataType.TSDB_DATA_TYPE_INT: return "INT"; case TDengineDataType.TSDB_DATA_TYPE_BIGINT: - return "LONG"; + return "BIGINT"; + case TDengineDataType.TSDB_DATA_TYPE_UTINYINT: + return "TINYINT UNSIGNED"; + case TDengineDataType.TSDB_DATA_TYPE_USMALLINT: + return "SMALLINT UNSIGNED"; + case TDengineDataType.TSDB_DATA_TYPE_UINT: + return "INT UNSIGNED"; + case TDengineDataType.TSDB_DATA_TYPE_UBIGINT: + return "BIGINT UNSIGNED"; case TDengineDataType.TSDB_DATA_TYPE_FLOAT: return "FLOAT"; case TDengineDataType.TSDB_DATA_TYPE_DOUBLE: diff --git a/src/connector/jdbc/CMakeLists.txt b/src/connector/jdbc/CMakeLists.txt index 5d5a6f5f12..de4b8f6bfb 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.27-dist.jar ${LIBRARY_OUTPUT_PATH} + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.28-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 d4febe70d6..a31796ffde 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.27 + 2.0.28 jar JDBCDriver diff --git a/src/connector/jdbc/pom.xml b/src/connector/jdbc/pom.xml index b8a88562ab..3400a82e73 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.27 + 2.0.28 jar JDBCDriver https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java index abd348e68c..4b5b88d93b 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java @@ -10,6 +10,7 @@ import java.util.Map; public abstract class AbstractResultSet extends WrapperImpl implements ResultSet { private int fetchSize; + protected boolean wasNull; protected void checkAvailability(int columnIndex, int bounds) throws SQLException { if (isClosed()) @@ -28,7 +29,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet @Override public boolean wasNull() throws SQLException { - return false; + return wasNull; } @Override 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 32e517f564..db635f5f79 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 @@ -6,12 +6,10 @@ import com.google.common.primitives.Ints; import com.google.common.primitives.Longs; import com.google.common.primitives.Shorts; import com.taosdata.jdbc.*; -import com.taosdata.jdbc.utils.UtcTimestampUtil; import java.math.BigDecimal; import java.sql.*; import java.time.Instant; -import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.util.ArrayList; import java.util.Calendar; @@ -89,7 +87,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { String timestampFormat = this.statement.getConnection().getClientInfo(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT); if ("TIMESTAMP".equalsIgnoreCase(timestampFormat)) { Long value = row.getLong(colIndex); - //TODO: + //TODO: this implementation has bug if the timestamp bigger than 9999_9999_9999_9 if (value < 1_0000_0000_0000_0L) return new Timestamp(value); long epochSec = value / 1000_000l; @@ -164,12 +162,12 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { } } - @Override - public boolean wasNull() throws SQLException { - if (isClosed()) - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED); - return resultSet.isEmpty(); - } +// @Override +// public boolean wasNull() throws SQLException { +// if (isClosed()) +// throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED); +// return resultSet.isEmpty(); +// } @Override public String getString(int columnIndex) throws SQLException { @@ -188,8 +186,11 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { checkAvailability(columnIndex, resultSet.get(pos).size()); Object value = resultSet.get(pos).get(columnIndex - 1); - if (value == null) + if (value == null) { + wasNull = true; return false; + } + wasNull = false; if (value instanceof Boolean) return (boolean) value; return Boolean.valueOf(value.toString()); @@ -200,8 +201,11 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { checkAvailability(columnIndex, resultSet.get(pos).size()); Object value = resultSet.get(pos).get(columnIndex - 1); - if (value == null) + if (value == null) { + wasNull = true; return 0; + } + wasNull = false; long valueAsLong = Long.parseLong(value.toString()); if (valueAsLong == Byte.MIN_VALUE) return 0; @@ -221,8 +225,11 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { checkAvailability(columnIndex, resultSet.get(pos).size()); Object value = resultSet.get(pos).get(columnIndex - 1); - if (value == null) + if (value == null) { + wasNull = true; return 0; + } + wasNull = false; long valueAsLong = Long.parseLong(value.toString()); if (valueAsLong == Short.MIN_VALUE) return 0; @@ -236,8 +243,11 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { checkAvailability(columnIndex, resultSet.get(pos).size()); Object value = resultSet.get(pos).get(columnIndex - 1); - if (value == null) + if (value == null) { + wasNull = true; return 0; + } + wasNull = false; long valueAsLong = Long.parseLong(value.toString()); if (valueAsLong == Integer.MIN_VALUE) return 0; @@ -251,12 +261,14 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { checkAvailability(columnIndex, resultSet.get(pos).size()); Object value = resultSet.get(pos).get(columnIndex - 1); - if (value == null) + if (value == null) { + wasNull = true; return 0; + } + wasNull = false; if (value instanceof Timestamp) { return ((Timestamp) value).getTime(); } - long valueAsLong = 0; try { valueAsLong = Long.parseLong(value.toString()); @@ -273,8 +285,11 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { checkAvailability(columnIndex, resultSet.get(pos).size()); Object value = resultSet.get(pos).get(columnIndex - 1); - if (value == null) + if (value == null) { + wasNull = true; return 0; + } + wasNull = false; if (value instanceof Float || value instanceof Double) return (float) value; return Float.parseFloat(value.toString()); @@ -285,8 +300,11 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { checkAvailability(columnIndex, resultSet.get(pos).size()); Object value = resultSet.get(pos).get(columnIndex - 1); - if (value == null) + if (value == null) { + wasNull = true; return 0; + } + wasNull = false; if (value instanceof Double || value instanceof Float) return (double) value; return Double.parseDouble(value.toString()); diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD3841Test.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD3841Test.java new file mode 100644 index 0000000000..c6fba81eb2 --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD3841Test.java @@ -0,0 +1,91 @@ +package com.taosdata.jdbc.cases; + +import com.taosdata.jdbc.TSDBDriver; +import com.taosdata.jdbc.utils.TimestampUtil; +import org.junit.*; + +import java.sql.*; +import java.util.Properties; + +public class TD3841Test { + private static final String host = "127.0.0.1"; + private static Properties properties; + private static Connection conn_restful; + private static Connection conn_jni; + + @Test + public void testRestful() throws SQLException { + String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata"; + conn_restful = DriverManager.getConnection(url, properties); + + try (Statement stmt = conn_restful.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 timestamp, f2 int, f3 bigint, f4 float, f5 double, f6 smallint, f7 tinyint, f8 bool, f9 binary(64), f10 nchar(64))"); + stmt.executeUpdate("insert into weather(ts, f1) values(now+1s, " + TimestampUtil.datetimeToLong("2021-04-21 12:00:00.000") + ")"); + ResultSet rs = stmt.executeQuery("select * from weather"); + rs.next(); + + Assert.assertEquals("2021-04-21 12:00:00.000", TimestampUtil.longToDatetime(rs.getTimestamp(2).getTime())); + Assert.assertEquals(true, rs.getInt(3) == 0 && rs.wasNull()); + Assert.assertEquals(true, rs.getLong(4) == 0 && rs.wasNull()); + Assert.assertEquals(true, rs.getFloat(5) == 0.0f && rs.wasNull()); + Assert.assertEquals(true, rs.getDouble(6) == 0.0f && rs.wasNull()); + Assert.assertEquals(true, rs.getByte(7) == 0 && rs.wasNull()); + Assert.assertEquals(true, rs.getShort(8) == 0 && rs.wasNull()); + Assert.assertEquals(null, rs.getBytes(9)); + Assert.assertEquals(null, rs.getString(10)); + + rs.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void testJNI() throws SQLException { + final String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"; + conn_jni = DriverManager.getConnection(url, properties); + + try (Statement stmt = conn_jni.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 timestamp, f2 int, f3 bigint, f4 float, f5 double, f6 smallint, f7 tinyint, f8 bool, f9 binary(64), f10 nchar(64))"); + stmt.executeUpdate("insert into weather(ts, f1) values(now+1s, " + TimestampUtil.datetimeToLong("2021-04-21 12:00:00.000") + ")"); + ResultSet rs = stmt.executeQuery("select * from weather"); + rs.next(); + + Assert.assertEquals("2021-04-21 12:00:00.000", TimestampUtil.longToDatetime(rs.getTimestamp(2).getTime())); + Assert.assertEquals(true, rs.getInt(3) == 0 && rs.wasNull()); + Assert.assertEquals(true, rs.getLong(4) == 0 && rs.wasNull()); + Assert.assertEquals(true, rs.getFloat(5) == 0.0f && rs.wasNull()); + Assert.assertEquals(true, rs.getDouble(6) == 0.0f && rs.wasNull()); + Assert.assertEquals(true, rs.getByte(7) == 0 && rs.wasNull()); + Assert.assertEquals(true, rs.getShort(8) == 0 && rs.wasNull()); + Assert.assertEquals(null, rs.getBytes(9)); + Assert.assertEquals(null, rs.getString(10)); + + rs.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @BeforeClass + public static void beforeClass() { + properties = new Properties(); + properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); + } + + @AfterClass + public static void afterClass() throws SQLException { + if (conn_restful != null) + conn_restful.close(); + if (conn_jni != null) + conn_jni.close(); + } +} diff --git a/src/connector/python/linux/python2/setup.py b/src/connector/python/linux/python2/setup.py index d1fca047c6..ff2d90fcb3 100644 --- a/src/connector/python/linux/python2/setup.py +++ b/src/connector/python/linux/python2/setup.py @@ -5,7 +5,7 @@ with open("README.md", "r") as fh: setuptools.setup( name="taos", - version="2.0.7", + version="2.0.8", author="Taosdata Inc.", author_email="support@taosdata.com", description="TDengine python client package", diff --git a/src/connector/python/linux/python2/taos/cursor.py b/src/connector/python/linux/python2/taos/cursor.py index 8f9aab82da..4c0456b503 100644 --- a/src/connector/python/linux/python2/taos/cursor.py +++ b/src/connector/python/linux/python2/taos/cursor.py @@ -42,7 +42,7 @@ class TDengineCursor(object): def __iter__(self): return self - def __next__(self): + def next(self): if self._result is None or self._fields is None: raise OperationalError("Invalid use of fetch iterator") diff --git a/src/cq/src/cqMain.c b/src/cq/src/cqMain.c index d4d202267c..5d5d5f339e 100644 --- a/src/cq/src/cqMain.c +++ b/src/cq/src/cqMain.c @@ -310,8 +310,23 @@ void *cqCreate(void *handle, uint64_t uid, int32_t sid, const char* dstTable, ch } 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; @@ -386,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); @@ -427,10 +445,11 @@ 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) { - pObj->pStream = taos_open_stream(pContext->dbConn, pObj->sqlStr, cqProcessStreamRes, 0, (void *)pObj->rid, NULL); + pObj->pStream = taos_open_stream(pContext->dbConn, pObj->sqlStr, cqProcessStreamRes, INT64_MIN, (void *)pObj->rid, NULL); // TODO the pObj->pStream may be released if error happens if (pObj->pStream) { diff --git a/src/inc/taosdef.h b/src/inc/taosdef.h index 7aabac1786..e9282d0816 100644 --- a/src/inc/taosdef.h +++ b/src/inc/taosdef.h @@ -247,8 +247,9 @@ do { \ #define TSDB_MAX_REPLICA 5 #define TSDB_TBNAME_COLUMN_INDEX (-1) -#define TSDB_BLOCK_DIST_COLUMN_INDEX (-2) -#define TSDB_UD_COLUMN_INDEX (-100) +#define TSDB_BLOCK_DIST_COLUMN_INDEX (-2) +#define TSDB_UD_COLUMN_INDEX (-1000) +#define TSDB_RES_COL_ID (-5000) #define TSDB_MULTI_TABLEMETA_MAX_NUM 100000 // maximum batch size allowed to load table meta @@ -396,9 +397,10 @@ typedef enum { typedef enum { TSDB_SUPER_TABLE = 0, // super table TSDB_CHILD_TABLE = 1, // table created from super table - TSDB_NORMAL_TABLE = 2, // ordinary table - TSDB_STREAM_TABLE = 3, // table created from stream computing - TSDB_TABLE_MAX = 4 + TSDB_NORMAL_TABLE = 2, // ordinary table + TSDB_STREAM_TABLE = 3, // table created from stream computing + TSDB_TEMP_TABLE = 4, // temp table created by nest query + TSDB_TABLE_MAX = 5 } ETableType; typedef enum { diff --git a/src/inc/taosmsg.h b/src/inc/taosmsg.h index 6c69b33d90..72acd744dd 100644 --- a/src/inc/taosmsg.h +++ b/src/inc/taosmsg.h @@ -76,9 +76,9 @@ TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_CREATE_DNODE, "create-dnode" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_DROP_DNODE, "drop-dnode" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_CREATE_DB, "create-db" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_CREATE_FUNCTION, "create-function" ) -TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_DROP_DB, "drop-db" ) -TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_DROP_FUNCTION, "drop-function" ) -TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_USE_DB, "use-db" ) +TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_DROP_DB, "drop-db" ) +TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_DROP_FUNCTION, "drop-function" ) +TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_USE_DB, "use-db" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_ALTER_DB, "alter-db" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_SYNC_DB, "sync-db-replica" ) TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_CREATE_TABLE, "create-table" ) @@ -402,7 +402,6 @@ typedef struct SColIndex { char name[TSDB_COL_NAME_LEN]; // TODO remove it } SColIndex; - typedef struct SColumnFilterInfo { int16_t lowerRelOptr; int16_t upperRelOptr; @@ -424,42 +423,13 @@ 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; - +typedef struct SColumnFilterList { + int16_t numOfFilters; + union{ + int64_t placeholder; + SColumnFilterInfo *filterInfo; + }; +} SColumnFilterList; /* * 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. @@ -468,11 +438,7 @@ typedef struct SColumnInfo { int16_t colId; int16_t type; int16_t bytes; - int16_t numOfFilters; - union{ - int64_t placeholder; - SColumnFilterInfo *filters; - }; + SColumnFilterList flist; } SColumnInfo; typedef struct STableIdInfo { @@ -486,10 +452,29 @@ typedef struct STimeWindow { TSKEY ekey; } STimeWindow; +typedef struct { + int32_t tsOffset; // offset value in current msg body, NOTE: ts list is compressed + int32_t tsLen; // total length of ts comp block + int32_t tsNumOfBlocks; // ts comp block numbers + int32_t tsOrder; // ts comp block order +} STsBufInfo; + typedef struct { SMsgHead head; char version[TSDB_VERSION_LEN]; + bool stableQuery; // super table query or not + bool topBotQuery; // TODO used bitwise flag + bool groupbyColumn; // denote if this is a groupby normal column query + bool hasTagResults; // if there are tag values in final result or not + bool timeWindowInterpo;// if the time window start/end required interpolation + bool queryBlockDist; // if query data block distribution + bool stabledev; // super table stddev query + bool tsCompQuery; // is tscomp query + bool simpleAgg; + bool pointInterpQuery; // point interpolation query + bool needReverseScan; // need reverse scan + STimeWindow window; int32_t numOfTables; int16_t order; @@ -512,17 +497,16 @@ typedef struct { int16_t fillType; // interpolate type uint64_t fillVal; // default value array list int32_t secondStageOutput; - int32_t tsOffset; // offset value in current msg body, NOTE: ts list is compressed - int32_t tsLen; // total length of ts comp block - int32_t tsNumOfBlocks; // ts comp block numbers - int32_t tsOrder; // ts comp block order + STsBufInfo tsBuf; // tsBuf info int32_t numOfTags; // number of tags columns involved int32_t sqlstrLen; // sql query string int32_t prevResultLen; // previous result length + int32_t numOfOperator; + int32_t tableScanOperator;// table scan operator. -1 means no scan operator int32_t udfNum; // number of udf function int32_t udfContentOffset; int32_t udfContentLen; - SColumnInfo colList[]; + SColumnInfo tableCols[]; } SQueryTableMsg; typedef struct { @@ -868,7 +852,7 @@ typedef struct { uint32_t queryId; int64_t useconds; int64_t stime; - uint64_t qHandle; + uint64_t qId; } SQueryDesc; typedef struct { diff --git a/src/inc/tsdb.h b/src/inc/tsdb.h index 85ee9f0443..1ba5131f6d 100644 --- a/src/inc/tsdb.h +++ b/src/inc/tsdb.h @@ -221,7 +221,7 @@ typedef struct { typedef struct { uint32_t numOfTables; - SArray * pGroupList; + SArray *pGroupList; SHashObj *map; // speedup acquire the tableQueryInfo by table uid } STableGroupInfo; diff --git a/src/inc/ttokendef.h b/src/inc/ttokendef.h index 945f44424e..f7eac0d205 100644 --- a/src/inc/ttokendef.h +++ b/src/inc/ttokendef.h @@ -209,27 +209,6 @@ #define TK_INTO 190 #define TK_VALUES 191 - - - - - - - - - - - - - - - - - - - - - #define TK_SPACE 300 #define TK_COMMENT 301 #define TK_ILLEGAL 302 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/taosdemo.c b/src/kit/taosdemo/taosdemo.c index 01a7e31940..3631fbec1c 100644 --- a/src/kit/taosdemo/taosdemo.c +++ b/src/kit/taosdemo/taosdemo.c @@ -97,7 +97,7 @@ enum QUERY_MODE { #define MAX_TAG_COUNT 128 #define MAX_QUERY_SQL_COUNT 100 -#define MAX_QUERY_SQL_LENGTH 256 +#define MAX_QUERY_SQL_LENGTH 1024 #define MAX_DATABASE_COUNT 256 #define INPUT_BUF_LEN 256 @@ -355,7 +355,7 @@ typedef struct SDbs_S { } SDbs; typedef struct SpecifiedQueryInfo_S { - int rate; // 0: unlimit > 0 loop/s + int queryInterval; // 0: unlimit > 0 loop/s int concurrent; int sqlCount; int mode; // 0: sync, 1: async @@ -371,7 +371,7 @@ typedef struct SpecifiedQueryInfo_S { typedef struct SuperQueryInfo_S { char sTblName[MAX_TB_NAME_SIZE+1]; - int rate; // 0: unlimit > 0 loop/s + int queryInterval; // 0: unlimit > 0 loop/s int threadCnt; int mode; // 0: sync, 1: async int subscribeInterval; // ms @@ -530,56 +530,50 @@ char *aggreFunc[] = {"*", "count(*)", "avg(col0)", "sum(col0)", "max(col0)", "min(col0)", "first(col0)", "last(col0)"}; SArguments g_args = { - NULL, // metaFile - 0, // test_mode - "127.0.0.1", // host - 6030, // port - "root", // user - #ifdef _TD_POWER_ - "powerdb", // password - #else - "taosdata", // password - #endif - "test", // database - 1, // replica - "t", // tb_prefix - NULL, // sqlFile - true, // use_metric - true, // drop_database - true, // insert_only - false, // debug_print - false, // verbose_print - false, // performance statistic print - false, // answer_yes; - "./output.txt", // output_file - 0, // mode : sync or async - { - "TINYINT", // datatype - "SMALLINT", - "INT", - "BIGINT", - "FLOAT", - "DOUBLE", - "BINARY", - "NCHAR", - "BOOL", - "TIMESTAMP" - }, - 16, // len_of_binary - 10, // num_of_CPR - 10, // num_of_connections/thread - 0, // insert_interval - 1, // query_times - 0, // interlace_rows; - 100, // num_of_RPR - TSDB_PAYLOAD_SIZE, // max_sql_len - 10000, // num_of_tables - 10000, // num_of_DPT - 0, // abort - 0, // disorderRatio - 1000, // disorderRange - 1, // method_of_delete - NULL // arg_list + NULL, // metaFile + 0, // test_mode + "127.0.0.1", // host + 6030, // port + "root", // user +#ifdef _TD_POWER_ + "powerdb", // password +#else + "taosdata", // password +#endif + "test", // database + 1, // replica + "t", // tb_prefix + NULL, // sqlFile + true, // use_metric + true, // drop_database + true, // insert_only + false, // debug_print + false, // verbose_print + false, // performance statistic print + false, // answer_yes; + "./output.txt", // output_file + 0, // mode : sync or async + { + "INT", // datatype + "INT", // datatype + "INT", // datatype + "INT", // datatype + }, + 16, // len_of_binary + 4, // num_of_CPR + 10, // num_of_connections/thread + 0, // insert_interval + 1, // query_times + 0, // interlace_rows; + 30000, // num_of_RPR + 1024000, // max_sql_len + 10000, // num_of_tables + 10000, // num_of_DPT + 0, // abort + 0, // disorderRatio + 1000, // disorderRange + 1, // method_of_delete + NULL // arg_list }; @@ -667,7 +661,7 @@ static void printHelp() { printf("%s%s%s%s\n", indent, "-o", indent, "Direct output to the named file. Default is './output.txt'."); printf("%s%s%s%s\n", indent, "-q", indent, - "Query mode--0: SYNC, 1: ASYNC. Default is SYNC."); + "Query mode -- 0: SYNC, 1: ASYNC. Default is SYNC."); printf("%s%s%s%s\n", indent, "-b", indent, "The data_type of columns, default: TINYINT,SMALLINT,INT,BIGINT,FLOAT,DOUBLE,BINARY,NCHAR,BOOL,TIMESTAMP."); printf("%s%s%s%s\n", indent, "-w", indent, @@ -679,7 +673,7 @@ static void printHelp() { printf("%s%s%s%s\n", indent, "-i", indent, "The sleep time (ms) between insertion. Default is 0."); printf("%s%s%s%s\n", indent, "-r", indent, - "The number of records per request. Default is 100."); + "The number of records per request. Default is 30000."); printf("%s%s%s%s\n", indent, "-t", indent, "The number of tables. Default is 10000."); printf("%s%s%s%s\n", indent, "-n", indent, @@ -692,13 +686,30 @@ static void printHelp() { "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, + printf("%s%s%s\n", indent, "-V, --version\t", "Print version info."); + printf("%s%s%s%s\n", indent, "--help\t", indent, + "Print command line arguments list info."); /* printf("%s%s%s%s\n", indent, "-D", indent, "if elete database if exists. 0: no, 1: yes, default is 1"); */ } +static bool isStringNumber(char *input) +{ + int len = strlen(input); + if (0 == len) { + return false; + } + + for (int i = 0; i < len; i++) { + if (!isdigit(input[i])) + return false; + } + + return true; +} + static void parse_args(int argc, char *argv[], SArguments *arguments) { char **sptr; @@ -706,39 +717,134 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { if (strcmp(argv[i], "-f") == 0) { arguments->metaFile = argv[++i]; } else if (strcmp(argv[i], "-c") == 0) { - tstrncpy(configDir, argv[++i], TSDB_FILENAME_LEN); + if (argc == i+1) { + printHelp(); + errorPrint("%s", "\n\t-c need a valid path following!\n"); + exit(EXIT_FAILURE); + } + tstrncpy(configDir, argv[++i], MAX_FILE_NAME_LEN); } else if (strcmp(argv[i], "-h") == 0) { + if (argc == i+1) { + printHelp(); + errorPrint("%s", "\n\t-h need a valid string following!\n"); + exit(EXIT_FAILURE); + } arguments->host = argv[++i]; } else if (strcmp(argv[i], "-p") == 0) { + if ((argc == i+1) || + (!isStringNumber(argv[i+1]))) { + printHelp(); + errorPrint("%s", "\n\t-p need a number following!\n"); + exit(EXIT_FAILURE); + } arguments->port = atoi(argv[++i]); } else if (strcmp(argv[i], "-u") == 0) { + if (argc == i+1) { + printHelp(); + errorPrint("%s", "\n\t-u need a valid string following!\n"); + exit(EXIT_FAILURE); + } arguments->user = argv[++i]; } else if (strcmp(argv[i], "-P") == 0) { + if (argc == i+1) { + printHelp(); + errorPrint("%s", "\n\t-P need a valid string following!\n"); + exit(EXIT_FAILURE); + } arguments->password = argv[++i]; } else if (strcmp(argv[i], "-o") == 0) { + if (argc == i+1) { + printHelp(); + errorPrint("%s", "\n\t-o need a valid string following!\n"); + exit(EXIT_FAILURE); + } arguments->output_file = argv[++i]; } else if (strcmp(argv[i], "-s") == 0) { + if (argc == i+1) { + printHelp(); + errorPrint("%s", "\n\t-s need a valid string following!\n"); + exit(EXIT_FAILURE); + } arguments->sqlFile = argv[++i]; } else if (strcmp(argv[i], "-q") == 0) { + if ((argc == i+1) || + (!isStringNumber(argv[i+1]))) { + printHelp(); + errorPrint("%s", "\n\t-q need a number following!\nQuery mode -- 0: SYNC, 1: ASYNC. Default is SYNC.\n"); + exit(EXIT_FAILURE); + } arguments->query_mode = atoi(argv[++i]); } else if (strcmp(argv[i], "-T") == 0) { + if ((argc == i+1) || + (!isStringNumber(argv[i+1]))) { + printHelp(); + errorPrint("%s", "\n\t-T need a number following!\n"); + exit(EXIT_FAILURE); + } arguments->num_of_threads = atoi(argv[++i]); } else if (strcmp(argv[i], "-i") == 0) { + if ((argc == i+1) || + (!isStringNumber(argv[i+1]))) { + printHelp(); + errorPrint("%s", "\n\t-i need a number following!\n"); + exit(EXIT_FAILURE); + } arguments->insert_interval = atoi(argv[++i]); } else if (strcmp(argv[i], "-qt") == 0) { + if ((argc == i+1) || + (!isStringNumber(argv[i+1]))) { + printHelp(); + errorPrint("%s", "\n\t-qt need a number following!\n"); + exit(EXIT_FAILURE); + } arguments->query_times = atoi(argv[++i]); } else if (strcmp(argv[i], "-B") == 0) { + if ((argc == i+1) || + (!isStringNumber(argv[i+1]))) { + printHelp(); + errorPrint("%s", "\n\t-B need a number following!\n"); + exit(EXIT_FAILURE); + } arguments->interlace_rows = atoi(argv[++i]); } else if (strcmp(argv[i], "-r") == 0) { + if ((argc == i+1) || + (!isStringNumber(argv[i+1]))) { + printHelp(); + errorPrint("%s", "\n\t-r need a number following!\n"); + exit(EXIT_FAILURE); + } arguments->num_of_RPR = atoi(argv[++i]); } else if (strcmp(argv[i], "-t") == 0) { + if ((argc == i+1) || + (!isStringNumber(argv[i+1]))) { + printHelp(); + errorPrint("%s", "\n\t-t need a number following!\n"); + exit(EXIT_FAILURE); + } arguments->num_of_tables = atoi(argv[++i]); } else if (strcmp(argv[i], "-n") == 0) { + if ((argc == i+1) || + (!isStringNumber(argv[i+1]))) { + printHelp(); + errorPrint("%s", "\n\t-n need a number following!\n"); + exit(EXIT_FAILURE); + } arguments->num_of_DPT = atoi(argv[++i]); } else if (strcmp(argv[i], "-d") == 0) { + if (argc == i+1) { + printHelp(); + errorPrint("%s", "\n\t-d need a valid string following!\n"); + exit(EXIT_FAILURE); + } arguments->database = argv[++i]; } else if (strcmp(argv[i], "-l") == 0) { + if ((argc == i+1) || + (!isStringNumber(argv[i+1]))) { + printHelp(); + errorPrint("%s", "\n\t-l need a number following!\n"); + exit(EXIT_FAILURE); + } arguments->num_of_CPR = atoi(argv[++i]); } else if (strcmp(argv[i], "-b") == 0) { sptr = arguments->datatype; @@ -746,16 +852,16 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { if (strstr(argv[i], ",") == NULL) { // only one col if (strcasecmp(argv[i], "INT") - && strcasecmp(argv[i], "FLOAT") - && strcasecmp(argv[i], "TINYINT") - && strcasecmp(argv[i], "BOOL") - && strcasecmp(argv[i], "SMALLINT") - && strcasecmp(argv[i], "BIGINT") - && strcasecmp(argv[i], "DOUBLE") - && strcasecmp(argv[i], "BINARY") - && strcasecmp(argv[i], "NCHAR")) { + && strcasecmp(argv[i], "FLOAT") + && strcasecmp(argv[i], "TINYINT") + && strcasecmp(argv[i], "BOOL") + && strcasecmp(argv[i], "SMALLINT") + && strcasecmp(argv[i], "BIGINT") + && strcasecmp(argv[i], "DOUBLE") + && strcasecmp(argv[i], "BINARY") + && strcasecmp(argv[i], "NCHAR")) { printHelp(); - ERROR_EXIT( "Invalid data_type!\n"); + errorPrint("%s", "-b: Invalid data_type!\n"); exit(EXIT_FAILURE); } sptr[0] = argv[i]; @@ -767,17 +873,17 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { char *token = strsep(&running, ","); while(token != NULL) { if (strcasecmp(token, "INT") - && strcasecmp(token, "FLOAT") - && strcasecmp(token, "TINYINT") - && strcasecmp(token, "BOOL") - && strcasecmp(token, "SMALLINT") - && strcasecmp(token, "BIGINT") - && strcasecmp(token, "DOUBLE") - && strcasecmp(token, "BINARY") - && strcasecmp(token, "NCHAR")) { + && strcasecmp(token, "FLOAT") + && strcasecmp(token, "TINYINT") + && strcasecmp(token, "BOOL") + && strcasecmp(token, "SMALLINT") + && strcasecmp(token, "BIGINT") + && strcasecmp(token, "DOUBLE") + && strcasecmp(token, "BINARY") + && strcasecmp(token, "NCHAR")) { printHelp(); free(dupstr); - ERROR_EXIT("Invalid data_type!\n"); + errorPrint("%s", "-b: Invalid data_type!\n"); exit(EXIT_FAILURE); } sptr[index++] = token; @@ -788,8 +894,20 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { sptr[index] = NULL; } } else if (strcmp(argv[i], "-w") == 0) { + if ((argc == i+1) || + (!isStringNumber(argv[i+1]))) { + printHelp(); + errorPrint("%s", "\n\t-w need a number following!\n"); + exit(EXIT_FAILURE); + } arguments->len_of_binary = atoi(argv[++i]); } else if (strcmp(argv[i], "-m") == 0) { + if ((argc == i+1) || + (!isStringNumber(argv[i+1]))) { + printHelp(); + errorPrint("%s", "\n\t-m need a number following!\n"); + exit(EXIT_FAILURE); + } arguments->tb_prefix = argv[++i]; } else if (strcmp(argv[i], "-N") == 0) { arguments->use_metric = false; @@ -804,22 +922,42 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { } else if (strcmp(argv[i], "-pp") == 0) { arguments->performance_print = true; } else if (strcmp(argv[i], "-O") == 0) { + if ((argc == i+1) || + (!isStringNumber(argv[i+1]))) { + printHelp(); + errorPrint("%s", "\n\t-O need a number following!\n"); + exit(EXIT_FAILURE); + } arguments->disorderRatio = atoi(argv[++i]); - if (arguments->disorderRatio > 50) + if (arguments->disorderRatio > 50) { arguments->disorderRatio = 50; + } - if (arguments->disorderRatio < 0) + if (arguments->disorderRatio < 0) { arguments->disorderRatio = 0; + } } else if (strcmp(argv[i], "-R") == 0) { + if ((argc == i+1) || + (!isStringNumber(argv[i+1]))) { + printHelp(); + errorPrint("%s", "\n\t-R need a number following!\n"); + exit(EXIT_FAILURE); + } arguments->disorderRange = atoi(argv[++i]); if (arguments->disorderRange < 0) arguments->disorderRange = 1000; } else if (strcmp(argv[i], "-a") == 0) { + if ((argc == i+1) || + (!isStringNumber(argv[i+1]))) { + printHelp(); + errorPrint("%s", "\n\t-a need a number following!\n"); + exit(EXIT_FAILURE); + } arguments->replica = atoi(argv[++i]); if (arguments->replica > 3 || arguments->replica < 1) { arguments->replica = 1; @@ -839,29 +977,29 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { exit(0); } else { printHelp(); - ERROR_EXIT("ERROR: wrong options\n"); + errorPrint("%s", "ERROR: wrong options\n"); exit(EXIT_FAILURE); } } if (((arguments->debug_print) && (arguments->metaFile == NULL)) - || arguments->verbose_print) { + || arguments->verbose_print) { printf("###################################################################\n"); printf("# meta file: %s\n", arguments->metaFile); printf("# Server IP: %s:%hu\n", - arguments->host == NULL ? "localhost" : arguments->host, - arguments->port ); + arguments->host == NULL ? "localhost" : arguments->host, + arguments->port ); printf("# User: %s\n", arguments->user); printf("# Password: %s\n", arguments->password); printf("# Use metric: %s\n", arguments->use_metric ? "true" : "false"); if (*(arguments->datatype)) { - printf("# Specified data type: "); - for (int i = 0; i < MAX_NUM_DATATYPE; i++) - if (arguments->datatype[i]) - printf("%s,", arguments->datatype[i]); - else - break; - printf("\n"); + printf("# Specified data type: "); + for (int i = 0; i < MAX_NUM_DATATYPE; i++) + if (arguments->datatype[i]) + printf("%s,", arguments->datatype[i]); + else + break; + printf("\n"); } printf("# Insertion interval: %d\n", arguments->insert_interval); printf("# Number of records per req: %d\n", arguments->num_of_RPR); @@ -994,7 +1132,7 @@ static void selectAndGetResult(TAOS *taos, char *command, char* resultFileName) TAOS_RES *res = taos_query(taos, command); if (res == NULL || taos_errno(res) != 0) { errorPrint("%s() LN%d, failed to execute sql:%s, reason:%s\n", - __func__, __LINE__, command, taos_errstr(res)); + __func__, __LINE__, command, taos_errstr(res)); taos_free_result(res); return; } @@ -1003,17 +1141,6 @@ static void selectAndGetResult(TAOS *taos, char *command, char* resultFileName) taos_free_result(res); } -static double getCurrentTimeUs() { - struct timeval tv; - - if (gettimeofday(&tv, NULL) != 0) { - perror("Failed to get current time in ms"); - return 0.0; - } - - return tv.tv_sec + tv.tv_usec / 1E6; -} - static int32_t rand_bool(){ static int cursor; cursor++; @@ -1108,7 +1235,7 @@ static void init_rand_data() { g_args.metaFile); } while(0) static int printfInsertMeta() { - SHOW_PARSE_RESULT_START(); + SHOW_PARSE_RESULT_START(); 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); @@ -1170,23 +1297,23 @@ 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))) { + || (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "us", 2))) { printf(" precision: \033[33m%s\033[0m\n", - g_Dbs.db[i].dbCfg.precision); + 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); + g_Dbs.db[i].dbCfg.precision); return -1; } } printf(" super table count: \033[33m%d\033[0m\n", - g_Dbs.db[i].superTblCount); + 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); + 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"); @@ -1205,23 +1332,23 @@ static int printfInsertMeta() { } printf(" childTblCount: \033[33m%d\033[0m\n", - g_Dbs.db[i].superTbls[j].childTblCount); + g_Dbs.db[i].superTbls[j].childTblCount); printf(" childTblPrefix: \033[33m%s\033[0m\n", - g_Dbs.db[i].superTbls[j].childTblPrefix); + g_Dbs.db[i].superTbls[j].childTblPrefix); printf(" dataSource: \033[33m%s\033[0m\n", - g_Dbs.db[i].superTbls[j].dataSource); + g_Dbs.db[i].superTbls[j].dataSource); printf(" insertMode: \033[33m%s\033[0m\n", - g_Dbs.db[i].superTbls[j].insertMode); + g_Dbs.db[i].superTbls[j].insertMode); if (g_Dbs.db[i].superTbls[j].childTblLimit > 0) { printf(" childTblLimit: \033[33m%d\033[0m\n", - g_Dbs.db[i].superTbls[j].childTblLimit); + g_Dbs.db[i].superTbls[j].childTblLimit); } if (g_Dbs.db[i].superTbls[j].childTblOffset >= 0) { printf(" childTblOffset: \033[33m%d\033[0m\n", - g_Dbs.db[i].superTbls[j].childTblOffset); + g_Dbs.db[i].superTbls[j].childTblOffset); } printf(" insertRows: \033[33m%"PRId64"\033[0m\n", - g_Dbs.db[i].superTbls[j].insertRows); + g_Dbs.db[i].superTbls[j].insertRows); if (0 == g_Dbs.db[i].superTbls[j].multiThreadWriteOneTbl) { printf(" multiThreadWriteOneTbl: \033[33mno\033[0m\n"); @@ -1229,61 +1356,61 @@ static int printfInsertMeta() { printf(" multiThreadWriteOneTbl: \033[33myes\033[0m\n"); } printf(" interlaceRows: \033[33m%d\033[0m\n", - g_Dbs.db[i].superTbls[j].interlaceRows); + g_Dbs.db[i].superTbls[j].interlaceRows); if (g_Dbs.db[i].superTbls[j].interlaceRows > 0) { printf(" stable insert interval: \033[33m%d\033[0m\n", - g_Dbs.db[i].superTbls[j].insertInterval); + g_Dbs.db[i].superTbls[j].insertInterval); } printf(" disorderRange: \033[33m%d\033[0m\n", - g_Dbs.db[i].superTbls[j].disorderRange); + g_Dbs.db[i].superTbls[j].disorderRange); printf(" disorderRatio: \033[33m%d\033[0m\n", - g_Dbs.db[i].superTbls[j].disorderRatio); + g_Dbs.db[i].superTbls[j].disorderRatio); printf(" maxSqlLen: \033[33m%d\033[0m\n", - g_Dbs.db[i].superTbls[j].maxSqlLen); + g_Dbs.db[i].superTbls[j].maxSqlLen); printf(" timeStampStep: \033[33m%d\033[0m\n", - g_Dbs.db[i].superTbls[j].timeStampStep); + g_Dbs.db[i].superTbls[j].timeStampStep); printf(" startTimestamp: \033[33m%s\033[0m\n", - g_Dbs.db[i].superTbls[j].startTimestamp); + g_Dbs.db[i].superTbls[j].startTimestamp); printf(" sampleFormat: \033[33m%s\033[0m\n", - g_Dbs.db[i].superTbls[j].sampleFormat); + g_Dbs.db[i].superTbls[j].sampleFormat); printf(" sampleFile: \033[33m%s\033[0m\n", - g_Dbs.db[i].superTbls[j].sampleFile); + g_Dbs.db[i].superTbls[j].sampleFile); printf(" tagsFile: \033[33m%s\033[0m\n", - g_Dbs.db[i].superTbls[j].tagsFile); + g_Dbs.db[i].superTbls[j].tagsFile); printf(" columnCount: \033[33m%d\033[0m\n", - g_Dbs.db[i].superTbls[j].columnCount); + 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); if ((0 == strncasecmp(g_Dbs.db[i].superTbls[j].columns[k].dataType, - "binary", 6)) - || (0 == strncasecmp(g_Dbs.db[i].superTbls[j].columns[k].dataType, - "nchar", 5))) { + "binary", 6)) + || (0 == strncasecmp(g_Dbs.db[i].superTbls[j].columns[k].dataType, + "nchar", 5))) { printf("column[\033[33m%d\033[0m]:\033[33m%s(%d)\033[0m ", k, - g_Dbs.db[i].superTbls[j].columns[k].dataType, - g_Dbs.db[i].superTbls[j].columns[k].dataLen); + g_Dbs.db[i].superTbls[j].columns[k].dataType, + g_Dbs.db[i].superTbls[j].columns[k].dataLen); } else { printf("column[%d]:\033[33m%s\033[0m ", k, - g_Dbs.db[i].superTbls[j].columns[k].dataType); + g_Dbs.db[i].superTbls[j].columns[k].dataType); } } printf("\n"); printf(" tagCount: \033[33m%d\033[0m\n ", - g_Dbs.db[i].superTbls[j].tagCount); + g_Dbs.db[i].superTbls[j].tagCount); for (int k = 0; k < g_Dbs.db[i].superTbls[j].tagCount; k++) { //printf("dataType:%s, dataLen:%d\t", g_Dbs.db[i].superTbls[j].tags[k].dataType, g_Dbs.db[i].superTbls[j].tags[k].dataLen); if ((0 == strncasecmp(g_Dbs.db[i].superTbls[j].tags[k].dataType, - "binary", strlen("binary"))) - || (0 == strncasecmp(g_Dbs.db[i].superTbls[j].tags[k].dataType, - "nchar", strlen("nchar")))) { + "binary", strlen("binary"))) + || (0 == strncasecmp(g_Dbs.db[i].superTbls[j].tags[k].dataType, + "nchar", strlen("nchar")))) { printf("tag[%d]:\033[33m%s(%d)\033[0m ", k, - g_Dbs.db[i].superTbls[j].tags[k].dataType, - g_Dbs.db[i].superTbls[j].tags[k].dataLen); + g_Dbs.db[i].superTbls[j].tags[k].dataType, + g_Dbs.db[i].superTbls[j].tags[k].dataLen); } else { printf("tag[%d]:\033[33m%s\033[0m ", k, - g_Dbs.db[i].superTbls[j].tags[k].dataType); + g_Dbs.db[i].superTbls[j].tags[k].dataType); } } printf("\n"); @@ -1357,7 +1484,7 @@ static void printfInsertMetaToFile(FILE* fp) { } 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))) { + || (0 == strncasecmp(g_Dbs.db[i].dbCfg.precision, "us", 2))) { fprintf(fp, " precision: %s\n", g_Dbs.db[i].dbCfg.precision); } else { fprintf(fp, " precision error: %s\n", g_Dbs.db[i].dbCfg.precision); @@ -1424,10 +1551,10 @@ static void printfInsertMetaToFile(FILE* fp) { 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); if ((0 == strncasecmp( - g_Dbs.db[i].superTbls[j].columns[k].dataType, - "binary", strlen("binary"))) - || (0 == strncasecmp(g_Dbs.db[i].superTbls[j].columns[k].dataType, - "nchar", strlen("nchar")))) { + g_Dbs.db[i].superTbls[j].columns[k].dataType, + "binary", strlen("binary"))) + || (0 == strncasecmp(g_Dbs.db[i].superTbls[j].columns[k].dataType, + "nchar", strlen("nchar")))) { fprintf(fp, "column[%d]:%s(%d) ", k, g_Dbs.db[i].superTbls[j].columns[k].dataType, g_Dbs.db[i].superTbls[j].columns[k].dataLen); @@ -1442,9 +1569,9 @@ static void printfInsertMetaToFile(FILE* fp) { for (int k = 0; k < g_Dbs.db[i].superTbls[j].tagCount; k++) { //printf("dataType:%s, dataLen:%d\t", g_Dbs.db[i].superTbls[j].tags[k].dataType, g_Dbs.db[i].superTbls[j].tags[k].dataLen); if ((0 == strncasecmp(g_Dbs.db[i].superTbls[j].tags[k].dataType, - "binary", strlen("binary"))) - || (0 == strncasecmp(g_Dbs.db[i].superTbls[j].tags[k].dataType, - "nchar", strlen("nchar")))) { + "binary", strlen("binary"))) + || (0 == strncasecmp(g_Dbs.db[i].superTbls[j].tags[k].dataType, + "nchar", strlen("nchar")))) { fprintf(fp, "tag[%d]:%s(%d) ", k, g_Dbs.db[i].superTbls[j].tags[k].dataType, g_Dbs.db[i].superTbls[j].tags[k].dataLen); } else { @@ -1464,67 +1591,67 @@ static void printfQueryMeta() { SHOW_PARSE_RESULT_START(); printf("host: \033[33m%s:%u\033[0m\n", - g_queryInfo.host, g_queryInfo.port); + g_queryInfo.host, g_queryInfo.port); printf("user: \033[33m%s\033[0m\n", g_queryInfo.user); printf("database name: \033[33m%s\033[0m\n", g_queryInfo.dbName); 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 ms\033[0m\n", + g_queryInfo.specifiedQueryInfo.queryInterval); 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); + g_queryInfo.specifiedQueryInfo.concurrent); printf("sqlCount: \033[33m%d\033[0m\n", - g_queryInfo.specifiedQueryInfo.sqlCount); + g_queryInfo.specifiedQueryInfo.sqlCount); printf("specified tbl query times:\n"); printf(" \033[33m%d\033[0m\n", - g_queryInfo.specifiedQueryInfo.queryTimes); + g_queryInfo.specifiedQueryInfo.queryTimes); if (SUBSCRIBE_TEST == g_args.test_mode) { printf("mod: \033[33m%d\033[0m\n", - g_queryInfo.specifiedQueryInfo.mode); + g_queryInfo.specifiedQueryInfo.mode); printf("interval: \033[33m%d\033[0m\n", - g_queryInfo.specifiedQueryInfo.subscribeInterval); + g_queryInfo.specifiedQueryInfo.subscribeInterval); printf("restart: \033[33m%d\033[0m\n", - g_queryInfo.specifiedQueryInfo.subscribeRestart); + g_queryInfo.specifiedQueryInfo.subscribeRestart); printf("keepProgress: \033[33m%d\033[0m\n", - g_queryInfo.specifiedQueryInfo.subscribeKeepProgress); + 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]); + 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); + g_queryInfo.superQueryInfo.queryInterval); printf("threadCnt: \033[33m%d\033[0m\n", - g_queryInfo.superQueryInfo.threadCnt); + g_queryInfo.superQueryInfo.threadCnt); printf("childTblCount: \033[33m%d\033[0m\n", - g_queryInfo.superQueryInfo.childTblCount); + g_queryInfo.superQueryInfo.childTblCount); printf("stable name: \033[33m%s\033[0m\n", - g_queryInfo.superQueryInfo.sTblName); + g_queryInfo.superQueryInfo.sTblName); printf("stb query times:\033[33m%d\033[0m\n", - g_queryInfo.superQueryInfo.queryTimes); + g_queryInfo.superQueryInfo.queryTimes); if (SUBSCRIBE_TEST == g_args.test_mode) { printf("mod: \033[33m%d\033[0m\n", - g_queryInfo.superQueryInfo.mode); + g_queryInfo.superQueryInfo.mode); printf("interval: \033[33m%d\033[0m\n", - g_queryInfo.superQueryInfo.subscribeInterval); + g_queryInfo.superQueryInfo.subscribeInterval); printf("restart: \033[33m%d\033[0m\n", - g_queryInfo.superQueryInfo.subscribeRestart); + g_queryInfo.superQueryInfo.subscribeRestart); printf("keepProgress: \033[33m%d\033[0m\n", - g_queryInfo.superQueryInfo.subscribeKeepProgress); + g_queryInfo.superQueryInfo.subscribeKeepProgress); } printf("sqlCount: \033[33m%d\033[0m\n", - g_queryInfo.superQueryInfo.sqlCount); + 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]); + i, g_queryInfo.superQueryInfo.sql[i]); } printf("\n"); @@ -1564,7 +1691,7 @@ static char* formatTimestamp(char* buf, int64_t val, int precision) { } static void xDumpFieldToFile(FILE* fp, const char* val, - TAOS_FIELD* field, int32_t length, int precision) { + TAOS_FIELD* field, int32_t length, int precision) { if (val == NULL) { fprintf(fp, "%s", TSDB_DATA_NULL_STR); @@ -1671,7 +1798,7 @@ static int getDbFromServer(TAOS * taos, SDbInfo** dbInfos) { 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) { + fields[TSDB_SHOW_DB_NAME_INDEX].bytes) == 0) { continue; } @@ -1682,10 +1809,10 @@ static int getDbFromServer(TAOS * taos, SDbInfo** dbInfos) { } tstrncpy(dbInfos[count]->name, (char *)row[TSDB_SHOW_DB_NAME_INDEX], - fields[TSDB_SHOW_DB_NAME_INDEX].bytes); + fields[TSDB_SHOW_DB_NAME_INDEX].bytes); formatTimestamp(dbInfos[count]->create_time, - *(int64_t*)row[TSDB_SHOW_DB_CREATED_TIME_INDEX], - TSDB_TIME_PRECISION_MILLI); + *(int64_t*)row[TSDB_SHOW_DB_CREATED_TIME_INDEX], + TSDB_TIME_PRECISION_MILLI); dbInfos[count]->ntables = *((int32_t *)row[TSDB_SHOW_DB_NTABLES_INDEX]); dbInfos[count]->vgroups = *((int32_t *)row[TSDB_SHOW_DB_VGROUPS_INDEX]); dbInfos[count]->replica = *((int16_t *)row[TSDB_SHOW_DB_REPLICA_INDEX]); @@ -1693,7 +1820,7 @@ static int getDbFromServer(TAOS * taos, SDbInfo** dbInfos) { dbInfos[count]->days = *((int16_t *)row[TSDB_SHOW_DB_DAYS_INDEX]); tstrncpy(dbInfos[count]->keeplist, (char *)row[TSDB_SHOW_DB_KEEP_INDEX], - fields[TSDB_SHOW_DB_KEEP_INDEX].bytes); + fields[TSDB_SHOW_DB_KEEP_INDEX].bytes); dbInfos[count]->cache = *((int32_t *)row[TSDB_SHOW_DB_CACHE_INDEX]); dbInfos[count]->blocks = *((int32_t *)row[TSDB_SHOW_DB_BLOCKS_INDEX]); dbInfos[count]->minrows = *((int32_t *)row[TSDB_SHOW_DB_MINROWS_INDEX]); @@ -1702,19 +1829,19 @@ static int getDbFromServer(TAOS * taos, SDbInfo** dbInfos) { 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])); + (int8_t)(*((int8_t *)row[TSDB_SHOW_DB_CACHELAST_INDEX])); tstrncpy(dbInfos[count]->precision, - (char *)row[TSDB_SHOW_DB_PRECISION_INDEX], - fields[TSDB_SHOW_DB_PRECISION_INDEX].bytes); + (char *)row[TSDB_SHOW_DB_PRECISION_INDEX], + fields[TSDB_SHOW_DB_PRECISION_INDEX].bytes); dbInfos[count]->update = *((int8_t *)row[TSDB_SHOW_DB_UPDATE_INDEX]); tstrncpy(dbInfos[count]->status, (char *)row[TSDB_SHOW_DB_STATUS_INDEX], - fields[TSDB_SHOW_DB_STATUS_INDEX].bytes); + fields[TSDB_SHOW_DB_STATUS_INDEX].bytes); count++; if (count > MAX_DATABASE_COUNT) { errorPrint("%s() LN%d, The database count overflow than %d\n", - __func__, __LINE__, MAX_DATABASE_COUNT); + __func__, __LINE__, MAX_DATABASE_COUNT); break; } } @@ -1723,10 +1850,10 @@ static int getDbFromServer(TAOS * taos, SDbInfo** dbInfos) { } static void printfDbInfoForQueryToFile( - char* filename, SDbInfo* dbInfos, int index) { + char* filename, SDbInfo* dbInfos, int index) { if (filename[0] == 0) - return; + return; FILE *fp = fopen(filename, "at"); if (fp == NULL) { @@ -1769,8 +1896,8 @@ static void printfQuerySystemInfo(TAOS * taos) { time(&t); lt = localtime(&t); snprintf(filename, MAX_QUERY_SQL_LENGTH, "querySystemInfo-%d-%d-%d %d:%d:%d", - lt->tm_year+1900, lt->tm_mon, lt->tm_mday, lt->tm_hour, lt->tm_min, - lt->tm_sec); + lt->tm_year+1900, lt->tm_mon, lt->tm_mday, lt->tm_hour, lt->tm_min, + lt->tm_sec); // show variables res = taos_query(taos, "show variables;"); @@ -1791,8 +1918,8 @@ static void printfQuerySystemInfo(TAOS * taos) { } int dbCount = getDbFromServer(taos, dbInfos); if (dbCount <= 0) { - free(dbInfos); - return; + free(dbInfos); + return; } for (int i = 0; i < dbCount; i++) { @@ -1817,182 +1944,184 @@ static void printfQuerySystemInfo(TAOS * taos) { static int postProceSql(char* host, uint16_t port, char* sqlstr) { - char *req_fmt = "POST %s HTTP/1.1\r\nHost: %s:%d\r\nAccept: */*\r\nAuthorization: Basic %s\r\nContent-Length: %d\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\n%s"; + char *req_fmt = "POST %s HTTP/1.1\r\nHost: %s:%d\r\nAccept: */*\r\nAuthorization: Basic %s\r\nContent-Length: %d\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\n%s"; - char *url = "/rest/sql"; + char *url = "/rest/sql"; - struct hostent *server; - struct sockaddr_in serv_addr; - int bytes, sent, received, req_str_len, resp_len; - char *request_buf; - char response_buf[RESP_BUF_LEN]; - uint16_t rest_port = port + TSDB_PORT_HTTP; + struct hostent *server; + struct sockaddr_in serv_addr; + int bytes, sent, received, req_str_len, resp_len; + char *request_buf; + char response_buf[RESP_BUF_LEN]; + uint16_t rest_port = port + TSDB_PORT_HTTP; - int req_buf_len = strlen(sqlstr) + REQ_EXTRA_BUF_LEN; + int req_buf_len = strlen(sqlstr) + REQ_EXTRA_BUF_LEN; - request_buf = malloc(req_buf_len); - if (NULL == request_buf) - ERROR_EXIT("ERROR, cannot allocate memory."); + request_buf = malloc(req_buf_len); + if (NULL == request_buf) { + errorPrint("%s", "ERROR, cannot allocate memory.\n"); + exit(EXIT_FAILURE); + } - char userpass_buf[INPUT_BUF_LEN]; - int mod_table[] = {0, 2, 1}; + char userpass_buf[INPUT_BUF_LEN]; + int mod_table[] = {0, 2, 1}; - static char base64[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '+', '/'}; + static char base64[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '+', '/'}; - snprintf(userpass_buf, INPUT_BUF_LEN, "%s:%s", - g_Dbs.user, g_Dbs.password); - size_t userpass_buf_len = strlen(userpass_buf); - size_t encoded_len = 4 * ((userpass_buf_len +2) / 3); + snprintf(userpass_buf, INPUT_BUF_LEN, "%s:%s", + g_Dbs.user, g_Dbs.password); + size_t userpass_buf_len = strlen(userpass_buf); + size_t encoded_len = 4 * ((userpass_buf_len +2) / 3); - char base64_buf[INPUT_BUF_LEN]; + char base64_buf[INPUT_BUF_LEN]; #ifdef WINDOWS - WSADATA wsaData; + WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); SOCKET sockfd; #else - int sockfd; + int sockfd; #endif - sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (sockfd < 0) { + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) { #ifdef WINDOWS - errorPrint( "Could not create socket : %d" , WSAGetLastError()); + errorPrint( "Could not create socket : %d" , WSAGetLastError()); #endif - debugPrint("%s() LN%d, sockfd=%d\n", __func__, __LINE__, sockfd); - free(request_buf); - ERROR_EXIT("ERROR opening socket"); - } - - server = gethostbyname(host); - if (server == NULL) { - free(request_buf); - ERROR_EXIT("ERROR, no such host"); - } - - debugPrint("h_name: %s\nh_addretype: %s\nh_length: %d\n", - server->h_name, - (server->h_addrtype == AF_INET)?"ipv4":"ipv6", - server->h_length); - - memset(&serv_addr, 0, sizeof(serv_addr)); - serv_addr.sin_family = AF_INET; - serv_addr.sin_port = htons(rest_port); -#ifdef WINDOWS - serv_addr.sin_addr.s_addr = inet_addr(host); -#else - memcpy(&serv_addr.sin_addr.s_addr,server->h_addr,server->h_length); -#endif - - int retConn = connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)); - debugPrint("%s() LN%d connect() return %d\n", __func__, __LINE__, retConn); - if (retConn < 0) { - free(request_buf); - ERROR_EXIT("ERROR connecting"); - } - - memset(base64_buf, 0, INPUT_BUF_LEN); - - for (int n = 0, m = 0; n < userpass_buf_len;) { - uint32_t oct_a = n < userpass_buf_len ? - (unsigned char) userpass_buf[n++]:0; - uint32_t oct_b = n < userpass_buf_len ? - (unsigned char) userpass_buf[n++]:0; - uint32_t oct_c = n < userpass_buf_len ? - (unsigned char) userpass_buf[n++]:0; - uint32_t triple = (oct_a << 0x10) + (oct_b << 0x08) + oct_c; - - base64_buf[m++] = base64[(triple >> 3* 6) & 0x3f]; - base64_buf[m++] = base64[(triple >> 2* 6) & 0x3f]; - base64_buf[m++] = base64[(triple >> 1* 6) & 0x3f]; - base64_buf[m++] = base64[(triple >> 0* 6) & 0x3f]; - } - - for (int l = 0; l < mod_table[userpass_buf_len % 3]; l++) - base64_buf[encoded_len - 1 - l] = '='; - - debugPrint("%s() LN%d: auth string base64 encoded: %s\n", - __func__, __LINE__, base64_buf); - char *auth = base64_buf; - - int r = snprintf(request_buf, - req_buf_len, - req_fmt, url, host, rest_port, - auth, strlen(sqlstr), sqlstr); - if (r >= req_buf_len) { - free(request_buf); - ERROR_EXIT("ERROR too long request"); - } - verbosePrint("%s() LN%d: Request:\n%s\n", __func__, __LINE__, request_buf); - - req_str_len = strlen(request_buf); - sent = 0; - do { -#ifdef WINDOWS - bytes = send(sockfd, request_buf + sent, req_str_len - sent, 0); -#else - bytes = write(sockfd, request_buf + sent, req_str_len - sent); -#endif - if (bytes < 0) - ERROR_EXIT("ERROR writing message to socket"); - if (bytes == 0) - break; - sent+=bytes; - } while(sent < req_str_len); - - memset(response_buf, 0, RESP_BUF_LEN); - resp_len = sizeof(response_buf) - 1; - received = 0; - do { -#ifdef WINDOWS - bytes = recv(sockfd, response_buf + received, resp_len - received, 0); -#else - bytes = read(sockfd, response_buf + received, resp_len - received); -#endif - if (bytes < 0) { - free(request_buf); - ERROR_EXIT("ERROR reading response from socket"); - } - if (bytes == 0) - break; - received += bytes; - } while(received < resp_len); - - if (received == resp_len) { - free(request_buf); - ERROR_EXIT("ERROR storing complete response from socket"); - } - - response_buf[RESP_BUF_LEN - 1] = '\0'; - printf("Response:\n%s\n", response_buf); - + debugPrint("%s() LN%d, sockfd=%d\n", __func__, __LINE__, sockfd); free(request_buf); + ERROR_EXIT("ERROR opening socket"); + } + + server = gethostbyname(host); + if (server == NULL) { + free(request_buf); + ERROR_EXIT("ERROR, no such host"); + } + + debugPrint("h_name: %s\nh_addretype: %s\nh_length: %d\n", + server->h_name, + (server->h_addrtype == AF_INET)?"ipv4":"ipv6", + server->h_length); + + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons(rest_port); #ifdef WINDOWS - closesocket(sockfd); + serv_addr.sin_addr.s_addr = inet_addr(host); +#else + memcpy(&serv_addr.sin_addr.s_addr,server->h_addr,server->h_length); +#endif + + int retConn = connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)); + debugPrint("%s() LN%d connect() return %d\n", __func__, __LINE__, retConn); + if (retConn < 0) { + free(request_buf); + ERROR_EXIT("ERROR connecting"); + } + + memset(base64_buf, 0, INPUT_BUF_LEN); + + for (int n = 0, m = 0; n < userpass_buf_len;) { + uint32_t oct_a = n < userpass_buf_len ? + (unsigned char) userpass_buf[n++]:0; + uint32_t oct_b = n < userpass_buf_len ? + (unsigned char) userpass_buf[n++]:0; + uint32_t oct_c = n < userpass_buf_len ? + (unsigned char) userpass_buf[n++]:0; + uint32_t triple = (oct_a << 0x10) + (oct_b << 0x08) + oct_c; + + base64_buf[m++] = base64[(triple >> 3* 6) & 0x3f]; + base64_buf[m++] = base64[(triple >> 2* 6) & 0x3f]; + base64_buf[m++] = base64[(triple >> 1* 6) & 0x3f]; + base64_buf[m++] = base64[(triple >> 0* 6) & 0x3f]; + } + + for (int l = 0; l < mod_table[userpass_buf_len % 3]; l++) + base64_buf[encoded_len - 1 - l] = '='; + + debugPrint("%s() LN%d: auth string base64 encoded: %s\n", + __func__, __LINE__, base64_buf); + char *auth = base64_buf; + + int r = snprintf(request_buf, + req_buf_len, + req_fmt, url, host, rest_port, + auth, strlen(sqlstr), sqlstr); + if (r >= req_buf_len) { + free(request_buf); + ERROR_EXIT("ERROR too long request"); + } + verbosePrint("%s() LN%d: Request:\n%s\n", __func__, __LINE__, request_buf); + + req_str_len = strlen(request_buf); + sent = 0; + do { +#ifdef WINDOWS + bytes = send(sockfd, request_buf + sent, req_str_len - sent, 0); +#else + bytes = write(sockfd, request_buf + sent, req_str_len - sent); +#endif + if (bytes < 0) + ERROR_EXIT("ERROR writing message to socket"); + if (bytes == 0) + break; + sent+=bytes; + } while(sent < req_str_len); + + memset(response_buf, 0, RESP_BUF_LEN); + resp_len = sizeof(response_buf) - 1; + received = 0; + do { +#ifdef WINDOWS + bytes = recv(sockfd, response_buf + received, resp_len - received, 0); +#else + bytes = read(sockfd, response_buf + received, resp_len - received); +#endif + if (bytes < 0) { + free(request_buf); + ERROR_EXIT("ERROR reading response from socket"); + } + if (bytes == 0) + break; + received += bytes; + } while(received < resp_len); + + if (received == resp_len) { + free(request_buf); + ERROR_EXIT("ERROR storing complete response from socket"); + } + + response_buf[RESP_BUF_LEN - 1] = '\0'; + printf("Response:\n%s\n", response_buf); + + free(request_buf); +#ifdef WINDOWS + closesocket(sockfd); WSACleanup(); #else - close(sockfd); + close(sockfd); #endif - return 0; + return 0; } 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); + __func__, __LINE__, TSDB_MAX_SQL_LEN+1); return NULL; } int dataLen = 0; dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen, - "(%s)", stbInfo->tagDataBuf + stbInfo->lenOfTagOfOneRow * tagUsePos); + "(%s)", stbInfo->tagDataBuf + stbInfo->lenOfTagOfOneRow * tagUsePos); return dataBuf; } @@ -2008,10 +2137,10 @@ static char* generateTagVaulesForStb(SSuperTable* stbInfo, int32_t tableSeq) { dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen, "("); for (int i = 0; i < stbInfo->tagCount; i++) { if ((0 == strncasecmp(stbInfo->tags[i].dataType, "binary", strlen("binary"))) - || (0 == strncasecmp(stbInfo->tags[i].dataType, "nchar", strlen("nchar")))) { + || (0 == strncasecmp(stbInfo->tags[i].dataType, "nchar", strlen("nchar")))) { if (stbInfo->tags[i].dataLen > TSDB_MAX_BINARY_LEN) { printf("binary or nchar length overflow, max size:%u\n", - (uint32_t)TSDB_MAX_BINARY_LEN); + (uint32_t)TSDB_MAX_BINARY_LEN); tmfree(dataBuf); return NULL; } @@ -2031,40 +2160,40 @@ static char* generateTagVaulesForStb(SSuperTable* stbInfo, int32_t tableSeq) { } //rand_string(buf, stbInfo->tags[i].dataLen); dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen, - "\'%s\', ", buf); + "\'%s\', ", buf); tmfree(buf); } else if (0 == strncasecmp(stbInfo->tags[i].dataType, - "int", strlen("int"))) { + "int", strlen("int"))) { dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen, - "%d, ", tableSeq); + "%d, ", tableSeq); } else if (0 == strncasecmp(stbInfo->tags[i].dataType, - "bigint", strlen("bigint"))) { + "bigint", strlen("bigint"))) { dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen, - "%"PRId64", ", rand_bigint()); + "%"PRId64", ", rand_bigint()); } else if (0 == strncasecmp(stbInfo->tags[i].dataType, - "float", strlen("float"))) { + "float", strlen("float"))) { dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen, - "%f, ", rand_float()); + "%f, ", rand_float()); } else if (0 == strncasecmp(stbInfo->tags[i].dataType, - "double", strlen("double"))) { + "double", strlen("double"))) { dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen, - "%f, ", rand_double()); + "%f, ", rand_double()); } else if (0 == strncasecmp(stbInfo->tags[i].dataType, - "smallint", strlen("smallint"))) { + "smallint", strlen("smallint"))) { dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen, - "%d, ", rand_smallint()); + "%d, ", rand_smallint()); } else if (0 == strncasecmp(stbInfo->tags[i].dataType, - "tinyint", strlen("tinyint"))) { + "tinyint", strlen("tinyint"))) { dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen, - "%d, ", rand_tinyint()); + "%d, ", rand_tinyint()); } else if (0 == strncasecmp(stbInfo->tags[i].dataType, - "bool", strlen("bool"))) { + "bool", strlen("bool"))) { dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen, - "%d, ", rand_bool()); + "%d, ", rand_bool()); } else if (0 == strncasecmp(stbInfo->tags[i].dataType, - "timestamp", strlen("timestamp"))) { + "timestamp", strlen("timestamp"))) { dataLen += snprintf(dataBuf + dataLen, TSDB_MAX_SQL_LEN - dataLen, - "%"PRId64", ", rand_bigint()); + "%"PRId64", ", rand_bigint()); } else { printf("No support data type: %s\n", stbInfo->tags[i].dataType); tmfree(dataBuf); @@ -2148,8 +2277,8 @@ static int calcRowLen(SSuperTable* superTbls) { static int getChildNameOfSuperTableWithLimitAndOffset(TAOS * taos, - char* dbName, char* sTblName, char** childTblNameOfSuperTbl, - int* childTblCountOfSuperTbl, int limit, int offset) { + char* dbName, char* sTblName, char** childTblNameOfSuperTbl, + int* childTblCountOfSuperTbl, int limit, int offset) { char command[BUFFER_SIZE] = "\0"; char limitBuf[100] = "\0"; @@ -2165,7 +2294,7 @@ static int getChildNameOfSuperTableWithLimitAndOffset(TAOS * taos, //get all child table name use cmd: select tbname from superTblName; snprintf(command, BUFFER_SIZE, "select tbname from %s.%s %s", - dbName, sTblName, limitBuf); + dbName, sTblName, limitBuf); res = taos_query(taos, command); int32_t code = taos_errno(res); @@ -2173,7 +2302,7 @@ static int getChildNameOfSuperTableWithLimitAndOffset(TAOS * taos, taos_free_result(res); taos_close(taos); errorPrint("%s() LN%d, failed to run command %s\n", - __func__, __LINE__, command); + __func__, __LINE__, command); exit(-1); } @@ -2182,10 +2311,10 @@ static int getChildNameOfSuperTableWithLimitAndOffset(TAOS * taos, if (childTblName == NULL) { childTblName = (char*)calloc(1, childTblCount * TSDB_TABLE_NAME_LEN); if (NULL == childTblName) { - taos_free_result(res); - taos_close(taos); - errorPrint("%s() LN%d, failed to allocate memory!\n", __func__, __LINE__); - exit(-1); + taos_free_result(res); + taos_close(taos); + errorPrint("%s() LN%d, failed to allocate memory!\n", __func__, __LINE__); + exit(-1); } } @@ -2197,16 +2326,16 @@ static int getChildNameOfSuperTableWithLimitAndOffset(TAOS * taos, count++; if (count >= childTblCount - 1) { char *tmp = realloc(childTblName, - (size_t)childTblCount*1.5*TSDB_TABLE_NAME_LEN+1); + (size_t)childTblCount*1.5*TSDB_TABLE_NAME_LEN+1); if (tmp != NULL) { childTblName = tmp; childTblCount = (int)(childTblCount*1.5); memset(childTblName + count*TSDB_TABLE_NAME_LEN, 0, - (size_t)((childTblCount-count)*TSDB_TABLE_NAME_LEN)); + (size_t)((childTblCount-count)*TSDB_TABLE_NAME_LEN)); } else { // exit, if allocate more memory failed errorPrint("%s() LN%d, realloc fail for save child table name of %s.%s\n", - __func__, __LINE__, dbName, sTblName); + __func__, __LINE__, dbName, sTblName); tmfree(childTblName); taos_free_result(res); taos_close(taos); @@ -2224,16 +2353,16 @@ static int getChildNameOfSuperTableWithLimitAndOffset(TAOS * taos, } static int getAllChildNameOfSuperTable(TAOS * taos, char* dbName, - char* sTblName, char** childTblNameOfSuperTbl, - int* childTblCountOfSuperTbl) { + char* sTblName, char** childTblNameOfSuperTbl, + int* childTblCountOfSuperTbl) { - return getChildNameOfSuperTableWithLimitAndOffset(taos, dbName, sTblName, - childTblNameOfSuperTbl, childTblCountOfSuperTbl, - -1, -1); + return getChildNameOfSuperTableWithLimitAndOffset(taos, dbName, sTblName, + childTblNameOfSuperTbl, childTblCountOfSuperTbl, + -1, -1); } static int getSuperTableFromServer(TAOS * taos, char* dbName, - SSuperTable* superTbls) { + SSuperTable* superTbls) { char command[BUFFER_SIZE] = "\0"; TAOS_RES * res; @@ -2261,29 +2390,29 @@ static int getSuperTableFromServer(TAOS * taos, char* dbName, if (strcmp((char *)row[TSDB_DESCRIBE_METRIC_NOTE_INDEX], "TAG") == 0) { tstrncpy(superTbls->tags[tagIndex].field, - (char *)row[TSDB_DESCRIBE_METRIC_FIELD_INDEX], - fields[TSDB_DESCRIBE_METRIC_FIELD_INDEX].bytes); + (char *)row[TSDB_DESCRIBE_METRIC_FIELD_INDEX], + fields[TSDB_DESCRIBE_METRIC_FIELD_INDEX].bytes); tstrncpy(superTbls->tags[tagIndex].dataType, - (char *)row[TSDB_DESCRIBE_METRIC_TYPE_INDEX], - fields[TSDB_DESCRIBE_METRIC_TYPE_INDEX].bytes); + (char *)row[TSDB_DESCRIBE_METRIC_TYPE_INDEX], + fields[TSDB_DESCRIBE_METRIC_TYPE_INDEX].bytes); superTbls->tags[tagIndex].dataLen = *((int *)row[TSDB_DESCRIBE_METRIC_LENGTH_INDEX]); tstrncpy(superTbls->tags[tagIndex].note, - (char *)row[TSDB_DESCRIBE_METRIC_NOTE_INDEX], - fields[TSDB_DESCRIBE_METRIC_NOTE_INDEX].bytes); + (char *)row[TSDB_DESCRIBE_METRIC_NOTE_INDEX], + fields[TSDB_DESCRIBE_METRIC_NOTE_INDEX].bytes); tagIndex++; } else { tstrncpy(superTbls->columns[columnIndex].field, - (char *)row[TSDB_DESCRIBE_METRIC_FIELD_INDEX], - fields[TSDB_DESCRIBE_METRIC_FIELD_INDEX].bytes); + (char *)row[TSDB_DESCRIBE_METRIC_FIELD_INDEX], + fields[TSDB_DESCRIBE_METRIC_FIELD_INDEX].bytes); tstrncpy(superTbls->columns[columnIndex].dataType, - (char *)row[TSDB_DESCRIBE_METRIC_TYPE_INDEX], - fields[TSDB_DESCRIBE_METRIC_TYPE_INDEX].bytes); + (char *)row[TSDB_DESCRIBE_METRIC_TYPE_INDEX], + fields[TSDB_DESCRIBE_METRIC_TYPE_INDEX].bytes); superTbls->columns[columnIndex].dataLen = *((int *)row[TSDB_DESCRIBE_METRIC_LENGTH_INDEX]); tstrncpy(superTbls->columns[columnIndex].note, - (char *)row[TSDB_DESCRIBE_METRIC_NOTE_INDEX], - fields[TSDB_DESCRIBE_METRIC_NOTE_INDEX].bytes); + (char *)row[TSDB_DESCRIBE_METRIC_NOTE_INDEX], + fields[TSDB_DESCRIBE_METRIC_NOTE_INDEX].bytes); columnIndex++; } count++; @@ -2313,8 +2442,10 @@ static int getSuperTableFromServer(TAOS * taos, char* dbName, return 0; } -static int createSuperTable(TAOS * taos, char* dbName, - SSuperTable* superTbl) { +static int createSuperTable( + TAOS * taos, char* dbName, + SSuperTable* superTbl) { + char command[BUFFER_SIZE] = "\0"; char cols[STRING_LEN] = "\0"; @@ -2325,7 +2456,7 @@ static int createSuperTable(TAOS * taos, char* dbName, if (superTbl->columnCount == 0) { errorPrint("%s() LN%d, super table column count is %d\n", - __func__, __LINE__, superTbl->columnCount); + __func__, __LINE__, superTbl->columnCount); return -1; } @@ -2334,13 +2465,13 @@ static int createSuperTable(TAOS * taos, char* dbName, if (strcasecmp(dataType, "BINARY") == 0) { len += snprintf(cols + len, STRING_LEN - len, - ", col%d %s(%d)", colIndex, "BINARY", - superTbl->columns[colIndex].dataLen); + ", col%d %s(%d)", colIndex, "BINARY", + 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", - superTbl->columns[colIndex].dataLen); + ", col%d %s(%d)", colIndex, "NCHAR", + 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"); @@ -2369,7 +2500,7 @@ static int createSuperTable(TAOS * taos, char* dbName, } else { taos_close(taos); errorPrint("%s() LN%d, config error data type : %s\n", - __func__, __LINE__, dataType); + __func__, __LINE__, dataType); exit(-1); } } @@ -2381,18 +2512,18 @@ static int createSuperTable(TAOS * taos, char* dbName, superTbl->colsOfCreateChildTable = (char*)calloc(len+20, 1); if (NULL == superTbl->colsOfCreateChildTable) { errorPrint("%s() LN%d, Failed when calloc, size:%d", - __func__, __LINE__, len+1); + __func__, __LINE__, len+1); taos_close(taos); exit(-1); } snprintf(superTbl->colsOfCreateChildTable, len+20, "(ts timestamp%s)", cols); verbosePrint("%s() LN%d: %s\n", - __func__, __LINE__, superTbl->colsOfCreateChildTable); + __func__, __LINE__, superTbl->colsOfCreateChildTable); if (superTbl->tagCount == 0) { errorPrint("%s() LN%d, super table tag count is %d\n", - __func__, __LINE__, superTbl->tagCount); + __func__, __LINE__, superTbl->tagCount); return -1; } @@ -2407,44 +2538,44 @@ static int createSuperTable(TAOS * taos, char* dbName, if (strcasecmp(dataType, "BINARY") == 0) { len += snprintf(tags + len, STRING_LEN - len, "t%d %s(%d), ", tagIndex, - "BINARY", superTbl->tags[tagIndex].dataLen); + "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); + "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"); + "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"); + "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"); + "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"); + "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"); + "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"); + "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"); + "DOUBLE"); lenOfTagOfOneRow += superTbl->tags[tagIndex].dataLen + 42; } else { taos_close(taos); errorPrint("%s() LN%d, config error tag type : %s\n", - __func__, __LINE__, dataType); + __func__, __LINE__, dataType); exit(-1); } } @@ -2455,14 +2586,14 @@ static int createSuperTable(TAOS * taos, char* dbName, superTbl->lenOfTagOfOneRow = lenOfTagOfOneRow; snprintf(command, BUFFER_SIZE, - "create table if not exists %s.%s (ts timestamp%s) tags %s", - dbName, superTbl->sTblName, cols, tags); + "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; + errorPrint( "create supertable %s failed!\n\n", + superTbl->sTblName); + return -1; } debugPrint("create supertable %s success!\n\n", superTbl->sTblName); return 0; @@ -2489,35 +2620,35 @@ static int createDatabasesAndStables() { int dataLen = 0; dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, "create database if not exists %s", g_Dbs.db[i].dbName); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + BUFFER_SIZE - dataLen, " update %d", g_Dbs.db[i].dbCfg.update); } //if (g_Dbs.db[i].dbCfg.maxtablesPerVnode > 0) { // dataLen += snprintf(command + dataLen, @@ -2525,33 +2656,33 @@ static int createDatabasesAndStables() { //} if (g_Dbs.db[i].dbCfg.minRows > 0) { dataLen += snprintf(command + dataLen, - BUFFER_SIZE - dataLen, " minrows %d", g_Dbs.db[i].dbCfg.minRows); + 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); + 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); + 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); + 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); + 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); + " 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")))) { + || (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); + " precision \'%s\';", g_Dbs.db[i].dbCfg.precision); } debugPrint("%s() %d command: %s\n", __func__, __LINE__, command); @@ -2564,7 +2695,7 @@ static int createDatabasesAndStables() { } debugPrint("%s() %d supertbl count:%d\n", - __func__, __LINE__, g_Dbs.db[i].superTblCount); + __func__, __LINE__, g_Dbs.db[i].superTblCount); int validStbCount = 0; @@ -2577,7 +2708,7 @@ static int createDatabasesAndStables() { if ((ret != 0) || (g_Dbs.db[i].drop)) { ret = createSuperTable(taos, g_Dbs.db[i].dbName, - &g_Dbs.db[i].superTbls[j]); + &g_Dbs.db[i].superTbls[j]); if (0 != ret) { errorPrint("create super table %d failed!\n\n", j); @@ -2586,10 +2717,10 @@ static int createDatabasesAndStables() { } ret = getSuperTableFromServer(taos, g_Dbs.db[i].dbName, - &g_Dbs.db[i].superTbls[j]); + &g_Dbs.db[i].superTbls[j]); 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); + g_Dbs.db[i].dbName, g_Dbs.db[i].superTbls[j].sTblName); continue; } @@ -2623,20 +2754,20 @@ static void* createTable(void *sarg) int batchNum = 0; verbosePrint("%s() LN%d: Creating table from %d to %d\n", - __func__, __LINE__, - pThreadInfo->start_table_from, pThreadInfo->end_table_to); + __func__, __LINE__, + pThreadInfo->start_table_from, pThreadInfo->end_table_to); 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;", - pThreadInfo->db_name, - g_args.tb_prefix, i, - pThreadInfo->cols); + "create table if not exists %s.%s%d %s;", + pThreadInfo->db_name, + g_args.tb_prefix, i, + pThreadInfo->cols); } else { if (superTblInfo == NULL) { errorPrint("%s() LN%d, use metric, but super table info is NULL\n", - __func__, __LINE__); + __func__, __LINE__); free(buffer); exit(-1); } else { @@ -2644,31 +2775,31 @@ static void* createTable(void *sarg) batchNum = 0; memset(buffer, 0, buff_len); len += snprintf(buffer + len, - buff_len - len, "create table "); + buff_len - len, "create table "); } char* tagsValBuf = NULL; if (0 == superTblInfo->tagSource) { tagsValBuf = generateTagVaulesForStb(superTblInfo, i); } else { tagsValBuf = getTagValueFromTagSample( - superTblInfo, - i % superTblInfo->tagSampleCount); + superTblInfo, + i % superTblInfo->tagSampleCount); } if (NULL == tagsValBuf) { free(buffer); return NULL; } len += snprintf(buffer + len, - buff_len - len, - "if not exists %s.%s%d using %s.%s tags %s ", - pThreadInfo->db_name, superTblInfo->childTblPrefix, - i, pThreadInfo->db_name, - superTblInfo->sTblName, tagsValBuf); + buff_len - len, + "if not exists %s.%s%d using %s.%s tags %s ", + pThreadInfo->db_name, superTblInfo->childTblPrefix, + i, pThreadInfo->db_name, + superTblInfo->sTblName, tagsValBuf); free(tagsValBuf); batchNum++; if ((batchNum < superTblInfo->batchCreateTableNum) - && ((buff_len - len) - >= (superTblInfo->lenOfTagOfOneRow + 256))) { + && ((buff_len - len) + >= (superTblInfo->lenOfTagOfOneRow + 256))) { continue; } } @@ -2685,7 +2816,7 @@ static void* createTable(void *sarg) int64_t currentPrintTime = taosGetTimestampMs(); if (currentPrintTime - lastPrintTime > 30*1000) { printf("thread[%d] already create %d - %d tables\n", - pThreadInfo->threadID, pThreadInfo->start_table_from, i); + pThreadInfo->threadID, pThreadInfo->start_table_from, i); lastPrintTime = currentPrintTime; } } @@ -2702,8 +2833,8 @@ static void* createTable(void *sarg) } static int startMultiThreadCreateChildTable( - char* cols, int threads, int startFrom, int ntables, - char* db_name, SSuperTable* superTblInfo) { + char* cols, int threads, int startFrom, int ntables, + char* db_name, SSuperTable* superTblInfo) { pthread_t *pids = malloc(threads * sizeof(pthread_t)); threadInfo *infos = malloc(threads * sizeof(threadInfo)); @@ -2733,14 +2864,14 @@ static int startMultiThreadCreateChildTable( t_info->superTblInfo = superTblInfo; verbosePrint("%s() %d db_name: %s\n", __func__, __LINE__, db_name); t_info->taos = taos_connect( - g_Dbs.host, - g_Dbs.user, - g_Dbs.password, - db_name, - g_Dbs.port); + g_Dbs.host, + g_Dbs.user, + g_Dbs.password, + db_name, + g_Dbs.port); if (t_info->taos == NULL) { errorPrint( "%s() LN%d, Failed to connect to TDengine, reason:%s\n", - __func__, __LINE__, taos_errstr(NULL)); + __func__, __LINE__, taos_errstr(NULL)); free(pids); free(infos); return -1; @@ -2772,64 +2903,62 @@ static int startMultiThreadCreateChildTable( } static void createChildTables() { - char tblColsBuf[MAX_SQL_SIZE]; - int len; + char tblColsBuf[MAX_SQL_SIZE]; + int len; for (int i = 0; i < g_Dbs.dbCount; i++) { if (g_Dbs.use_metric) { if (g_Dbs.db[i].superTblCount > 0) { - // with super table + // 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)) { + || (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); + 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); + __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])); + 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++; + for (int j = 0; j < g_args.num_of_CPR; 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(%d)", j, g_args.datatype[j], g_args.len_of_binary); + } else { + snprintf(tblColsBuf + len, MAX_SQL_SIZE - len, + ", COL%d %s", j, g_args.datatype[j]); + } + len = strlen(tblColsBuf); } 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); + __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); + tblColsBuf, + g_Dbs.threadCountByCreateTbl, + 0, + g_args.num_of_tables, + g_Dbs.db[i].dbName, + NULL); } } } @@ -2845,7 +2974,7 @@ static int readTagFromCsvFileToMem(SSuperTable * superTblInfo) { FILE *fp = fopen(superTblInfo->tagsFile, "r"); if (fp == NULL) { printf("Failed to open tags file: %s, reason:%s\n", - superTblInfo->tagsFile, strerror(errno)); + superTblInfo->tagsFile, strerror(errno)); return -1; } @@ -2877,12 +3006,12 @@ static int readTagFromCsvFileToMem(SSuperTable * superTblInfo) { if (count >= tagCount - 1) { char *tmp = realloc(tagDataBuf, - (size_t)tagCount*1.5*superTblInfo->lenOfTagOfOneRow); + (size_t)tagCount*1.5*superTblInfo->lenOfTagOfOneRow); if (tmp != NULL) { tagDataBuf = tmp; tagCount = (int)(tagCount*1.5); memset(tagDataBuf + count*superTblInfo->lenOfTagOfOneRow, - 0, (size_t)((tagCount-count)*superTblInfo->lenOfTagOfOneRow)); + 0, (size_t)((tagCount-count)*superTblInfo->lenOfTagOfOneRow)); } else { // exit, if allocate more memory failed printf("realloc fail for save tag val from %s\n", superTblInfo->tagsFile); @@ -2911,7 +3040,7 @@ int readSampleFromJsonFileToMem(SSuperTable * superTblInfo) { Read 10000 lines at most. If more than 10000 lines, continue to read after using */ static int readSampleFromCsvFileToMem( - SSuperTable* superTblInfo) { + SSuperTable* superTblInfo) { size_t n = 0; ssize_t readLen = 0; char * line = NULL; @@ -2919,20 +3048,20 @@ static int readSampleFromCsvFileToMem( FILE* fp = fopen(superTblInfo->sampleFile, "r"); if (fp == NULL) { - errorPrint( "Failed to open sample file: %s, reason:%s\n", - superTblInfo->sampleFile, strerror(errno)); - return -1; + errorPrint( "Failed to open sample file: %s, reason:%s\n", + superTblInfo->sampleFile, strerror(errno)); + return -1; } assert(superTblInfo->sampleDataBuf); memset(superTblInfo->sampleDataBuf, 0, - MAX_SAMPLES_ONCE_FROM_FILE * superTblInfo->lenOfOneRow); + MAX_SAMPLES_ONCE_FROM_FILE * superTblInfo->lenOfOneRow); while(1) { readLen = tgetline(&line, &n, fp); if (-1 == readLen) { if(0 != fseek(fp, 0, SEEK_SET)) { errorPrint( "Failed to fseek file: %s, reason:%s\n", - superTblInfo->sampleFile, strerror(errno)); + superTblInfo->sampleFile, strerror(errno)); fclose(fp); return -1; } @@ -2949,12 +3078,12 @@ static int readSampleFromCsvFileToMem( if (readLen > superTblInfo->lenOfOneRow) { printf("sample row len[%d] overflow define schema len[%d], so discard this row\n", - (int32_t)readLen, superTblInfo->lenOfOneRow); + (int32_t)readLen, superTblInfo->lenOfOneRow); continue; } memcpy(superTblInfo->sampleDataBuf + getRows * superTblInfo->lenOfOneRow, - line, readLen); + line, readLen); getRows++; if (getRows == MAX_SAMPLES_ONCE_FROM_FILE) { @@ -2968,7 +3097,7 @@ static int readSampleFromCsvFileToMem( } static bool getColumnAndTagTypeFromInsertJsonFile( - cJSON* stbInfo, SSuperTable* superTbls) { + cJSON* stbInfo, SSuperTable* superTbls) { bool ret = false; // columns @@ -2985,7 +3114,7 @@ static bool getColumnAndTagTypeFromInsertJsonFile( int columnSize = cJSON_GetArraySize(columns); 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); + __func__, __LINE__, MAX_COLUMN_COUNT); goto PARSE_OVER; } @@ -3004,7 +3133,7 @@ static bool getColumnAndTagTypeFromInsertJsonFile( 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__); + __func__, __LINE__); goto PARSE_OVER; } else { count = 1; @@ -3016,7 +3145,7 @@ static bool getColumnAndTagTypeFromInsertJsonFile( if (!dataType || dataType->type != cJSON_String || dataType->valuestring == NULL) { errorPrint("%s() LN%d: failed to read json, column type not found\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } //tstrncpy(superTbls->columns[k].dataType, dataType->valuestring, MAX_TB_NAME_SIZE); @@ -3027,7 +3156,7 @@ static bool getColumnAndTagTypeFromInsertJsonFile( 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__); + __func__, __LINE__); goto PARSE_OVER; } else { columnCase.dataLen = 8; @@ -3035,7 +3164,7 @@ static bool getColumnAndTagTypeFromInsertJsonFile( for (int n = 0; n < count; ++n) { tstrncpy(superTbls->columns[index].dataType, - columnCase.dataType, MAX_TB_NAME_SIZE); + columnCase.dataType, MAX_TB_NAME_SIZE); superTbls->columns[index].dataLen = columnCase.dataLen; index++; } @@ -3043,7 +3172,7 @@ static bool getColumnAndTagTypeFromInsertJsonFile( 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); + __func__, __LINE__, MAX_COLUMN_COUNT); goto PARSE_OVER; } @@ -3055,14 +3184,14 @@ static bool getColumnAndTagTypeFromInsertJsonFile( cJSON *tags = cJSON_GetObjectItem(stbInfo, "tags"); if (!tags || tags->type != cJSON_Array) { errorPrint("%s() LN%d, failed to read json, tags not found\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } int tagSize = cJSON_GetArraySize(tags); if (tagSize > 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); + __func__, __LINE__, MAX_TAG_COUNT); goto PARSE_OVER; } @@ -3088,7 +3217,7 @@ static bool getColumnAndTagTypeFromInsertJsonFile( if (!dataType || dataType->type != cJSON_String || dataType->valuestring == NULL) { errorPrint("%s() LN%d, failed to read json, tag type not found\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } tstrncpy(columnCase.dataType, dataType->valuestring, MAX_TB_NAME_SIZE); @@ -3098,7 +3227,7 @@ static bool getColumnAndTagTypeFromInsertJsonFile( columnCase.dataLen = dataLen->valueint; } else if (dataLen && dataLen->type != cJSON_Number) { errorPrint("%s() LN%d, failed to read json, column len not found\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } else { columnCase.dataLen = 0; @@ -3106,7 +3235,7 @@ static bool getColumnAndTagTypeFromInsertJsonFile( for (int n = 0; n < count; ++n) { tstrncpy(superTbls->tags[index].dataType, columnCase.dataType, - MAX_TB_NAME_SIZE); + MAX_TB_NAME_SIZE); superTbls->tags[index].dataLen = columnCase.dataLen; index++; } @@ -3114,7 +3243,7 @@ static bool getColumnAndTagTypeFromInsertJsonFile( 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); + __func__, __LINE__, MAX_TAG_COUNT); goto PARSE_OVER; } @@ -3122,12 +3251,12 @@ static bool getColumnAndTagTypeFromInsertJsonFile( 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); + __func__, __LINE__, MAX_COLUMN_COUNT); goto PARSE_OVER; } ret = true; -PARSE_OVER: + PARSE_OVER: return ret; } @@ -3194,7 +3323,7 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { g_Dbs.threadCountByCreateTbl = g_args.num_of_threads; } else { errorPrint("%s() LN%d, failed to read json, threads2 not found\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } @@ -3205,7 +3334,7 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { g_args.insert_interval = 0; } else { errorPrint("%s() LN%d, failed to read json, insert_interval input mistake\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } @@ -3216,9 +3345,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_req %d\n\n", - g_args.interlace_rows, g_args.num_of_RPR); + g_args.interlace_rows, g_args.num_of_RPR); printf(" interlace rows value will be set to num_of_records_per_req %d\n\n", - g_args.num_of_RPR); + g_args.num_of_RPR); printf(" press Enter key to continue or Ctrl-C to stop."); (void)getchar(); g_args.interlace_rows = g_args.num_of_RPR; @@ -3227,7 +3356,7 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { 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__); + __func__, __LINE__); goto PARSE_OVER; } @@ -3235,10 +3364,10 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { if (maxSqlLen && maxSqlLen->type == cJSON_Number) { g_args.max_sql_len = maxSqlLen->valueint; } else if (!maxSqlLen) { - g_args.max_sql_len = TSDB_PAYLOAD_SIZE; + g_args.max_sql_len = 1024000; } else { errorPrint("%s() LN%d, failed to read json, max_sql_len input mistake\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } @@ -3249,14 +3378,14 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { 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__); + __func__, __LINE__); goto PARSE_OVER; } cJSON *answerPrompt = cJSON_GetObjectItem(root, "confirm_parameter_prompt"); // yes, no, if (answerPrompt - && answerPrompt->type == cJSON_String - && answerPrompt->valuestring != NULL) { + && answerPrompt->type == cJSON_String + && answerPrompt->valuestring != NULL) { if (0 == strncasecmp(answerPrompt->valuestring, "yes", 3)) { g_args.answer_yes = false; } else if (0 == strncasecmp(answerPrompt->valuestring, "no", 2)) { @@ -3280,8 +3409,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { int dbSize = cJSON_GetArraySize(dbs); if (dbSize > MAX_DB_COUNT) { errorPrint( - "ERROR: failed to read json, databases size overflow, max database is %d\n", - MAX_DB_COUNT); + "ERROR: failed to read json, databases size overflow, max database is %d\n", + MAX_DB_COUNT); goto PARSE_OVER; } @@ -3315,15 +3444,15 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { g_Dbs.db[i].drop = g_args.drop_database; } else { errorPrint("%s() LN%d, failed to read json, drop input mistake\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } cJSON *precision = cJSON_GetObjectItem(dbinfo, "precision"); if (precision && precision->type == cJSON_String - && precision->valuestring != NULL) { + && precision->valuestring != NULL) { tstrncpy(g_Dbs.db[i].dbCfg.precision, precision->valuestring, - MAX_DB_NAME_SIZE); + MAX_DB_NAME_SIZE); } else if (!precision) { //tstrncpy(g_Dbs.db[i].dbCfg.precision, "ms", MAX_DB_NAME_SIZE); memset(g_Dbs.db[i].dbCfg.precision, 0, MAX_DB_NAME_SIZE); @@ -3358,8 +3487,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { } else if (!keep) { g_Dbs.db[i].dbCfg.keep = -1; } else { - printf("ERROR: failed to read json, keep not found\n"); - goto PARSE_OVER; + printf("ERROR: failed to read json, keep not found\n"); + goto PARSE_OVER; } cJSON* days = cJSON_GetObjectItem(dbinfo, "days"); @@ -3368,8 +3497,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { } else if (!days) { g_Dbs.db[i].dbCfg.days = -1; } else { - printf("ERROR: failed to read json, days not found\n"); - goto PARSE_OVER; + printf("ERROR: failed to read json, days not found\n"); + goto PARSE_OVER; } cJSON* cache = cJSON_GetObjectItem(dbinfo, "cache"); @@ -3378,8 +3507,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { } else if (!cache) { g_Dbs.db[i].dbCfg.cache = -1; } else { - printf("ERROR: failed to read json, cache not found\n"); - goto PARSE_OVER; + printf("ERROR: failed to read json, cache not found\n"); + goto PARSE_OVER; } cJSON* blocks= cJSON_GetObjectItem(dbinfo, "blocks"); @@ -3388,8 +3517,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { } else if (!blocks) { g_Dbs.db[i].dbCfg.blocks = -1; } else { - printf("ERROR: failed to read json, block not found\n"); - goto PARSE_OVER; + printf("ERROR: failed to read json, block not found\n"); + goto PARSE_OVER; } //cJSON* maxtablesPerVnode= cJSON_GetObjectItem(dbinfo, "maxtablesPerVnode"); @@ -3408,8 +3537,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { } else if (!minRows) { g_Dbs.db[i].dbCfg.minRows = -1; } else { - printf("ERROR: failed to read json, minRows not found\n"); - goto PARSE_OVER; + printf("ERROR: failed to read json, minRows not found\n"); + goto PARSE_OVER; } cJSON* maxRows= cJSON_GetObjectItem(dbinfo, "maxRows"); @@ -3418,8 +3547,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { } else if (!maxRows) { g_Dbs.db[i].dbCfg.maxRows = -1; } else { - printf("ERROR: failed to read json, maxRows not found\n"); - goto PARSE_OVER; + printf("ERROR: failed to read json, maxRows not found\n"); + goto PARSE_OVER; } cJSON* comp= cJSON_GetObjectItem(dbinfo, "comp"); @@ -3428,8 +3557,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { } else if (!comp) { g_Dbs.db[i].dbCfg.comp = -1; } else { - printf("ERROR: failed to read json, comp not found\n"); - goto PARSE_OVER; + printf("ERROR: failed to read json, comp not found\n"); + goto PARSE_OVER; } cJSON* walLevel= cJSON_GetObjectItem(dbinfo, "walLevel"); @@ -3438,8 +3567,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { } else if (!walLevel) { g_Dbs.db[i].dbCfg.walLevel = -1; } else { - printf("ERROR: failed to read json, walLevel not found\n"); - goto PARSE_OVER; + printf("ERROR: failed to read json, walLevel not found\n"); + goto PARSE_OVER; } cJSON* cacheLast= cJSON_GetObjectItem(dbinfo, "cachelast"); @@ -3448,8 +3577,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { } else if (!cacheLast) { g_Dbs.db[i].dbCfg.cacheLast = -1; } else { - printf("ERROR: failed to read json, cacheLast not found\n"); - goto PARSE_OVER; + printf("ERROR: failed to read json, cacheLast not found\n"); + goto PARSE_OVER; } cJSON* quorum= cJSON_GetObjectItem(dbinfo, "quorum"); @@ -3458,8 +3587,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { } else if (!quorum) { g_Dbs.db[i].dbCfg.quorum = 1; } else { - printf("failed to read json, quorum input mistake"); - goto PARSE_OVER; + printf("failed to read json, quorum input mistake"); + goto PARSE_OVER; } cJSON* fsync= cJSON_GetObjectItem(dbinfo, "fsync"); @@ -3469,7 +3598,7 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { g_Dbs.db[i].dbCfg.fsync = -1; } else { errorPrint("%s() LN%d, failed to read json, fsync input mistake\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } @@ -3477,15 +3606,15 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { cJSON *stables = cJSON_GetObjectItem(dbinfos, "super_tables"); if (!stables || stables->type != cJSON_Array) { errorPrint("%s() LN%d, failed to read json, super_tables not found\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } int stbSize = cJSON_GetArraySize(stables); if (stbSize > MAX_SUPER_TABLE_COUNT) { errorPrint( - "%s() LN%d, failed to read json, supertable size overflow, max supertable is %d\n", - __func__, __LINE__, MAX_SUPER_TABLE_COUNT); + "%s() LN%d, failed to read json, supertable size overflow, max supertable is %d\n", + __func__, __LINE__, MAX_SUPER_TABLE_COUNT); goto PARSE_OVER; } @@ -3498,7 +3627,7 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { cJSON *stbName = cJSON_GetObjectItem(stbInfo, "name"); if (!stbName || stbName->type != cJSON_String || stbName->valuestring == NULL) { errorPrint("%s() LN%d, failed to read json, stb name not found\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } tstrncpy(g_Dbs.db[i].superTbls[j].sTblName, stbName->valuestring, MAX_TB_NAME_SIZE); @@ -3512,8 +3641,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { cJSON *autoCreateTbl = cJSON_GetObjectItem(stbInfo, "auto_create_table"); // yes, no, null if (autoCreateTbl - && autoCreateTbl->type == cJSON_String - && autoCreateTbl->valuestring != NULL) { + && autoCreateTbl->type == cJSON_String + && autoCreateTbl->valuestring != NULL) { if (0 == strncasecmp(autoCreateTbl->valuestring, "yes", 3)) { g_Dbs.db[i].superTbls[j].autoCreateTable = AUTO_CREATE_SUBTBL; } else if (0 == strncasecmp(autoCreateTbl->valuestring, "no", 2)) { @@ -3528,6 +3657,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; @@ -3537,16 +3667,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) { + && childTblExists->type == cJSON_String + && childTblExists->valuestring != NULL) { 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) - || (g_Dbs.db[i].drop == true))) { + || (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; @@ -3555,36 +3686,36 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { g_Dbs.db[i].superTbls[j].childTblExists = TBL_NO_EXISTS; } else { errorPrint("%s() LN%d, failed to read json, child_table_exists not found\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } cJSON* count = cJSON_GetObjectItem(stbInfo, "childtable_count"); if (!count || count->type != cJSON_Number || 0 >= count->valueint) { errorPrint("%s() LN%d, failed to read json, childtable_count not found\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } g_Dbs.db[i].superTbls[j].childTblCount = count->valueint; cJSON *dataSource = cJSON_GetObjectItem(stbInfo, "data_source"); if (dataSource && dataSource->type == cJSON_String - && dataSource->valuestring != NULL) { + && dataSource->valuestring != NULL) { tstrncpy(g_Dbs.db[i].superTbls[j].dataSource, - dataSource->valuestring, MAX_DB_NAME_SIZE); + dataSource->valuestring, MAX_DB_NAME_SIZE); } 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__); + __func__, __LINE__); goto PARSE_OVER; } cJSON *insertMode = cJSON_GetObjectItem(stbInfo, "insert_mode"); // taosc , restful if (insertMode && insertMode->type == cJSON_String - && insertMode->valuestring != NULL) { + && insertMode->valuestring != NULL) { tstrncpy(g_Dbs.db[i].superTbls[j].insertMode, - insertMode->valuestring, MAX_DB_NAME_SIZE); + insertMode->valuestring, MAX_DB_NAME_SIZE); } else if (!insertMode) { tstrncpy(g_Dbs.db[i].superTbls[j].insertMode, "taosc", MAX_DB_NAME_SIZE); } else { @@ -3596,8 +3727,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { 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; + printf("ERROR: failed to read json, childtable_limit\n"); + goto PARSE_OVER; } g_Dbs.db[i].superTbls[j].childTblLimit = childTbl_limit->valueint; } else { @@ -3608,8 +3739,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { 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; + printf("ERROR: failed to read json, childtable_offset\n"); + goto PARSE_OVER; } g_Dbs.db[i].superTbls[j].childTblOffset = childTbl_offset->valueint; } else { @@ -3619,10 +3750,10 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { cJSON *ts = cJSON_GetObjectItem(stbInfo, "start_timestamp"); if (ts && ts->type == cJSON_String && ts->valuestring != NULL) { tstrncpy(g_Dbs.db[i].superTbls[j].startTimestamp, - ts->valuestring, MAX_DB_NAME_SIZE); + ts->valuestring, MAX_DB_NAME_SIZE); } else if (!ts) { tstrncpy(g_Dbs.db[i].superTbls[j].startTimestamp, - "now", MAX_DB_NAME_SIZE); + "now", MAX_DB_NAME_SIZE); } else { printf("ERROR: failed to read json, start_timestamp not found\n"); goto PARSE_OVER; @@ -3640,9 +3771,9 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { cJSON *sampleFormat = cJSON_GetObjectItem(stbInfo, "sample_format"); if (sampleFormat && sampleFormat->type - == cJSON_String && sampleFormat->valuestring != NULL) { + == cJSON_String && sampleFormat->valuestring != NULL) { tstrncpy(g_Dbs.db[i].superTbls[j].sampleFormat, - sampleFormat->valuestring, MAX_DB_NAME_SIZE); + sampleFormat->valuestring, MAX_DB_NAME_SIZE); } else if (!sampleFormat) { tstrncpy(g_Dbs.db[i].superTbls[j].sampleFormat, "csv", MAX_DB_NAME_SIZE); } else { @@ -3654,7 +3785,7 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { if (sampleFile && sampleFile->type == cJSON_String && sampleFile->valuestring != NULL) { tstrncpy(g_Dbs.db[i].superTbls[j].sampleFile, - sampleFile->valuestring, MAX_FILE_NAME_LEN); + sampleFile->valuestring, MAX_FILE_NAME_LEN); } else if (!sampleFile) { memset(g_Dbs.db[i].superTbls[j].sampleFile, 0, MAX_FILE_NAME_LEN); } else { @@ -3665,7 +3796,7 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { cJSON *tagsFile = cJSON_GetObjectItem(stbInfo, "tags_file"); if (tagsFile && tagsFile->type == cJSON_String && tagsFile->valuestring != NULL) { tstrncpy(g_Dbs.db[i].superTbls[j].tagsFile, - tagsFile->valuestring, MAX_FILE_NAME_LEN); + tagsFile->valuestring, MAX_FILE_NAME_LEN); if (0 == g_Dbs.db[i].superTbls[j].tagsFile[0]) { g_Dbs.db[i].superTbls[j].tagSource = 0; } else { @@ -3692,7 +3823,7 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { g_Dbs.db[i].superTbls[j].maxSqlLen = g_args.max_sql_len; } else { errorPrint("%s() LN%d, failed to read json, maxSqlLen input mistake\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } /* @@ -3719,9 +3850,9 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { // 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_req %d\n\n", - i, j, g_Dbs.db[i].superTbls[j].interlaceRows, g_args.num_of_RPR); + 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_req %d\n\n", - g_args.num_of_RPR); + g_args.num_of_RPR); printf(" press Enter key to continue or Ctrl-C to stop."); (void)getchar(); g_Dbs.db[i].superTbls[j].interlaceRows = g_args.num_of_RPR; @@ -3730,8 +3861,8 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { g_Dbs.db[i].superTbls[j].interlaceRows = 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__); + "%s() LN%d, failed to read json, interlace rows input mistake\n", + __func__, __LINE__); goto PARSE_OVER; } @@ -3768,7 +3899,7 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { g_Dbs.db[i].superTbls[j].insertRows = 0x7FFFFFFFFFFFFFFF; } else { errorPrint("%s() LN%d, failed to read json, insert_rows input mistake\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } @@ -3777,16 +3908,16 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { g_Dbs.db[i].superTbls[j].insertInterval = insertInterval->valueint; } else if (!insertInterval) { verbosePrint("%s() LN%d: stable insert interval be overrided by global %d.\n", - __func__, __LINE__, g_args.insert_interval); + __func__, __LINE__, g_args.insert_interval); g_Dbs.db[i].superTbls[j].insertInterval = g_args.insert_interval; } else { errorPrint("%s() LN%d, failed to read json, insert_interval input mistake\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } int retVal = getColumnAndTagTypeFromInsertJsonFile( - stbInfo, &g_Dbs.db[i].superTbls[j]); + stbInfo, &g_Dbs.db[i].superTbls[j]); if (false == retVal) { goto PARSE_OVER; } @@ -3795,7 +3926,7 @@ static bool getMetaFromInsertJsonFile(cJSON* root) { ret = true; -PARSE_OVER: + PARSE_OVER: return ret; } @@ -3840,7 +3971,7 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { cJSON *answerPrompt = cJSON_GetObjectItem(root, "confirm_parameter_prompt"); // yes, no, if (answerPrompt && answerPrompt->type == cJSON_String - && answerPrompt->valuestring != NULL) { + && answerPrompt->valuestring != NULL) { if (0 == strncasecmp(answerPrompt->valuestring, "yes", 3)) { g_args.answer_yes = false; } else if (0 == strncasecmp(answerPrompt->valuestring, "no", 2)) { @@ -3862,7 +3993,7 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { g_args.query_times = 1; } else { errorPrint("%s() LN%d, failed to read json, query_times input mistake\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } @@ -3893,22 +4024,22 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { printf("ERROR: failed to read json, super_table_query not found\n"); goto PARSE_OVER; } else { - cJSON* rate = cJSON_GetObjectItem(specifiedQuery, "query_interval"); - if (rate && rate->type == cJSON_Number) { - g_queryInfo.specifiedQueryInfo.rate = rate->valueint; - } else if (!rate) { - g_queryInfo.specifiedQueryInfo.rate = 0; + cJSON* queryInterval = cJSON_GetObjectItem(specifiedQuery, "query_interval"); + if (queryInterval && queryInterval->type == cJSON_Number) { + g_queryInfo.specifiedQueryInfo.queryInterval = queryInterval->valueint; + } else if (!queryInterval) { + g_queryInfo.specifiedQueryInfo.queryInterval = 0; } cJSON* specifiedQueryTimes = cJSON_GetObjectItem(specifiedQuery, - "query_times"); + "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__); + __func__, __LINE__); goto PARSE_OVER; } @@ -3917,24 +4048,24 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { 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); + __func__, __LINE__, g_queryInfo.specifiedQueryInfo.sqlCount, + g_queryInfo.specifiedQueryInfo.concurrent); goto PARSE_OVER; } } else if (!concurrent) { g_queryInfo.specifiedQueryInfo.concurrent = 1; } - cJSON* queryMode = cJSON_GetObjectItem(specifiedQuery, "mode"); - if (queryMode && queryMode->type == cJSON_String - && queryMode->valuestring != NULL) { - if (0 == strcmp("sync", queryMode->valuestring)) { + cJSON* mode = cJSON_GetObjectItem(specifiedQuery, "mode"); + if (mode && mode->type == cJSON_String + && mode->valuestring != NULL) { + if (0 == strcmp("sync", mode->valuestring)) { g_queryInfo.specifiedQueryInfo.mode = SYNC_QUERY_MODE; - } else if (0 == strcmp("async", queryMode->valuestring)) { + } else if (0 == strcmp("async", mode->valuestring)) { g_queryInfo.specifiedQueryInfo.mode = ASYNC_QUERY_MODE; } else { errorPrint("%s() LN%d, failed to read json, query mode input error\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } } else { @@ -3966,8 +4097,8 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { cJSON* keepProgress = cJSON_GetObjectItem(specifiedQuery, "keepProgress"); if (keepProgress - && keepProgress->type == cJSON_String - && keepProgress->valuestring != NULL) { + && keepProgress->type == cJSON_String + && keepProgress->valuestring != NULL) { if (0 == strcmp("yes", keepProgress->valuestring)) { g_queryInfo.specifiedQueryInfo.subscribeKeepProgress = 1; } else if (0 == strcmp("no", keepProgress->valuestring)) { @@ -3986,13 +4117,13 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { g_queryInfo.specifiedQueryInfo.sqlCount = 0; } else if (superSqls->type != cJSON_Array) { errorPrint("%s() LN%d, failed to read json, super sqls not found\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } else { int superSqlSize = cJSON_GetArraySize(superSqls); if (superSqlSize > 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); + __func__, __LINE__, MAX_QUERY_SQL_COUNT); goto PARSE_OVER; } @@ -4033,9 +4164,9 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { } else { cJSON* subrate = cJSON_GetObjectItem(superQuery, "query_interval"); if (subrate && subrate->type == cJSON_Number) { - g_queryInfo.superQueryInfo.rate = subrate->valueint; + g_queryInfo.superQueryInfo.queryInterval = subrate->valueint; } else if (!subrate) { - g_queryInfo.superQueryInfo.rate = 0; + g_queryInfo.superQueryInfo.queryInterval = 0; } cJSON* superQueryTimes = cJSON_GetObjectItem(superQuery, "query_times"); @@ -4045,7 +4176,7 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { g_queryInfo.superQueryInfo.queryTimes = g_args.query_times; } else { errorPrint("%s() LN%d, failed to read json, query_times input mistake\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } @@ -4067,10 +4198,10 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { if (stblname && stblname->type == cJSON_String && stblname->valuestring != NULL) { tstrncpy(g_queryInfo.superQueryInfo.sTblName, stblname->valuestring, - MAX_TB_NAME_SIZE); + MAX_TB_NAME_SIZE); } else { errorPrint("%s() LN%d, failed to read json, super table name input error\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } @@ -4083,7 +4214,7 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { g_queryInfo.superQueryInfo.mode = ASYNC_QUERY_MODE; } else { errorPrint("%s() LN%d, failed to read json, query mode input error\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } } else { @@ -4116,8 +4247,8 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { cJSON* subkeepProgress = cJSON_GetObjectItem(superQuery, "keepProgress"); if (subkeepProgress && - subkeepProgress->type == cJSON_String - && subkeepProgress->valuestring != NULL) { + subkeepProgress->type == cJSON_String + && subkeepProgress->valuestring != NULL) { if (0 == strcmp("yes", subkeepProgress->valuestring)) { g_queryInfo.superQueryInfo.subscribeKeepProgress = 1; } else if (0 == strcmp("no", subkeepProgress->valuestring)) { @@ -4136,13 +4267,13 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { g_queryInfo.superQueryInfo.sqlCount = 0; } else if (subsqls->type != cJSON_Array) { errorPrint("%s() LN%d: failed to read json, super sqls not found\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } else { int superSqlSize = cJSON_GetArraySize(subsqls); if (superSqlSize > 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); + __func__, __LINE__, MAX_QUERY_SQL_COUNT); goto PARSE_OVER; } @@ -4155,22 +4286,22 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { if (!sqlStr || sqlStr->type != cJSON_String || sqlStr->valuestring == NULL) { errorPrint("%s() LN%d, failed to read json, sql not found\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } tstrncpy(g_queryInfo.superQueryInfo.sql[j], sqlStr->valuestring, - MAX_QUERY_SQL_LENGTH); + 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); + result->valuestring, MAX_FILE_NAME_LEN); } else if (NULL == result) { memset(g_queryInfo.superQueryInfo.result[j], 0, MAX_FILE_NAME_LEN); } else { errorPrint("%s() LN%d, failed to read json, sub query result file not found\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } } @@ -4179,12 +4310,12 @@ static bool getMetaFromQueryJsonFile(cJSON* root) { ret = true; -PARSE_OVER: + PARSE_OVER: return ret; } static bool getInfoFromJsonFile(char* file) { - debugPrint("%s %d %s\n", __func__, __LINE__, file); + debugPrint("%s %d %s\n", __func__, __LINE__, file); FILE *fp = fopen(file, "r"); if (!fp) { @@ -4232,15 +4363,15 @@ static bool getInfoFromJsonFile(char* file) { if (INSERT_TEST == g_args.test_mode) { ret = getMetaFromInsertJsonFile(root); } else if ((QUERY_TEST == g_args.test_mode) - || (SUBSCRIBE_TEST == g_args.test_mode)) { + || (SUBSCRIBE_TEST == g_args.test_mode)) { ret = getMetaFromQueryJsonFile(root); } else { errorPrint("%s() LN%d, input json file type error! please input correct file type: insert or query or subscribe\n", - __func__, __LINE__); + __func__, __LINE__); goto PARSE_OVER; } -PARSE_OVER: + PARSE_OVER: free(content); cJSON_Delete(root); fclose(fp); @@ -4282,7 +4413,7 @@ static void postFreeResource() { } static int getRowDataFromSample(char* dataBuf, int maxLen, int64_t timestamp, - SSuperTable* superTblInfo, int* sampleUsePos) { + SSuperTable* superTblInfo, int* sampleUsePos) { if ((*sampleUsePos) == MAX_SAMPLES_ONCE_FROM_FILE) { /* int ret = readSampleFromCsvFileToMem(superTblInfo); if (0 != ret) { @@ -4297,9 +4428,9 @@ static int getRowDataFromSample(char* dataBuf, int maxLen, int64_t timestamp, int dataLen = 0; dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen, - "(%" PRId64 ", ", timestamp); + "(%" PRId64 ", ", timestamp); dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen, - "%s", superTblInfo->sampleDataBuf + superTblInfo->lenOfOneRow * (*sampleUsePos)); + "%s", superTblInfo->sampleDataBuf + superTblInfo->lenOfOneRow * (*sampleUsePos)); dataLen += snprintf(dataBuf + dataLen, maxLen - dataLen, ")"); (*sampleUsePos)++; @@ -4316,10 +4447,10 @@ static int generateRowData(char* recBuf, int64_t timestamp, SSuperTable* stbInfo 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))) { + || (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); + (uint32_t)TSDB_MAX_BINARY_LEN); return -1; } @@ -4332,37 +4463,37 @@ static int generateRowData(char* recBuf, int64_t timestamp, SSuperTable* stbInfo dataLen += snprintf(pstr + dataLen, maxLen - dataLen, "\'%s\', ", buf); tmfree(buf); } else if (0 == strncasecmp(stbInfo->columns[i].dataType, - "int", 3)) { + "int", 3)) { dataLen += snprintf(pstr + dataLen, maxLen - dataLen, - "%d, ", rand_int()); + "%d, ", rand_int()); } else if (0 == strncasecmp(stbInfo->columns[i].dataType, - "bigint", 6)) { + "bigint", 6)) { dataLen += snprintf(pstr + dataLen, maxLen - dataLen, - "%"PRId64", ", rand_bigint()); + "%"PRId64", ", rand_bigint()); } else if (0 == strncasecmp(stbInfo->columns[i].dataType, - "float", 5)) { + "float", 5)) { dataLen += snprintf(pstr + dataLen, maxLen - dataLen, - "%f, ", rand_float()); + "%f, ", rand_float()); } else if (0 == strncasecmp(stbInfo->columns[i].dataType, - "double", 6)) { + "double", 6)) { dataLen += snprintf(pstr + dataLen, maxLen - dataLen, - "%f, ", rand_double()); + "%f, ", rand_double()); } else if (0 == strncasecmp(stbInfo->columns[i].dataType, - "smallint", 8)) { + "smallint", 8)) { dataLen += snprintf(pstr + dataLen, maxLen - dataLen, - "%d, ", rand_smallint()); + "%d, ", rand_smallint()); } else if (0 == strncasecmp(stbInfo->columns[i].dataType, - "tinyint", strlen("tinyint"))) { + "tinyint", strlen("tinyint"))) { dataLen += snprintf(pstr + dataLen, maxLen - dataLen, - "%d, ", rand_tinyint()); + "%d, ", rand_tinyint()); } else if (0 == strncasecmp(stbInfo->columns[i].dataType, - "bool", strlen("bool"))) { + "bool", strlen("bool"))) { dataLen += snprintf(pstr + dataLen, maxLen - dataLen, - "%d, ", rand_bool()); + "%d, ", rand_bool()); } else if (0 == strncasecmp(stbInfo->columns[i].dataType, - "timestamp", strlen("timestamp"))) { + "timestamp", strlen("timestamp"))) { dataLen += snprintf(pstr + dataLen, maxLen - dataLen, - "%"PRId64", ", rand_bigint()); + "%"PRId64", ", rand_bigint()); } else { errorPrint( "No support data type: %s\n", stbInfo->columns[i].dataType); return -1; @@ -4378,7 +4509,7 @@ static int generateRowData(char* recBuf, int64_t timestamp, SSuperTable* stbInfo } static int32_t generateData(char *recBuf, char **data_type, - int num_of_cols, int64_t timestamp, int lenOfBinary) { + int num_of_cols, int64_t timestamp, int lenOfBinary) { memset(recBuf, 0, MAX_DATA_SIZE); char *pstr = recBuf; pstr += sprintf(pstr, "(%" PRId64, timestamp); @@ -4395,7 +4526,7 @@ static int32_t generateData(char *recBuf, char **data_type, exit(-1); } - for (int i = 0; i < num_of_cols; i++) { + for (int i = 0; i < c; i++) { if (strcasecmp(data_type[i % c], "tinyint") == 0) { pstr += sprintf(pstr, ", %d", rand_tinyint() ); } else if (strcasecmp(data_type[i % c], "smallint") == 0) { @@ -4417,7 +4548,7 @@ static int32_t generateData(char *recBuf, char **data_type, rand_string(s, lenOfBinary); pstr += sprintf(pstr, ", \"%s\"", s); free(s); - }else if (strcasecmp(data_type[i % c], "nchar") == 0) { + } else if (strcasecmp(data_type[i % c], "nchar") == 0) { char *s = malloc(lenOfBinary); rand_string(s, lenOfBinary); pstr += sprintf(pstr, ", \"%s\"", s); @@ -4441,24 +4572,24 @@ static int prepareSampleDataForSTable(SSuperTable *superTblInfo) { char* sampleDataBuf = NULL; sampleDataBuf = calloc( - superTblInfo->lenOfOneRow * MAX_SAMPLES_ONCE_FROM_FILE, 1); + superTblInfo->lenOfOneRow * MAX_SAMPLES_ONCE_FROM_FILE, 1); if (sampleDataBuf == NULL) { - errorPrint("%s() LN%d, Failed to calloc %d Bytes, reason:%s\n", - __func__, __LINE__, - superTblInfo->lenOfOneRow * MAX_SAMPLES_ONCE_FROM_FILE, - strerror(errno)); - return -1; + errorPrint("%s() LN%d, Failed to calloc %d Bytes, reason:%s\n", + __func__, __LINE__, + superTblInfo->lenOfOneRow * MAX_SAMPLES_ONCE_FROM_FILE, + strerror(errno)); + return -1; } superTblInfo->sampleDataBuf = sampleDataBuf; int ret = readSampleFromCsvFileToMem(superTblInfo); if (0 != ret) { - errorPrint("%s() LN%d, read sample from csv file failed.\n", - __func__, __LINE__); - tmfree(sampleDataBuf); - superTblInfo->sampleDataBuf = NULL; - return -1; + errorPrint("%s() LN%d, read sample from csv file failed.\n", + __func__, __LINE__); + tmfree(sampleDataBuf); + superTblInfo->sampleDataBuf = NULL; + return -1; } return 0; @@ -4470,7 +4601,7 @@ static int execInsert(threadInfo *pThreadInfo, char *buffer, int k) SSuperTable* superTblInfo = pThreadInfo->superTblInfo; verbosePrint("[%d] %s() LN%d %s\n", pThreadInfo->threadID, - __func__, __LINE__, buffer); + __func__, __LINE__, buffer); if (superTblInfo) { if (0 == strncasecmp(superTblInfo->insertMode, "taosc", strlen("taosc"))) { affectedRows = queryDbExec(pThreadInfo->taos, buffer, INSERT_TYPE, false); @@ -4478,7 +4609,7 @@ static int execInsert(threadInfo *pThreadInfo, char *buffer, int k) if (0 != postProceSql(g_Dbs.host, g_Dbs.port, buffer)) { affectedRows = -1; printf("========restful return fail, threadID[%d]\n", - pThreadInfo->threadID); + pThreadInfo->threadID); } else { affectedRows = k; } @@ -4495,29 +4626,29 @@ static void getTableName(char *pTblName, threadInfo* pThreadInfo, int tableSeq) SSuperTable* superTblInfo = pThreadInfo->superTblInfo; if (superTblInfo) { if ((superTblInfo->childTblOffset >= 0) - && (superTblInfo->childTblLimit > 0)) { - snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s", - superTblInfo->childTblName + - (tableSeq - superTblInfo->childTblOffset) * TSDB_TABLE_NAME_LEN); + && (superTblInfo->childTblLimit > 0)) { + snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s", + superTblInfo->childTblName + + (tableSeq - superTblInfo->childTblOffset) * TSDB_TABLE_NAME_LEN); } else { - verbosePrint("[%d] %s() LN%d: from=%d count=%d seq=%d\n", - pThreadInfo->threadID, __func__, __LINE__, - pThreadInfo->start_table_from, - pThreadInfo->ntables, tableSeq); - snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s", - superTblInfo->childTblName + tableSeq * TSDB_TABLE_NAME_LEN); + verbosePrint("[%d] %s() LN%d: from=%d count=%d seq=%d\n", + pThreadInfo->threadID, __func__, __LINE__, + pThreadInfo->start_table_from, + pThreadInfo->ntables, tableSeq); + snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s", + superTblInfo->childTblName + tableSeq * TSDB_TABLE_NAME_LEN); } } else { snprintf(pTblName, TSDB_TABLE_NAME_LEN, "%s%d", - g_args.tb_prefix, tableSeq); + g_args.tb_prefix, tableSeq); } } static int generateDataTail( - SSuperTable* superTblInfo, - int batch, char* buffer, int remainderBufLen, int64_t insertRows, - int64_t startFrom, uint64_t startTime, int *pSamplePos, int *dataLen) { + 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 @@ -4526,8 +4657,8 @@ static int generateDataTail( if (superTblInfo == NULL) { int datatypeSeq = 0; while(g_args.datatype[datatypeSeq]) { - datatypeSeq ++; - ncols_per_record ++; + datatypeSeq ++; + ncols_per_record ++; } } @@ -4542,15 +4673,15 @@ static int generateDataTail( if (superTblInfo) { if (0 == strncasecmp(superTblInfo->dataSource, - "sample", strlen("sample"))) { - retLen = getRowDataFromSample( - data, - remainderBufLen, - startTime + superTblInfo->timeStampStep * k, - superTblInfo, - pSamplePos); + "sample", strlen("sample"))) { + retLen = getRowDataFromSample( + data, + remainderBufLen, + startTime + superTblInfo->timeStampStep * k, + superTblInfo, + pSamplePos); } else if (0 == strncasecmp(superTblInfo->dataSource, - "rand", strlen("rand"))) { + "rand", strlen("rand"))) { int randTail = superTblInfo->timeStampStep * k; if (superTblInfo->disorderRatio > 0) { @@ -4562,11 +4693,11 @@ static int generateDataTail( } uint64_t d = startTime - + randTail; + + randTail; retLen = generateRowData( - data, - d, - superTblInfo); + data, + d, + superTblInfo); } if (retLen > remainderBufLen) { @@ -4585,30 +4716,30 @@ static int generateDataTail( int randTail; if ((g_args.disorderRatio != 0) - && (rand_num < g_args.disorderRatio)) { + && (rand_num < g_args.disorderRatio)) { randTail = (DEFAULT_TIMESTAMP_STEP * k - + (taosRandom() % g_args.disorderRange + 1)) * (-1); + + (taosRandom() % g_args.disorderRange + 1)) * (-1); debugPrint("rand data generated, back %d\n", randTail); } else { randTail = DEFAULT_TIMESTAMP_STEP * k; } retLen = generateData(data, data_type, - ncols_per_record, - startTime + randTail, - lenOfBinary); + ncols_per_record, + startTime + randTail, + lenOfBinary); if (len > remainderBufLen) break; - pstr += sprintf(pstr, " %s", data); + 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); + __func__, __LINE__, len, k, buffer); startFrom ++; @@ -4622,8 +4753,8 @@ static int generateDataTail( } static int generateSQLHead(char *tableName, int32_t tableSeq, - threadInfo* pThreadInfo, SSuperTable* superTblInfo, - char *buffer, int remainderBufLen) + threadInfo* pThreadInfo, SSuperTable* superTblInfo, + char *buffer, int remainderBufLen) { int len; @@ -4634,50 +4765,50 @@ static int generateSQLHead(char *tableName, int32_t tableSeq, if (AUTO_CREATE_SUBTBL == superTblInfo->autoCreateTable) { char* tagsValBuf = NULL; if (0 == superTblInfo->tagSource) { - tagsValBuf = generateTagVaulesForStb(superTblInfo, tableSeq); + tagsValBuf = generateTagVaulesForStb(superTblInfo, tableSeq); } else { - tagsValBuf = getTagValueFromTagSample( - superTblInfo, - tableSeq % superTblInfo->tagSampleCount); + tagsValBuf = getTagValueFromTagSample( + superTblInfo, + tableSeq % superTblInfo->tagSampleCount); } if (NULL == tagsValBuf) { errorPrint("%s() LN%d, tag buf failed to allocate memory\n", - __func__, __LINE__); + __func__, __LINE__); return -1; } len = snprintf( headBuf, - HEAD_BUFF_LEN, - "%s.%s using %s.%s tags %s values", - pThreadInfo->db_name, - tableName, - pThreadInfo->db_name, - superTblInfo->sTblName, - tagsValBuf); + HEAD_BUFF_LEN, + "%s.%s using %s.%s tags %s values", + pThreadInfo->db_name, + tableName, + pThreadInfo->db_name, + superTblInfo->sTblName, + tagsValBuf); tmfree(tagsValBuf); } else if (TBL_ALREADY_EXISTS == superTblInfo->childTblExists) { len = snprintf( headBuf, - HEAD_BUFF_LEN, - "%s.%s values", - pThreadInfo->db_name, - tableName); + HEAD_BUFF_LEN, + "%s.%s values", + pThreadInfo->db_name, + tableName); } else { len = snprintf( headBuf, - HEAD_BUFF_LEN, - "%s.%s values", - pThreadInfo->db_name, - tableName); + HEAD_BUFF_LEN, + "%s.%s values", + pThreadInfo->db_name, + tableName); } } else { - len = snprintf( - headBuf, - HEAD_BUFF_LEN, - "%s.%s values", - pThreadInfo->db_name, - tableName); + len = snprintf( + headBuf, + HEAD_BUFF_LEN, + "%s.%s values", + pThreadInfo->db_name, + tableName); } if (len > remainderBufLen) @@ -4689,26 +4820,26 @@ static int generateSQLHead(char *tableName, int32_t tableSeq, } static int generateInterlaceDataBuffer( - char *tableName, int batchPerTbl, int i, int batchPerTblTimes, - int32_t tableSeq, - threadInfo *pThreadInfo, char *buffer, - int64_t insertRows, - int64_t startTime, - int *pRemainderBufLen) + char *tableName, int batchPerTbl, int i, int batchPerTblTimes, + int32_t tableSeq, + threadInfo *pThreadInfo, char *buffer, + int64_t insertRows, + int64_t startTime, + int *pRemainderBufLen) { assert(buffer); char *pstr = buffer; SSuperTable* superTblInfo = pThreadInfo->superTblInfo; int headLen = generateSQLHead(tableName, tableSeq, pThreadInfo, - superTblInfo, pstr, *pRemainderBufLen); + 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); + pThreadInfo->threadID, __func__, __LINE__, i, buffer); pstr += headLen; *pRemainderBufLen -= headLen; @@ -4716,22 +4847,22 @@ static int generateInterlaceDataBuffer( int dataLen = 0; verbosePrint("[%d] %s() LN%d i=%d batchPerTblTimes=%d batchPerTbl = %d\n", - pThreadInfo->threadID, __func__, __LINE__, - i, batchPerTblTimes, batchPerTbl); + pThreadInfo->threadID, __func__, __LINE__, + i, batchPerTblTimes, batchPerTbl); if (superTblInfo) { if (0 == strncasecmp(superTblInfo->startTimestamp, "now", 3)) { startTime = taosGetTimestamp(pThreadInfo->time_precision); } } else { - startTime = 1500000000000; + startTime = 1500000000000; } int k = generateDataTail( - superTblInfo, - batchPerTbl, pstr, *pRemainderBufLen, insertRows, 0, - startTime, - &(pThreadInfo->samplePos), &dataLen); + superTblInfo, + batchPerTbl, pstr, *pRemainderBufLen, insertRows, 0, + startTime, + &(pThreadInfo->samplePos), &dataLen); if (k == batchPerTbl) { pstr += dataLen; @@ -4746,12 +4877,12 @@ static int generateInterlaceDataBuffer( } 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) + 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; @@ -4760,8 +4891,8 @@ static int generateProgressiveDataBuffer( if (superTblInfo == NULL) { int datatypeSeq = 0; while(g_args.datatype[datatypeSeq]) { - datatypeSeq ++; - ncols_per_record ++; + datatypeSeq ++; + ncols_per_record ++; } } @@ -4773,7 +4904,7 @@ static int generateProgressiveDataBuffer( memset(buffer, 0, *pRemainderBufLen); int headLen = generateSQLHead(tableName, tableSeq, pThreadInfo, superTblInfo, - buffer, *pRemainderBufLen); + buffer, *pRemainderBufLen); if (headLen <= 0) { return 0; @@ -4783,16 +4914,16 @@ static int generateProgressiveDataBuffer( int dataLen; k = generateDataTail(superTblInfo, - g_args.num_of_RPR, pstr, *pRemainderBufLen, insertRows, startFrom, - startTime, - pSamplePos, &dataLen); + g_args.num_of_RPR, pstr, *pRemainderBufLen, insertRows, startFrom, + startTime, + pSamplePos, &dataLen); return k; } static void* syncWriteInterlace(threadInfo *pThreadInfo) { debugPrint("[%d] %s() LN%d: ### interlace write\n", - pThreadInfo->threadID, __func__, __LINE__); + pThreadInfo->threadID, __func__, __LINE__); SSuperTable* superTblInfo = pThreadInfo->superTblInfo; @@ -4800,7 +4931,7 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { int interlaceRows = superTblInfo?superTblInfo->interlaceRows:g_args.interlace_rows; if (interlaceRows > insertRows) - interlaceRows = insertRows; + interlaceRows = insertRows; if (interlaceRows > g_args.num_of_RPR) interlaceRows = g_args.num_of_RPR; @@ -4820,7 +4951,7 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { char* buffer = calloc(maxSqlLen, 1); if (NULL == buffer) { errorPrint( "%s() LN%d, Failed to alloc %d Bytes, reason:%s\n", - __func__, __LINE__, maxSqlLen, strerror(errno)); + __func__, __LINE__, maxSqlLen, strerror(errno)); return NULL; } @@ -4837,14 +4968,14 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { uint64_t et = 0xffffffff; int64_t lastPrintTime = taosGetTimestampMs(); - int64_t startTs = taosGetTimestampUs(); + int64_t startTs = taosGetTimestampMs(); int64_t endTs; int tableSeq = pThreadInfo->start_table_from; debugPrint("[%d] %s() LN%d: start_table_from=%d ntables=%d insertRows=%"PRId64"\n", - pThreadInfo->threadID, __func__, __LINE__, pThreadInfo->start_table_from, - pThreadInfo->ntables, insertRows); + pThreadInfo->threadID, __func__, __LINE__, pThreadInfo->start_table_from, + pThreadInfo->ntables, insertRows); int64_t startTime = pThreadInfo->start_time; @@ -4869,8 +5000,8 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { while(pThreadInfo->totalInsertRows < pThreadInfo->ntables * insertRows) { if ((flagSleep) && (insert_interval)) { - st = taosGetTimestampUs(); - flagSleep = false; + st = taosGetTimestampMs(); + flagSleep = false; } // generate data memset(buffer, 0, maxSqlLen); @@ -4888,23 +5019,23 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { getTableName(tableName, pThreadInfo, tableSeq); if (0 == strlen(tableName)) { errorPrint("[%d] %s() LN%d, getTableName return null\n", - pThreadInfo->threadID, __func__, __LINE__); + pThreadInfo->threadID, __func__, __LINE__); free(buffer); return NULL; } int oldRemainderLen = remainderBufLen; int generated = generateInterlaceDataBuffer( - tableName, batchPerTbl, i, batchPerTblTimes, - tableSeq, - pThreadInfo, pstr, - insertRows, - startTime, - &remainderBufLen); + tableName, batchPerTbl, i, batchPerTblTimes, + tableSeq, + pThreadInfo, pstr, + insertRows, + startTime, + &remainderBufLen); if (generated < 0) { debugPrint("[%d] %s() LN%d, generated data is %d\n", - pThreadInfo->threadID, __func__, __LINE__, generated); + pThreadInfo->threadID, __func__, __LINE__, generated); goto free_and_statistics_interlace; } else if (generated == 0) { break; @@ -4916,25 +5047,25 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { // startTime += batchPerTbl * superTblInfo->timeStampStep; pThreadInfo->totalInsertRows += batchPerTbl; verbosePrint("[%d] %s() LN%d batchPerTbl=%d recOfBatch=%d\n", - pThreadInfo->threadID, __func__, __LINE__, - batchPerTbl, recOfBatch); + pThreadInfo->threadID, __func__, __LINE__, + batchPerTbl, recOfBatch); if (insertMode == INTERLACE_INSERT_MODE) { - if (tableSeq == pThreadInfo->start_table_from + pThreadInfo->ntables) { - // turn to first table - tableSeq = pThreadInfo->start_table_from; - generatedRecPerTbl += batchPerTbl; + if (tableSeq == pThreadInfo->start_table_from + pThreadInfo->ntables) { + // turn to first table + tableSeq = pThreadInfo->start_table_from; + generatedRecPerTbl += batchPerTbl; - startTime = pThreadInfo->start_time - + generatedRecPerTbl * nTimeStampStep; + startTime = pThreadInfo->start_time + + generatedRecPerTbl * nTimeStampStep; - flagSleep = true; - if (generatedRecPerTbl >= insertRows) - break; + flagSleep = true; + if (generatedRecPerTbl >= insertRows) + break; - if (pThreadInfo->ntables * batchPerTbl < g_args.num_of_RPR) - break; - } + if (pThreadInfo->ntables * batchPerTbl < g_args.num_of_RPR) + break; + } } int remainRows = insertRows - generatedRecPerTbl; @@ -4942,27 +5073,27 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { batchPerTbl = remainRows; verbosePrint("[%d] %s() LN%d generatedRecPerTbl=%d insertRows=%"PRId64"\n", - pThreadInfo->threadID, __func__, __LINE__, - generatedRecPerTbl, insertRows); + pThreadInfo->threadID, __func__, __LINE__, + generatedRecPerTbl, insertRows); if ((g_args.num_of_RPR - recOfBatch) < batchPerTbl) break; } verbosePrint("[%d] %s() LN%d recOfBatch=%d totalInsertRows=%"PRId64"\n", - pThreadInfo->threadID, __func__, __LINE__, recOfBatch, - pThreadInfo->totalInsertRows); + pThreadInfo->threadID, __func__, __LINE__, recOfBatch, + pThreadInfo->totalInsertRows); verbosePrint("[%d] %s() LN%d, buffer=%s\n", - pThreadInfo->threadID, __func__, __LINE__, buffer); + pThreadInfo->threadID, __func__, __LINE__, buffer); - startTs = taosGetTimestampUs(); + startTs = taosGetTimestampMs(); int affectedRows = execInsert(pThreadInfo, buffer, recOfBatch); - endTs = taosGetTimestampUs(); + endTs = taosGetTimestampMs(); int64_t delay = endTs - startTs; - performancePrint("%s() LN%d, insert execution time is %10.6fms\n", - __func__, __LINE__, delay/1000.0); + performancePrint("%s() LN%d, insert execution time is %"PRId64"ms\n", + __func__, __LINE__, delay); if (delay > pThreadInfo->maxDelay) pThreadInfo->maxDelay = delay; if (delay < pThreadInfo->minDelay) pThreadInfo->minDelay = delay; @@ -4970,12 +5101,12 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { pThreadInfo->totalDelay += delay; verbosePrint("[%d] %s() LN%d affectedRows=%d\n", pThreadInfo->threadID, - __func__, __LINE__, affectedRows); + __func__, __LINE__, affectedRows); if ((affectedRows < 0) || (recOfBatch != affectedRows)) { - errorPrint("[%d] %s() LN%d execInsert insert %d, affected rows: %d\n%s\n", - pThreadInfo->threadID, __func__, __LINE__, - recOfBatch, affectedRows, buffer); - goto free_and_statistics_interlace; + errorPrint("[%d] %s() LN%d execInsert insert %d, affected rows: %d\n%s\n", + pThreadInfo->threadID, __func__, __LINE__, + recOfBatch, affectedRows, buffer); + goto free_and_statistics_interlace; } pThreadInfo->totalAffectedRows += affectedRows; @@ -4983,32 +5114,32 @@ static void* syncWriteInterlace(threadInfo *pThreadInfo) { int64_t currentPrintTime = taosGetTimestampMs(); if (currentPrintTime - lastPrintTime > 30*1000) { printf("thread[%d] has currently inserted rows: %"PRId64 ", affected rows: %"PRId64 "\n", - pThreadInfo->threadID, - pThreadInfo->totalInsertRows, - pThreadInfo->totalAffectedRows); + pThreadInfo->threadID, + pThreadInfo->totalInsertRows, + pThreadInfo->totalAffectedRows); lastPrintTime = currentPrintTime; } if ((insert_interval) && flagSleep) { - et = taosGetTimestampUs(); + et = taosGetTimestampMs(); - if (insert_interval > ((et - st)/1000) ) { - int sleepTime = insert_interval - (et -st)/1000; + if (insert_interval > (et - st) ) { + int sleepTime = insert_interval - (et -st); performancePrint("%s() LN%d sleep: %d ms for insert interval\n", - __func__, __LINE__, sleepTime); + __func__, __LINE__, sleepTime); taosMsleep(sleepTime); // ms sleepTimeTotal += insert_interval; } } } -free_and_statistics_interlace: + free_and_statistics_interlace: tmfree(buffer); printf("====thread[%d] completed total inserted rows: %"PRId64 ", total affected rows: %"PRId64 "====\n", - pThreadInfo->threadID, - pThreadInfo->totalInsertRows, - pThreadInfo->totalAffectedRows); + pThreadInfo->threadID, + pThreadInfo->totalInsertRows, + pThreadInfo->totalAffectedRows); return NULL; } @@ -5029,13 +5160,13 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { char* buffer = calloc(maxSqlLen, 1); if (NULL == buffer) { errorPrint( "Failed to alloc %d Bytes, reason:%s\n", - maxSqlLen, - strerror(errno)); + maxSqlLen, + strerror(errno)); return NULL; } int64_t lastPrintTime = taosGetTimestampMs(); - int64_t startTs = taosGetTimestampUs(); + int64_t startTs = taosGetTimestampMs(); int64_t endTs; int timeStampStep = @@ -5052,25 +5183,25 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { pThreadInfo->samplePos = 0; for (uint32_t tableSeq = - pThreadInfo->start_table_from; tableSeq <= pThreadInfo->end_table_to; - tableSeq ++) { + pThreadInfo->start_table_from; tableSeq <= pThreadInfo->end_table_to; + tableSeq ++) { int64_t start_time = pThreadInfo->start_time; int64_t insertRows = (superTblInfo)?superTblInfo->insertRows:g_args.num_of_DPT; verbosePrint("%s() LN%d insertRows=%"PRId64"\n", __func__, __LINE__, insertRows); for (int64_t i = 0; i < insertRows;) { - /* - if (insert_interval) { - st = taosGetTimestampUs(); - } - */ + /* + if (insert_interval) { + st = taosGetTimestampMs(); + } + */ char tableName[TSDB_TABLE_NAME_LEN]; getTableName(tableName, pThreadInfo, tableSeq); verbosePrint("%s() LN%d: tid=%d seq=%d tableName=%s\n", - __func__, __LINE__, - pThreadInfo->threadID, tableSeq, tableName); + __func__, __LINE__, + pThreadInfo->threadID, tableSeq, tableName); int remainderBufLen = maxSqlLen; char *pstr = buffer; @@ -5082,10 +5213,10 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { remainderBufLen -= len; int generated = generateProgressiveDataBuffer( - tableName, tableSeq, pThreadInfo, pstr, insertRows, - i, start_time, - &(pThreadInfo->samplePos), - &remainderBufLen); + tableName, tableSeq, pThreadInfo, pstr, insertRows, + i, start_time, + &(pThreadInfo->samplePos), + &remainderBufLen); if (generated > 0) i += generated; else @@ -5094,14 +5225,14 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { start_time += generated * timeStampStep; pThreadInfo->totalInsertRows += generated; - startTs = taosGetTimestampUs(); + startTs = taosGetTimestampMs(); int affectedRows = execInsert(pThreadInfo, buffer, generated); - endTs = taosGetTimestampUs(); + endTs = taosGetTimestampMs(); int64_t delay = endTs - startTs; - performancePrint("%s() LN%d, insert execution time is %10.6fms\n", - __func__, __LINE__, delay/1000.0); + performancePrint("%s() LN%d, insert execution time is %"PRId64"ms\n", + __func__, __LINE__, delay); if (delay > pThreadInfo->maxDelay) pThreadInfo->maxDelay = delay; if (delay < pThreadInfo->minDelay) pThreadInfo->minDelay = delay; @@ -5116,9 +5247,9 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { int64_t currentPrintTime = taosGetTimestampMs(); if (currentPrintTime - lastPrintTime > 30*1000) { printf("thread[%d] has currently inserted rows: %"PRId64 ", affected rows: %"PRId64 "\n", - pThreadInfo->threadID, - pThreadInfo->totalInsertRows, - pThreadInfo->totalAffectedRows); + pThreadInfo->threadID, + pThreadInfo->totalInsertRows, + pThreadInfo->totalAffectedRows); lastPrintTime = currentPrintTime; } @@ -5126,10 +5257,10 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { break; /* if (insert_interval) { - et = taosGetTimestampUs(); + et = taosGetTimestampMs(); - if (insert_interval > ((et - st)/1000) ) { - int sleep_time = insert_interval - (et -st)/1000; + if (insert_interval > ((et - st)) ) { + int sleep_time = insert_interval - (et -st); performancePrint("%s() LN%d sleep: %d ms for insert interval\n", __func__, __LINE__, sleep_time); taosMsleep(sleep_time); // ms @@ -5140,21 +5271,21 @@ static void* syncWriteProgressive(threadInfo *pThreadInfo) { if (g_args.verbose_print) { if ((tableSeq == pThreadInfo->ntables - 1) && superTblInfo && - (0 == strncasecmp( - superTblInfo->dataSource, "sample", strlen("sample")))) { - verbosePrint("%s() LN%d samplePos=%d\n", - __func__, __LINE__, pThreadInfo->samplePos); + (0 == strncasecmp( + superTblInfo->dataSource, "sample", strlen("sample")))) { + verbosePrint("%s() LN%d samplePos=%d\n", + __func__, __LINE__, pThreadInfo->samplePos); } } } // tableSeq -free_and_statistics_2: + free_and_statistics_2: tmfree(buffer); printf("====thread[%d] completed total inserted rows: %"PRId64 ", total affected rows: %"PRId64 "====\n", - pThreadInfo->threadID, - pThreadInfo->totalInsertRows, - pThreadInfo->totalAffectedRows); + pThreadInfo->threadID, + pThreadInfo->totalInsertRows, + pThreadInfo->totalAffectedRows); return NULL; } @@ -5181,9 +5312,9 @@ static void callBack(void *param, TAOS_RES *res, int code) { int insert_interval = superTblInfo?superTblInfo->insertInterval:g_args.insert_interval; if (insert_interval) { - pThreadInfo->et = taosGetTimestampUs(); - if (((pThreadInfo->et - pThreadInfo->st)/1000) < insert_interval) { - taosMsleep(insert_interval - (pThreadInfo->et - pThreadInfo->st)/1000); // ms + pThreadInfo->et = taosGetTimestampMs(); + if ((pThreadInfo->et - pThreadInfo->st) < insert_interval) { + taosMsleep(insert_interval - (pThreadInfo->et - pThreadInfo->st)); // ms } } @@ -5191,7 +5322,7 @@ static void callBack(void *param, TAOS_RES *res, int code) { char data[MAX_DATA_SIZE]; char *pstr = buffer; pstr += sprintf(pstr, "insert into %s.%s%d values", pThreadInfo->db_name, pThreadInfo->tb_prefix, - pThreadInfo->start_table_from); + pThreadInfo->start_table_from); // if (pThreadInfo->counter >= pThreadInfo->superTblInfo->insertRows) { if (pThreadInfo->counter >= g_args.num_of_RPR) { pThreadInfo->start_table_from++; @@ -5207,7 +5338,7 @@ static void callBack(void *param, TAOS_RES *res, int code) { for (int i = 0; i < g_args.num_of_RPR; i++) { int rand_num = taosRandom() % 100; if (0 != pThreadInfo->superTblInfo->disorderRatio - && rand_num < pThreadInfo->superTblInfo->disorderRatio) { + && rand_num < pThreadInfo->superTblInfo->disorderRatio) { int64_t d = pThreadInfo->lastTs - (taosRandom() % pThreadInfo->superTblInfo->disorderRange + 1); generateRowData(data, d, pThreadInfo->superTblInfo); } else { @@ -5222,7 +5353,7 @@ static void callBack(void *param, TAOS_RES *res, int code) { } if (insert_interval) { - pThreadInfo->st = taosGetTimestampUs(); + pThreadInfo->st = taosGetTimestampMs(); } taos_query_a(pThreadInfo->taos, buffer, callBack, pThreadInfo); free(buffer); @@ -5241,7 +5372,7 @@ static void *asyncWrite(void *sarg) { int insert_interval = superTblInfo?superTblInfo->insertInterval:g_args.insert_interval; if (insert_interval) { - pThreadInfo->st = taosGetTimestampUs(); + pThreadInfo->st = taosGetTimestampMs(); } taos_query_a(pThreadInfo->taos, "show databases", callBack, pThreadInfo); @@ -5251,7 +5382,7 @@ static void *asyncWrite(void *sarg) { } static void startMultiThreadInsertData(int threads, char* db_name, - char* precision,SSuperTable* superTblInfo) { + char* precision,SSuperTable* superTblInfo) { pthread_t *pids = malloc(threads * sizeof(pthread_t)); assert(pids != NULL); @@ -5286,48 +5417,48 @@ static void startMultiThreadInsertData(int threads, char* db_name, int64_t start_time; if (superTblInfo) { if (0 == strncasecmp(superTblInfo->startTimestamp, "now", 3)) { - start_time = taosGetTimestamp(timePrec); + start_time = taosGetTimestamp(timePrec); } else { if (TSDB_CODE_SUCCESS != taosParseTime( - superTblInfo->startTimestamp, - &start_time, - strlen(superTblInfo->startTimestamp), - timePrec, 0)) { - ERROR_EXIT("failed to parse time!\n"); + superTblInfo->startTimestamp, + &start_time, + strlen(superTblInfo->startTimestamp), + timePrec, 0)) { + ERROR_EXIT("failed to parse time!\n"); } } } else { - start_time = 1500000000000; + start_time = 1500000000000; } - double start = getCurrentTimeUs(); + int64_t start = taosGetTimestampMs(); // read sample data from file first if ((superTblInfo) && (0 == strncasecmp(superTblInfo->dataSource, - "sample", strlen("sample")))) { + "sample", strlen("sample")))) { if (0 != prepareSampleDataForSTable(superTblInfo)) { errorPrint("%s() LN%d, prepare sample data for stable failed!\n", - __func__, __LINE__); + __func__, __LINE__); exit(-1); } } // read sample data from file first if ((superTblInfo) && (0 == strncasecmp(superTblInfo->dataSource, - "sample", strlen("sample")))) { + "sample", strlen("sample")))) { if (0 != prepareSampleDataForSTable(superTblInfo)) { errorPrint("%s() LN%d, prepare sample data for stable failed!\n", - __func__, __LINE__); + __func__, __LINE__); exit(-1); } } TAOS* taos = taos_connect( - g_Dbs.host, g_Dbs.user, - g_Dbs.password, db_name, g_Dbs.port); + g_Dbs.host, g_Dbs.user, + g_Dbs.password, db_name, g_Dbs.port); if (NULL == taos) { errorPrint("%s() LN%d, connect to server fail , reason: %s\n", - __func__, __LINE__, taos_errstr(NULL)); + __func__, __LINE__, taos_errstr(NULL)); exit(-1); } @@ -5337,16 +5468,16 @@ static void startMultiThreadInsertData(int threads, char* db_name, if (superTblInfo) { int limit, offset; - 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 ((NULL != g_args.sqlFile) && (superTblInfo->childTblExists == TBL_NO_EXISTS) && + ((superTblInfo->childTblOffset != 0) || (superTblInfo->childTblLimit >= 0))) { + printf("WARNING: offset and limit will not be used since the child tables not exists!\n"); } if ((superTblInfo->childTblExists == TBL_ALREADY_EXISTS) - && (superTblInfo->childTblOffset >= 0)) { + && (superTblInfo->childTblOffset >= 0)) { if ((superTblInfo->childTblLimit < 0) || ((superTblInfo->childTblOffset + superTblInfo->childTblLimit) - > (superTblInfo->childTblCount))) { + > (superTblInfo->childTblCount))) { superTblInfo->childTblLimit = superTblInfo->childTblCount - superTblInfo->childTblOffset; } @@ -5372,7 +5503,7 @@ static void startMultiThreadInsertData(int threads, char* db_name, } if ((superTblInfo->childTblExists != TBL_NO_EXISTS) - && (0 == superTblInfo->childTblLimit)) { + && (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"); @@ -5381,7 +5512,7 @@ static void startMultiThreadInsertData(int threads, char* db_name, } superTblInfo->childTblName = (char*)calloc(1, - limit * TSDB_TABLE_NAME_LEN); + limit * TSDB_TABLE_NAME_LEN); if (superTblInfo->childTblName == NULL) { errorPrint("%s() LN%d, alloc memory failed!\n", __func__, __LINE__); taos_close(taos); @@ -5424,15 +5555,15 @@ static void startMultiThreadInsertData(int threads, char* db_name, t_info->minDelay = INT16_MAX; if ((NULL == superTblInfo) || - (0 == strncasecmp(superTblInfo->insertMode, "taosc", 5))) { + (0 == strncasecmp(superTblInfo->insertMode, "taosc", 5))) { //t_info->taos = taos; t_info->taos = taos_connect( - g_Dbs.host, g_Dbs.user, - g_Dbs.password, db_name, g_Dbs.port); + g_Dbs.host, g_Dbs.user, + g_Dbs.password, db_name, g_Dbs.port); if (NULL == t_info->taos) { errorPrint( - "connect to server fail from insert sub thread, reason: %s\n", - taos_errstr(NULL)); + "connect to server fail from insert sub thread, reason: %s\n", + taos_errstr(NULL)); exit(-1); } } else { @@ -5440,7 +5571,7 @@ static void startMultiThreadInsertData(int threads, char* db_name, } if ((NULL == superTblInfo) - || (0 == superTblInfo->multiThreadWriteOneTbl)) { + || (0 == superTblInfo->multiThreadWriteOneTbl)) { t_info->start_table_from = startFrom; t_info->ntables = iend_table_to = i < b ? startFrom + a : startFrom + a - 1; @@ -5476,15 +5607,15 @@ static void startMultiThreadInsertData(int threads, char* db_name, taos_close(t_info->taos); debugPrint("%s() LN%d, [%d] totalInsert=%"PRId64" totalAffected=%"PRId64"\n", - __func__, __LINE__, - t_info->threadID, t_info->totalInsertRows, - t_info->totalAffectedRows); + __func__, __LINE__, + t_info->threadID, t_info->totalInsertRows, + t_info->totalAffectedRows); if (superTblInfo) { - superTblInfo->totalAffectedRows += t_info->totalAffectedRows; - superTblInfo->totalInsertRows += t_info->totalInsertRows; + superTblInfo->totalAffectedRows += t_info->totalAffectedRows; + superTblInfo->totalInsertRows += t_info->totalInsertRows; } else { - g_args.totalAffectedRows += t_info->totalAffectedRows; - g_args.totalInsertRows += t_info->totalInsertRows; + g_args.totalAffectedRows += t_info->totalAffectedRows; + g_args.totalInsertRows += t_info->totalInsertRows; } totalDelay += t_info->totalDelay; @@ -5497,39 +5628,39 @@ static void startMultiThreadInsertData(int threads, char* db_name, if (cntDelay == 0) cntDelay = 1; avgDelay = (double)totalDelay / cntDelay; - double end = getCurrentTimeUs(); - double t = end - start; + int64_t end = taosGetTimestampMs(); + int64_t t = end - start; if (superTblInfo) { - printf("Spent %.4f seconds to insert rows: %"PRId64", affected rows: %"PRId64" with %d thread(s) into %s.%s. %2.f records/second\n\n", - t, superTblInfo->totalInsertRows, - superTblInfo->totalAffectedRows, - threads, db_name, superTblInfo->sTblName, - superTblInfo->totalInsertRows / t); + printf("Spent %.2f seconds to insert rows: %"PRId64", affected rows: %"PRId64" with %d thread(s) into %s.%s. %2.f records/second\n\n", + t / 1000.0, superTblInfo->totalInsertRows, + superTblInfo->totalAffectedRows, + threads, db_name, superTblInfo->sTblName, + (double)superTblInfo->totalInsertRows / (t / 1000.0)); fprintf(g_fpOfInsertResult, - "Spent %.4f seconds to insert rows: %"PRId64", affected rows: %"PRId64" with %d thread(s) into %s.%s. %2.f records/second\n\n", - t, superTblInfo->totalInsertRows, - superTblInfo->totalAffectedRows, - threads, db_name, superTblInfo->sTblName, - superTblInfo->totalInsertRows/ t); + "Spent %.2f seconds to insert rows: %"PRId64", affected rows: %"PRId64" with %d thread(s) into %s.%s. %2.f records/second\n\n", + t / 1000.0, superTblInfo->totalInsertRows, + superTblInfo->totalAffectedRows, + threads, db_name, superTblInfo->sTblName, + (double)superTblInfo->totalInsertRows / (t / 1000.0)); } else { - printf("Spent %.4f seconds to insert rows: %"PRId64", affected rows: %"PRId64" with %d thread(s) into %s %2.f records/second\n\n", - t, g_args.totalInsertRows, - g_args.totalAffectedRows, - threads, db_name, - g_args.totalInsertRows / t); + printf("Spent %.2f seconds to insert rows: %"PRId64", affected rows: %"PRId64" with %d thread(s) into %s %2.f records/second\n\n", + t / 1000.0, g_args.totalInsertRows, + g_args.totalAffectedRows, + threads, db_name, + (double)g_args.totalInsertRows / (t / 1000.0)); fprintf(g_fpOfInsertResult, - "Spent %.4f seconds to insert rows: %"PRId64", affected rows: %"PRId64" with %d thread(s) into %s %2.f records/second\n\n", - t, g_args.totalInsertRows, - g_args.totalAffectedRows, - threads, db_name, - g_args.totalInsertRows / t); + "Spent %.2f seconds to insert rows: %"PRId64", affected rows: %"PRId64" with %d thread(s) into %s %2.f records/second\n\n", + t * 1000.0, g_args.totalInsertRows, + g_args.totalAffectedRows, + threads, db_name, + (double)g_args.totalInsertRows / (t / 1000.0)); } - printf("insert delay, avg: %10.6fms, max: %10.6fms, min: %10.6fms\n\n", - avgDelay/1000.0, (double)maxDelay/1000.0, (double)minDelay/1000.0); - fprintf(g_fpOfInsertResult, "insert delay, avg:%10.6fms, max: %10.6fms, min: %10.6fms\n\n", - avgDelay/1000.0, (double)maxDelay/1000.0, (double)minDelay/1000.0); + printf("insert delay, avg: %10.2fms, max: %"PRId64"ms, min: %"PRId64"ms\n\n", + avgDelay, maxDelay, minDelay); + fprintf(g_fpOfInsertResult, "insert delay, avg:%10.2fms, max: %"PRId64"ms, min: %"PRId64"ms\n\n", + avgDelay, maxDelay, minDelay); //taos_close(taos); @@ -5550,12 +5681,12 @@ static void *readTable(void *sarg) { return NULL; } - int num_of_DPT; + int num_of_DPT; /* if (rinfo->superTblInfo) { num_of_DPT = rinfo->superTblInfo->insertRows; // nrecords_per_table; } else { */ - num_of_DPT = g_args.num_of_DPT; + num_of_DPT = g_args.num_of_DPT; // } int num_of_tables = rinfo->ntables; // rinfo->end_table_to - rinfo->start_table_from + 1; @@ -5576,7 +5707,7 @@ static void *readTable(void *sarg) { sprintf(command, "select %s from %s%d where ts>= %" PRId64, aggreFunc[j], tb_prefix, i, sTime); - double t = getCurrentTimeUs(); + double t = taosGetTimestampMs(); TAOS_RES *pSql = taos_query(taos, command); int32_t code = taos_errno(pSql); @@ -5592,7 +5723,7 @@ static void *readTable(void *sarg) { count++; } - t = getCurrentTimeUs() - t; + t = taosGetTimestampMs() - t; totalT += t; taos_free_result(pSql); @@ -5601,7 +5732,7 @@ static void *readTable(void *sarg) { fprintf(fp, "|%10s | %10d | %12.2f | %10.2f |\n", aggreFunc[j][0] == '*' ? " * " : aggreFunc[j], totalData, (double)(num_of_tables * num_of_DPT) / totalT, totalT * 1000); - printf("select %10s took %.6f second(s)\n", aggreFunc[j], totalT); + printf("select %10s took %.6f second(s)\n", aggreFunc[j], totalT * 1000); } fprintf(fp, "\n"); fclose(fp); @@ -5651,7 +5782,7 @@ static void *readMetric(void *sarg) { printf("Where condition: %s\n", condition); fprintf(fp, "%s\n", command); - double t = getCurrentTimeUs(); + double t = taosGetTimestampMs(); TAOS_RES *pSql = taos_query(taos, command); int32_t code = taos_errno(pSql); @@ -5667,11 +5798,11 @@ static void *readMetric(void *sarg) { while(taos_fetch_row(pSql) != NULL) { count++; } - t = getCurrentTimeUs() - t; + t = taosGetTimestampMs() - t; fprintf(fp, "| Speed: %12.2f(per s) | Latency: %.4f(ms) |\n", - num_of_tables * num_of_DPT / t, t * 1000); - printf("select %10s took %.6f second(s)\n\n", aggreFunc[j], t); + num_of_tables * num_of_DPT / (t * 1000.0), t); + printf("select %10s took %.6f second(s)\n\n", aggreFunc[j], t * 1000.0); taos_free_result(pSql); } @@ -5721,21 +5852,21 @@ static int insertTestProcess() { double end; // create child tables - start = getCurrentTimeUs(); + start = taosGetTimestampMs(); createChildTables(); - end = getCurrentTimeUs(); + end = taosGetTimestampMs(); if (g_totalChildTables > 0) { printf("Spent %.4f seconds to create %d tables with %d thread(s)\n\n", - end - start, g_totalChildTables, g_Dbs.threadCountByCreateTbl); + (end - start)/1000.0, g_totalChildTables, g_Dbs.threadCountByCreateTbl); fprintf(g_fpOfInsertResult, "Spent %.4f seconds to create %d tables with %d thread(s)\n\n", - end - start, g_totalChildTables, g_Dbs.threadCountByCreateTbl); + (end - start)/1000.0, g_totalChildTables, g_Dbs.threadCountByCreateTbl); } taosMsleep(1000); // create sub threads for inserting data - //start = getCurrentTimeUs(); + //start = taosGetTimestampMs(); for (int i = 0; i < g_Dbs.dbCount; i++) { if (g_Dbs.use_metric) { if (g_Dbs.db[i].superTblCount > 0) { @@ -5745,22 +5876,22 @@ static int insertTestProcess() { if (superTblInfo && (superTblInfo->insertRows > 0)) { startMultiThreadInsertData( - g_Dbs.threadCount, - g_Dbs.db[i].dbName, - g_Dbs.db[i].dbCfg.precision, - superTblInfo); + g_Dbs.threadCount, + g_Dbs.db[i].dbName, + g_Dbs.db[i].dbCfg.precision, + superTblInfo); } } } } else { - startMultiThreadInsertData( + startMultiThreadInsertData( g_Dbs.threadCount, g_Dbs.db[i].dbName, g_Dbs.db[i].dbCfg.precision, NULL); } } - //end = getCurrentTimeUs(); + //end = taosGetTimestampMs(); //int64_t totalInsertRows = 0; //int64_t totalAffectedRows = 0; @@ -5781,13 +5912,13 @@ static void *specifiedTableQuery(void *sarg) { if (pThreadInfo->taos == NULL) { TAOS * taos = NULL; taos = taos_connect(g_queryInfo.host, - g_queryInfo.user, - g_queryInfo.password, - NULL, - g_queryInfo.port); + g_queryInfo.user, + g_queryInfo.password, + NULL, + g_queryInfo.port); if (taos == NULL) { errorPrint("[%d] Failed to connect to TDengine, reason:%s\n", - pThreadInfo->threadID, taos_errstr(NULL)); + pThreadInfo->threadID, taos_errstr(NULL)); return NULL; } else { pThreadInfo->taos = taos; @@ -5813,16 +5944,15 @@ static void *specifiedTableQuery(void *sarg) { 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, pThreadInfo->start_table_from, pThreadInfo->end_table_to); + if (g_queryInfo.specifiedQueryInfo.queryInterval && (et - st) < + (int64_t)g_queryInfo.specifiedQueryInfo.queryInterval) { + taosMsleep(g_queryInfo.specifiedQueryInfo.queryInterval - (et - st)); // ms } - st = taosGetTimestampUs(); + st = taosGetTimestampMs(); if (0 == strncasecmp(g_queryInfo.queryMode, "taosc", 5)) { - int64_t t1 = taosGetTimestampUs(); + int64_t t1 = taosGetTimestampMs(); char tmpFile[MAX_FILE_NAME_LEN*2] = {0}; if (g_queryInfo.specifiedQueryInfo.result[pThreadInfo->querySeq][0] != 0) { sprintf(tmpFile, "%s-%d", @@ -5830,38 +5960,39 @@ static void *specifiedTableQuery(void *sarg) { 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); + g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq], tmpFile); + int64_t t2 = taosGetTimestampMs(); + printf("=[taosc] thread[%"PRId64"] complete one sql, Spent %10.3f s\n", + taosGetSelfPthreadId(), (t2 - t1)/1000.0); } else { - int64_t t1 = taosGetTimestampUs(); + int64_t t1 = taosGetTimestampMs(); int retCode = postProceSql(g_queryInfo.host, - g_queryInfo.port, - g_queryInfo.specifiedQueryInfo.sql[pThreadInfo->querySeq]); + 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); + int64_t t2 = taosGetTimestampMs(); + printf("=[restful] thread[%"PRId64"] complete one sql, Spent %10.3f s\n", + taosGetSelfPthreadId(), (t2 - t1)/1000.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); + + et = taosGetTimestampMs(); 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", + debugPrint("%s() LN%d, endTs=%"PRId64"ms, startTs=%"PRId64"ms\n", + __func__, __LINE__, endTs, startTs); + printf("thread[%d] has currently completed queries: %d, QPS: %10.6f\n", pThreadInfo->threadID, totalQueried, - totalQueried/((endTs-startTs)/1000.0)); + (double)(totalQueried/((endTs-startTs)/1000.0))); } lastPrintTime = currentPrintTime; } @@ -5903,7 +6034,7 @@ static void *superTableQuery(void *sarg) { g_queryInfo.port); if (taos == NULL) { errorPrint("[%d] Failed to connect to TDengine, reason:%s\n", - pThreadInfo->threadID, taos_errstr(NULL)); + pThreadInfo->threadID, taos_errstr(NULL)); return NULL; } else { pThreadInfo->taos = taos; @@ -5911,7 +6042,7 @@ static void *superTableQuery(void *sarg) { } int64_t st = 0; - int64_t et = (int64_t)g_queryInfo.superQueryInfo.rate*1000; + int64_t et = (int64_t)g_queryInfo.superQueryInfo.queryInterval; int queryTimes = g_queryInfo.superQueryInfo.queryTimes; int totalQueried = 0; @@ -5919,13 +6050,13 @@ static void *superTableQuery(void *sarg) { 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 + if (g_queryInfo.superQueryInfo.queryInterval + && (et - st) < (int64_t)g_queryInfo.superQueryInfo.queryInterval) { + taosMsleep(g_queryInfo.superQueryInfo.queryInterval - (et - st)); // ms //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(); + st = taosGetTimestampMs(); 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)); @@ -5944,20 +6075,20 @@ static void *superTableQuery(void *sarg) { 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", + printf("thread[%d] has currently completed queries: %d, QPS: %10.3f\n", pThreadInfo->threadID, totalQueried, - totalQueried/((endTs-startTs)/1000.0)); + (double)(totalQueried/((endTs-startTs)/1000.0))); } lastPrintTime = currentPrintTime; } } - et = taosGetTimestampUs(); + et = taosGetTimestampMs(); printf("####thread[%"PRId64"] complete all sqls to allocate all sub-tables[%d - %d] once queries duration:%.4fs\n\n", taosGetSelfPthreadId(), pThreadInfo->start_table_from, pThreadInfo->end_table_to, - (double)(et - st)/1000000.0); + (double)(et - st)/1000.0); } return NULL; @@ -6118,9 +6249,9 @@ static int queryTestProcess() { int totalQueried = g_queryInfo.specifiedQueryInfo.totalQueried + g_queryInfo.superQueryInfo.totalQueried; - printf("==== completed total queries: %d, the QPS of all threads: %10.2f====\n", + printf("==== completed total queries: %d, the QPS of all threads: %10.3f====\n", totalQueried, - totalQueried/((endTs-startTs)/1000.0)); + (double)(totalQueried/((endTs-startTs)/1000.0))); return 0; } @@ -6190,8 +6321,8 @@ static void *superSubscribe(void *sarg) { //int64_t st = 0; //int64_t et = 0; do { - //if (g_queryInfo.specifiedQueryInfo.rate && (et - st) < g_queryInfo.specifiedQueryInfo.rate*1000) { - // taosMsleep(g_queryInfo.specifiedQueryInfo.rate*1000 - (et - st)); // ms + //if (g_queryInfo.specifiedQueryInfo.queryInterval && (et - st) < g_queryInfo.specifiedQueryInfo.queryInterval) { + // taosMsleep(g_queryInfo.specifiedQueryInfo.queryInterval- (et - st)); // ms // //printf("========sleep duration:%"PRId64 "========inserted rows:%d, table range:%d - %d\n", (1000 - (et - st)), i, pThreadInfo->start_table_from, pThreadInfo->end_table_to); //} @@ -6277,8 +6408,8 @@ static void *specifiedSubscribe(void *sarg) { //int64_t st = 0; //int64_t et = 0; do { - //if (g_queryInfo.specifiedQueryInfo.rate && (et - st) < g_queryInfo.specifiedQueryInfo.rate*1000) { - // taosMsleep(g_queryInfo.specifiedQueryInfo.rate*1000 - (et - st)); // ms + //if (g_queryInfo.specifiedQueryInfo.queryInterval && (et - st) < g_queryInfo.specifiedQueryInfo.queryInterval) { + // taosMsleep(g_queryInfo.specifiedQueryInfo.queryInterval- (et - st)); // ms // //printf("========sleep duration:%"PRId64 "========inserted rows:%d, table range:%d - %d\n", (1000 - (et - st)), i, pThreadInfo->start_table_from, pThreadInfo->end_table_to); //} @@ -6628,7 +6759,7 @@ static void querySqlFile(TAOS* taos, char* sqlFile) char * line = NULL; size_t line_len = 0; - double t = getCurrentTimeUs(); + double t = taosGetTimestampMs(); while((read_len = tgetline(&line, &line_len, fp)) != -1) { if (read_len >= MAX_SQL_SIZE) continue; @@ -6659,7 +6790,7 @@ static void querySqlFile(TAOS* taos, char* sqlFile) cmd_len = 0; } - t = getCurrentTimeUs() - t; + t = taosGetTimestampMs() - t; printf("run %s took %.6f second(s)\n\n", sqlFile, t); tmfree(cmd); diff --git a/src/kit/taosdump/taosdump.c b/src/kit/taosdump/taosdump.c index 092374cef1..96a1cd16f8 100644 --- a/src/kit/taosdump/taosdump.c +++ b/src/kit/taosdump/taosdump.c @@ -214,8 +214,8 @@ static struct argp_option options[] = { // 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. Epoch or ISO8601/RFC3339 format is acceptable. For example: 2017-10-01T18:00:00+0800", 3}, + {"start-time", 'S', "START_TIME", 0, "Start time to dump. Either Epoch or ISO8601/RFC3339 format is acceptable. Epoch precision millisecond. ISO8601 format example: 2017-10-01T18:00:00.000+0800 or 2017-10-0100:00:00.000+0800 or '2017-10-01 00:00:00.000+0800'", 3}, + {"end-time", 'E', "END_TIME", 0, "End time to dump. Either Epoch or ISO8601/RFC3339 format is acceptable. Epoch precision millisecond. ISO8601 format example: 2017-10-01T18:00:00.000+0800 or 2017-10-0100:00:00.000+0800 or '2017-10-01 00:00:00.000+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}, @@ -482,7 +482,8 @@ static int queryDbImpl(TAOS *taos, char *command) { static void parse_args(int argc, char *argv[], SArguments *arguments) { for (int i = 1; i < argc; i++) { - if (strcmp(argv[i], "-E") == 0) { + if ((strcmp(argv[i], "-S") == 0) + || (strcmp(argv[i], "-E") == 0)) { if (argv[i+1]) { char *tmp = strdup(argv[++i]); @@ -509,7 +510,7 @@ static void parse_args(int argc, char *argv[], SArguments *arguments) { exit(-1); } } else { - errorPrint("%s() LN%d, -E need a valid value following!\n", __func__, __LINE__); + errorPrint("%s need a valid value following!\n", argv[i]); exit(-1); } } else if (strcmp(argv[i], "-g") == 0) { @@ -522,7 +523,8 @@ int main(int argc, char *argv[]) { /* Parse our arguments; every option seen by parse_opt will be reflected in arguments. */ - parse_args(argc, argv, &g_args); + if (argc > 1) + parse_args(argc, argv, &g_args); argp_parse(&argp, argc, argv, 0, 0, &g_args); diff --git a/src/mnode/src/mnodeProfile.c b/src/mnode/src/mnodeProfile.c index 17a4282d05..459d981138 100644 --- a/src/mnode/src/mnodeProfile.c +++ b/src/mnode/src/mnodeProfile.c @@ -344,7 +344,7 @@ static int32_t mnodeGetQueryMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pC pShow->bytes[cols] = 24; pSchema[cols].type = TSDB_DATA_TYPE_BINARY; - strcpy(pSchema[cols].name, "qhandle"); + strcpy(pSchema[cols].name, "qid"); pSchema[cols].bytes = htons(pShow->bytes[cols]); cols++; @@ -420,7 +420,7 @@ static int32_t mnodeRetrieveQueries(SShowObj *pShow, char *data, int32_t rows, v cols++; char handleBuf[24] = {0}; - snprintf(handleBuf, tListLen(handleBuf), "%p", (void*)htobe64(pDesc->qHandle)); + snprintf(handleBuf, tListLen(handleBuf), "%"PRIu64, htobe64(pDesc->qId)); pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; STR_WITH_MAXSIZE_TO_VARSTR(pWrite, handleBuf, pShow->bytes[cols]); diff --git a/src/os/inc/os.h b/src/os/inc/os.h index a384ac9b06..ff3427dae3 100644 --- a/src/os/inc/os.h +++ b/src/os/inc/os.h @@ -32,6 +32,10 @@ extern "C" { #include "osArm32.h" #endif +#ifdef _TD_MIPS_64 +#include "osMips64.h" +#endif + #ifdef _TD_LINUX_64 #include "osLinux64.h" #endif diff --git a/src/os/inc/osMips64.h b/src/os/inc/osMips64.h new file mode 100644 index 0000000000..ed7b08a311 --- /dev/null +++ b/src/os/inc/osMips64.h @@ -0,0 +1,87 @@ +/* + * 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_OS_MIPS64_H +#define TDENGINE_OS_MIPS64_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/os/src/darwin/darwinSysInfo.c b/src/os/src/darwin/darwinSysInfo.c index 55c07766b3..6e70043779 100644 --- a/src/os/src/darwin/darwinSysInfo.c +++ b/src/os/src/darwin/darwinSysInfo.c @@ -217,7 +217,7 @@ void taosSetCoreDump() {} int32_t taosGetDiskSize(char *dataDir, SysDiskSize *diskSize) { struct statvfs info; - if (statvfs(tsDataDir, &info)) { + if (statvfs(dataDir, &info)) { uError("failed to get disk size, dataDir:%s errno:%s", tsDataDir, strerror(errno)); terrno = TAOS_SYSTEM_ERROR(errno); return -1; diff --git a/src/os/src/detail/osSysinfo.c b/src/os/src/detail/osSysinfo.c index c0d46878a8..bbda08aa25 100644 --- a/src/os/src/detail/osSysinfo.c +++ b/src/os/src/detail/osSysinfo.c @@ -319,7 +319,7 @@ bool taosGetCpuUsage(float *sysCpuUsage, float *procCpuUsage) { int32_t taosGetDiskSize(char *dataDir, SysDiskSize *diskSize) { struct statvfs info; - if (statvfs(tsDataDir, &info)) { + if (statvfs(dataDir, &info)) { uError("failed to get disk size, dataDir:%s errno:%s", tsDataDir, strerror(errno)); terrno = TAOS_SYSTEM_ERROR(errno); return -1; diff --git a/src/os/tests/test.cpp b/src/os/tests/test.cpp index 600e5d71a7..12e9546ff1 100644 --- a/src/os/tests/test.cpp +++ b/src/os/tests/test.cpp @@ -18,7 +18,7 @@ TEST(testCase, parse_time) { deltaToUtcInitOnce(); // window: 1500000001000, 1500002000000 - // pQuery->interval: interval: 86400000, sliding:3600000 + // pQueryAttr->interval: interval: 86400000, sliding:3600000 int64_t key = 1500000001000; SInterval interval = {0}; interval.interval = 86400000; diff --git a/src/plugins/http/inc/httpContext.h b/src/plugins/http/inc/httpContext.h index b016da2dd3..af52fdd1eb 100644 --- a/src/plugins/http/inc/httpContext.h +++ b/src/plugins/http/inc/httpContext.h @@ -25,7 +25,7 @@ const char *httpContextStateStr(HttpContextState state); HttpContext *httpCreateContext(SOCKET fd); bool httpInitContext(HttpContext *pContext); HttpContext *httpGetContext(void * pContext); -void httpReleaseContext(HttpContext *pContext, bool clearRes); +void httpReleaseContext(HttpContext *pContext/*, bool clearRes*/); void httpCloseContextByServer(HttpContext *pContext); void httpCloseContextByApp(HttpContext *pContext); void httpNotifyContextClose(HttpContext *pContext); diff --git a/src/plugins/http/src/httpContext.c b/src/plugins/http/src/httpContext.c index 13f706af65..51adef11b9 100644 --- a/src/plugins/http/src/httpContext.c +++ b/src/plugins/http/src/httpContext.c @@ -146,20 +146,20 @@ HttpContext *httpGetContext(void *ptr) { return NULL; } -void httpReleaseContext(HttpContext *pContext, bool clearRes) { +void httpReleaseContext(HttpContext *pContext/*, bool clearRes*/) { int32_t refCount = atomic_sub_fetch_32(&pContext->refCount, 1); if (refCount < 0) { httpError("context:%p, is already released, refCount:%d", pContext, refCount); return; } - + /* if (clearRes) { if (pContext->parser) { httpClearParser(pContext->parser); } memset(&pContext->singleCmd, 0, sizeof(HttpSqlCmd)); } - + */ HttpContext **ppContext = pContext->ppContext; httpTrace("context:%p, is released, data:%p refCount:%d", pContext, ppContext, refCount); @@ -217,7 +217,7 @@ void httpCloseContextByApp(HttpContext *pContext) { httpContextStateStr(pContext->state), pContext->state); } - httpReleaseContext(pContext, true); + httpReleaseContext(pContext/*, true*/); } void httpCloseContextByServer(HttpContext *pContext) { @@ -235,5 +235,5 @@ void httpCloseContextByServer(HttpContext *pContext) { pContext->parsed = false; httpRemoveContextFromEpoll(pContext); - httpReleaseContext(pContext, true); + httpReleaseContext(pContext/*, true*/); } diff --git a/src/plugins/http/src/httpHandle.c b/src/plugins/http/src/httpHandle.c index ad79e24061..d51c774ff2 100644 --- a/src/plugins/http/src/httpHandle.c +++ b/src/plugins/http/src/httpHandle.c @@ -50,6 +50,7 @@ bool httpProcessData(HttpContext* pContext) { */ // httpCloseContextByApp(pContext); } else { + httpClearParser(pContext->parser); httpProcessRequest(pContext); } } diff --git a/src/plugins/http/src/httpServer.c b/src/plugins/http/src/httpServer.c index a5f40fdc4c..4dcf3d5501 100644 --- a/src/plugins/http/src/httpServer.c +++ b/src/plugins/http/src/httpServer.c @@ -177,7 +177,7 @@ static void httpProcessHttpData(void *param) { if (!httpAlterContextState(pContext, HTTP_CONTEXT_STATE_READY, HTTP_CONTEXT_STATE_READY)) { httpDebug("context:%p, fd:%d, state:%s, not in ready state, ignore read events", pContext, pContext->fd, httpContextStateStr(pContext->state)); - httpReleaseContext(pContext, true); + httpReleaseContext(pContext/*, true*/); continue; } @@ -191,7 +191,7 @@ static void httpProcessHttpData(void *param) { (*(pThread->processData))(pContext); atomic_fetch_add_32(&pServer->requestNum, 1); } else { - httpReleaseContext(pContext, false); + httpReleaseContext(pContext/*, false*/); } } } @@ -275,7 +275,7 @@ static void *httpAcceptHttpConnection(void *arg) { httpError("context:%p, fd:%d, ip:%s, thread:%s, failed to add http fd for epoll, error:%s", pContext, connFd, pContext->ipstr, pThread->label, strerror(errno)); taosCloseSocket(pContext->fd); - httpReleaseContext(pContext, true); + httpReleaseContext(pContext/*, true*/); continue; } diff --git a/src/plugins/http/src/httpSql.c b/src/plugins/http/src/httpSql.c index 4e9b54b7bd..b345c1531f 100644 --- a/src/plugins/http/src/httpSql.c +++ b/src/plugins/http/src/httpSql.c @@ -376,6 +376,8 @@ void httpExecCmd(HttpContext *pContext) { httpCloseContextByApp(pContext); break; } + + memset(&pContext->singleCmd, 0, sizeof(HttpSqlCmd)); } void httpProcessRequestCb(void *param, TAOS_RES *result, int32_t code) { diff --git a/src/query/inc/qAggMain.h b/src/query/inc/qAggMain.h index b31b8ba775..7ea578e68f 100644 --- a/src/query/inc/qAggMain.h +++ b/src/query/inc/qAggMain.h @@ -123,7 +123,7 @@ enum { #define QUERY_IS_FREE_RESOURCE(type) (((type)&TSDB_QUERY_TYPE_FREE_RESOURCE) != 0) typedef struct SArithmeticSupport { - SExprInfo *pArithExpr; + SExprInfo *pExprInfo; int32_t numOfCols; SColumnInfo *colList; void *exprList; // client side used @@ -211,9 +211,6 @@ typedef struct SAggFunctionInfo { void (*xFunction)(SQLFunctionCtx *pCtx); // blocks version function void (*xFunctionF)(SQLFunctionCtx *pCtx, int32_t position); // single-row function version, todo merge with blockwise function - // some sql function require scan data twice or more, e.g.,stddev, percentile - void (*xNextStep)(SQLFunctionCtx *pCtx); - // finalizer must be called after all xFunction has been executed to generated final result. void (*xFinalize)(SQLFunctionCtx *pCtx); void (*mergeFunc)(SQLFunctionCtx *pCtx); diff --git a/src/query/inc/qExecutor.h b/src/query/inc/qExecutor.h index 170683d00d..5c8ac615f9 100644 --- a/src/query/inc/qExecutor.h +++ b/src/query/inc/qExecutor.h @@ -87,7 +87,7 @@ 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 - STimeWindow win; + STimeWindow win; char* key; // start key of current result row } SResultRow; @@ -179,8 +179,11 @@ typedef struct SSDataBlock { SDataBlockInfo info; } SSDataBlock; -typedef struct SQuery { +// The basic query information extracted from the SQueryInfo tree to support the +// execution of query in a data node. +typedef struct SQueryAttr { SLimitVal limit; + SLimitVal slimit; bool stableQuery; // super table query or not bool topBotQuery; // TODO used bitwise flag @@ -189,6 +192,11 @@ typedef struct SQuery { bool timeWindowInterpo;// if the time window start/end required interpolation bool queryBlockDist; // if query data block distribution bool stabledev; // super table stddev query + bool tsCompQuery; // is tscomp query + bool simpleAgg; + bool pointInterpQuery; // point interpolation query + bool needReverseScan; // need reverse scan + bool distinctTag; // distinct tag query int32_t interBufSize; // intermediate buffer sizse int32_t havingNum; // having expr number @@ -203,39 +211,41 @@ typedef struct SQuery { int16_t precision; int16_t numOfOutput; int16_t fillType; - int16_t checkResultBuf; // check if the buffer is full during scan each block int32_t srcRowSize; // todo extract struct int32_t resultRowSize; int32_t intermediateResultRowSize; // intermediate result row size, in case of top-k query. - int32_t maxSrcColumnSize; + int32_t maxTableColumnWidth; int32_t tagLen; // tag value length of current query SSqlGroupbyExpr* pGroupbyExpr; + SExprInfo* pExpr1; SExprInfo* pExpr2; int32_t numOfExpr2; - SColumnInfo* colList; + SExprInfo* pExpr3; + int32_t numOfExpr3; + + SColumnInfo* tableCols; SColumnInfo* tagColList; int32_t numOfFilterCols; int64_t* fillVal; SOrderedPrjQueryInfo prjInfo; // limit value for each vgroup, only available in global order projection query. SSingleColumnFilterInfo* pFilterInfo; - STableQueryInfo* current; void* tsdb; SMemRef memRef; STableGroupInfo tableGroupInfo; // table list SArray int32_t vgId; -} SQuery; +} SQueryAttr; -typedef SSDataBlock* (*__operator_fn_t)(void* param); +typedef SSDataBlock* (*__operator_fn_t)(void* param, bool* newgroup); typedef void (*__optr_cleanup_fn_t)(void* param, int32_t num); struct SOperatorInfo; typedef struct SQueryRuntimeEnv { jmp_buf env; - SQuery* pQuery; + SQueryAttr* pQueryAttr; uint32_t status; // query status void* qinfo; uint8_t scanFlag; // denotes reversed scan of data or not @@ -258,10 +268,10 @@ typedef struct SQueryRuntimeEnv { SSDataBlock *outputBuf; STableGroupInfo tableqinfoGroupInfo; // this is a group array list, including SArray structure struct SOperatorInfo *proot; - struct SOperatorInfo *pTableScanner; // table scan operator SGroupResInfo groupResInfo; int64_t currentOffset; // dynamic offset value + STableQueryInfo *current; SRspResultInfo resultInfo; SHashObj *pTableRetrieveTsMap; SUdfInfo *pUdfInfo; @@ -283,13 +293,17 @@ enum OPERATOR_TYPE_E { OP_Arithmetic = 7, OP_Groupby = 8, OP_Limit = 9, - OP_Offset = 10, + OP_SLimit = 10, OP_TimeWindow = 11, OP_SessionWindow = 12, OP_Fill = 13, OP_MultiTableAggregate = 14, OP_MultiTableTimeInterval = 15, - OP_Having = 16, + OP_DummyInput = 16, //TODO remove it after fully refactor. + OP_MultiwayMergeSort = 17, // multi-way data merge into one input stream. + OP_GlobalAggregate = 18, // global merge for the multi-way data sources. + OP_Filter = 19, + OP_Distinct = 20, }; typedef struct SOperatorInfo { @@ -312,6 +326,12 @@ enum { QUERY_RESULT_READY = 2, }; +typedef struct { + int32_t numOfTags; + int32_t numOfCols; + SColumnInfo *colList; +} SQueriedTableInfo; + typedef struct SQInfo { void* signature; uint64_t qId; @@ -319,7 +339,7 @@ typedef struct SQInfo { int64_t owner; // if it is in execution SQueryRuntimeEnv runtimeEnv; - SQuery query; + SQueryAttr query; void* pBuf; // allocated buffer for STableQueryInfo, sizeof(STableQueryInfo)*numOfTables; pthread_mutex_t lock; // used to synchronize the rsp/query threads @@ -337,14 +357,16 @@ typedef struct SQueryParam { char *tbnameCond; char *prevResult; SArray *pTableIdList; - SSqlFuncMsg **pExprMsg; - SSqlFuncMsg **pSecExprMsg; + SSqlExpr **pExpr; + SSqlExpr **pSecExpr; SExprInfo *pExprs; SExprInfo *pSecExprs; SColIndex *pGroupColIndex; SColumnInfo *pTagColumnInfo; SSqlGroupbyExpr *pGroupbyExpr; + int32_t tableScanOperator; + SArray *pOperator; SUdfInfo *pUdfInfo; } SQueryParam; @@ -397,26 +419,39 @@ typedef struct SArithOperatorInfo { SOptrBasicInfo binfo; int32_t bufCapacity; uint32_t seed; + + SSDataBlock *existDataBlock; } SArithOperatorInfo; typedef struct SLimitOperatorInfo { - int64_t limit; - int64_t total; + int64_t limit; + int64_t total; } SLimitOperatorInfo; -typedef struct SOffsetOperatorInfo { - int64_t offset; -} SOffsetOperatorInfo; +typedef struct SSLimitOperatorInfo { + int64_t groupTotal; + int64_t currentGroupOffset; -typedef struct SHavingOperatorInfo { - SArray* fp; -} SHavingOperatorInfo; + int64_t rowsTotal; + int64_t currentOffset; + SLimitVal limit; + SLimitVal slimit; + char **prevRow; + SArray *orderColumnList; +} SSLimitOperatorInfo; + +typedef struct SFilterOperatorInfo { + SSingleColumnFilterInfo *pFilterInfo; + int32_t numOfFilterCols; +} SFilterOperatorInfo; typedef struct SFillOperatorInfo { SFillInfo *pFillInfo; SSDataBlock *pRes; int64_t totalInputRows; + + SSDataBlock *existNewGroupBlock; } SFillOperatorInfo; typedef struct SGroupbyOperatorInfo { @@ -433,27 +468,97 @@ typedef struct SSWindowOperatorInfo { int32_t start; // start row index } SSWindowOperatorInfo; +typedef struct SDistinctOperatorInfo { + SHashObj *pSet; + SSDataBlock *pRes; + bool recordNullVal; //has already record the null value, no need to try again + int64_t threshold; + int64_t outputCapacity; +} SDistinctOperatorInfo; + +struct SLocalMerger; + +typedef struct SMultiwayMergeInfo { + struct SLocalMerger *pMerge; + SOptrBasicInfo binfo; + int32_t bufCapacity; + int64_t seed; + char **prevRow; + SArray *orderColumnList; + int32_t resultRowFactor; + + bool hasGroupColData; + char **currentGroupColData; + SArray *groupColumnList; + bool hasDataBlockForNewGroup; + SSDataBlock *pExistBlock; + + bool hasPrev; + bool groupMix; +} SMultiwayMergeInfo; + +SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime, int32_t reverseTime); +SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime); +SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv); + +SOperatorInfo* createAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createArithOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream); +SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createTagScanOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); +SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv); +SOperatorInfo* createMultiwaySortOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput, + int32_t numOfRows, void* merger, bool groupMix); +SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* param); +SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* merger); +SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); + +SSDataBlock* doGlobalAggregate(void* param, bool* newgroup); +SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup); +SSDataBlock* doSLimit(void* param, bool* newgroup); + +SSDataBlock* createOutputBuf(SExprInfo* pExpr, int32_t numOfOutput, int32_t numOfRows); +void* destroyOutputBuf(SSDataBlock* pBlock); + +void setInputDataBlock(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order); +int32_t getNumOfResult(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput); +void finalizeQueryResult(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset); +void updateOutputBuf(SOptrBasicInfo* pBInfo, int32_t *bufCapacity, int32_t numOfInputRows); + void freeParam(SQueryParam *param); int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param); -int32_t createQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t numOfOutput, SExprInfo **pExprInfo, SSqlFuncMsg **pExprMsg, - SColumnInfo* pTagCols, SUdfInfo* pUdfInfo); +int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExprInfo** pExprInfo, + SSqlExpr** pExprMsg, SColumnInfo* pTagCols, int32_t queryType, void* pMsg, SUdfInfo* pUdfInfo); + int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t numOfOutput, SExprInfo **pExprInfo, - SSqlFuncMsg **pExprMsg, SExprInfo *prevExpr, SUdfInfo *pUdfInfo); + SSqlExpr **pExpr, SExprInfo *prevExpr, SUdfInfo *pUdfInfo); SSqlGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pColIndex, int32_t *code); SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SSqlGroupbyExpr *pGroupbyExpr, SExprInfo *pExprs, SExprInfo *pSecExprs, STableGroupInfo *pTableGroupInfo, SColumnInfo* pTagCols, bool stableQuery, char* sql, uint64_t *qId, SUdfInfo* pUdfInfo); -int32_t initQInfo(SQueryTableMsg *pQueryMsg, void *tsdb, int32_t vgId, SQInfo *pQInfo, SQueryParam* param, bool isSTable); + +int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* pQInfo, SQueryParam* param, char* start, + int32_t prevResultLen, void* merger); + void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters); +STableQueryInfo *createTableQueryInfo(SQueryAttr* pQueryAttr, void* pTable, bool groupbyColumn, STimeWindow win, void* buf); +int32_t buildArithmeticExprFromMsg(SExprInfo *pArithExprInfo, void *pQueryMsg); + bool isQueryKilled(SQInfo *pQInfo); int32_t checkForQueryBuf(size_t numOfTables); bool doBuildResCheck(SQInfo* pQInfo); void setQueryStatus(SQueryRuntimeEnv *pRuntimeEnv, int8_t status); +bool onlyQueryTags(SQueryAttr* pQueryAttr); void destroyUdfInfo(SUdfInfo* pUdfInfo); -bool onlyQueryTags(SQuery* pQuery); bool isValidQInfo(void *param); int32_t doDumpQueryResult(SQInfo *pQInfo, char *data); @@ -462,6 +567,7 @@ size_t getResultSize(SQInfo *pQInfo, int64_t *numOfRows); void setQueryKilled(SQInfo *pQInfo); void queryCostStatis(SQInfo *pQInfo); void freeQInfo(SQInfo *pQInfo); +void freeQueryAttr(SQueryAttr *pQuery); int32_t getMaximumIdleDurationSec(); diff --git a/src/query/inc/qExtbuffer.h b/src/query/inc/qExtbuffer.h index df6e64ddd8..b851fbb3e0 100644 --- a/src/query/inc/qExtbuffer.h +++ b/src/query/inc/qExtbuffer.h @@ -237,6 +237,11 @@ int32_t compare_a(tOrderDescriptor *, int32_t numOfRow1, int32_t s1, char *data1 int32_t compare_d(tOrderDescriptor *, int32_t numOfRow1, int32_t s1, char *data1, int32_t numOfRow2, int32_t s2, char *data2); +struct SSDataBlock; +int32_t compare_aRv(struct SSDataBlock* pBlock, SArray* colIndex, int32_t numOfCols, int32_t rowIndex, char** buffer, int32_t order); + +int32_t columnValueAscendingComparator(char *f1, char *f2, int32_t type, int32_t bytes); + #ifdef __cplusplus } #endif diff --git a/src/query/inc/qPlan.h b/src/query/inc/qPlan.h new file mode 100644 index 0000000000..8f35565e4b --- /dev/null +++ b/src/query/inc/qPlan.h @@ -0,0 +1,24 @@ +/* + * 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_QPLAN_H +#define TDENGINE_QPLAN_H + +//TODO refactor +SArray* createTableScanPlan(SQueryAttr* pQueryAttr); +SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr); +SArray* createGlobalMergePlan(SQueryAttr* pQueryAttr); + +#endif // TDENGINE_QPLAN_H diff --git a/src/query/inc/qSqlparser.h b/src/query/inc/qSqlparser.h index ff6d25e1ff..44a8ed1ece 100644 --- a/src/query/inc/qSqlparser.h +++ b/src/query/inc/qSqlparser.h @@ -40,8 +40,14 @@ enum SQL_NODE_TYPE { }; enum SQL_NODE_FROM_TYPE { - SQL_NODE_FROM_SUBQUERY = 1, - SQL_NODE_FROM_NAMELIST = 2, + SQL_NODE_FROM_SUBQUERY = 1, + SQL_NODE_FROM_TABLELIST = 2, +}; + +enum SQL_EXPR_FLAG { + EXPR_FLAG_TS_ERROR = 1, + EXPR_FLAG_US_TIMESTAMP = 2, + EXPR_FLAG_TIMESTAMP_VAR = 3, }; extern char tTokenTypeSwitcher[13]; @@ -83,11 +89,11 @@ typedef struct SSessionWindowVal { SStrToken gap; } SSessionWindowVal; -struct SFromInfo; +struct SRelationInfo; -typedef struct SQuerySqlNode { - struct SArray *pSelectList; // select clause - struct SFromInfo *from; // from clause SArray +typedef struct SSqlNode { + struct SArray *pSelNodeList; // select clause + struct SRelationInfo *from; // from clause SArray struct tSqlExpr *pWhere; // where clause [optional] SArray *pGroupby; // groupby clause, only for tags[optional], SArray SArray *pSortOrder; // orderby [optional], SArray @@ -99,25 +105,17 @@ typedef struct SQuerySqlNode { SLimitVal slimit; // group limit offset [optional] SStrToken sqlstr; // sql string in select clause struct tSqlExpr *pHaving; // having clause [optional] -} SQuerySqlNode; +} SSqlNode; typedef struct STableNamePair { SStrToken name; SStrToken aliasName; } STableNamePair; -typedef struct SSubclauseInfo { // "UNION" multiple select sub-clause - SQuerySqlNode **pClause; - int32_t numOfClause; -} SSubclauseInfo; - -typedef struct SFromInfo { - int32_t type; // nested query|table name list - union { - SSubclauseInfo *pNode; - SArray *tableList; // SArray - }; -} SFromInfo; +typedef struct SRelationInfo { + int32_t type; // nested query|table name list + SArray *list; // SArray|SArray +} SRelationInfo; typedef struct SCreatedTableInfo { SStrToken name; // table name token @@ -140,7 +138,7 @@ typedef struct SCreateTableSql { } colInfo; SArray *childTableInfo; // SArray - SQuerySqlNode *pSelect; + SSqlNode *pSelect; } SCreateTableSql; typedef struct SAlterTableInfo { @@ -227,7 +225,7 @@ typedef struct SMiscInfo { typedef struct SSqlInfo { int32_t type; bool valid; - SSubclauseInfo subclauseInfo; + SArray *list; // todo refactor char msg[256]; union { SCreateTableSql *pCreateTableInfo; @@ -247,7 +245,8 @@ typedef struct tSqlExpr { SStrToken colInfo; // table column info tVariant value; // the use input value SStrToken token; // original sql expr string - + uint32_t flags; + struct tSqlExpr *pLeft; // left child struct tSqlExpr *pRight; // right child struct SArray *pParam; // function parameters list @@ -264,14 +263,9 @@ 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); +SRelationInfo *setTableNameList(SRelationInfo* pFromInfo, SStrToken *pName, SStrToken* pAlias); +SRelationInfo *setSubquery(SRelationInfo* pFromInfo, SArray* pSqlNode); +void *destroyRelationInfo(SRelationInfo* pFromInfo); // sql expr leaf node tSqlExpr *tSqlExprCreateIdValue(SStrToken *pToken, int32_t optrType); @@ -286,23 +280,23 @@ void tSqlExprDestroy(tSqlExpr *pExpr); SArray *tSqlExprListAppend(SArray *pList, tSqlExpr *pNode, SStrToken *pDistinct, SStrToken *pToken); void tSqlExprListDestroy(SArray *pList); -SQuerySqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelectList, SFromInfo *pFrom, tSqlExpr *pWhere, +SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelationInfo *pFrom, tSqlExpr *pWhere, SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval, SSessionWindowVal *ps, SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *pgLimit, tSqlExpr *pHaving); +int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right); -SCreateTableSql *tSetCreateTableInfo(SArray *pCols, SArray *pTags, SQuerySqlNode *pSelect, int32_t type); +SCreateTableSql *tSetCreateTableInfo(SArray *pCols, SArray *pTags, SSqlNode *pSelect, int32_t type); SAlterTableInfo *tSetAlterTableInfo(SStrToken *pTableName, SArray *pCols, SArray *pVals, int32_t type, int16_t tableTable); SCreatedTableInfo createNewChildTableInfo(SStrToken *pTableName, SArray *pTagNames, SArray *pTagVals, SStrToken *pToken, SStrToken* igExists); -void destroyAllSelectClause(SSubclauseInfo *pSql); -void destroyQuerySqlNode(SQuerySqlNode *pSql); +void destroyAllSqlNode(SArray *pSqlNode); +void destroySqlNode(SSqlNode *pSql); void freeCreateTableInfo(void* p); -SSqlInfo *setSqlInfo(SSqlInfo *pInfo, void *pSqlExprInfo, SStrToken *pTableName, int32_t type); -SSubclauseInfo *setSubclause(SSubclauseInfo *pClause, void *pSqlExprInfo); - -SSubclauseInfo *appendSelectClause(SSubclauseInfo *pInfo, void *pSubclause); +SSqlInfo *setSqlInfo(SSqlInfo *pInfo, void *pSqlExprInfo, SStrToken *pTableName, int32_t type); +SArray *setSubclause(SArray *pList, void *pSqlNode); +SArray *appendSelectClause(SArray *pList, void *pSubclause); void setCreatedTableName(SSqlInfo *pInfo, SStrToken *pTableNameToken, SStrToken *pIfNotExists); diff --git a/src/query/inc/qUtil.h b/src/query/inc/qUtil.h index b9d52da39b..c6ffcf7181 100644 --- a/src/query/inc/qUtil.h +++ b/src/query/inc/qUtil.h @@ -28,9 +28,9 @@ #define GET_QID(_r) (((SQInfo*)((_r)->qinfo))->qId) #define curTimeWindowIndex(_winres) ((_winres)->curIndex) -#define GET_ROW_PARAM_FOR_MULTIOUTPUT(_q, tbq, sq) (((tbq) && (!(sq)))? (_q)->pExpr1[1].base.arg->argValue.i64:1) +#define GET_ROW_PARAM_FOR_MULTIOUTPUT(_q, tbq, sq) (((tbq) && (!(sq)))? (_q)->pExpr1[1].base.param[0].i64:1) -int32_t getOutputInterResultBufSize(SQuery* pQuery); +int32_t getOutputInterResultBufSize(SQueryAttr* pQueryAttr); size_t getResultRowSize(SQueryRuntimeEnv* pRuntimeEnv); int32_t initResultRowInfo(SResultRowInfo* pResultRowInfo, int32_t size, int16_t type); @@ -52,20 +52,11 @@ static FORCE_INLINE SResultRow *getResultRow(SResultRowInfo *pResultRowInfo, int return pResultRowInfo->pResult[slot]; } -static FORCE_INLINE char* getPosInResultPage(SQueryRuntimeEnv* pRuntimeEnv, tFilePage* page, int32_t rowOffset, - int16_t offset, int32_t size) { - assert(rowOffset >= 0 && pRuntimeEnv != NULL); +static FORCE_INLINE char *getPosInResultPage(SQueryAttr *pQueryAttr, tFilePage* page, int32_t rowOffset, int16_t offset) { + assert(rowOffset >= 0 && pQueryAttr != 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); - - // buffer overflow check - int64_t bufEnd = (rowOffset + offset * numOfRows + size); - assert(page->num <= pageSize && bufEnd <= page->num); - - return ((char*)page->data) + rowOffset + offset * numOfRows; + int32_t numOfRows = (int32_t)GET_ROW_PARAM_FOR_MULTIOUTPUT(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery); + 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 e44092e14d..96c6b04b5a 100644 --- a/src/query/inc/sql.y +++ b/src/query/inc/sql.y @@ -457,16 +457,16 @@ tagitem(A) ::= PLUS(X) FLOAT(Y). { } //////////////////////// The SELECT statement ///////////////////////////////// -%type select {SQuerySqlNode*} -%destructor select {destroyQuerySqlNode($$);} +%type select {SSqlNode*} +%destructor select {destroySqlNode($$);} 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, N); } select(A) ::= LP select(B) RP. {A = B;} -%type union {SSubclauseInfo*} -%destructor union {destroyAllSelectClause($$);} +%type union {SArray*} +%destructor union {destroyAllSqlNode($$);} union(Y) ::= select(X). { Y = setSubclause(NULL, X); } union(Y) ::= union(Z) UNION ALL select(X). { Y = appendSelectClause(Z, X); } @@ -512,35 +512,30 @@ distinct(X) ::= DISTINCT(Y). { X = Y; } distinct(X) ::= . { X.n = 0;} // A complete FROM clause. -%type from {SFromInfo*} +%type from {SRelationInfo*} +%destructor from {destroyRelationInfo($$);} from(A) ::= FROM tablelist(X). {A = X;} -from(A) ::= FROM LP union(Y) RP. {A = Y;} +from(A) ::= FROM LP union(Y) RP. {A = setSubquery(NULL, Y);} -%type tablelist {SArray*} +%type tablelist {SRelationInfo*} +%destructor tablelist {destroyRelationInfo($$);} tablelist(A) ::= ids(X) cpxName(Y). { - toTSDBType(X.type); X.n += Y.n; A = setTableNameList(NULL, &X, NULL); } tablelist(A) ::= ids(X) cpxName(Y) ids(Z). { - toTSDBType(X.type); - toTSDBType(Z.type); X.n += Y.n; A = setTableNameList(NULL, &X, &Z); } tablelist(A) ::= tablelist(Y) COMMA ids(X) cpxName(Z). { - toTSDBType(X.type); X.n += Z.n; A = setTableNameList(Y, &X, NULL); } tablelist(A) ::= tablelist(Y) COMMA ids(X) cpxName(Z) ids(F). { - toTSDBType(X.type); - toTSDBType(F.type); X.n += Z.n; - A = setTableNameList(Y, &X, &F); } @@ -681,6 +676,8 @@ expr(A) ::= PLUS(X) FLOAT(Y). { X.n += Y.n; X.type = TK_FLOAT; A = tSqlExprCr expr(A) ::= STRING(X). { A = tSqlExprCreateIdValue(&X, TK_STRING);} expr(A) ::= NOW(X). { A = tSqlExprCreateIdValue(&X, TK_NOW); } expr(A) ::= VARIABLE(X). { A = tSqlExprCreateIdValue(&X, TK_VARIABLE);} +expr(A) ::= PLUS(X) VARIABLE(Y). { X.n += Y.n; X.type = TK_VARIABLE; A = tSqlExprCreateIdValue(&X, TK_VARIABLE);} +expr(A) ::= MINUS(X) VARIABLE(Y). { X.n += Y.n; X.type = TK_VARIABLE; A = tSqlExprCreateIdValue(&X, TK_VARIABLE);} expr(A) ::= BOOL(X). { A = tSqlExprCreateIdValue(&X, TK_BOOL);} expr(A) ::= NULL(X). { A = tSqlExprCreateIdValue(&X, TK_NULL);} diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index 18bbbd400c..1ae4d14f47 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -169,7 +169,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI qError("Illegal data type %d or data type length %d", dataType, dataBytes); return TSDB_CODE_TSC_INVALID_SQL; } - + if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TAGPRJ || @@ -231,10 +231,10 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI *bytes = pUdfInfo->resBytes; *interBytes = *bytes; } - + return TSDB_CODE_SUCCESS; } - + if (functionId == TSDB_FUNC_MIN || functionId == TSDB_FUNC_MAX) { *type = TSDB_DATA_TYPE_BINARY; *bytes = (int16_t)(dataBytes + DATA_SET_FLAG_SIZE); @@ -289,7 +289,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI return TSDB_CODE_SUCCESS; } } - + if (functionId == TSDB_FUNC_SUM) { if (IS_SIGNED_NUMERIC_TYPE(dataType)) { *type = TSDB_DATA_TYPE_BIGINT; @@ -324,10 +324,10 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI } else { *interBytes = *bytes; } - + return TSDB_CODE_SUCCESS; } - + if (functionId == TSDB_FUNC_AVG) { *type = TSDB_DATA_TYPE_DOUBLE; *bytes = sizeof(double); @@ -404,14 +404,7 @@ int32_t isValidFunction(const char* name, int32_t len) { return -1; } -// set the query flag to denote that query is completed -static void no_next_step(SQLFunctionCtx *pCtx) { - SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); - pResInfo->complete = true; -} - static bool function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo) { -// SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); if (pResultInfo->initialized) { return false; } @@ -1569,7 +1562,7 @@ static void stddev_function_f(SQLFunctionCtx *pCtx, int32_t index) { } } -static void stddev_next_step(SQLFunctionCtx *pCtx) { +static UNUSED_FUNC void stddev_next_step(SQLFunctionCtx *pCtx) { /* * the stddevInfo and the average info struct share the same buffer area * And the position of each element in their struct is exactly the same matched @@ -2511,6 +2504,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) { @@ -2524,6 +2540,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) { @@ -2563,27 +2583,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, SResultRowCellInfo* pResInfo) { if (!function_setup(pCtx, pResInfo)) { return false; @@ -2637,7 +2636,11 @@ static void top_function_f(SQLFunctionCtx *pCtx, int32_t index) { STopBotInfo *pRes = getTopBotOutputInfo(pCtx); assert(pRes->num >= 0); - + + if ((void *)pRes->res[0] != (void *)((char *)pRes + sizeof(STopBotInfo) + POINTER_BYTES * pCtx->param[0].i64)) { + buildTopBotStruct(pRes, pCtx); + } + SET_VAL(pCtx, 1, 1); TSKEY ts = GET_TS_DATA(pCtx, index); @@ -2938,7 +2941,7 @@ static void percentile_finalizer(SQLFunctionCtx *pCtx) { doFinalizer(pCtx); } -static void percentile_next_step(SQLFunctionCtx *pCtx) { +static UNUSED_FUNC void percentile_next_step(SQLFunctionCtx *pCtx) { SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx); SPercentileInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); @@ -3043,7 +3046,7 @@ static void apercentile_func_merge(SQLFunctionCtx *pCtx) { pInput->pHisto = (SHistogramInfo*) ((char *)pInput + sizeof(SAPercentileInfo)); pInput->pHisto->elems = (SHistBin*) ((char *)pInput->pHisto + sizeof(SHistogramInfo)); - + if (pInput->pHisto->numOfElems <= 0) { return; } @@ -3062,7 +3065,7 @@ static void apercentile_func_merge(SQLFunctionCtx *pCtx) { pHisto->elems = (SHistBin*) ((char *)pHisto + sizeof(SHistogramInfo)); tHistogramDestroy(&pRes); } - + SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); pResInfo->hasResult = DATA_SET_FLAG; SET_VAL(pCtx, 1, 1); @@ -3073,7 +3076,7 @@ static void apercentile_finalizer(SQLFunctionCtx *pCtx) { SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx); SAPercentileInfo *pOutput = GET_ROWCELL_INTERBUF(pResInfo); - + if (pCtx->currentStage == MERGE_STAGE) { if (pResInfo->hasResult == DATA_SET_FLAG) { // check for null assert(pOutput->pHisto->numOfElems > 0); @@ -3108,7 +3111,7 @@ static bool leastsquares_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo if (!function_setup(pCtx, pResInfo)) { return false; } - + SLeastsquaresInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); // 2*3 matrix @@ -3348,8 +3351,6 @@ static void col_project_function_f(SQLFunctionCtx *pCtx, int32_t index) { INC_INIT_VAL(pCtx, 1); char *pData = GET_INPUT_DATA(pCtx, index); memcpy(pCtx->pOutput, pData, pCtx->inputBytes); - - pCtx->pOutput += pCtx->inputBytes; } /** @@ -3387,9 +3388,15 @@ static void tag_project_function_f(SQLFunctionCtx *pCtx, int32_t index) { * @param pCtx * @return */ +static void copy_function(SQLFunctionCtx *pCtx); + static void tag_function(SQLFunctionCtx *pCtx) { SET_VAL(pCtx, 1, 1); - tVariantDump(&pCtx->tag, pCtx->pOutput, pCtx->outputType, true); + if (pCtx->currentStage == MERGE_STAGE) { + copy_function(pCtx); + } else { + tVariantDump(&pCtx->tag, pCtx->pOutput, pCtx->outputType, true); + } } static void tag_function_f(SQLFunctionCtx *pCtx, int32_t index) { @@ -3726,7 +3733,7 @@ static void arithmetic_function(SQLFunctionCtx *pCtx) { GET_RES_INFO(pCtx)->numOfRes += pCtx->size; SArithmeticSupport *sas = (SArithmeticSupport *)pCtx->param[1].pz; - arithmeticTreeTraverse(sas->pArithExpr->pExpr, pCtx->size, pCtx->pOutput, sas, pCtx->order, getArithColumnData); + arithmeticTreeTraverse(sas->pExprInfo->pExpr, pCtx->size, pCtx->pOutput, sas, pCtx->order, getArithColumnData); } static void arithmetic_function_f(SQLFunctionCtx *pCtx, int32_t index) { @@ -3734,7 +3741,7 @@ static void arithmetic_function_f(SQLFunctionCtx *pCtx, int32_t index) { SArithmeticSupport *sas = (SArithmeticSupport *)pCtx->param[1].pz; sas->offset = index; - arithmeticTreeTraverse(sas->pArithExpr->pExpr, 1, pCtx->pOutput, sas, pCtx->order, getArithColumnData); + arithmeticTreeTraverse(sas->pExprInfo->pExpr, 1, pCtx->pOutput, sas, pCtx->order, getArithColumnData); pCtx->pOutput += pCtx->outputBytes; } @@ -4358,7 +4365,7 @@ static bool ts_comp_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pRe if (!function_setup(pCtx, pResInfo)) { return false; // not initialized since it has been initialized } - + STSCompInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); pInfo->pTSBuf = tsBufCreate(false, pCtx->order); pInfo->pTSBuf->tsOrder = pCtx->order; @@ -4918,7 +4925,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, count_function, count_function_f, - no_next_step, doFinalizer, count_func_merge, countRequired, @@ -4932,7 +4938,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, sum_function, sum_function_f, - no_next_step, function_finalizer, sum_func_merge, statisRequired, @@ -4946,7 +4951,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, avg_function, avg_function_f, - no_next_step, avg_finalizer, avg_func_merge, statisRequired, @@ -4960,7 +4964,6 @@ SAggFunctionInfo aAggs[] = {{ min_func_setup, min_function, min_function_f, - no_next_step, function_finalizer, min_func_merge, statisRequired, @@ -4974,7 +4977,6 @@ SAggFunctionInfo aAggs[] = {{ max_func_setup, max_function, max_function_f, - no_next_step, function_finalizer, max_func_merge, statisRequired, @@ -4988,7 +4990,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, stddev_function, stddev_function_f, - stddev_next_step, stddev_finalizer, noop1, dataBlockRequired, @@ -5002,7 +5003,6 @@ SAggFunctionInfo aAggs[] = {{ percentile_function_setup, percentile_function, percentile_function_f, - percentile_next_step, percentile_finalizer, noop1, dataBlockRequired, @@ -5016,7 +5016,6 @@ SAggFunctionInfo aAggs[] = {{ apercentile_function_setup, apercentile_function, apercentile_function_f, - no_next_step, apercentile_finalizer, apercentile_func_merge, dataBlockRequired, @@ -5030,7 +5029,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, first_function, first_function_f, - no_next_step, function_finalizer, noop1, firstFuncRequired, @@ -5044,7 +5042,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, last_function, last_function_f, - no_next_step, function_finalizer, noop1, lastFuncRequired, @@ -5059,7 +5056,6 @@ SAggFunctionInfo aAggs[] = {{ first_last_function_setup, last_row_function, noop2, - no_next_step, last_row_finalizer, last_dist_func_merge, dataBlockRequired, @@ -5074,7 +5070,6 @@ SAggFunctionInfo aAggs[] = {{ top_bottom_function_setup, top_function, top_function_f, - no_next_step, top_bottom_func_finalizer, top_func_merge, dataBlockRequired, @@ -5089,7 +5084,6 @@ SAggFunctionInfo aAggs[] = {{ top_bottom_function_setup, bottom_function, bottom_function_f, - no_next_step, top_bottom_func_finalizer, bottom_func_merge, dataBlockRequired, @@ -5103,7 +5097,6 @@ SAggFunctionInfo aAggs[] = {{ spread_function_setup, spread_function, spread_function_f, - no_next_step, spread_function_finalizer, spread_func_merge, countRequired, @@ -5117,7 +5110,6 @@ SAggFunctionInfo aAggs[] = {{ twa_function_setup, twa_function, twa_function_f, - no_next_step, twa_function_finalizer, twa_function_copy, dataBlockRequired, @@ -5131,7 +5123,6 @@ SAggFunctionInfo aAggs[] = {{ leastsquares_function_setup, leastsquares_function, leastsquares_function_f, - no_next_step, leastsquares_finalizer, noop1, dataBlockRequired, @@ -5145,35 +5136,32 @@ SAggFunctionInfo aAggs[] = {{ function_setup, date_col_output_function, date_col_output_function_f, - no_next_step, doFinalizer, copy_function, noDataRequired, }, { // 17 - "ts", + "ts_dummy", TSDB_FUNC_TS_DUMMY, TSDB_FUNC_TS_DUMMY, TSDB_BASE_FUNC_SO | TSDB_FUNCSTATE_NEED_TS, function_setup, noop1, noop2, - no_next_step, doFinalizer, copy_function, dataBlockRequired, }, { // 18 - "tag", + "tag_dummy", TSDB_FUNC_TAG_DUMMY, TSDB_FUNC_TAG_DUMMY, TSDB_BASE_FUNC_SO, function_setup, tag_function, noop2, - no_next_step, doFinalizer, copy_function, noDataRequired, @@ -5187,7 +5175,6 @@ SAggFunctionInfo aAggs[] = {{ ts_comp_function_setup, ts_comp_function, ts_comp_function_f, - no_next_step, ts_comp_finalize, copy_function, dataBlockRequired, @@ -5201,7 +5188,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, tag_function, tag_function_f, - no_next_step, doFinalizer, copy_function, noDataRequired, @@ -5215,7 +5201,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, col_project_function, col_project_function_f, - no_next_step, doFinalizer, copy_function, dataBlockRequired, @@ -5229,7 +5214,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, tag_project_function, tag_project_function_f, - no_next_step, doFinalizer, copy_function, noDataRequired, @@ -5243,7 +5227,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, arithmetic_function, arithmetic_function_f, - no_next_step, doFinalizer, copy_function, dataBlockRequired, @@ -5257,7 +5240,6 @@ SAggFunctionInfo aAggs[] = {{ diff_function_setup, diff_function, diff_function_f, - no_next_step, doFinalizer, noop1, dataBlockRequired, @@ -5272,7 +5254,6 @@ SAggFunctionInfo aAggs[] = {{ first_last_function_setup, first_dist_function, first_dist_function_f, - no_next_step, function_finalizer, first_dist_func_merge, firstDistFuncRequired, @@ -5286,7 +5267,6 @@ SAggFunctionInfo aAggs[] = {{ first_last_function_setup, last_dist_function, last_dist_function_f, - no_next_step, function_finalizer, last_dist_func_merge, lastDistFuncRequired, @@ -5300,7 +5280,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, stddev_dst_function, stddev_dst_function_f, - no_next_step, stddev_dst_finalizer, stddev_dst_merge, dataBlockRequired, @@ -5314,7 +5293,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, interp_function, do_sum_f, // todo filter handle - no_next_step, doFinalizer, copy_function, dataBlockRequired, @@ -5328,7 +5306,6 @@ SAggFunctionInfo aAggs[] = {{ rate_function_setup, rate_function, rate_function_f, - no_next_step, rate_finalizer, rate_func_copy, dataBlockRequired, @@ -5342,7 +5319,6 @@ SAggFunctionInfo aAggs[] = {{ rate_function_setup, irate_function, irate_function_f, - no_next_step, rate_finalizer, rate_func_copy, dataBlockRequired, @@ -5356,7 +5332,6 @@ SAggFunctionInfo aAggs[] = {{ rate_function_setup, rate_function, rate_function_f, - no_next_step, sumrate_finalizer, sumrate_func_merge, dataBlockRequired, @@ -5370,7 +5345,6 @@ SAggFunctionInfo aAggs[] = {{ rate_function_setup, irate_function, irate_function_f, - no_next_step, sumrate_finalizer, sumrate_func_merge, dataBlockRequired, @@ -5384,7 +5358,6 @@ SAggFunctionInfo aAggs[] = {{ rate_function_setup, rate_function, rate_function_f, - no_next_step, sumrate_finalizer, sumrate_func_merge, dataBlockRequired, @@ -5398,7 +5371,6 @@ SAggFunctionInfo aAggs[] = {{ rate_function_setup, irate_function, irate_function_f, - no_next_step, sumrate_finalizer, sumrate_func_merge, dataBlockRequired, @@ -5412,7 +5384,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, noop1, noop2, - no_next_step, noop1, noop1, dataBlockRequired, @@ -5426,7 +5397,6 @@ SAggFunctionInfo aAggs[] = {{ function_setup, blockInfo_func, noop2, - no_next_step, blockinfo_func_finalizer, block_func_merge, dataBlockRequired, diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 271a29736d..7bd181c5b3 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -98,21 +98,20 @@ 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; @@ -120,22 +119,19 @@ int64_t genQueryId(void) { 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') { - tw->skey += pQuery->interval.sliding * factor; - tw->ekey = tw->skey + pQuery->interval.interval - 1; +static void getNextTimeWindow(SQueryAttr* pQueryAttr, STimeWindow* tw) { + int32_t factor = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order); + if (pQueryAttr->interval.intervalUnit != 'n' && pQueryAttr->interval.intervalUnit != 'y') { + tw->skey += pQueryAttr->interval.sliding * factor; + tw->ekey = tw->skey + pQueryAttr->interval.interval - 1; return; } - int64_t key = tw->skey / 1000, interval = pQuery->interval.interval; - if (pQuery->precision == TSDB_TIME_PRECISION_MICRO) { + int64_t key = tw->skey / 1000, interval = pQueryAttr->interval.interval; + if (pQueryAttr->precision == TSDB_TIME_PRECISION_MICRO) { key /= 1000; } - - if (pQuery->interval.intervalUnit == 'y') { + if (pQueryAttr->interval.intervalUnit == 'y') { interval *= 12; } @@ -153,7 +149,7 @@ static void getNextTimeWindow(SQuery* pQuery, STimeWindow* tw) { tm.tm_mon = mon % 12; tw->ekey = mktime(&tm) * 1000L; - if (pQuery->precision == TSDB_TIME_PRECISION_MICRO) { + if (pQueryAttr->precision == TSDB_TIME_PRECISION_MICRO) { tw->skey *= 1000L; tw->ekey *= 1000L; } @@ -161,8 +157,8 @@ static void getNextTimeWindow(SQuery* pQuery, STimeWindow* tw) { } static void doSetTagValueToResultBuf(char* output, const char* val, int16_t type, int16_t bytes); -static void setResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult, SQLFunctionCtx* pCtx, - int32_t numOfCols, int32_t* rowCellInfoOffset); +static void setResultOutputBuf(SQueryRuntimeEnv* pRuntimeEnv, SResultRow* pResult, SQLFunctionCtx* pCtx, + int32_t numOfCols, int32_t* rowCellInfoOffset); void setResultRowOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult, SQLFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowCellInfoOffset); static bool functionNeedToExecute(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *pCtx, int32_t functionId); @@ -170,36 +166,20 @@ static bool functionNeedToExecute(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx static void setBlockStatisInfo(SQLFunctionCtx *pCtx, SSDataBlock* pSDataBlock, SColIndex* pColIndex); static void destroyTableQueryInfoImpl(STableQueryInfo *pTableQueryInfo); -static bool hasMainOutput(SQuery *pQuery); +static bool hasMainOutput(SQueryAttr *pQueryAttr); static int32_t setTimestampListJoinInfo(SQueryRuntimeEnv* pRuntimeEnv, tVariant* pTag, STableQueryInfo *pTableQueryInfo); static void releaseQueryBuf(size_t numOfTables); static int32_t binarySearchForKey(char *pValue, int num, TSKEY key, int order); -static STsdbQueryCond createTsdbQueryCond(SQuery* pQuery, STimeWindow* win); +static STsdbQueryCond createTsdbQueryCond(SQueryAttr* pQueryAttr, STimeWindow* win); static STableIdInfo createTableIdInfo(STableQueryInfo* pTableQueryInfo); static void setTableScanFilterOperatorInfo(STableScanInfo* pTableScanInfo, SOperatorInfo* pDownstream); +static int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfFilterCols, + SSingleColumnFilterInfo** pFilterInfo, uint64_t qId); +static void* doDestroyFilterInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols); -static int32_t getNumOfScanTimes(SQuery* pQuery); -static bool isFixedOutputQuery(SQueryRuntimeEnv *pRuntimeEnv); - -static SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime, int32_t reverseTime); -static SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime); -static SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv); - -static SOperatorInfo* createAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -static SOperatorInfo* createArithOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -static SOperatorInfo* createLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream); -static SOperatorInfo* createOffsetOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream); -static SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -static SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -static SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -static SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -static SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput); -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 int32_t getNumOfScanTimes(SQueryAttr* pQueryAttr); static void destroyBasicOperatorInfo(void* param, int32_t numOfOutput); static void destroySFillOperatorInfo(void* param, int32_t numOfOutput); @@ -213,10 +193,9 @@ static int32_t doCopyToSDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SGroupResInfo* static int32_t getGroupbyColumnIndex(SSqlGroupbyExpr *pGroupbyExpr, SSDataBlock* pDataBlock); static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SGroupbyOperatorInfo *pInfo, int32_t numOfCols, char *pData, int16_t type, int16_t bytes, int32_t groupIndex); -static void initCtxOutputBuffer(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t size); -static void getAlignQueryTimeWindow(SQuery *pQuery, int64_t key, int64_t keyFirst, int64_t keyLast, STimeWindow *win); -static bool isPointInterpoQuery(SQuery *pQuery); -static void setResultBufSize(SQuery* pQuery, SRspResultInfo* pResultInfo); +static void initCtxOutputBuffer(SQLFunctionCtx* pCtx, int32_t size); +static void getAlignQueryTimeWindow(SQueryAttr *pQueryAttr, int64_t key, int64_t keyFirst, int64_t keyLast, STimeWindow *win); +static void setResultBufSize(SQueryAttr* pQueryAttr, 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); @@ -225,7 +204,7 @@ static void doSetTableGroupOutputBuf(SQueryRuntimeEnv* pRuntimeEnv, SResultRowIn int32_t groupIndex); // setup the output buffer for each operator -static SSDataBlock* createOutputBuf(SExprInfo* pExpr, int32_t numOfOutput, int32_t numOfRows) { +SSDataBlock* createOutputBuf(SExprInfo* pExpr, int32_t numOfOutput, int32_t numOfRows) { const static int32_t minSize = 8; SSDataBlock *res = calloc(1, sizeof(SSDataBlock)); @@ -234,18 +213,19 @@ static SSDataBlock* createOutputBuf(SExprInfo* pExpr, int32_t numOfOutput, int32 res->pDataBlock = taosArrayInit(numOfOutput, sizeof(SColumnInfoData)); for (int32_t i = 0; i < numOfOutput; ++i) { SColumnInfoData idata = {{0}}; - idata.info.type = pExpr[i].type; - idata.info.bytes = pExpr[i].bytes; + idata.info.type = pExpr[i].base.resType; + idata.info.bytes = pExpr[i].base.resBytes; idata.info.colId = pExpr[i].base.resColId; - idata.pData = calloc(1, MAX(idata.info.bytes * numOfRows, minSize)); // at least to hold a pointer on x64 platform + int32_t size = MAX(idata.info.bytes * numOfRows, minSize); + idata.pData = calloc(1, size); // at least to hold a pointer on x64 platform taosArrayPush(res->pDataBlock, &idata); } return res; } -static void* destroyOutputBuf(SSDataBlock* pBlock) { +void* destroyOutputBuf(SSDataBlock* pBlock) { if (pBlock == NULL) { return NULL; } @@ -263,8 +243,8 @@ static void* destroyOutputBuf(SSDataBlock* pBlock) { } int32_t getNumOfResult(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput) { - SQuery *pQuery = pRuntimeEnv->pQuery; - bool hasMainFunction = hasMainOutput(pQuery); + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; + bool hasMainFunction = hasMainOutput(pQueryAttr); int32_t maxOutput = 0; for (int32_t j = 0; j < numOfOutput; ++j) { @@ -295,37 +275,6 @@ static void clearNumOfRes(SQLFunctionCtx* pCtx, int32_t numOfOutput) { } } -static bool isGroupbyColumn(SSqlGroupbyExpr *pGroupbyExpr) { - if (pGroupbyExpr == NULL || pGroupbyExpr->numOfGroupCols == 0) { - return false; - } - - for (int32_t i = 0; i < pGroupbyExpr->numOfGroupCols; ++i) { - SColIndex *pColIndex = taosArrayGet(pGroupbyExpr->columnInfo, i); - if (TSDB_COL_IS_NORMAL_COL(pColIndex->flag)) { - //make sure the normal column locates at the second position if tbname exists in group by clause - if (pGroupbyExpr->numOfGroupCols > 1) { - assert(pColIndex->colIndex > 0); - } - - return true; - } - } - - return false; -} - -static bool isStabledev(SQuery* pQuery) { - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - int32_t functId = pQuery->pExpr1[i].base.functionId; - if (functId == TSDB_FUNC_STDDEV_DST) { - return true; - } - } - - return false; -} - static bool isSelectivityWithTagsQuery(SQLFunctionCtx *pCtx, int32_t numOfOutput) { bool hasTags = false; int32_t numOfSelectivity = 0; @@ -345,9 +294,9 @@ static bool isSelectivityWithTagsQuery(SQLFunctionCtx *pCtx, int32_t numOfOutput return (numOfSelectivity > 0 && hasTags); } -static bool isProjQuery(SQuery *pQuery) { - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - int32_t functId = pQuery->pExpr1[i].base.functionId; +static bool isProjQuery(SQueryAttr *pQueryAttr) { + for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { + int32_t functId = pQueryAttr->pExpr1[i].base.functionId; if (functId != TSDB_FUNC_PRJ && functId != TSDB_FUNC_TAGPRJ) { return false; } @@ -356,52 +305,6 @@ static bool isProjQuery(SQuery *pQuery) { return true; } -static bool isTsCompQuery(SQuery *pQuery) { return pQuery->pExpr1[0].base.functionId == TSDB_FUNC_TS_COMP; } - -static bool isTopBottomQuery(SQuery *pQuery) { - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - int32_t functionId = pQuery->pExpr1[i].base.functionId; - if (functionId == TSDB_FUNC_TS) { - continue; - } - - if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) { - return true; - } - } - - return false; -} - -static bool timeWindowInterpoRequired(SQuery *pQuery) { - for(int32_t i = 0; i < pQuery->numOfOutput; ++i) { - int32_t functionId = pQuery->pExpr1[i].base.functionId; - if (functionId == TSDB_FUNC_TWA || functionId == TSDB_FUNC_INTERP) { - return true; - } - } - - return false; -} - -static bool hasTagValOutput(SQuery* pQuery) { - SExprInfo *pExprInfo = &pQuery->pExpr1[0]; - if (pQuery->numOfOutput == 1 && pExprInfo->base.functionId == TSDB_FUNC_TS_COMP) { - return true; - } else { // set tag value, by which the results are aggregated. - for (int32_t idx = 0; idx < pQuery->numOfOutput; ++idx) { - SExprInfo *pLocalExprInfo = &pQuery->pExpr1[idx]; - - // ts_comp column required the tag value for join filter - if (TSDB_COL_IS_TAG(pLocalExprInfo->base.colInfo.flag)) { - return true; - } - } - } - - return false; -} - static bool hasNullRv(SColIndex* pColIndex, SDataStatis *pStatis) { if (TSDB_COL_IS_TAG(pColIndex->flag) || TSDB_COL_IS_UD_COL(pColIndex->flag) || pColIndex->colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { return false; @@ -449,7 +352,7 @@ static SResultRow *doPrepareResultRowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SRes (SResultRow **)taosHashGet(pRuntimeEnv->pResultRowHashTable, pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes)); // in case of repeat scan/reverse scan, no new time window added. - if (QUERY_IS_INTERVAL_QUERY(pRuntimeEnv->pQuery)) { + if (QUERY_IS_INTERVAL_QUERY(pRuntimeEnv->pQueryAttr)) { if (!masterscan) { // the *p1 may be NULL in case of sliding+offset exists. return (p1 != NULL)? *p1:NULL; } @@ -473,7 +376,6 @@ static SResultRow *doPrepareResultRowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SRes prepareResultListBuffer(pResultRowInfo, pRuntimeEnv); SResultRow *pResult = NULL; - if (p1 == NULL) { pResult = getNewResultRow(pRuntimeEnv->pool); int32_t ret = initResultRow(pResult); @@ -499,19 +401,19 @@ static SResultRow *doPrepareResultRowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SRes return getResultRow(pResultRowInfo, pResultRowInfo->curIndex); } -static void getInitialStartTimeWindow(SQuery* pQuery, TSKEY ts, STimeWindow* w) { - if (QUERY_IS_ASC_QUERY(pQuery)) { - getAlignQueryTimeWindow(pQuery, ts, ts, pQuery->window.ekey, w); +static void getInitialStartTimeWindow(SQueryAttr* pQueryAttr, TSKEY ts, STimeWindow* w) { + if (QUERY_IS_ASC_QUERY(pQueryAttr)) { + getAlignQueryTimeWindow(pQueryAttr, ts, ts, pQueryAttr->window.ekey, w); } else { // the start position of the first time window in the endpoint that spreads beyond the queried last timestamp - getAlignQueryTimeWindow(pQuery, ts, pQuery->window.ekey, ts, w); + getAlignQueryTimeWindow(pQueryAttr, ts, pQueryAttr->window.ekey, ts, w); int64_t key = w->skey; while(key < ts) { // moving towards end - if (pQuery->interval.intervalUnit == 'n' || pQuery->interval.intervalUnit == 'y') { - key = taosTimeAdd(key, pQuery->interval.sliding, pQuery->interval.slidingUnit, pQuery->precision); + if (pQueryAttr->interval.intervalUnit == 'n' || pQueryAttr->interval.intervalUnit == 'y') { + key = taosTimeAdd(key, pQueryAttr->interval.sliding, pQueryAttr->interval.slidingUnit, pQueryAttr->precision); } else { - key += pQuery->interval.sliding; + key += pQueryAttr->interval.sliding; } if (key >= ts) { @@ -524,21 +426,21 @@ static void getInitialStartTimeWindow(SQuery* pQuery, TSKEY ts, STimeWindow* w) } // get the correct time window according to the handled timestamp -static STimeWindow getActiveTimeWindow(SResultRowInfo * pResultRowInfo, int64_t ts, SQuery *pQuery) { +static STimeWindow getActiveTimeWindow(SResultRowInfo * pResultRowInfo, int64_t ts, SQueryAttr *pQueryAttr) { STimeWindow w = {0}; if (pResultRowInfo->curIndex == -1) { // the first window, from the previous stored value if (pResultRowInfo->prevSKey == TSKEY_INITIAL_VAL) { - getInitialStartTimeWindow(pQuery, ts, &w); + getInitialStartTimeWindow(pQueryAttr, ts, &w); pResultRowInfo->prevSKey = w.skey; } else { w.skey = pResultRowInfo->prevSKey; } - if (pQuery->interval.intervalUnit == 'n' || pQuery->interval.intervalUnit == 'y') { - w.ekey = taosTimeAdd(w.skey, pQuery->interval.interval, pQuery->interval.intervalUnit, pQuery->precision) - 1; + if (pQueryAttr->interval.intervalUnit == 'n' || pQueryAttr->interval.intervalUnit == 'y') { + w.ekey = taosTimeAdd(w.skey, pQueryAttr->interval.interval, pQueryAttr->interval.intervalUnit, pQueryAttr->precision) - 1; } else { - w.ekey = w.skey + pQuery->interval.interval - 1; + w.ekey = w.skey + pQueryAttr->interval.interval - 1; } } else { int32_t slot = curTimeWindowIndex(pResultRowInfo); @@ -547,23 +449,23 @@ static STimeWindow getActiveTimeWindow(SResultRowInfo * pResultRowInfo, int64_t } if (w.skey > ts || w.ekey < ts) { - if (pQuery->interval.intervalUnit == 'n' || pQuery->interval.intervalUnit == 'y') { - w.skey = taosTimeTruncate(ts, &pQuery->interval, pQuery->precision); - w.ekey = taosTimeAdd(w.skey, pQuery->interval.interval, pQuery->interval.intervalUnit, pQuery->precision) - 1; + if (pQueryAttr->interval.intervalUnit == 'n' || pQueryAttr->interval.intervalUnit == 'y') { + w.skey = taosTimeTruncate(ts, &pQueryAttr->interval, pQueryAttr->precision); + w.ekey = taosTimeAdd(w.skey, pQueryAttr->interval.interval, pQueryAttr->interval.intervalUnit, pQueryAttr->precision) - 1; } else { int64_t st = w.skey; if (st > ts) { - st -= ((st - ts + pQuery->interval.sliding - 1) / pQuery->interval.sliding) * pQuery->interval.sliding; + st -= ((st - ts + pQueryAttr->interval.sliding - 1) / pQueryAttr->interval.sliding) * pQueryAttr->interval.sliding; } - int64_t et = st + pQuery->interval.interval - 1; + int64_t et = st + pQueryAttr->interval.interval - 1; if (et < ts) { - st += ((ts - et + pQuery->interval.sliding - 1) / pQuery->interval.sliding) * pQuery->interval.sliding; + st += ((ts - et + pQueryAttr->interval.sliding - 1) / pQueryAttr->interval.sliding) * pQueryAttr->interval.sliding; } w.skey = st; - w.ekey = w.skey + pQuery->interval.interval - 1; + w.ekey = w.skey + pQueryAttr->interval.interval - 1; } } @@ -571,8 +473,8 @@ static STimeWindow getActiveTimeWindow(SResultRowInfo * pResultRowInfo, int64_t * query border check, skey should not be bounded by the query time range, since the value skey will * be used as the time window index value. So we only change ekey of time window accordingly. */ - if (w.ekey > pQuery->window.ekey && QUERY_IS_ASC_QUERY(pQuery)) { - w.ekey = pQuery->window.ekey; + if (w.ekey > pQueryAttr->window.ekey && QUERY_IS_ASC_QUERY(pQueryAttr)) { + w.ekey = pQueryAttr->window.ekey; } return w; @@ -637,7 +539,7 @@ static int32_t setWindowOutputBufByKey(SQueryRuntimeEnv *pRuntimeEnv, SResultRow // not assign result buffer yet, add new result buffer if (pResultRow->pageId == -1) { - int32_t ret = addNewWindowResultBuf(pResultRow, pResultBuf, (int32_t) groupId, pRuntimeEnv->pQuery->intermediateResultRowSize); + int32_t ret = addNewWindowResultBuf(pResultRow, pResultBuf, (int32_t) groupId, pRuntimeEnv->pQueryAttr->intermediateResultRowSize); if (ret != TSDB_CODE_SUCCESS) { return -1; } @@ -748,28 +650,28 @@ static void doUpdateResultRowIndex(SResultRowInfo*pResultRowInfo, TSKEY lastKey, } } -static void updateResultRowInfoActiveIndex(SResultRowInfo* pResultRowInfo, SQuery* pQuery, TSKEY lastKey) { - bool ascQuery = QUERY_IS_ASC_QUERY(pQuery); - if ((lastKey > pQuery->window.ekey && ascQuery) || (lastKey < pQuery->window.ekey && (!ascQuery))) { +static void updateResultRowInfoActiveIndex(SResultRowInfo* pResultRowInfo, SQueryAttr* pQueryAttr, TSKEY lastKey) { + bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); + if ((lastKey > pQueryAttr->window.ekey && ascQuery) || (lastKey < pQueryAttr->window.ekey && (!ascQuery))) { closeAllResultRows(pResultRowInfo); pResultRowInfo->curIndex = pResultRowInfo->size - 1; } else { int32_t step = ascQuery ? 1 : -1; - doUpdateResultRowIndex(pResultRowInfo, lastKey - step, ascQuery, pQuery->timeWindowInterpo); + doUpdateResultRowIndex(pResultRowInfo, lastKey - step, ascQuery, pQueryAttr->timeWindowInterpo); } } -static int32_t getNumOfRowsInTimeWindow(SQuery *pQuery, SDataBlockInfo *pDataBlockInfo, TSKEY *pPrimaryColumn, +static int32_t getNumOfRowsInTimeWindow(SQueryRuntimeEnv* pRuntimeEnv, SDataBlockInfo *pDataBlockInfo, TSKEY *pPrimaryColumn, int32_t startPos, TSKEY ekey, __block_search_fn_t searchFn, bool updateLastKey) { assert(startPos >= 0 && startPos < pDataBlockInfo->rows); + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STableQueryInfo* item = pRuntimeEnv->current; int32_t num = -1; - int32_t order = pQuery->order.order; + int32_t order = pQueryAttr->order.order; int32_t step = GET_FORWARD_DIRECTION_FACTOR(order); - STableQueryInfo* item = pQuery->current; - - if (QUERY_IS_ASC_QUERY(pQuery)) { + if (QUERY_IS_ASC_QUERY(pQueryAttr)) { if (ekey < pDataBlockInfo->window.ekey) { num = getForwardStepsInBlock(pDataBlockInfo->rows, searchFn, ekey, startPos, order, pPrimaryColumn); if (updateLastKey) { // update the last key @@ -802,19 +704,19 @@ static int32_t getNumOfRowsInTimeWindow(SQuery *pQuery, SDataBlockInfo *pDataBlo static void doInvokeUdf(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *pCtx, int32_t idx) { int32_t output = 0; SUdfInfo* pUdfInfo = pRuntimeEnv->pUdfInfo; - + if (pUdfInfo && pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL]) { qDebug("invoke udf function:%s,%p", pUdfInfo->name, pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL]); if (pUdfInfo->isScript) { - (*(scriptNormalFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL])(pUdfInfo->pScriptCtx, + (*(scriptNormalFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL])(pUdfInfo->pScriptCtx, (char *)pCtx->pInput + idx * pCtx->inputType, pCtx->inputType, pCtx->inputBytes, pCtx->size, pCtx->ptsList, pCtx->pOutput, (char *)pCtx->ptsOutputBuf, &output, pCtx->outputType, pCtx->outputBytes); } else { SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); - + void *interBuf = (void *)GET_ROWCELL_INTERBUF(pResInfo); - - (*(udfNormalFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL])((char *)pCtx->pInput + idx * pCtx->inputType, pCtx->inputType, pCtx->inputBytes, pCtx->size, pCtx->ptsList, + + (*(udfNormalFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL])((char *)pCtx->pInput + idx * pCtx->inputType, pCtx->inputType, pCtx->inputBytes, pCtx->size, pCtx->ptsList, pCtx->pOutput, interBuf, (char *)pCtx->ptsOutputBuf, &output, pCtx->outputType, pCtx->outputBytes, &pUdfInfo->init); } @@ -823,21 +725,21 @@ static void doInvokeUdf(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *pCtx, int } else { pCtx->resultInfo->numOfRes += output; } - + if (pCtx->resultInfo->numOfRes > 0) { pCtx->resultInfo->hasResult = DATA_SET_FLAG; } return; } - + qError("empty udf function"); return; } static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, STimeWindow* pWin, int32_t offset, int32_t forwardStep, TSKEY* tsCol, int32_t numOfTotal, int32_t numOfOutput) { - SQuery *pQuery = pRuntimeEnv->pQuery; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; bool hasPrev = pCtx[0].preAggVals.isSet; for (int32_t k = 0; k < numOfOutput; ++k) { @@ -846,7 +748,7 @@ static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx char* start = pCtx[k].pInput; - int32_t pos = (QUERY_IS_ASC_QUERY(pQuery)) ? offset : offset - (forwardStep - 1); + int32_t pos = (QUERY_IS_ASC_QUERY(pQueryAttr)) ? offset : offset - (forwardStep - 1); if (pCtx[k].pInput != NULL) { pCtx[k].pInput = (char *)pCtx[k].pInput + pos * pCtx[k].inputBytes; } @@ -879,42 +781,42 @@ static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx } -static int32_t getNextQualifiedWindow(SQuery* pQuery, STimeWindow *pNext, SDataBlockInfo *pDataBlockInfo, +static int32_t getNextQualifiedWindow(SQueryAttr* pQueryAttr, STimeWindow *pNext, SDataBlockInfo *pDataBlockInfo, TSKEY *primaryKeys, __block_search_fn_t searchFn, int32_t prevPosition) { - getNextTimeWindow(pQuery, pNext); + getNextTimeWindow(pQueryAttr, pNext); // next time window is not in current block - if ((pNext->skey > pDataBlockInfo->window.ekey && QUERY_IS_ASC_QUERY(pQuery)) || - (pNext->ekey < pDataBlockInfo->window.skey && !QUERY_IS_ASC_QUERY(pQuery))) { + if ((pNext->skey > pDataBlockInfo->window.ekey && QUERY_IS_ASC_QUERY(pQueryAttr)) || + (pNext->ekey < pDataBlockInfo->window.skey && !QUERY_IS_ASC_QUERY(pQueryAttr))) { return -1; } TSKEY startKey = -1; - if (QUERY_IS_ASC_QUERY(pQuery)) { + if (QUERY_IS_ASC_QUERY(pQueryAttr)) { startKey = pNext->skey; - if (startKey < pQuery->window.skey) { - startKey = pQuery->window.skey; + if (startKey < pQueryAttr->window.skey) { + startKey = pQueryAttr->window.skey; } } else { startKey = pNext->ekey; - if (startKey > pQuery->window.skey) { - startKey = pQuery->window.skey; + if (startKey > pQueryAttr->window.skey) { + startKey = pQueryAttr->window.skey; } } int32_t startPos = 0; // tumbling time window query, a special case of sliding time window query - if (pQuery->interval.sliding == pQuery->interval.interval && prevPosition != -1) { - int32_t factor = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); + if (pQueryAttr->interval.sliding == pQueryAttr->interval.interval && prevPosition != -1) { + int32_t factor = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order); startPos = prevPosition + factor; } else { - if (startKey <= pDataBlockInfo->window.skey && QUERY_IS_ASC_QUERY(pQuery)) { + if (startKey <= pDataBlockInfo->window.skey && QUERY_IS_ASC_QUERY(pQueryAttr)) { startPos = 0; - } else if (startKey >= pDataBlockInfo->window.ekey && !QUERY_IS_ASC_QUERY(pQuery)) { + } else if (startKey >= pDataBlockInfo->window.ekey && !QUERY_IS_ASC_QUERY(pQueryAttr)) { startPos = pDataBlockInfo->rows - 1; } else { - startPos = searchFn((char *)primaryKeys, pDataBlockInfo->rows, startKey, pQuery->order.order); + startPos = searchFn((char *)primaryKeys, pDataBlockInfo->rows, startKey, pQueryAttr->order.order); } } @@ -923,29 +825,29 @@ static int32_t getNextQualifiedWindow(SQuery* pQuery, STimeWindow *pNext, SDataB * this case may happen when the time window is too small */ if (primaryKeys == NULL) { - if (QUERY_IS_ASC_QUERY(pQuery)) { + if (QUERY_IS_ASC_QUERY(pQueryAttr)) { assert(pDataBlockInfo->window.skey <= pNext->ekey); } else { assert(pDataBlockInfo->window.ekey >= pNext->skey); } } else { - if (QUERY_IS_ASC_QUERY(pQuery) && primaryKeys[startPos] > pNext->ekey) { + if (QUERY_IS_ASC_QUERY(pQueryAttr) && primaryKeys[startPos] > pNext->ekey) { TSKEY next = primaryKeys[startPos]; - if (pQuery->interval.intervalUnit == 'n' || pQuery->interval.intervalUnit == 'y') { - pNext->skey = taosTimeTruncate(next, &pQuery->interval, pQuery->precision); - pNext->ekey = taosTimeAdd(pNext->skey, pQuery->interval.interval, pQuery->interval.intervalUnit, pQuery->precision) - 1; + if (pQueryAttr->interval.intervalUnit == 'n' || pQueryAttr->interval.intervalUnit == 'y') { + pNext->skey = taosTimeTruncate(next, &pQueryAttr->interval, pQueryAttr->precision); + pNext->ekey = taosTimeAdd(pNext->skey, pQueryAttr->interval.interval, pQueryAttr->interval.intervalUnit, pQueryAttr->precision) - 1; } else { - pNext->ekey += ((next - pNext->ekey + pQuery->interval.sliding - 1)/pQuery->interval.sliding) * pQuery->interval.sliding; - pNext->skey = pNext->ekey - pQuery->interval.interval + 1; + pNext->ekey += ((next - pNext->ekey + pQueryAttr->interval.sliding - 1)/pQueryAttr->interval.sliding) * pQueryAttr->interval.sliding; + pNext->skey = pNext->ekey - pQueryAttr->interval.interval + 1; } - } else if ((!QUERY_IS_ASC_QUERY(pQuery)) && primaryKeys[startPos] < pNext->skey) { + } else if ((!QUERY_IS_ASC_QUERY(pQueryAttr)) && primaryKeys[startPos] < pNext->skey) { TSKEY next = primaryKeys[startPos]; - if (pQuery->interval.intervalUnit == 'n' || pQuery->interval.intervalUnit == 'y') { - pNext->skey = taosTimeTruncate(next, &pQuery->interval, pQuery->precision); - pNext->ekey = taosTimeAdd(pNext->skey, pQuery->interval.interval, pQuery->interval.intervalUnit, pQuery->precision) - 1; + if (pQueryAttr->interval.intervalUnit == 'n' || pQueryAttr->interval.intervalUnit == 'y') { + pNext->skey = taosTimeTruncate(next, &pQueryAttr->interval, pQueryAttr->precision); + pNext->ekey = taosTimeAdd(pNext->skey, pQueryAttr->interval.interval, pQueryAttr->interval.intervalUnit, pQueryAttr->precision) - 1; } else { - pNext->skey -= ((pNext->skey - next + pQuery->interval.sliding - 1) / pQuery->interval.sliding) * pQuery->interval.sliding; - pNext->ekey = pNext->skey + pQuery->interval.interval - 1; + pNext->skey -= ((pNext->skey - next + pQueryAttr->interval.sliding - 1) / pQueryAttr->interval.sliding) * pQueryAttr->interval.sliding; + pNext->ekey = pNext->skey + pQueryAttr->interval.interval - 1; } } } @@ -953,17 +855,17 @@ static int32_t getNextQualifiedWindow(SQuery* pQuery, STimeWindow *pNext, SDataB return startPos; } -static FORCE_INLINE TSKEY reviseWindowEkey(SQuery *pQuery, STimeWindow *pWindow) { +static FORCE_INLINE TSKEY reviseWindowEkey(SQueryAttr *pQueryAttr, STimeWindow *pWindow) { TSKEY ekey = -1; - if (QUERY_IS_ASC_QUERY(pQuery)) { + if (QUERY_IS_ASC_QUERY(pQueryAttr)) { ekey = pWindow->ekey; - if (ekey > pQuery->window.ekey) { - ekey = pQuery->window.ekey; + if (ekey > pQueryAttr->window.ekey) { + ekey = pQueryAttr->window.ekey; } } else { ekey = pWindow->skey; - if (ekey < pQuery->window.ekey) { - ekey = pQuery->window.ekey; + if (ekey < pQueryAttr->window.ekey) { + ekey = pQueryAttr->window.ekey; } } @@ -991,17 +893,17 @@ static void saveDataBlockLastRow(SQueryRuntimeEnv* pRuntimeEnv, SDataBlockInfo* return; } - SQuery* pQuery = pRuntimeEnv->pQuery; - for (int32_t k = 0; k < pQuery->numOfCols; ++k) { + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + for (int32_t k = 0; k < pQueryAttr->numOfCols; ++k) { SColumnInfoData *pColInfo = taosArrayGet(pDataBlock, k); memcpy(pRuntimeEnv->prevRow[k], ((char*)pColInfo->pData) + (pColInfo->info.bytes * rowIndex), pColInfo->info.bytes); } } -static TSKEY getStartTsKey(SQuery* pQuery, STimeWindow* win, const TSKEY* tsCols, int32_t rows) { +static TSKEY getStartTsKey(SQueryAttr* pQueryAttr, STimeWindow* win, const TSKEY* tsCols, int32_t rows) { TSKEY ts = TSKEY_INITIAL_VAL; - bool ascQuery = QUERY_IS_ASC_QUERY(pQuery); + bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); if (tsCols == NULL) { ts = ascQuery? win->skey : win->ekey; } else { @@ -1014,7 +916,7 @@ static TSKEY getStartTsKey(SQuery* pQuery, STimeWindow* win, const TSKEY* tsCols static void setArithParams(SArithmeticSupport* sas, SExprInfo *pExprInfo, SSDataBlock* pSDataBlock) { sas->numOfCols = (int32_t) pSDataBlock->info.numOfCols; - sas->pArithExpr = pExprInfo; + sas->pExprInfo = pExprInfo; sas->colList = calloc(1, pSDataBlock->info.numOfCols*sizeof(SColumnInfo)); for(int32_t i = 0; i < sas->numOfCols; ++i) { @@ -1042,7 +944,7 @@ static void doSetInputDataBlockInfo(SOperatorInfo* pOperator, SQLFunctionCtx* pC } } -static void setInputDataBlock(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order) { +void setInputDataBlock(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order) { if (pCtx[0].functionId == TSDB_FUNC_ARITHM) { SArithmeticSupport* pSupport = (SArithmeticSupport*) pCtx[0].param[1].pz; if (pSupport->colList == NULL) { @@ -1071,19 +973,30 @@ static void doSetInputDataBlock(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, setArithParams((SArithmeticSupport*)pCtx[i].param[1].pz, &pOperator->pExpr[i], pBlock); } else { SColIndex* pCol = &pOperator->pExpr[i].base.colInfo; - if (TSDB_COL_IS_NORMAL_COL(pCol->flag) || pCol->colId == TSDB_BLOCK_DIST_COLUMN_INDEX) { + if (TSDB_COL_IS_NORMAL_COL(pCol->flag) || (pCol->colId == TSDB_BLOCK_DIST_COLUMN_INDEX) || + (TSDB_COL_IS_TAG(pCol->flag) && pOperator->pRuntimeEnv->scanFlag == MERGE_STAGE)) { SColIndex* pColIndex = &pOperator->pExpr[i].base.colInfo; SColumnInfoData* p = taosArrayGet(pBlock->pDataBlock, pColIndex->colIndex); // in case of the block distribution query, the inputBytes is not a constant value. pCtx[i].pInput = p->pData; - assert(p->info.colId == pColIndex->colId && pCtx[i].inputType == p->info.type);// && pCtx[i].inputBytes == p->info.bytes); + assert(p->info.colId == pColIndex->colId && pCtx[i].inputType == p->info.type); uint32_t status = aAggs[pCtx[i].functionId].status; if ((status & (TSDB_FUNCSTATE_SELECTIVITY | TSDB_FUNCSTATE_NEED_TS)) != 0) { SColumnInfoData* tsInfo = taosArrayGet(pBlock->pDataBlock, 0); pCtx[i].ptsList = (int64_t*) tsInfo->pData; } + } else if (TSDB_COL_IS_UD_COL(pCol->flag) && (pOperator->pRuntimeEnv->scanFlag == MERGE_STAGE)) { + SColIndex* pColIndex = &pOperator->pExpr[i].base.colInfo; + SColumnInfoData* p = taosArrayGet(pBlock->pDataBlock, pColIndex->colIndex); + + pCtx[i].pInput = p->pData; + assert(p->info.colId == pColIndex->colId && pCtx[i].inputType == p->info.type); + for(int32_t j = 0; j < pBlock->info.rows; ++j) { + char* dst = p->pData + j * p->info.bytes; + tVariantDump(&pOperator->pExpr[i].base.param[1], dst, p->info.type, true); + } } } } @@ -1107,10 +1020,17 @@ static void doAggregateImpl(SOperatorInfo* pOperator, TSKEY startTs, SQLFunction } static void arithmeticApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *pCtx, int32_t numOfOutput) { - SQuery *pQuery = pRuntimeEnv->pQuery; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; for (int32_t k = 0; k < numOfOutput; ++k) { - pCtx[k].startTs = pQuery->window.skey; + pCtx[k].startTs = pQueryAttr->window.skey; + + // Always set the asc order for merge stage process + if (pCtx[k].currentStage == MERGE_STAGE) { + pCtx[k].order = TSDB_ORDER_ASC; + } + + pCtx[k].startTs = pQueryAttr->window.skey; if (pCtx[k].functionId < 0) { // load the script and exec @@ -1179,9 +1099,9 @@ void doTimeWindowInterpolation(SOperatorInfo* pOperator, SOptrBasicInfo* pInfo, static bool setTimeWindowInterpolationStartTs(SOperatorInfo* pOperatorInfo, SQLFunctionCtx* pCtx, int32_t pos, int32_t numOfRows, SArray* pDataBlock, const TSKEY* tsCols, STimeWindow* win) { SQueryRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv; - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; - bool ascQuery = QUERY_IS_ASC_QUERY(pQuery); + bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); TSKEY curTs = tsCols[pos]; TSKEY lastTs = *(TSKEY *) pRuntimeEnv->prevRow[0]; @@ -1199,7 +1119,7 @@ static bool setTimeWindowInterpolationStartTs(SOperatorInfo* pOperatorInfo, SQLF return true; } - int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); + int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order); TSKEY prevTs = ((pos == 0 && ascQuery) || (pos == (numOfRows - 1) && !ascQuery))? lastTs:tsCols[pos - step]; doTimeWindowInterpolation(pOperatorInfo, pOperatorInfo->info, pDataBlock, prevTs, pos - step, curTs, pos, @@ -1210,15 +1130,15 @@ static bool setTimeWindowInterpolationStartTs(SOperatorInfo* pOperatorInfo, SQLF static bool setTimeWindowInterpolationEndTs(SOperatorInfo* pOperatorInfo, SQLFunctionCtx* pCtx, int32_t endRowIndex, SArray* pDataBlock, const TSKEY* tsCols, TSKEY blockEkey, STimeWindow* win) { SQueryRuntimeEnv *pRuntimeEnv = pOperatorInfo->pRuntimeEnv; - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t numOfOutput = pOperatorInfo->numOfOutput; TSKEY actualEndKey = tsCols[endRowIndex]; - TSKEY key = QUERY_IS_ASC_QUERY(pQuery)? win->ekey:win->skey; + TSKEY key = QUERY_IS_ASC_QUERY(pQueryAttr)? win->ekey:win->skey; // not ended in current data block, do not invoke interpolation - if ((key > blockEkey && QUERY_IS_ASC_QUERY(pQuery)) || (key < blockEkey && !QUERY_IS_ASC_QUERY(pQuery))) { + if ((key > blockEkey && QUERY_IS_ASC_QUERY(pQueryAttr)) || (key < blockEkey && !QUERY_IS_ASC_QUERY(pQueryAttr))) { setNotInterpoWindowKey(pCtx, numOfOutput, RESULT_ROW_END_INTERP); return false; } @@ -1229,7 +1149,7 @@ static bool setTimeWindowInterpolationEndTs(SOperatorInfo* pOperatorInfo, SQLFun return true; } - int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); + int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order); int32_t nextRowIndex = endRowIndex + step; assert(nextRowIndex >= 0); @@ -1242,13 +1162,13 @@ static bool setTimeWindowInterpolationEndTs(SOperatorInfo* pOperatorInfo, SQLFun static void doWindowBorderInterpolation(SOperatorInfo* pOperatorInfo, SSDataBlock* pBlock, SQLFunctionCtx* pCtx, SResultRow* pResult, STimeWindow* win, int32_t startPos, int32_t forwardStep) { SQueryRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv; - SQuery* pQuery = pRuntimeEnv->pQuery; - if (!pQuery->timeWindowInterpo) { + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + if (!pQueryAttr->timeWindowInterpo) { return; } assert(pBlock != NULL); - int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); + int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order); SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, 0); @@ -1262,11 +1182,11 @@ static void doWindowBorderInterpolation(SOperatorInfo* pOperatorInfo, SSDataBloc setResultRowInterpo(pResult, RESULT_ROW_START_INTERP); } } else { - setNotInterpoWindowKey(pCtx, pQuery->numOfOutput, RESULT_ROW_START_INTERP); + setNotInterpoWindowKey(pCtx, pQueryAttr->numOfOutput, RESULT_ROW_START_INTERP); } // point interpolation does not require the end key time window interpolation. - if (isPointInterpoQuery(pQuery)) { + if (pQueryAttr->pointInterpQuery) { return; } @@ -1275,13 +1195,13 @@ static void doWindowBorderInterpolation(SOperatorInfo* pOperatorInfo, SSDataBloc if (!done) { int32_t endRowIndex = startPos + (forwardStep - 1) * step; - TSKEY endKey = QUERY_IS_ASC_QUERY(pQuery)? pBlock->info.window.ekey:pBlock->info.window.skey; + TSKEY endKey = QUERY_IS_ASC_QUERY(pQueryAttr)? pBlock->info.window.ekey:pBlock->info.window.skey; bool interp = setTimeWindowInterpolationEndTs(pOperatorInfo, pCtx, endRowIndex, pBlock->pDataBlock, tsCols, endKey, win); if (interp) { setResultRowInterpo(pResult, RESULT_ROW_END_INTERP); } } else { - setNotInterpoWindowKey(pCtx, pQuery->numOfOutput, RESULT_ROW_END_INTERP); + setNotInterpoWindowKey(pCtx, pQueryAttr->numOfOutput, RESULT_ROW_END_INTERP); } } @@ -1290,10 +1210,10 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul SQueryRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv; int32_t numOfOutput = pOperatorInfo->numOfOutput; - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; - int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); - bool ascQuery = QUERY_IS_ASC_QUERY(pQuery); + int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order); + bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); int32_t prevIndex = curTimeWindowIndex(pResultRowInfo); @@ -1306,9 +1226,9 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul } int32_t startPos = ascQuery? 0 : (pSDataBlock->info.rows - 1); - TSKEY ts = getStartTsKey(pQuery, &pSDataBlock->info.window, tsCols, pSDataBlock->info.rows); + TSKEY ts = getStartTsKey(pQueryAttr, &pSDataBlock->info.window, tsCols, pSDataBlock->info.rows); - STimeWindow win = getActiveTimeWindow(pResultRowInfo, ts, pQuery); + STimeWindow win = getActiveTimeWindow(pResultRowInfo, ts, pQueryAttr); bool masterScan = IS_MASTER_SCAN(pRuntimeEnv); SResultRow* pResult = NULL; @@ -1319,13 +1239,13 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul } int32_t forwardStep = 0; - TSKEY ekey = reviseWindowEkey(pQuery, &win); + TSKEY ekey = reviseWindowEkey(pQueryAttr, &win); forwardStep = - getNumOfRowsInTimeWindow(pQuery, &pSDataBlock->info, tsCols, startPos, ekey, binarySearchForKey, true); + getNumOfRowsInTimeWindow(pRuntimeEnv, &pSDataBlock->info, tsCols, startPos, ekey, binarySearchForKey, true); // prev time window not interpolation yet. int32_t curIndex = curTimeWindowIndex(pResultRowInfo); - if (prevIndex != -1 && prevIndex < curIndex && pQuery->timeWindowInterpo) { + if (prevIndex != -1 && prevIndex < curIndex && pQueryAttr->timeWindowInterpo) { for (int32_t j = prevIndex; j < curIndex; ++j) { // previous time window may be all closed already. SResultRow* pRes = pResultRowInfo->pResult[j]; if (pRes->closed) { @@ -1347,7 +1267,7 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul -1, tsCols[startPos], startPos, w.ekey, RESULT_ROW_END_INTERP); setResultRowInterpo(pResult, RESULT_ROW_END_INTERP); - setNotInterpoWindowKey(pInfo->pCtx, pQuery->numOfOutput, RESULT_ROW_START_INTERP); + setNotInterpoWindowKey(pInfo->pCtx, pQueryAttr->numOfOutput, RESULT_ROW_START_INTERP); doApplyFunctions(pRuntimeEnv, pInfo->pCtx, &w, startPos, 0, tsCols, pSDataBlock->info.rows, numOfOutput); } @@ -1367,7 +1287,7 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul STimeWindow nextWin = win; while (1) { int32_t prevEndPos = (forwardStep - 1) * step + startPos; - startPos = getNextQualifiedWindow(pQuery, &nextWin, &pSDataBlock->info, tsCols, binarySearchForKey, prevEndPos); + startPos = getNextQualifiedWindow(pQueryAttr, &nextWin, &pSDataBlock->info, tsCols, binarySearchForKey, prevEndPos); if (startPos < 0) { break; } @@ -1379,33 +1299,34 @@ static void hashIntervalAgg(SOperatorInfo* pOperatorInfo, SResultRowInfo* pResul longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY); } - ekey = reviseWindowEkey(pQuery, &nextWin); - forwardStep = getNumOfRowsInTimeWindow(pQuery, &pSDataBlock->info, tsCols, startPos, ekey, binarySearchForKey, true); + ekey = reviseWindowEkey(pQueryAttr, &nextWin); + forwardStep = getNumOfRowsInTimeWindow(pRuntimeEnv, &pSDataBlock->info, tsCols, startPos, ekey, binarySearchForKey, true); // window start(end) key interpolation doWindowBorderInterpolation(pOperatorInfo, pSDataBlock, pInfo->pCtx, pResult, &nextWin, startPos, forwardStep); doApplyFunctions(pRuntimeEnv, pInfo->pCtx, &nextWin, startPos, forwardStep, tsCols, pSDataBlock->info.rows, numOfOutput); } - if (pQuery->timeWindowInterpo) { + if (pQueryAttr->timeWindowInterpo) { int32_t rowIndex = ascQuery? (pSDataBlock->info.rows-1):0; saveDataBlockLastRow(pRuntimeEnv, &pSDataBlock->info, pSDataBlock->pDataBlock, rowIndex); } - updateResultRowInfoActiveIndex(pResultRowInfo, pQuery, pQuery->current->lastKey); + updateResultRowInfoActiveIndex(pResultRowInfo, pQueryAttr, pRuntimeEnv->current->lastKey); } static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pInfo, SSDataBlock *pSDataBlock) { SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; - STableQueryInfo* item = pRuntimeEnv->pQuery->current; + STableQueryInfo* item = pRuntimeEnv->current; SColumnInfoData* pColInfoData = taosArrayGet(pSDataBlock->pDataBlock, pInfo->colIndex); - int16_t bytes = pColInfoData->info.bytes; - int16_t type = pColInfoData->info.type; - SQuery *pQuery = pRuntimeEnv->pQuery; + + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int16_t bytes = pColInfoData->info.bytes; + int16_t type = pColInfoData->info.type; 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)); + qError("QInfo:0x%"PRIx64" group by not supported on double/float columns, abort", GET_QID(pRuntimeEnv)); return; } @@ -1423,7 +1344,7 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn memcpy(pInfo->prevData, val, bytes); - if (pQuery->stableQuery && pQuery->stabledev && (pRuntimeEnv->prevResult != NULL)) { + if (pQueryAttr->stableQuery && pQueryAttr->stabledev && (pRuntimeEnv->prevResult != NULL)) { setParamForStableStddevByColData(pRuntimeEnv, pInfo->binfo.pCtx, pOperator->numOfOutput, pOperator->pExpr, val, bytes); } @@ -1448,7 +1369,7 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSWindowOperatorInfo *pInfo, SSDataBlock *pSDataBlock) { SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; - STableQueryInfo* item = pRuntimeEnv->pQuery->current; + STableQueryInfo* item = pRuntimeEnv->current; // primary timestamp column SColumnInfoData* pColInfoData = taosArrayGet(pSDataBlock->pDataBlock, 0); @@ -1456,7 +1377,7 @@ static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSWindowOperatorInf bool masterScan = IS_MASTER_SCAN(pRuntimeEnv); SOptrBasicInfo* pBInfo = &pInfo->binfo; - int64_t gap = pOperator->pRuntimeEnv->pQuery->sw.gap; + int64_t gap = pOperator->pRuntimeEnv->pQueryAttr->sw.gap; pInfo->numOfRows = 0; TSKEY* tsList = (TSKEY*)pColInfoData->pData; @@ -1542,14 +1463,14 @@ static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SGroupbyOp setResultRowKey(pResultRow, pData, type); if (pResultRow->pageId == -1) { - int32_t ret = addNewWindowResultBuf(pResultRow, pResultBuf, groupIndex, pRuntimeEnv->pQuery->resultRowSize); + int32_t ret = addNewWindowResultBuf(pResultRow, pResultBuf, groupIndex, pRuntimeEnv->pQueryAttr->resultRowSize); if (ret != 0) { return -1; } } setResultOutputBuf(pRuntimeEnv, pResultRow, pCtx, numOfCols, rowCellInfoOffset); - initCtxOutputBuffer(pRuntimeEnv, pCtx, numOfCols); + initCtxOutputBuffer(pCtx, numOfCols); return TSDB_CODE_SUCCESS; } @@ -1576,7 +1497,7 @@ static int32_t getGroupbyColumnIndex(SSqlGroupbyExpr *pGroupbyExpr, SSDataBlock* static bool functionNeedToExecute(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *pCtx, int32_t functionId) { SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; // in case of timestamp column, always generated results. if (functionId == TSDB_FUNC_TS) { @@ -1588,12 +1509,12 @@ static bool functionNeedToExecute(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx } if (functionId == TSDB_FUNC_FIRST_DST || functionId == TSDB_FUNC_FIRST) { - return QUERY_IS_ASC_QUERY(pQuery); + return QUERY_IS_ASC_QUERY(pQueryAttr); } // denote the order type if ((functionId == TSDB_FUNC_LAST_DST || functionId == TSDB_FUNC_LAST)) { - return pCtx->param[0].i64 == pQuery->order.order; + return pCtx->param[0].i64 == pQueryAttr->order.order; } // in the reverse table scan, only the following functions need to be executed @@ -1672,7 +1593,7 @@ static int32_t setCtxTagColumnInfo(SQLFunctionCtx *pCtx, int32_t numOfOutput) { static SQLFunctionCtx* createSQLFunctionCtx(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput, int32_t** rowCellInfoOffset) { - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; SQLFunctionCtx * pFuncCtx = (SQLFunctionCtx *)calloc(numOfOutput, sizeof(SQLFunctionCtx)); if (pFuncCtx == NULL) { @@ -1686,10 +1607,10 @@ static SQLFunctionCtx* createSQLFunctionCtx(SQueryRuntimeEnv* pRuntimeEnv, SExpr } for (int32_t i = 0; i < numOfOutput; ++i) { - SSqlFuncMsg *pSqlFuncMsg = &pExpr[i].base; + SSqlExpr *pSqlExpr = &pExpr[i].base; SQLFunctionCtx* pCtx = &pFuncCtx[i]; - SColIndex *pIndex = &pSqlFuncMsg->colInfo; + SColIndex *pIndex = &pSqlExpr->colInfo; if (TSDB_COL_REQ_NULL(pIndex->flag)) { pCtx->requireNull = true; @@ -1698,33 +1619,33 @@ static SQLFunctionCtx* createSQLFunctionCtx(SQueryRuntimeEnv* pRuntimeEnv, SExpr pCtx->requireNull = false; } - pCtx->inputBytes = pSqlFuncMsg->colBytes; - pCtx->inputType = pSqlFuncMsg->colType; + pCtx->inputBytes = pSqlExpr->colBytes; + pCtx->inputType = pSqlExpr->colType; pCtx->ptsOutputBuf = NULL; - pCtx->outputBytes = pExpr[i].bytes; - pCtx->outputType = pExpr[i].type; + pCtx->outputBytes = pSqlExpr->resBytes; + pCtx->outputType = pSqlExpr->resType; - pCtx->order = pQuery->order.order; - pCtx->functionId = pSqlFuncMsg->functionId; - pCtx->stableQuery = pQuery->stableQuery; - pCtx->interBufBytes = pExpr[i].interBytes; + pCtx->order = pQueryAttr->order.order; + pCtx->functionId = pSqlExpr->functionId; + pCtx->stableQuery = pQueryAttr->stableQuery; + pCtx->interBufBytes = pSqlExpr->interBytes; pCtx->start.key = INT64_MIN; pCtx->end.key = INT64_MIN; - pCtx->numOfParams = pSqlFuncMsg->numOfParams; + pCtx->numOfParams = pSqlExpr->numOfParams; for (int32_t j = 0; j < pCtx->numOfParams; ++j) { - int16_t type = pSqlFuncMsg->arg[j].argType; - int16_t bytes = pSqlFuncMsg->arg[j].argBytes; - if (pSqlFuncMsg->functionId == TSDB_FUNC_STDDEV_DST) { + int16_t type = pSqlExpr->param[j].nType; + int16_t bytes = pSqlExpr->param[j].nLen; + if (pSqlExpr->functionId == TSDB_FUNC_STDDEV_DST) { continue; } if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) { - tVariantCreateFromBinary(&pCtx->param[j], pSqlFuncMsg->arg[j].argValue.pz, bytes, type); + tVariantCreateFromBinary(&pCtx->param[j], pSqlExpr->param[j].pz, bytes, type); } else { - tVariantCreateFromBinary(&pCtx->param[j], (char *)&pSqlFuncMsg->arg[j].argValue.i64, bytes, type); + tVariantCreateFromBinary(&pCtx->param[j], (char *)&pSqlExpr->param[j].i64, bytes, type); } } @@ -1735,30 +1656,30 @@ static SQLFunctionCtx* createSQLFunctionCtx(SQueryRuntimeEnv* pRuntimeEnv, SExpr int32_t f = pExpr[0].base.functionId; assert(f == TSDB_FUNC_TS || f == TSDB_FUNC_TS_DUMMY); - pCtx->param[2].i64 = pQuery->order.order; + pCtx->param[2].i64 = pQueryAttr->order.order; pCtx->param[2].nType = TSDB_DATA_TYPE_BIGINT; pCtx->param[3].i64 = functionId; pCtx->param[3].nType = TSDB_DATA_TYPE_BIGINT; - pCtx->param[1].i64 = pQuery->order.orderColId; + pCtx->param[1].i64 = pQueryAttr->order.orderColId; } else if (functionId == TSDB_FUNC_INTERP) { - pCtx->param[2].i64 = (int8_t)pQuery->fillType; - if (pQuery->fillVal != NULL) { - if (isNull((const char *)&pQuery->fillVal[i], pCtx->inputType)) { + pCtx->param[2].i64 = (int8_t)pQueryAttr->fillType; + if (pQueryAttr->fillVal != NULL) { + if (isNull((const char *)&pQueryAttr->fillVal[i], pCtx->inputType)) { pCtx->param[1].nType = TSDB_DATA_TYPE_NULL; } else { // todo refactor, tVariantCreateFromBinary should handle the NULL value if (pCtx->inputType != TSDB_DATA_TYPE_BINARY && pCtx->inputType != TSDB_DATA_TYPE_NCHAR) { - tVariantCreateFromBinary(&pCtx->param[1], (char *)&pQuery->fillVal[i], pCtx->inputBytes, pCtx->inputType); + tVariantCreateFromBinary(&pCtx->param[1], (char *)&pQueryAttr->fillVal[i], pCtx->inputBytes, pCtx->inputType); } } } } else if (functionId == TSDB_FUNC_TS_COMP) { - pCtx->param[0].i64 = pQuery->vgId; //TODO this should be the parameter from client + pCtx->param[0].i64 = pQueryAttr->vgId; //TODO this should be the parameter from client pCtx->param[0].nType = TSDB_DATA_TYPE_BIGINT; } else if (functionId == TSDB_FUNC_TWA) { - pCtx->param[1].i64 = pQuery->window.skey; + pCtx->param[1].i64 = pQueryAttr->window.skey; pCtx->param[1].nType = TSDB_DATA_TYPE_BIGINT; - pCtx->param[2].i64 = pQuery->window.ekey; + pCtx->param[2].i64 = pQueryAttr->window.ekey; pCtx->param[2].nType = TSDB_DATA_TYPE_BIGINT; } else if (functionId == TSDB_FUNC_ARITHM) { pCtx->param[1].pz = (char*) &pRuntimeEnv->sasArray[i]; @@ -1767,7 +1688,7 @@ static SQLFunctionCtx* createSQLFunctionCtx(SQueryRuntimeEnv* pRuntimeEnv, SExpr for(int32_t i = 1; i < numOfOutput; ++i) { (*rowCellInfoOffset)[i] = (int32_t)((*rowCellInfoOffset)[i - 1] + sizeof(SResultRowCellInfo) + - pExpr[i - 1].interBytes * GET_ROW_PARAM_FOR_MULTIOUTPUT(pQuery, pQuery->topBotQuery, pQuery->stableQuery)); + pExpr[i - 1].base.interBytes * GET_ROW_PARAM_FOR_MULTIOUTPUT(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery)); } setCtxTagColumnInfo(pFuncCtx, numOfOutput); @@ -1793,120 +1714,159 @@ static void* destroySQLFunctionCtx(SQLFunctionCtx* pCtx, int32_t numOfOutput) { return NULL; } -static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOfTables) { - qDebug("QInfo:%"PRIu64" setup runtime env", GET_QID(pRuntimeEnv)); - SQuery *pQuery = pRuntimeEnv->pQuery; +static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOfTables, SArray* pOperator, void* merger) { + qDebug("QInfo:0x%"PRIx64" setup runtime env", GET_QID(pRuntimeEnv)); + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; pRuntimeEnv->prevGroupId = INT32_MIN; - pRuntimeEnv->pQuery = pQuery; + pRuntimeEnv->pQueryAttr = pQueryAttr; pRuntimeEnv->pResultRowHashTable = taosHashInit(numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK); - pRuntimeEnv->keyBuf = malloc(pQuery->maxSrcColumnSize + sizeof(int64_t)); + pRuntimeEnv->keyBuf = malloc(pQueryAttr->maxTableColumnWidth + sizeof(int64_t)); pRuntimeEnv->pool = initResultRowPool(getResultRowSize(pRuntimeEnv)); - pRuntimeEnv->prevRow = malloc(POINTER_BYTES * pQuery->numOfCols + pQuery->srcRowSize); - pRuntimeEnv->tagVal = malloc(pQuery->tagLen); - pRuntimeEnv->currentOffset = pQuery->limit.offset; + pRuntimeEnv->prevRow = malloc(POINTER_BYTES * pQueryAttr->numOfCols + pQueryAttr->srcRowSize); + pRuntimeEnv->tagVal = malloc(pQueryAttr->tagLen); + pRuntimeEnv->currentOffset = pQueryAttr->limit.offset; // NOTE: pTableCheckInfo need to update the query time range and the lastKey info pRuntimeEnv->pTableRetrieveTsMap = taosHashInit(numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK); - pRuntimeEnv->sasArray = calloc(pQuery->numOfOutput, sizeof(SArithmeticSupport)); + pRuntimeEnv->sasArray = calloc(pQueryAttr->numOfOutput, sizeof(SArithmeticSupport)); if (pRuntimeEnv->sasArray == NULL || pRuntimeEnv->pResultRowHashTable == NULL || pRuntimeEnv->keyBuf == NULL || pRuntimeEnv->prevRow == NULL || pRuntimeEnv->tagVal == NULL) { goto _clean; } - if (pQuery->numOfCols) { - char* start = POINTER_BYTES * pQuery->numOfCols + (char*) pRuntimeEnv->prevRow; + if (pQueryAttr->numOfCols) { + char* start = POINTER_BYTES * pQueryAttr->numOfCols + (char*) pRuntimeEnv->prevRow; pRuntimeEnv->prevRow[0] = start; - for(int32_t i = 1; i < pQuery->numOfCols; ++i) { - pRuntimeEnv->prevRow[i] = pRuntimeEnv->prevRow[i - 1] + pQuery->colList[i-1].bytes; + for(int32_t i = 1; i < pQueryAttr->numOfCols; ++i) { + pRuntimeEnv->prevRow[i] = pRuntimeEnv->prevRow[i - 1] + pQueryAttr->tableCols[i-1].bytes; } *(int64_t*) pRuntimeEnv->prevRow[0] = INT64_MIN; } - qDebug("QInfo:%"PRIu64" init runtime environment completed", GET_QID(pRuntimeEnv)); + qDebug("QInfo:0x%"PRIx64" init runtime environment completed", GET_QID(pRuntimeEnv)); // group by normal column, sliding window query, interval query are handled by interval query processor // interval (down sampling operation) - if (onlyQueryTags(pQuery)) { // do nothing for tags query + int32_t numOfOperator = (int32_t) taosArrayGetSize(pOperator); + for(int32_t i = 0; i < numOfOperator; ++i) { + int32_t* op = taosArrayGet(pOperator, i); - } else if (QUERY_IS_INTERVAL_QUERY(pQuery)) { - if (pQuery->stableQuery) { - pRuntimeEnv->proot = createMultiTableTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, - pQuery->pExpr1, pQuery->numOfOutput); - setTableScanFilterOperatorInfo(pRuntimeEnv->pTableScanner->info, pRuntimeEnv->proot); - } else { - pRuntimeEnv->proot = - createTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, pQuery->pExpr1, pQuery->numOfOutput); - setTableScanFilterOperatorInfo(pRuntimeEnv->pTableScanner->info, pRuntimeEnv->proot); - - if (pQuery->pExpr2 != NULL) { + switch (*op) { + case OP_TagScan: { + pRuntimeEnv->proot = createTagScanOperatorInfo(pRuntimeEnv, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); + break; + } + case OP_MultiTableTimeInterval: { pRuntimeEnv->proot = - createArithOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQuery->pExpr2, pQuery->numOfExpr2); + createMultiTableTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); + setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot); + break; + } + case OP_TimeWindow: { + pRuntimeEnv->proot = + createTimeIntervalOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); + setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot); + break; + } + case OP_Groupby: { + pRuntimeEnv->proot = + createGroupbyOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); + setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot); + break; + } + case OP_SessionWindow: { + pRuntimeEnv->proot = + createSWindowOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); + setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot); + break; + } + case OP_MultiTableAggregate: { + pRuntimeEnv->proot = + createMultiTableAggOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); + setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot); + break; + } + case OP_Aggregate: { + pRuntimeEnv->proot = + createAggregateOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); + if (pRuntimeEnv->proot->upstream->operatorType != OP_DummyInput) { + setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream->info, pRuntimeEnv->proot); + } + break; } - if (pQuery->fillType != TSDB_FILL_NONE && !isPointInterpoQuery(pQuery)) { + case OP_Arithmetic: { // TODO refactor to remove arith operator. + SOperatorInfo* prev = pRuntimeEnv->proot; + if (i == 0) { + pRuntimeEnv->proot = createArithOperatorInfo(pRuntimeEnv, prev, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); + if (pRuntimeEnv->proot != NULL && pRuntimeEnv->proot->operatorType != OP_DummyInput) { // TODO refactor + setTableScanFilterOperatorInfo(prev->info, pRuntimeEnv->proot); + } + } else { + prev = pRuntimeEnv->proot; + assert(pQueryAttr->pExpr2 != NULL); + pRuntimeEnv->proot = createArithOperatorInfo(pRuntimeEnv, prev, pQueryAttr->pExpr2, pQueryAttr->numOfExpr2); + } + break; + } + + case OP_Limit: { + pRuntimeEnv->proot = createLimitOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot); + break; + } + + case OP_Filter: { // todo refactor + assert(pQueryAttr->havingNum > 0); + if (pQueryAttr->stableQuery) { + pRuntimeEnv->proot = createFilterOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr3, pQueryAttr->numOfExpr3); + } else { + pRuntimeEnv->proot = createFilterOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); + } + break; + } + + case OP_Fill: { SOperatorInfo* pInfo = pRuntimeEnv->proot; pRuntimeEnv->proot = createFillOperatorInfo(pRuntimeEnv, pInfo, pInfo->pExpr, pInfo->numOfOutput); + break; + } + + case OP_MultiwayMergeSort: { + bool groupMix = true; + if(pQueryAttr->slimit.offset != 0 || pQueryAttr->slimit.limit != -1) { + groupMix = false; + } + pRuntimeEnv->proot = createMultiwaySortOperatorInfo(pRuntimeEnv, pQueryAttr->pExpr1, pQueryAttr->numOfOutput, + 4096, merger, groupMix); // TODO hack it + break; + } + + case OP_GlobalAggregate: { + pRuntimeEnv->proot = createGlobalAggregateOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr3, + pQueryAttr->numOfExpr3, merger); + break; + } + + case OP_SLimit: { + pRuntimeEnv->proot = createSLimitOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr3, + pQueryAttr->numOfExpr3, merger); + break; + } + + case OP_Distinct: { + pRuntimeEnv->proot = createDistinctOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput); + break; + } + + default: { + assert(0); } } - - } else if (pQuery->groupbyColumn) { - pRuntimeEnv->proot = - createGroupbyOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, pQuery->pExpr1, pQuery->numOfOutput); - setTableScanFilterOperatorInfo(pRuntimeEnv->pTableScanner->info, pRuntimeEnv->proot); - - if (pQuery->pExpr2 != NULL) { - pRuntimeEnv->proot = createArithOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQuery->pExpr2, pQuery->numOfExpr2); - } - } else if (pQuery->sw.gap > 0) { - pRuntimeEnv->proot = createSWindowOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, pQuery->pExpr1, pQuery->numOfOutput); - setTableScanFilterOperatorInfo(pRuntimeEnv->pTableScanner->info, pRuntimeEnv->proot); - - if (pQuery->pExpr2 != NULL) { - pRuntimeEnv->proot = createArithOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQuery->pExpr2, pQuery->numOfExpr2); - } - } else if (isFixedOutputQuery(pRuntimeEnv)) { - if (pQuery->stableQuery && !isTsCompQuery(pQuery)) { - pRuntimeEnv->proot = - createMultiTableAggOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, pQuery->pExpr1, pQuery->numOfOutput); - } else { - pRuntimeEnv->proot = - createAggregateOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, pQuery->pExpr1, pQuery->numOfOutput); - } - - setTableScanFilterOperatorInfo(pRuntimeEnv->pTableScanner->info, pRuntimeEnv->proot); - - if (pQuery->pExpr2 != NULL) { - pRuntimeEnv->proot = createArithOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQuery->pExpr2, pQuery->numOfExpr2); - } - } else { // diff/add/multiply/subtract/division - assert(pQuery->checkResultBuf == 1); - if (!onlyQueryTags(pQuery)) { - pRuntimeEnv->proot = - createArithOperatorInfo(pRuntimeEnv, pRuntimeEnv->pTableScanner, pQuery->pExpr1, pQuery->numOfOutput); - setTableScanFilterOperatorInfo(pRuntimeEnv->pTableScanner->info, pRuntimeEnv->proot); - - if (pQuery->pExpr2 != NULL) { - pRuntimeEnv->proot = createArithOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQuery->pExpr2, pQuery->numOfExpr2); - } - } - - } - - 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); - } - - if (pQuery->limit.limit > 0) { - pRuntimeEnv->proot = createLimitOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot); } return TSDB_CODE_SUCCESS; @@ -1922,48 +1882,50 @@ _clean: } static void doFreeQueryHandle(SQueryRuntimeEnv* pRuntimeEnv) { - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; tsdbCleanupQueryHandle(pRuntimeEnv->pQueryHandle); pRuntimeEnv->pQueryHandle = NULL; - SMemRef* pMemRef = &pQuery->memRef; + SMemRef* pMemRef = &pQueryAttr->memRef; assert(pMemRef->ref == 0 && pMemRef->snapshot.imem == NULL && pMemRef->snapshot.mem == NULL); } -static void destroyTsComp(SQueryRuntimeEnv *pRuntimeEnv, SQuery *pQuery) { - if (isTsCompQuery(pQuery)) { +static void destroyTsComp(SQueryRuntimeEnv *pRuntimeEnv, SQueryAttr *pQueryAttr) { + if (pQueryAttr->tsCompQuery && pRuntimeEnv->outputBuf && pRuntimeEnv->outputBuf->pDataBlock && taosArrayGetSize(pRuntimeEnv->outputBuf->pDataBlock) > 0) { SColumnInfoData* pColInfoData = taosArrayGet(pRuntimeEnv->outputBuf->pDataBlock, 0); - FILE *f = *(FILE **)pColInfoData->pData; // TODO refactor - if (f) { - fclose(f); - *(FILE **)pColInfoData->pData = NULL; + 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; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; SQInfo* pQInfo = (SQInfo*) pRuntimeEnv->qinfo; - qDebug("QInfo:%"PRIu64" teardown runtime env", pQInfo->qId); + qDebug("QInfo:0x%"PRIx64" teardown runtime env", pQInfo->qId); if (pRuntimeEnv->sasArray != NULL) { - for(int32_t i = 0; i < pQuery->numOfOutput; ++i) { + for(int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { tfree(pRuntimeEnv->sasArray[i].data); tfree(pRuntimeEnv->sasArray[i].colList); } tfree(pRuntimeEnv->sasArray); } - + destroyUdfInfo(pRuntimeEnv->pUdfInfo); destroyResultBuf(pRuntimeEnv->pResultBuf); doFreeQueryHandle(pRuntimeEnv); - destroyTsComp(pRuntimeEnv, pQuery); - + destroyTsComp(pRuntimeEnv, pQueryAttr); + pRuntimeEnv->pTsBuf = tsBufDestroy(pRuntimeEnv->pTsBuf); tfree(pRuntimeEnv->keyBuf); @@ -1981,7 +1943,6 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) { pRuntimeEnv->pool = destroyResultRowPool(pRuntimeEnv->pool); taosArrayDestroyEx(pRuntimeEnv->prevResult, freeInterResult); pRuntimeEnv->prevResult = NULL; - } static bool needBuildResAfterQueryComplete(SQInfo* pQInfo) { @@ -2009,59 +1970,47 @@ bool isQueryKilled(SQInfo *pQInfo) { void setQueryKilled(SQInfo *pQInfo) { pQInfo->code = TSDB_CODE_TSC_QUERY_CANCELLED;} -static bool isFixedOutputQuery(SQueryRuntimeEnv *pRuntimeEnv) { - SQuery* pQuery = pRuntimeEnv->pQuery; - - if (QUERY_IS_INTERVAL_QUERY(pQuery)) { - return false; - } - - if (pRuntimeEnv->pUdfInfo && pRuntimeEnv->pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE) { - return true; - } - - // Note:top/bottom query is fixed output query - if (pQuery->topBotQuery || pQuery->groupbyColumn || isTsCompQuery(pQuery)) { - return true; - } - - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - SSqlFuncMsg *pExprMsg = &pQuery->pExpr1[i].base; - - // ignore the ts_comp function - if (i == 0 && pExprMsg->functionId == TSDB_FUNC_PRJ && pExprMsg->numOfParams == 1 && - pExprMsg->colInfo.colIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX) { - continue; - } - - if (pExprMsg->functionId == TSDB_FUNC_TS || pExprMsg->functionId == TSDB_FUNC_TS_DUMMY) { - continue; - } - - if (!IS_MULTIOUTPUT(aAggs[pExprMsg->functionId].status)) { - return true; - } - } - - return false; -} +//static bool isFixedOutputQuery(SQueryAttr* pQueryAttr) { +// if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) { +// return false; +// } +// +// // Note:top/bottom query is fixed output query +// if (pQueryAttr->topBotQuery || pQueryAttr->groupbyColumn || pQueryAttr->tsCompQuery) { +// return true; +// } +// +// for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { +// SSqlExpr *pExpr = &pQueryAttr->pExpr1[i].base; +// +// if (pExpr->functionId == TSDB_FUNC_TS || pExpr->functionId == TSDB_FUNC_TS_DUMMY) { +// continue; +// } +// +// if (!IS_MULTIOUTPUT(aAggs[pExpr->functionId].status)) { +// return true; +// } +// } +// +// return false; +//} // todo refactor with isLastRowQuery -bool isPointInterpoQuery(SQuery *pQuery) { - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - int32_t functionId = pQuery->pExpr1[i].base.functionId; - if (functionId == TSDB_FUNC_INTERP) { - return true; - } - } - - return false; -} +//bool isPointInterpoQuery(SQueryAttr *pQueryAttr) { +// for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { +// int32_t functionId = pQueryAttr->pExpr1[i].base.functionId; +// if (functionId == TSDB_FUNC_INTERP) { +// return true; +// } +// } +// +// return false; +//} // TODO REFACTOR:MERGE WITH CLIENT-SIDE FUNCTION -static UNUSED_FUNC bool isSumAvgRateQuery(SQuery *pQuery) { - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - int32_t functionId = pQuery->pExpr1[i].base.functionId; +static UNUSED_FUNC bool isSumAvgRateQuery(SQueryAttr *pQueryAttr) { + for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { + int32_t functionId = pQueryAttr->pExpr1[i].base.functionId; if (functionId == TSDB_FUNC_TS) { continue; } @@ -2075,9 +2024,9 @@ static UNUSED_FUNC bool isSumAvgRateQuery(SQuery *pQuery) { return false; } -static bool isFirstLastRowQuery(SQuery *pQuery) { - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - int32_t functionID = pQuery->pExpr1[i].base.functionId; +static bool isFirstLastRowQuery(SQueryAttr *pQueryAttr) { + for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { + int32_t functionID = pQueryAttr->pExpr1[i].base.functionId; if (functionID == TSDB_FUNC_LAST_ROW) { return true; } @@ -2086,36 +2035,13 @@ static bool isFirstLastRowQuery(SQuery *pQuery) { return false; } -static bool needReverseScan(SQuery *pQuery) { - 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) { - continue; - } - - if ((functionId == TSDB_FUNC_FIRST || functionId == TSDB_FUNC_FIRST_DST) && !QUERY_IS_ASC_QUERY(pQuery)) { - return true; - } - - if (functionId == TSDB_FUNC_LAST || functionId == TSDB_FUNC_LAST_DST) { - // the scan order to acquire the last result of the specified column - int32_t order = (int32_t)pQuery->pExpr1[i].base.arg->argValue.i64; - if (order != pQuery->order.order) { - return true; - } - } - } - - return false; -} - /** * The following 4 kinds of query are treated as the tags query * tagprj, tid_tag query, count(tbname), 'abc' (user defined constant value column) query */ -bool onlyQueryTags(SQuery* pQuery) { - for(int32_t i = 0; i < pQuery->numOfOutput; ++i) { - SExprInfo* pExprInfo = &pQuery->pExpr1[i]; +bool onlyQueryTags(SQueryAttr* pQueryAttr) { + for(int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { + SExprInfo* pExprInfo = &pQueryAttr->pExpr1[i]; int32_t functionId = pExprInfo->base.functionId; @@ -2132,55 +2058,32 @@ bool onlyQueryTags(SQuery* pQuery) { ///////////////////////////////////////////////////////////////////////////////////////////// -void getAlignQueryTimeWindow(SQuery *pQuery, int64_t key, int64_t keyFirst, int64_t keyLast, STimeWindow *win) { - assert(key >= keyFirst && key <= keyLast && pQuery->interval.sliding <= pQuery->interval.interval); - win->skey = taosTimeTruncate(key, &pQuery->interval, pQuery->precision); +void getAlignQueryTimeWindow(SQueryAttr *pQueryAttr, int64_t key, int64_t keyFirst, int64_t keyLast, STimeWindow *win) { + assert(key >= keyFirst && key <= keyLast && pQueryAttr->interval.sliding <= pQueryAttr->interval.interval); + win->skey = taosTimeTruncate(key, &pQueryAttr->interval, pQueryAttr->precision); /* - * if the realSkey > INT64_MAX - pQuery->interval.interval, the query duration between + * if the realSkey > INT64_MAX - pQueryAttr->interval.interval, the query duration between * realSkey and realEkey must be less than one interval.Therefore, no need to adjust the query ranges. */ - if (keyFirst > (INT64_MAX - pQuery->interval.interval)) { - assert(keyLast - keyFirst < pQuery->interval.interval); + if (keyFirst > (INT64_MAX - pQueryAttr->interval.interval)) { + assert(keyLast - keyFirst < pQueryAttr->interval.interval); win->ekey = INT64_MAX; - } else if (pQuery->interval.intervalUnit == 'n' || pQuery->interval.intervalUnit == 'y') { - win->ekey = taosTimeAdd(win->skey, pQuery->interval.interval, pQuery->interval.intervalUnit, pQuery->precision) - 1; + } else if (pQueryAttr->interval.intervalUnit == 'n' || pQueryAttr->interval.intervalUnit == 'y') { + win->ekey = taosTimeAdd(win->skey, pQueryAttr->interval.interval, pQueryAttr->interval.intervalUnit, pQueryAttr->precision) - 1; } else { - win->ekey = win->skey + pQuery->interval.interval - 1; - } -} - -static void setScanLimitationByResultBuffer(SQuery *pQuery) { - if (isTopBottomQuery(pQuery)) { - pQuery->checkResultBuf = 0; - } else if (isGroupbyColumn(pQuery->pGroupbyExpr)) { - pQuery->checkResultBuf = 0; - } else { - bool hasMultioutput = false; - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - SSqlFuncMsg *pExprMsg = &pQuery->pExpr1[i].base; - if (pExprMsg->functionId == TSDB_FUNC_TS || pExprMsg->functionId == TSDB_FUNC_TS_DUMMY) { - continue; - } - - hasMultioutput = IS_MULTIOUTPUT(aAggs[pExprMsg->functionId].status); - if (!hasMultioutput) { - break; - } - } - - pQuery->checkResultBuf = hasMultioutput ? 1 : 0; + win->ekey = win->skey + pQueryAttr->interval.interval - 1; } } /* * todo add more parameters to check soon.. */ -bool colIdCheck(SQuery *pQuery, uint64_t qId) { +bool colIdCheck(SQueryAttr *pQueryAttr, uint64_t qId) { // load data column information is incorrect - for (int32_t i = 0; i < pQuery->numOfCols - 1; ++i) { - if (pQuery->colList[i].colId == pQuery->colList[i + 1].colId) { - qError("QInfo:%"PRIu64" invalid data load column for query", qId); + for (int32_t i = 0; i < pQueryAttr->numOfCols - 1; ++i) { + if (pQueryAttr->tableCols[i].colId == pQueryAttr->tableCols[i + 1].colId) { + qError("QInfo:0x%"PRIx64" invalid data load column for query", qId); return false; } } @@ -2190,9 +2093,9 @@ bool colIdCheck(SQuery *pQuery, uint64_t qId) { // todo ignore the avg/sum/min/max/count/stddev/top/bottom functions, of which // the scan order is not matter -static bool onlyOneQueryType(SQuery *pQuery, int32_t functId, int32_t functIdDst) { - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - int32_t functionId = pQuery->pExpr1[i].base.functionId; +static bool onlyOneQueryType(SQueryAttr *pQueryAttr, int32_t functId, int32_t functIdDst) { + for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { + int32_t functionId = pQueryAttr->pExpr1[i].base.functionId; if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TAG_DUMMY) { @@ -2207,11 +2110,11 @@ static bool onlyOneQueryType(SQuery *pQuery, int32_t functId, int32_t functIdDst return true; } -static bool onlyFirstQuery(SQuery *pQuery) { return onlyOneQueryType(pQuery, TSDB_FUNC_FIRST, TSDB_FUNC_FIRST_DST); } +static bool onlyFirstQuery(SQueryAttr *pQueryAttr) { return onlyOneQueryType(pQueryAttr, TSDB_FUNC_FIRST, TSDB_FUNC_FIRST_DST); } -static bool onlyLastQuery(SQuery *pQuery) { return onlyOneQueryType(pQuery, TSDB_FUNC_LAST, TSDB_FUNC_LAST_DST); } +static bool onlyLastQuery(SQueryAttr *pQueryAttr) { return onlyOneQueryType(pQueryAttr, TSDB_FUNC_LAST, TSDB_FUNC_LAST_DST); } -static int32_t updateBlockLoadStatus(SQuery *pQuery, int32_t status) { +static int32_t updateBlockLoadStatus(SQueryAttr *pQuery, int32_t status) { bool hasFirstLastFunc = false; bool hasOtherFunc = false; @@ -2246,10 +2149,10 @@ static int32_t updateBlockLoadStatus(SQuery *pQuery, int32_t status) { } static void doExchangeTimeWindow(SQInfo* pQInfo, STimeWindow* win) { - SQuery* pQuery = &pQInfo->query; - size_t t = taosArrayGetSize(pQuery->tableGroupInfo.pGroupList); + SQueryAttr* pQueryAttr = &pQInfo->query; + size_t t = taosArrayGetSize(pQueryAttr->tableGroupInfo.pGroupList); for(int32_t i = 0; i < t; ++i) { - SArray* p1 = taosArrayGetP(pQuery->tableGroupInfo.pGroupList, i); + SArray* p1 = taosArrayGetP(pQueryAttr->tableGroupInfo.pGroupList, i); size_t len = taosArrayGetSize(p1); for(int32_t j = 0; j < len; ++j) { @@ -2264,100 +2167,100 @@ static void doExchangeTimeWindow(SQInfo* pQInfo, STimeWindow* win) { } static void changeExecuteScanOrder(SQInfo *pQInfo, SQueryTableMsg* pQueryMsg, bool stableQuery) { - SQuery* pQuery = pQInfo->runtimeEnv.pQuery; + SQueryAttr* pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; // in case of point-interpolation query, use asc order scan - char msg[] = "QInfo:%"PRIu64" scan order changed for %s query, old:%d, new:%d, qrange exchanged, old qrange:%" PRId64 + char msg[] = "QInfo:0x%"PRIx64" scan order changed for %s query, old:%d, new:%d, qrange exchanged, old qrange:%" PRId64 "-%" PRId64 ", new qrange:%" PRId64 "-%" PRId64; // todo handle the case the the order irrelevant query type mixed up with order critical query type // descending order query for last_row query - if (isFirstLastRowQuery(pQuery)) { - qDebug("QInfo:%"PRIu64" scan order changed for last_row query, old:%d, new:%d", pQInfo->qId, pQuery->order.order, TSDB_ORDER_ASC); + if (isFirstLastRowQuery(pQueryAttr)) { + qDebug("QInfo:0x%"PRIx64" scan order changed for last_row query, old:%d, new:%d", pQInfo->qId, pQueryAttr->order.order, TSDB_ORDER_ASC); - pQuery->order.order = TSDB_ORDER_ASC; - if (pQuery->window.skey > pQuery->window.ekey) { - SWAP(pQuery->window.skey, pQuery->window.ekey, TSKEY); + pQueryAttr->order.order = TSDB_ORDER_ASC; + if (pQueryAttr->window.skey > pQueryAttr->window.ekey) { + SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY); } return; } - if (isGroupbyColumn(pQuery->pGroupbyExpr) && pQuery->order.order == TSDB_ORDER_DESC) { - pQuery->order.order = TSDB_ORDER_ASC; - if (pQuery->window.skey > pQuery->window.ekey) { - SWAP(pQuery->window.skey, pQuery->window.ekey, TSKEY); + if (pQueryAttr->groupbyColumn && pQueryAttr->order.order == TSDB_ORDER_DESC) { + pQueryAttr->order.order = TSDB_ORDER_ASC; + if (pQueryAttr->window.skey > pQueryAttr->window.ekey) { + SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY); } - doExchangeTimeWindow(pQInfo, &pQuery->window); + doExchangeTimeWindow(pQInfo, &pQueryAttr->window); return; } - if (isPointInterpoQuery(pQuery) && pQuery->interval.interval == 0) { - if (!QUERY_IS_ASC_QUERY(pQuery)) { - qDebug(msg, pQInfo->qId, "interp", pQuery->order.order, TSDB_ORDER_ASC, pQuery->window.skey, pQuery->window.ekey, pQuery->window.ekey, pQuery->window.skey); - SWAP(pQuery->window.skey, pQuery->window.ekey, TSKEY); + if (pQueryAttr->pointInterpQuery && pQueryAttr->interval.interval == 0) { + if (!QUERY_IS_ASC_QUERY(pQueryAttr)) { + qDebug(msg, pQInfo, "interp", pQueryAttr->order.order, TSDB_ORDER_ASC, pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey); + SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY); } - pQuery->order.order = TSDB_ORDER_ASC; + pQueryAttr->order.order = TSDB_ORDER_ASC; return; } - if (pQuery->interval.interval == 0) { - if (onlyFirstQuery(pQuery)) { - if (!QUERY_IS_ASC_QUERY(pQuery)) { - qDebug(msg, pQInfo->qId, "only-first", pQuery->order.order, TSDB_ORDER_ASC, pQuery->window.skey, - pQuery->window.ekey, pQuery->window.ekey, pQuery->window.skey); + if (pQueryAttr->interval.interval == 0) { + if (onlyFirstQuery(pQueryAttr)) { + if (!QUERY_IS_ASC_QUERY(pQueryAttr)) { + qDebug(msg, pQInfo, "only-first", pQueryAttr->order.order, TSDB_ORDER_ASC, pQueryAttr->window.skey, + pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey); - SWAP(pQuery->window.skey, pQuery->window.ekey, TSKEY); - doExchangeTimeWindow(pQInfo, &pQuery->window); + SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY); + doExchangeTimeWindow(pQInfo, &pQueryAttr->window); } - pQuery->order.order = TSDB_ORDER_ASC; - } else if (onlyLastQuery(pQuery)) { - if (QUERY_IS_ASC_QUERY(pQuery)) { - qDebug(msg, pQInfo->qId, "only-last", pQuery->order.order, TSDB_ORDER_DESC, pQuery->window.skey, - pQuery->window.ekey, pQuery->window.ekey, pQuery->window.skey); + pQueryAttr->order.order = TSDB_ORDER_ASC; + } else if (onlyLastQuery(pQueryAttr)) { + if (QUERY_IS_ASC_QUERY(pQueryAttr)) { + qDebug(msg, pQInfo, "only-last", pQueryAttr->order.order, TSDB_ORDER_DESC, pQueryAttr->window.skey, + pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey); - SWAP(pQuery->window.skey, pQuery->window.ekey, TSKEY); - doExchangeTimeWindow(pQInfo, &pQuery->window); + SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY); + doExchangeTimeWindow(pQInfo, &pQueryAttr->window); } - pQuery->order.order = TSDB_ORDER_DESC; + pQueryAttr->order.order = TSDB_ORDER_DESC; } } else { // interval query if (stableQuery) { - if (onlyFirstQuery(pQuery)) { - if (!QUERY_IS_ASC_QUERY(pQuery)) { - qDebug(msg, pQInfo->qId, "only-first stable", pQuery->order.order, TSDB_ORDER_ASC, - pQuery->window.skey, pQuery->window.ekey, pQuery->window.ekey, pQuery->window.skey); + if (onlyFirstQuery(pQueryAttr)) { + if (!QUERY_IS_ASC_QUERY(pQueryAttr)) { + qDebug(msg, pQInfo, "only-first stable", pQueryAttr->order.order, TSDB_ORDER_ASC, + pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey); - SWAP(pQuery->window.skey, pQuery->window.ekey, TSKEY); - doExchangeTimeWindow(pQInfo, &pQuery->window); + SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY); + doExchangeTimeWindow(pQInfo, &pQueryAttr->window); } - pQuery->order.order = TSDB_ORDER_ASC; - } else if (onlyLastQuery(pQuery)) { - if (QUERY_IS_ASC_QUERY(pQuery)) { - qDebug(msg, pQInfo->qId, "only-last stable", pQuery->order.order, TSDB_ORDER_DESC, - pQuery->window.skey, pQuery->window.ekey, pQuery->window.ekey, pQuery->window.skey); + pQueryAttr->order.order = TSDB_ORDER_ASC; + } else if (onlyLastQuery(pQueryAttr)) { + if (QUERY_IS_ASC_QUERY(pQueryAttr)) { + qDebug(msg, pQInfo, "only-last stable", pQueryAttr->order.order, TSDB_ORDER_DESC, + pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey); - SWAP(pQuery->window.skey, pQuery->window.ekey, TSKEY); - doExchangeTimeWindow(pQInfo, &pQuery->window); + SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY); + doExchangeTimeWindow(pQInfo, &pQueryAttr->window); } - pQuery->order.order = TSDB_ORDER_DESC; + pQueryAttr->order.order = TSDB_ORDER_DESC; } } } } static void getIntermediateBufInfo(SQueryRuntimeEnv* pRuntimeEnv, int32_t* ps, int32_t* rowsize) { - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t MIN_ROWS_PER_PAGE = 4; - *rowsize = (int32_t)(pQuery->resultRowSize * GET_ROW_PARAM_FOR_MULTIOUTPUT(pQuery, pQuery->topBotQuery, pQuery->stableQuery)); + *rowsize = (int32_t)(pQueryAttr->resultRowSize * GET_ROW_PARAM_FOR_MULTIOUTPUT(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery)); int32_t overhead = sizeof(tFilePage); // one page contains at least two rows @@ -2373,17 +2276,17 @@ static void getIntermediateBufInfo(SQueryRuntimeEnv* pRuntimeEnv, int32_t* ps, i #define IS_PREFILTER_TYPE(_t) ((_t) != TSDB_DATA_TYPE_BINARY && (_t) != TSDB_DATA_TYPE_NCHAR) static bool doFilterByBlockStatistics(SQueryRuntimeEnv* pRuntimeEnv, SDataStatis *pDataStatis, SQLFunctionCtx *pCtx, int32_t numOfRows) { - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; - if (pDataStatis == NULL || pQuery->numOfFilterCols == 0) { + if (pDataStatis == NULL || pQueryAttr->numOfFilterCols == 0) { return true; } - for (int32_t k = 0; k < pQuery->numOfFilterCols; ++k) { - SSingleColumnFilterInfo *pFilterInfo = &pQuery->pFilterInfo[k]; + for (int32_t k = 0; k < pQueryAttr->numOfFilterCols; ++k) { + SSingleColumnFilterInfo *pFilterInfo = &pQueryAttr->pFilterInfo[k]; int32_t index = -1; - for(int32_t i = 0; i < pQuery->numOfCols; ++i) { + for(int32_t i = 0; i < pQueryAttr->numOfCols; ++i) { if (pDataStatis[i].colId == pFilterInfo->info.colId) { index = i; break; @@ -2437,14 +2340,14 @@ static bool doFilterByBlockStatistics(SQueryRuntimeEnv* pRuntimeEnv, SDataStatis return false; } -static bool overlapWithTimeWindow(SQuery* pQuery, SDataBlockInfo* pBlockInfo) { +static bool overlapWithTimeWindow(SQueryAttr* pQueryAttr, SDataBlockInfo* pBlockInfo) { STimeWindow w = {0}; - TSKEY sk = MIN(pQuery->window.skey, pQuery->window.ekey); - TSKEY ek = MAX(pQuery->window.skey, pQuery->window.ekey); + TSKEY sk = MIN(pQueryAttr->window.skey, pQueryAttr->window.ekey); + TSKEY ek = MAX(pQueryAttr->window.skey, pQueryAttr->window.ekey); - if (QUERY_IS_ASC_QUERY(pQuery)) { - getAlignQueryTimeWindow(pQuery, pBlockInfo->window.skey, sk, ek, &w); + if (QUERY_IS_ASC_QUERY(pQueryAttr)) { + getAlignQueryTimeWindow(pQueryAttr, pBlockInfo->window.skey, sk, ek, &w); assert(w.ekey >= pBlockInfo->window.skey); if (w.ekey < pBlockInfo->window.ekey) { @@ -2452,7 +2355,7 @@ static bool overlapWithTimeWindow(SQuery* pQuery, SDataBlockInfo* pBlockInfo) { } while(1) { - getNextTimeWindow(pQuery, &w); + getNextTimeWindow(pQueryAttr, &w); if (w.skey > pBlockInfo->window.ekey) { break; } @@ -2463,7 +2366,7 @@ static bool overlapWithTimeWindow(SQuery* pQuery, SDataBlockInfo* pBlockInfo) { } } } else { - getAlignQueryTimeWindow(pQuery, pBlockInfo->window.ekey, sk, ek, &w); + getAlignQueryTimeWindow(pQueryAttr, pBlockInfo->window.ekey, sk, ek, &w); assert(w.skey <= pBlockInfo->window.ekey); if (w.skey > pBlockInfo->window.skey) { @@ -2471,7 +2374,7 @@ static bool overlapWithTimeWindow(SQuery* pQuery, SDataBlockInfo* pBlockInfo) { } while(1) { - getNextTimeWindow(pQuery, &w); + getNextTimeWindow(pQueryAttr, &w); if (w.ekey < pBlockInfo->window.skey) { break; } @@ -2491,7 +2394,7 @@ static int32_t doTSJoinFilter(SQueryRuntimeEnv *pRuntimeEnv, TSKEY key, bool asc #if defined(_DEBUG_VIEW) printf("elem in comp ts file:%" PRId64 ", key:%" PRId64 ", tag:%"PRIu64", query order:%d, ts order:%d, traverse:%d, index:%d\n", - elem.ts, key, elem.tag.i64, pQuery->order.order, pRuntimeEnv->pTsBuf->tsOrder, + elem.ts, key, elem.tag.i64, pQueryAttr->order.order, pRuntimeEnv->pTsBuf->tsOrder, pRuntimeEnv->pTsBuf->cur.order, pRuntimeEnv->pTsBuf->cur.tsIndex); #endif @@ -2513,7 +2416,7 @@ static int32_t doTSJoinFilter(SQueryRuntimeEnv *pRuntimeEnv, TSKEY key, bool asc } void filterRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, - SSDataBlock* pBlock, bool ascQuery) { + SSDataBlock* pBlock, bool ascQuery) { int32_t numOfRows = pBlock->info.rows; int8_t *p = calloc(numOfRows, sizeof(int8_t)); @@ -2542,7 +2445,7 @@ void filterRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSingleColumnFilterInf } // save the cursor status - pRuntimeEnv->pQuery->current->cur = tsBufGetCursor(pRuntimeEnv->pTsBuf); + pRuntimeEnv->current->cur = tsBufGetCursor(pRuntimeEnv->pTsBuf); } else { for (int32_t i = 0; i < numOfRows; ++i) { bool qualified = false; @@ -2629,11 +2532,11 @@ void filterRowsInDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SSingleColumnFilterInf if (start > 0) { SColumnInfoData* pColumnInfoData = taosArrayGet(pBlock->pDataBlock, 0); - assert(pColumnInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP && - pColumnInfoData->info.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX); - - pBlock->info.window.skey = *(int64_t*)pColumnInfoData->pData; - pBlock->info.window.ekey = *(int64_t*)(pColumnInfoData->pData + TSDB_KEYSIZE * (start - 1)); + if (pColumnInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP && + pColumnInfoData->info.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { + pBlock->info.window.skey = *(int64_t*)pColumnInfoData->pData; + pBlock->info.window.ekey = *(int64_t*)(pColumnInfoData->pData + TSDB_KEYSIZE * (start - 1)); + } } } @@ -2667,18 +2570,18 @@ static uint32_t doFilterByBlockTimeWindow(STableScanInfo* pTableScanInfo, SSData return status; } -static void doSetFilterColumnInfo(SQuery* pQuery, SSDataBlock* pBlock) { - if (pQuery->numOfFilterCols > 0 && pQuery->pFilterInfo[0].pData != NULL) { +static void doSetFilterColumnInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, SSDataBlock* pBlock) { + if (numOfFilterCols > 0 && pFilterInfo[0].pData != NULL) { return; } // set the initial static data value filter expression - for (int32_t i = 0; i < pQuery->numOfFilterCols; ++i) { + for (int32_t i = 0; i < numOfFilterCols; ++i) { for (int32_t j = 0; j < pBlock->info.numOfCols; ++j) { SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, j); - if (pQuery->pFilterInfo[i].info.colId == pColInfo->info.colId) { - pQuery->pFilterInfo[i].pData = pColInfo->pData; + if (pFilterInfo[i].info.colId == pColInfo->info.colId) { + pFilterInfo[i].pData = pColInfo->pData; break; } } @@ -2691,26 +2594,25 @@ 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); + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int64_t groupId = pRuntimeEnv->current->groupIndex; + bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); + SQInfo* pQInfo = pRuntimeEnv->qinfo; SQueryCostInfo* pCost = &pQInfo->summary; if (pRuntimeEnv->pTsBuf != NULL) { (*status) = BLK_DATA_ALL_NEEDED; - if (pQuery->stableQuery) { // todo refactor + if (pQueryAttr->stableQuery) { // todo refactor SExprInfo* pExprInfo = &pTableScanInfo->pExpr[0]; - int16_t tagId = (int16_t)pExprInfo->base.arg->argValue.i64; - SColumnInfo* pColInfo = doGetTagColumnInfoById(pQuery->tagColList, pQuery->numOfTags, tagId); + int16_t tagId = (int16_t)pExprInfo->base.param[0].i64; + SColumnInfo* pColInfo = doGetTagColumnInfoById(pQueryAttr->tagColList, pQueryAttr->numOfTags, tagId); // compare tag first tVariant t = {0}; - doSetTagValueInParam(pQuery->current->pTable, tagId, &t, pColInfo->type, pColInfo->bytes); - setTimestampListJoinInfo(pRuntimeEnv, &t, pQuery->current); + doSetTagValueInParam(pRuntimeEnv->current->pTable, tagId, &t, pColInfo->type, pColInfo->bytes); + setTimestampListJoinInfo(pRuntimeEnv, &t, pRuntimeEnv->current); STSElem elem = tsBufGetElem(pRuntimeEnv->pTsBuf); if (!tsBufIsValidElem(&elem) || (tsBufIsValidElem(&elem) && (tVariantCompare(&t, elem.tag) != 0))) { @@ -2722,8 +2624,8 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa // Calculate all time windows that are overlapping or contain current data block. // If current data block is contained by all possible time window, do not load current data block. - if (pQuery->numOfFilterCols > 0 || pQuery->groupbyColumn || pQuery->sw.gap > 0 || - (QUERY_IS_INTERVAL_QUERY(pQuery) && overlapWithTimeWindow(pQuery, &pBlock->info))) { + if (pQueryAttr->numOfFilterCols > 0 || pQueryAttr->groupbyColumn || pQueryAttr->sw.gap > 0 || + (QUERY_IS_INTERVAL_QUERY(pQueryAttr) && overlapWithTimeWindow(pQueryAttr, &pBlock->info))) { (*status) = BLK_DATA_ALL_NEEDED; } @@ -2731,32 +2633,32 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa if ((*status) != BLK_DATA_ALL_NEEDED) { // the pCtx[i] result is belonged to previous time window since the outputBuf has not been set yet, // the filter result may be incorrect. So in case of interval query, we need to set the correct time output buffer - if (QUERY_IS_INTERVAL_QUERY(pQuery)) { + if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) { SResultRow* pResult = NULL; bool masterScan = IS_MASTER_SCAN(pRuntimeEnv); TSKEY k = ascQuery? pBlock->info.window.skey : pBlock->info.window.ekey; - STimeWindow win = getActiveTimeWindow(pTableScanInfo->pResultRowInfo, k, pQuery); + STimeWindow win = getActiveTimeWindow(pTableScanInfo->pResultRowInfo, k, pQueryAttr); if (setWindowOutputBufByKey(pRuntimeEnv, pTableScanInfo->pResultRowInfo, &win, masterScan, &pResult, groupId, pTableScanInfo->pCtx, pTableScanInfo->numOfOutput, pTableScanInfo->rowCellInfoOffset) != TSDB_CODE_SUCCESS) { longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY); } - } else if (pQuery->stableQuery && (!isTsCompQuery(pQuery))) { // stable aggregate, not interval aggregate or normal column aggregate + } else if (pQueryAttr->stableQuery && (!pQueryAttr->tsCompQuery)) { // stable aggregate, not interval aggregate or normal column aggregate doSetTableGroupOutputBuf(pRuntimeEnv, pTableScanInfo->pResultRowInfo, pTableScanInfo->pCtx, pTableScanInfo->rowCellInfoOffset, pTableScanInfo->numOfOutput, - pQuery->current->groupIndex); + pRuntimeEnv->current->groupIndex); } (*status) = doFilterByBlockTimeWindow(pTableScanInfo, pBlock); } SDataBlockInfo* pBlockInfo = &pBlock->info; - *status = updateBlockLoadStatus(pRuntimeEnv->pQuery, *status); + *status = updateBlockLoadStatus(pRuntimeEnv->pQueryAttr, *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, + qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows); pCost->discardBlocks += 1; } else if ((*status) == BLK_DATA_STATIS_NEEDED) { @@ -2775,15 +2677,15 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa pCost->loadBlockStatis += 1; tsdbRetrieveDataBlockStatisInfo(pTableScanInfo->pQueryHandle, &pBlock->pBlockStatis); - if (pQuery->topBotQuery && pBlock->pBlockStatis != NULL) { + if (pQueryAttr->topBotQuery && pBlock->pBlockStatis != NULL) { { // set previous window - if (QUERY_IS_INTERVAL_QUERY(pQuery)) { + if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) { SResultRow* pResult = NULL; bool masterScan = IS_MASTER_SCAN(pRuntimeEnv); TSKEY k = ascQuery? pBlock->info.window.skey : pBlock->info.window.ekey; - STimeWindow win = getActiveTimeWindow(pTableScanInfo->pResultRowInfo, k, pQuery); + STimeWindow win = getActiveTimeWindow(pTableScanInfo->pResultRowInfo, k, pQueryAttr); if (setWindowOutputBufByKey(pRuntimeEnv, pTableScanInfo->pResultRowInfo, &win, masterScan, &pResult, groupId, pTableScanInfo->pCtx, pTableScanInfo->numOfOutput, pTableScanInfo->rowCellInfoOffset) != TSDB_CODE_SUCCESS) { @@ -2792,14 +2694,14 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa } } bool load = false; - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { + for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { int32_t functionId = pTableScanInfo->pCtx[i].functionId; if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM) { load = topbot_datablock_filter(&pTableScanInfo->pCtx[i], (char*)&(pBlock->pBlockStatis[i].min), (char*)&(pBlock->pBlockStatis[i].max)); if (!load) { // current block has been discard due to filter applied pCost->discardBlocks += 1; - qDebug("QInfo:%"PRIu64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, + qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows); (*status) = BLK_DATA_DISCARD; return TSDB_CODE_SUCCESS; @@ -2811,7 +2713,7 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa // current block has been discard due to filter applied if (!doFilterByBlockStatistics(pRuntimeEnv, pBlock->pBlockStatis, pTableScanInfo->pCtx, pBlockInfo->rows)) { pCost->discardBlocks += 1; - qDebug("QInfo:%"PRIu64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey, + qDebug("QInfo:0x%"PRIx64" data block discard, brange:%" PRId64 "-%" PRId64 ", rows:%d", pQInfo->qId, pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows); (*status) = BLK_DATA_DISCARD; return TSDB_CODE_SUCCESS; @@ -2824,9 +2726,9 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv* pRuntimeEnv, STableScanInfo* pTa return terrno; } - doSetFilterColumnInfo(pQuery, pBlock); - if (pQuery->numOfFilterCols > 0 || pRuntimeEnv->pTsBuf != NULL) { - filterRowsInDataBlock(pRuntimeEnv, pQuery->pFilterInfo, pQuery->numOfFilterCols, pBlock, ascQuery); + doSetFilterColumnInfo(pQueryAttr->pFilterInfo, pQueryAttr->numOfFilterCols, pBlock); + if (pQueryAttr->numOfFilterCols > 0 || pRuntimeEnv->pTsBuf != NULL) { + filterRowsInDataBlock(pRuntimeEnv, pQueryAttr->pFilterInfo, pQueryAttr->numOfFilterCols, pBlock, ascQuery); } } @@ -2941,22 +2843,22 @@ static SColumnInfo* doGetTagColumnInfoById(SColumnInfo* pTagColList, int32_t num void setTagValue(SOperatorInfo* pOperatorInfo, void *pTable, SQLFunctionCtx* pCtx, int32_t numOfOutput) { SQueryRuntimeEnv* pRuntimeEnv = pOperatorInfo->pRuntimeEnv; - SExprInfo *pExpr = pOperatorInfo->pExpr; - SQuery *pQuery = pRuntimeEnv->pQuery; + SExprInfo *pExpr = pOperatorInfo->pExpr; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; SExprInfo* pExprInfo = &pExpr[0]; - if (pQuery->numOfOutput == 1 && pExprInfo->base.functionId == TSDB_FUNC_TS_COMP && pQuery->stableQuery) { + if (pQueryAttr->numOfOutput == 1 && pExprInfo->base.functionId == TSDB_FUNC_TS_COMP && pQueryAttr->stableQuery) { assert(pExprInfo->base.numOfParams == 1); - int16_t tagColId = (int16_t)pExprInfo->base.arg->argValue.i64; - SColumnInfo* pColInfo = doGetTagColumnInfoById(pQuery->tagColList, pQuery->numOfTags, tagColId); + int16_t tagColId = (int16_t)pExprInfo->base.param[0].i64; + SColumnInfo* pColInfo = doGetTagColumnInfoById(pQueryAttr->tagColList, pQueryAttr->numOfTags, tagColId); doSetTagValueInParam(pTable, tagColId, &pCtx[0].tag, pColInfo->type, pColInfo->bytes); return; } else { // set tag value, by which the results are aggregated. int32_t offset = 0; - memset(pRuntimeEnv->tagVal, 0, pQuery->tagLen); + memset(pRuntimeEnv->tagVal, 0, pQueryAttr->tagLen); for (int32_t idx = 0; idx < numOfOutput; ++idx) { SExprInfo* pLocalExprInfo = &pExpr[idx]; @@ -2967,20 +2869,20 @@ void setTagValue(SOperatorInfo* pOperatorInfo, void *pTable, SQLFunctionCtx* pCt } // todo use tag column index to optimize performance - doSetTagValueInParam(pTable, pLocalExprInfo->base.colInfo.colId, &pCtx[idx].tag, pLocalExprInfo->type, - pLocalExprInfo->bytes); + doSetTagValueInParam(pTable, pLocalExprInfo->base.colInfo.colId, &pCtx[idx].tag, pLocalExprInfo->base.resType, + pLocalExprInfo->base.resBytes); - if (IS_NUMERIC_TYPE(pLocalExprInfo->type) || pLocalExprInfo->type == TSDB_DATA_TYPE_BOOL) { - memcpy(pRuntimeEnv->tagVal + offset, &pCtx[idx].tag.i64, pLocalExprInfo->bytes); + if (IS_NUMERIC_TYPE(pLocalExprInfo->base.resType) || pLocalExprInfo->base.resType == TSDB_DATA_TYPE_BOOL) { + memcpy(pRuntimeEnv->tagVal + offset, &pCtx[idx].tag.i64, pLocalExprInfo->base.resBytes); } else { memcpy(pRuntimeEnv->tagVal + offset, pCtx[idx].tag.pz, pCtx[idx].tag.nLen); } - offset += pLocalExprInfo->bytes; + offset += pLocalExprInfo->base.resBytes; } //todo : use index to avoid iterator all possible output columns - if (pQuery->stableQuery && pQuery->stabledev && (pRuntimeEnv->prevResult != NULL)) { + if (pQueryAttr->stableQuery && pQueryAttr->stabledev && (pRuntimeEnv->prevResult != NULL)) { setParamForStableStddev(pRuntimeEnv, pCtx, numOfOutput, pExprInfo); } } @@ -3061,32 +2963,32 @@ static UNUSED_FUNC void printBinaryData(int32_t functionId, char *data, int32_t } void UNUSED_FUNC displayInterResult(tFilePage **pdata, SQueryRuntimeEnv* pRuntimeEnv, int32_t numOfRows) { - SQuery* pQuery = pRuntimeEnv->pQuery; - int32_t numOfCols = pQuery->numOfOutput; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int32_t numOfCols = pQueryAttr->numOfOutput; printf("super table query intermediate result, total:%d\n", numOfRows); for (int32_t j = 0; j < numOfRows; ++j) { for (int32_t i = 0; i < numOfCols; ++i) { - switch (pQuery->pExpr1[i].type) { + switch (pQueryAttr->pExpr1[i].base.resType) { case TSDB_DATA_TYPE_BINARY: { - int32_t type = pQuery->pExpr1[i].type; - printBinaryData(pQuery->pExpr1[i].base.functionId, pdata[i]->data + pQuery->pExpr1[i].bytes * j, + int32_t type = pQueryAttr->pExpr1[i].base.resType; + printBinaryData(pQueryAttr->pExpr1[i].base.functionId, pdata[i]->data + pQueryAttr->pExpr1[i].base.resBytes * j, type); break; } case TSDB_DATA_TYPE_TIMESTAMP: case TSDB_DATA_TYPE_BIGINT: - printf("%" PRId64 "\t", *(int64_t *)(pdata[i]->data + pQuery->pExpr1[i].bytes * j)); + printf("%" PRId64 "\t", *(int64_t *)(pdata[i]->data + pQueryAttr->pExpr1[i].base.resBytes * j)); break; case TSDB_DATA_TYPE_INT: - printf("%d\t", *(int32_t *)(pdata[i]->data + pQuery->pExpr1[i].bytes * j)); + printf("%d\t", *(int32_t *)(pdata[i]->data + pQueryAttr->pExpr1[i].base.resBytes * j)); break; case TSDB_DATA_TYPE_FLOAT: - printf("%f\t", *(float *)(pdata[i]->data + pQuery->pExpr1[i].bytes * j)); + printf("%f\t", *(float *)(pdata[i]->data + pQueryAttr->pExpr1[i].base.resBytes * j)); break; case TSDB_DATA_TYPE_DOUBLE: - printf("%lf\t", *(double *)(pdata[i]->data + pQuery->pExpr1[i].bytes * j)); + printf("%lf\t", *(double *)(pdata[i]->data + pQueryAttr->pExpr1[i].base.resBytes * j)); break; } } @@ -3126,7 +3028,7 @@ void copyToSDataBlock(SQueryRuntimeEnv* pRuntimeEnv, int32_t threshold, SSDataBl } -static void updateTableQueryInfoForReverseScan(SQuery *pQuery, STableQueryInfo *pTableQueryInfo) { +static void updateTableQueryInfoForReverseScan(SQueryAttr *pQueryAttr, STableQueryInfo *pTableQueryInfo) { if (pTableQueryInfo == NULL) { return; } @@ -3142,17 +3044,17 @@ static void updateTableQueryInfoForReverseScan(SQuery *pQuery, STableQueryInfo * } static void setupQueryRangeForReverseScan(SQueryRuntimeEnv* pRuntimeEnv) { - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t numOfGroups = (int32_t)(GET_NUM_OF_TABLEGROUP(pRuntimeEnv)); for(int32_t i = 0; i < numOfGroups; ++i) { SArray *group = GET_TABLEGROUP(pRuntimeEnv, i); - SArray *tableKeyGroup = taosArrayGetP(pQuery->tableGroupInfo.pGroupList, i); + SArray *tableKeyGroup = taosArrayGetP(pQueryAttr->tableGroupInfo.pGroupList, i); size_t t = taosArrayGetSize(group); for (int32_t j = 0; j < t; ++j) { STableQueryInfo *pCheckInfo = taosArrayGetP(group, j); - updateTableQueryInfoForReverseScan(pQuery, pCheckInfo); + updateTableQueryInfoForReverseScan(pQueryAttr, pCheckInfo); // update the last key in tableKeyInfo list, the tableKeyInfo is used to build the tsdbQueryHandle and decide // the start check timestamp of tsdbQueryHandle @@ -3185,7 +3087,7 @@ int32_t initResultRow(SResultRow *pResultRow) { * +------------+-------------------------------------------+-------------------------------------------+ * offset[0] offset[1] */ -void setDefaultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *pInfo, int64_t uid) { +void setDefaultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *pInfo, int64_t uid, int32_t stage) { SQLFunctionCtx* pCtx = pInfo->pCtx; SSDataBlock* pDataBlock = pInfo->pRes; int32_t* rowCellInfoOffset = pInfo->rowCellInfoOffset; @@ -3204,8 +3106,9 @@ void setDefaultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *pInfo, i SResultRowCellInfo* pCellInfo = getResultCell(pRow, i, rowCellInfoOffset); RESET_RESULT_INFO(pCellInfo); - pCtx[i].resultInfo = pCellInfo; - pCtx[i].pOutput = pData->pData; + pCtx[i].resultInfo = pCellInfo; + pCtx[i].pOutput = pData->pData; + pCtx[i].currentStage = stage; assert(pCtx[i].pOutput != NULL); // set the timestamp output buffer for top/bottom/diff query @@ -3215,24 +3118,24 @@ void setDefaultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *pInfo, i } } - initCtxOutputBuffer(pRuntimeEnv, pCtx, pDataBlock->info.numOfCols); + initCtxOutputBuffer(pCtx, pDataBlock->info.numOfCols); } -void updateOutputBuf(SArithOperatorInfo* pInfo, int32_t numOfInputRows) { - SOptrBasicInfo* pBInfo = &pInfo->binfo; +void updateOutputBuf(SOptrBasicInfo* pBInfo, int32_t *bufCapacity, int32_t numOfInputRows) { SSDataBlock* pDataBlock = pBInfo->pRes; - int32_t newSize = pDataBlock->info.rows + numOfInputRows; - if (pInfo->bufCapacity < newSize) { + int32_t newSize = pDataBlock->info.rows + numOfInputRows + 5; // extra output buffer + if ((*bufCapacity) < newSize) { for(int32_t i = 0; i < pDataBlock->info.numOfCols; ++i) { SColumnInfoData *pColInfo = taosArrayGet(pDataBlock->pDataBlock, i); + char* p = realloc(pColInfo->pData, newSize * pColInfo->info.bytes); if (p != NULL) { pColInfo->pData = p; // it starts from the tail of the previously generated results. pBInfo->pCtx[i].pOutput = pColInfo->pData; - pInfo->bufCapacity = newSize; + (*bufCapacity) = newSize; } else { // longjmp } @@ -3251,7 +3154,7 @@ void updateOutputBuf(SArithOperatorInfo* pInfo, int32_t numOfInputRows) { } } -void initCtxOutputBuffer(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t size) { +void initCtxOutputBuffer(SQLFunctionCtx* pCtx, int32_t size) { for (int32_t j = 0; j < size; ++j) { SResultRowCellInfo* pResInfo = GET_RES_INFO(&pCtx[j]); if (pResInfo->initialized) { @@ -3259,7 +3162,6 @@ void initCtxOutputBuffer(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx* pCtx, in } if (pCtx[j].functionId < 0) { // todo udf initialization - continue; } else { aAggs[pCtx[j].functionId].init(&pCtx[j], pCtx[j].resultInfo); @@ -3278,7 +3180,7 @@ void setQueryStatus(SQueryRuntimeEnv *pRuntimeEnv, int8_t status) { } static void setupEnvForReverseScan(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo *pResultRowInfo, SQLFunctionCtx* pCtx, int32_t numOfOutput) { - SQuery *pQuery = pRuntimeEnv->pQuery; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; if (pRuntimeEnv->pTsBuf) { SWITCH_ORDER(pRuntimeEnv->pTsBuf->cur.order); @@ -3287,25 +3189,25 @@ static void setupEnvForReverseScan(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo } // reverse order time range - SWAP(pQuery->window.skey, pQuery->window.ekey, TSKEY); + SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY); SET_REVERSE_SCAN_FLAG(pRuntimeEnv); setQueryStatus(pRuntimeEnv, QUERY_NOT_COMPLETED); switchCtxOrder(pCtx, numOfOutput); - SWITCH_ORDER(pQuery->order.order); + SWITCH_ORDER(pQueryAttr->order.order); setupQueryRangeForReverseScan(pRuntimeEnv); } void finalizeQueryResult(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset) { SQueryRuntimeEnv *pRuntimeEnv = pOperator->pRuntimeEnv; - SQuery *pQuery = pRuntimeEnv->pQuery; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; int32_t numOfOutput = pOperator->numOfOutput; - if (pQuery->groupbyColumn || QUERY_IS_INTERVAL_QUERY(pQuery) || pQuery->sw.gap > 0) { + if (pQueryAttr->groupbyColumn || QUERY_IS_INTERVAL_QUERY(pQueryAttr) || pQueryAttr->sw.gap > 0) { // for each group result, call the finalize function for each column - if (pQuery->groupbyColumn) { + if (pQueryAttr->groupbyColumn) { closeAllResultRows(pResultRowInfo); } @@ -3322,7 +3224,7 @@ void finalizeQueryResult(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SResult int32_t output = 0; SResultRowCellInfo *pResInfo = GET_RES_INFO(&pCtx[j]); void *interBuf = (void *)GET_ROWCELL_INTERBUF(pResInfo); - + if (pRuntimeEnv->pUdfInfo && pRuntimeEnv->pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE]) { if (pRuntimeEnv->pUdfInfo->isScript) { (*(scriptFinalizeFunc)pRuntimeEnv->pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE])(pRuntimeEnv->pUdfInfo->pScriptCtx, pCtx[j].pOutput, &output); @@ -3355,7 +3257,7 @@ void finalizeQueryResult(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SResult int32_t output = 0; SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); void *interBuf = (void *)GET_ROWCELL_INTERBUF(pResInfo); - + if (pRuntimeEnv->pUdfInfo && pRuntimeEnv->pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE]) { if (pRuntimeEnv->pUdfInfo->isScript) { (*(scriptFinalizeFunc)pRuntimeEnv->pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE])(pRuntimeEnv->pUdfInfo->pScriptCtx, pCtx[j].pOutput, &output); @@ -3376,9 +3278,9 @@ void finalizeQueryResult(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SResult } } -static bool hasMainOutput(SQuery *pQuery) { - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - int32_t functionId = pQuery->pExpr1[i].base.functionId; +static bool hasMainOutput(SQueryAttr *pQueryAttr) { + for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { + int32_t functionId = pQueryAttr->pExpr1[i].base.functionId; if (functionId != TSDB_FUNC_TS && functionId != TSDB_FUNC_TAG && functionId != TSDB_FUNC_TAGPRJ) { return true; @@ -3388,7 +3290,7 @@ static bool hasMainOutput(SQuery *pQuery) { return false; } -static STableQueryInfo *createTableQueryInfo(SQuery* pQuery, void* pTable, bool groupbyColumn, STimeWindow win, void* buf) { +STableQueryInfo *createTableQueryInfo(SQueryAttr* pQueryAttr, void* pTable, bool groupbyColumn, STimeWindow win, void* buf) { STableQueryInfo *pTableQueryInfo = buf; pTableQueryInfo->win = win; @@ -3398,7 +3300,7 @@ static STableQueryInfo *createTableQueryInfo(SQuery* pQuery, void* pTable, bool pTableQueryInfo->cur.vgroupIndex = -1; // set more initial size of interval/groupby query - if (QUERY_IS_INTERVAL_QUERY(pQuery) || groupbyColumn) { + if (QUERY_IS_INTERVAL_QUERY(pQueryAttr) || groupbyColumn) { int32_t initialSize = 128; int32_t code = initResultRowInfo(&pTableQueryInfo->resInfo, initialSize, TSDB_DATA_TYPE_INT); if (code != TSDB_CODE_SUCCESS) { @@ -3434,14 +3336,14 @@ void setResultRowOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pRe continue; } - pCtx[i].pOutput = getPosInResultPage(pRuntimeEnv, bufPage, pResult->offset, offset, pCtx[i].outputBytes); + pCtx[i].pOutput = getPosInResultPage(pRuntimeEnv->pQueryAttr, bufPage, pResult->offset, offset); offset += pCtx[i].outputBytes; int32_t functionId = pCtx[i].functionId; if (functionId < 0) { continue; } - + if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF) { pCtx[i].ptsOutputBuf = pCtx[0].pOutput; } @@ -3464,7 +3366,7 @@ void doSetTableGroupOutputBuf(SQueryRuntimeEnv* pRuntimeEnv, SResultRowInfo* pRe * all group belong to one result set, and each group result has different group id so set the id to be one */ if (pResultRow->pageId == -1) { - int32_t ret = addNewWindowResultBuf(pResultRow, pRuntimeEnv->pResultBuf, groupIndex, pRuntimeEnv->pQuery->resultRowSize); + int32_t ret = addNewWindowResultBuf(pResultRow, pRuntimeEnv->pResultBuf, groupIndex, pRuntimeEnv->pQueryAttr->resultRowSize); if (ret != TSDB_CODE_SUCCESS) { return; } @@ -3475,7 +3377,7 @@ void doSetTableGroupOutputBuf(SQueryRuntimeEnv* pRuntimeEnv, SResultRowInfo* pRe void setExecutionContext(SQueryRuntimeEnv* pRuntimeEnv, SOptrBasicInfo* pInfo, int32_t numOfOutput, int32_t groupIndex, TSKEY nextKey) { - STableQueryInfo *pTableQueryInfo = pRuntimeEnv->pQuery->current; + STableQueryInfo *pTableQueryInfo = pRuntimeEnv->current; // lastKey needs to be updated pTableQueryInfo->lastKey = nextKey; @@ -3496,7 +3398,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, page, pResult->offset, offset, pCtx[i].outputBytes); + pCtx[i].pOutput = getPosInResultPage(pRuntimeEnv->pQueryAttr, page, pResult->offset, offset); offset += pCtx[i].outputBytes; int32_t functionId = pCtx[i].functionId; @@ -3513,32 +3415,32 @@ void setResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult, SQLF } void setCtxTagForJoin(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, SExprInfo* pExprInfo, void* pTable) { - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; - SSqlFuncMsg* pFuncMsg = &pExprInfo->base; - if (pQuery->stableQuery && (pRuntimeEnv->pTsBuf != NULL) && - (pFuncMsg->functionId == TSDB_FUNC_TS || pFuncMsg->functionId == TSDB_FUNC_PRJ) && - (pFuncMsg->colInfo.colIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX)) { - assert(pFuncMsg->numOfParams == 1); + SSqlExpr* pExpr = &pExprInfo->base; + if (pQueryAttr->stableQuery && (pRuntimeEnv->pTsBuf != NULL) && + (pExpr->functionId == TSDB_FUNC_TS || pExpr->functionId == TSDB_FUNC_PRJ) && + (pExpr->colInfo.colIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX)) { + assert(pExpr->numOfParams == 1); - int16_t tagColId = (int16_t)pExprInfo->base.arg->argValue.i64; - SColumnInfo* pColInfo = doGetTagColumnInfoById(pQuery->tagColList, pQuery->numOfTags, tagColId); + int16_t tagColId = (int16_t)pExprInfo->base.param[0].i64; + SColumnInfo* pColInfo = doGetTagColumnInfoById(pQueryAttr->tagColList, pQueryAttr->numOfTags, tagColId); doSetTagValueInParam(pTable, tagColId, &pCtx->tag, pColInfo->type, pColInfo->bytes); int16_t tagType = pCtx[0].tag.nType; if (tagType == TSDB_DATA_TYPE_BINARY || tagType == TSDB_DATA_TYPE_NCHAR) { - qDebug("QInfo:%"PRIu64" set tag value for join comparison, colId:%" PRId64 ", val:%s", GET_QID(pRuntimeEnv), - pExprInfo->base.arg->argValue.i64, pCtx[0].tag.pz); + qDebug("QInfo:0x%"PRIx64" set tag value for join comparison, colId:%" PRId64 ", val:%s", GET_QID(pRuntimeEnv), + pExprInfo->base.param[0].i64, pCtx[0].tag.pz); } else { - qDebug("QInfo:%"PRIu64" set tag value for join comparison, colId:%" PRId64 ", val:%" PRId64, GET_QID(pRuntimeEnv), - pExprInfo->base.arg->argValue.i64, pCtx[0].tag.i64); + qDebug("QInfo:0x%"PRIx64" set tag value for join comparison, colId:%" PRId64 ", val:%" PRId64, GET_QID(pRuntimeEnv), + pExprInfo->base.param[0].i64, pCtx[0].tag.i64); } } } int32_t setTimestampListJoinInfo(SQueryRuntimeEnv* pRuntimeEnv, tVariant* pTag, STableQueryInfo *pTableQueryInfo) { - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; assert(pRuntimeEnv->pTsBuf != NULL); @@ -3546,14 +3448,14 @@ int32_t setTimestampListJoinInfo(SQueryRuntimeEnv* pRuntimeEnv, tVariant* pTag, if (pTableQueryInfo->cur.vgroupIndex == -1) { tVariantAssign(&pTableQueryInfo->tag, pTag); - STSElem elem = tsBufGetElemStartPos(pRuntimeEnv->pTsBuf, pQuery->vgId, &pTableQueryInfo->tag); + STSElem elem = tsBufGetElemStartPos(pRuntimeEnv->pTsBuf, pQueryAttr->vgId, &pTableQueryInfo->tag); // failed to find data with the specified tag value and vnodeId if (!tsBufIsValidElem(&elem)) { if (pTag->nType == TSDB_DATA_TYPE_BINARY || pTag->nType == TSDB_DATA_TYPE_NCHAR) { - qError("QInfo:%"PRIu64" failed to find tag:%s in ts_comp", GET_QID(pRuntimeEnv), pTag->pz); + qError("QInfo:0x%"PRIx64" failed to find tag:%s in ts_comp", GET_QID(pRuntimeEnv), pTag->pz); } else { - qError("QInfo:%"PRIu64" failed to find tag:%" PRId64 " in ts_comp", GET_QID(pRuntimeEnv), pTag->i64); + qError("QInfo:0x%"PRIx64" failed to find tag:%" PRId64 " in ts_comp", GET_QID(pRuntimeEnv), pTag->i64); } return -1; @@ -3562,34 +3464,34 @@ int32_t setTimestampListJoinInfo(SQueryRuntimeEnv* pRuntimeEnv, tVariant* pTag, // Keep the cursor info of current table pTableQueryInfo->cur = tsBufGetCursor(pRuntimeEnv->pTsBuf); if (pTag->nType == TSDB_DATA_TYPE_BINARY || pTag->nType == TSDB_DATA_TYPE_NCHAR) { - qDebug("QInfo:%"PRIu64" find tag:%s start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_QID(pRuntimeEnv), pTag->pz, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex); + qDebug("QInfo:0x%"PRIx64" find tag:%s start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_QID(pRuntimeEnv), pTag->pz, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex); } else { - qDebug("QInfo:%"PRIu64" find tag:%"PRId64" start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_QID(pRuntimeEnv), pTag->i64, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex); + qDebug("QInfo:0x%"PRIx64" find tag:%"PRId64" start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_QID(pRuntimeEnv), pTag->i64, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex); } } else { tsBufSetCursor(pRuntimeEnv->pTsBuf, &pTableQueryInfo->cur); if (pTag->nType == TSDB_DATA_TYPE_BINARY || pTag->nType == TSDB_DATA_TYPE_NCHAR) { - qDebug("QInfo:%"PRIu64" find tag:%s start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_QID(pRuntimeEnv), pTag->pz, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex); + qDebug("QInfo:0x%"PRIx64" find tag:%s start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_QID(pRuntimeEnv), pTag->pz, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex); } else { - qDebug("QInfo:%"PRIu64" find tag:%"PRId64" start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_QID(pRuntimeEnv), pTag->i64, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex); + qDebug("QInfo:0x%"PRIx64" find tag:%"PRId64" start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_QID(pRuntimeEnv), pTag->i64, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex); } } return 0; } -void setParamForStableStddev(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, SExprInfo* pExpr) { - SQuery* pQuery = pRuntimeEnv->pQuery; +void setParamForStableStddev(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, SExprInfo* pExprInfo) { + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; - int32_t numOfExprs = pQuery->numOfOutput; + int32_t numOfExprs = pQueryAttr->numOfOutput; for(int32_t i = 0; i < numOfExprs; ++i) { - SExprInfo* pExprInfo = &(pExpr[i]); - if (pExprInfo->base.functionId != TSDB_FUNC_STDDEV_DST) { + SExprInfo* pExprInfo1 = &(pExprInfo[i]); + if (pExprInfo1->base.functionId != TSDB_FUNC_STDDEV_DST) { continue; } - SSqlFuncMsg* pFuncMsg = &pExprInfo->base; + SSqlExpr* pExpr = &pExprInfo1->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 @@ -3598,11 +3500,11 @@ void setParamForStableStddev(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx int32_t numOfGroup = (int32_t)taosArrayGetSize(pRuntimeEnv->prevResult); for (int32_t j = 0; j < numOfGroup; ++j) { SInterResult* p = taosArrayGet(pRuntimeEnv->prevResult, j); - if (pQuery->tagLen == 0 || memcmp(p->tags, pRuntimeEnv->tagVal, pQuery->tagLen) == 0) { + if (pQueryAttr->tagLen == 0 || memcmp(p->tags, pRuntimeEnv->tagVal, pQueryAttr->tagLen) == 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) { + if (pres->colId == pExpr->colInfo.colId) { pCtx[i].param[0].arr = pres->pResult; break; } @@ -3614,17 +3516,15 @@ 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; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; - int32_t numOfExprs = pQuery->numOfOutput; + int32_t numOfExprs = pQueryAttr->numOfOutput; for(int32_t i = 0; i < numOfExprs; ++i) { - SExprInfo* pExprInfo = &(pExpr[i]); - if (pExprInfo->base.functionId != TSDB_FUNC_STDDEV_DST) { + SSqlExpr* pExpr1 = &pExpr[i].base; + if (pExpr1->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 @@ -3636,7 +3536,7 @@ void setParamForStableStddevByColData(SQueryRuntimeEnv* pRuntimeEnv, SQLFunction 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) { + if (pres->colId == pExpr1->colInfo.colId) { pCtx[i].param[0].arr = pres->pResult; break; } @@ -3644,23 +3544,20 @@ void setParamForStableStddevByColData(SQueryRuntimeEnv* pRuntimeEnv, SQLFunction } } } - } - - /* * There are two cases to handle: * - * 1. Query range is not set yet (queryRangeSet = 0). we need to set the query range info, including pQuery->lastKey, - * pQuery->window.skey, and pQuery->eKey. + * 1. Query range is not set yet (queryRangeSet = 0). we need to set the query range info, including pQueryAttr->lastKey, + * pQueryAttr->window.skey, and pQueryAttr->eKey. * 2. Query range is set and query is in progress. There may be another result with the same query ranges to be * merged during merge stage. In this case, we need the pTableQueryInfo->lastResRows to decide if there * is a previous result generated or not. */ void setIntervalQueryRange(SQueryRuntimeEnv *pRuntimeEnv, TSKEY key) { - SQuery *pQuery = pRuntimeEnv->pQuery; - STableQueryInfo *pTableQueryInfo = pQuery->current; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; + STableQueryInfo *pTableQueryInfo = pRuntimeEnv->current; SResultRowInfo *pWindowResInfo = &pTableQueryInfo->resInfo; if (pWindowResInfo->prevSKey != TSKEY_INITIAL_VAL) { @@ -3668,7 +3565,7 @@ void setIntervalQueryRange(SQueryRuntimeEnv *pRuntimeEnv, TSKEY key) { } pTableQueryInfo->win.skey = key; - STimeWindow win = {.skey = key, .ekey = pQuery->window.ekey}; + STimeWindow win = {.skey = key, .ekey = pQueryAttr->window.ekey}; /** * In handling the both ascending and descending order super table query, we need to find the first qualified @@ -3680,11 +3577,11 @@ void setIntervalQueryRange(SQueryRuntimeEnv *pRuntimeEnv, TSKEY key) { TSKEY sk = MIN(win.skey, win.ekey); TSKEY ek = MAX(win.skey, win.ekey); - getAlignQueryTimeWindow(pQuery, win.skey, sk, ek, &w); + getAlignQueryTimeWindow(pQueryAttr, win.skey, sk, ek, &w); if (pWindowResInfo->prevSKey == TSKEY_INITIAL_VAL) { - if (!QUERY_IS_ASC_QUERY(pQuery)) { - assert(win.ekey == pQuery->window.ekey); + if (!QUERY_IS_ASC_QUERY(pQueryAttr)) { + assert(win.ekey == pQueryAttr->window.ekey); } pWindowResInfo->prevSKey = w.skey; @@ -3704,13 +3601,15 @@ void setIntervalQueryRange(SQueryRuntimeEnv *pRuntimeEnv, TSKEY key) { */ static int32_t doCopyToSDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SGroupResInfo* pGroupResInfo, int32_t orderType, SSDataBlock* pBlock) { + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; + int32_t numOfRows = getNumOfTotalRes(pGroupResInfo); int32_t numOfResult = pBlock->info.rows; // there are already exists result rows int32_t start = 0; int32_t step = -1; - qDebug("QInfo:%"PRIu64" start to copy data from windowResInfo to output buf", GET_QID(pRuntimeEnv)); + qDebug("QInfo:0x%"PRIx64" start to copy data from windowResInfo to output buf", GET_QID(pRuntimeEnv)); if (orderType == TSDB_ORDER_ASC) { start = pGroupResInfo->index; step = 1; @@ -3738,7 +3637,7 @@ static int32_t doCopyToSDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SGroupResInfo* int32_t bytes = pColInfoData->info.bytes; char *out = pColInfoData->pData + numOfResult * bytes; - char *in = getPosInResultPage(pRuntimeEnv, page, pRow->offset, offset, bytes); + char *in = getPosInResultPage(pQueryAttr, page, pRow->offset, offset); memcpy(out, in, bytes * numOfRowsToCopy); offset += bytes; @@ -3750,7 +3649,7 @@ static int32_t doCopyToSDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SGroupResInfo* } } - qDebug("QInfo:%"PRIu64" copy data to query buf completed", GET_QID(pRuntimeEnv)); + qDebug("QInfo:0x%"PRIx64" copy data to query buf completed", GET_QID(pRuntimeEnv)); pBlock->info.rows = numOfResult; return 0; } @@ -3763,10 +3662,11 @@ static void toSSDataBlock(SGroupResInfo *pGroupResInfo, SQueryRuntimeEnv* pRunti return; } - SQuery* pQuery = pRuntimeEnv->pQuery; - int32_t orderType = (pQuery->pGroupbyExpr != NULL) ? pQuery->pGroupbyExpr->orderType : TSDB_ORDER_ASC; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int32_t orderType = (pQueryAttr->pGroupbyExpr != NULL) ? pQueryAttr->pGroupbyExpr->orderType : TSDB_ORDER_ASC; doCopyToSDataBlock(pRuntimeEnv, pGroupResInfo, orderType, pBlock); + // refactor : extract method SColumnInfoData* pInfoData = taosArrayGet(pBlock->pDataBlock, 0); if (pInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP) { @@ -3776,12 +3676,12 @@ static void toSSDataBlock(SGroupResInfo *pGroupResInfo, SQueryRuntimeEnv* pRunti } } -static void updateNumOfRowsInResultRows(SQueryRuntimeEnv *pRuntimeEnv, - SQLFunctionCtx* pCtx, int32_t numOfOutput, SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset) { - SQuery *pQuery = pRuntimeEnv->pQuery; +static void updateNumOfRowsInResultRows(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, int32_t numOfOutput, + SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset) { + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; // update the number of result for each, only update the number of rows for the corresponding window result. - if (QUERY_IS_INTERVAL_QUERY(pQuery)) { + if (QUERY_IS_INTERVAL_QUERY(pQueryAttr)) { return; } @@ -3802,18 +3702,18 @@ static void updateNumOfRowsInResultRows(SQueryRuntimeEnv *pRuntimeEnv, static void doCopyQueryResultToMsg(SQInfo *pQInfo, int32_t numOfRows, char *data) { SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; - SQuery *pQuery = pRuntimeEnv->pQuery; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; SSDataBlock* pRes = pRuntimeEnv->outputBuf; - if (pQuery->pExpr2 == NULL) { - for (int32_t col = 0; col < pQuery->numOfOutput; ++col) { + if (pQueryAttr->pExpr2 == NULL) { + for (int32_t col = 0; col < pQueryAttr->numOfOutput; ++col) { SColumnInfoData* pColRes = taosArrayGet(pRes->pDataBlock, col); memmove(data, pColRes->pData, pColRes->info.bytes * pRes->info.rows); data += pColRes->info.bytes * pRes->info.rows; } } else { - for (int32_t col = 0; col < pQuery->numOfExpr2; ++col) { + for (int32_t col = 0; col < pQueryAttr->numOfExpr2; ++col) { SColumnInfoData* pColRes = taosArrayGet(pRes->pDataBlock, col); memmove(data, pColRes->pData, pColRes->info.bytes * numOfRows); data += pColRes->info.bytes * numOfRows; @@ -3836,11 +3736,11 @@ static void doCopyQueryResultToMsg(SQInfo *pQInfo, int32_t numOfRows, char *data data += sizeof(STableIdInfo); total++; - qDebug("QInfo:%"PRIu64" set subscribe info, tid:%d, uid:%"PRIu64", skey:%"PRId64, pQInfo->qId, item->tid, item->uid, item->key); + qDebug("QInfo:0x%"PRIx64" set subscribe info, tid:%d, uid:%"PRIu64", skey:%"PRId64, pQInfo->qId, item->tid, item->uid, item->key); item = taosHashIterate(pRuntimeEnv->pTableRetrieveTsMap, item); } - qDebug("QInfo:%"PRIu64" set %d subscribe info", pQInfo->qId, total); + qDebug("QInfo:0x%"PRIx64" set %d subscribe info", pQInfo->qId, total); // Check if query is completed or not for stable query or normal table query respectively. if (Q_STATUS_EQUAL(pRuntimeEnv->status, QUERY_COMPLETED) && pRuntimeEnv->proot->status == OP_EXEC_DONE) { setQueryStatus(pRuntimeEnv, QUERY_OVER); @@ -3879,62 +3779,62 @@ void queryCostStatis(SQInfo *pQInfo) { pSummary->numOfTimeWindows = 0; } - qDebug("QInfo:%"PRIu64" :cost summary: elapsed time:%"PRId64" us, first merge:%"PRId64" us, total blocks:%d, " + qDebug("QInfo:0x%"PRIx64" :cost summary: elapsed time:%"PRId64" us, first merge:%"PRId64" us, total blocks:%d, " "load block statis:%d, load data block:%d, total rows:%"PRId64 ", check rows:%"PRId64, pQInfo->qId, pSummary->elapsedTime, pSummary->firstStageMergeTime, pSummary->totalBlocks, pSummary->loadBlockStatis, pSummary->loadBlocks, pSummary->totalRows, pSummary->totalCheckedRows); - qDebug("QInfo:%"PRIu64" :cost summary: winResPool size:%.2f Kb, numOfWin:%"PRId64", tableInfoSize:%.2f Kb, hashTable:%.2f Kb", pQInfo->qId, pSummary->winInfoSize/1024.0, + qDebug("QInfo:0x%"PRIx64" :cost summary: winResPool size:%.2f Kb, numOfWin:%"PRId64", tableInfoSize:%.2f Kb, hashTable:%.2f Kb", pQInfo->qId, pSummary->winInfoSize/1024.0, pSummary->numOfTimeWindows, pSummary->tableInfoSize/1024.0, pSummary->hashSize/1024.0); } //static void updateOffsetVal(SQueryRuntimeEnv *pRuntimeEnv, SDataBlockInfo *pBlockInfo) { -// SQuery *pQuery = pRuntimeEnv->pQuery; -// STableQueryInfo* pTableQueryInfo = pQuery->current; +// SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; +// STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current; // -// int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); +// int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order); // -// if (pQuery->limit.offset == pBlockInfo->rows) { // current block will ignore completed -// pTableQueryInfo->lastKey = QUERY_IS_ASC_QUERY(pQuery) ? pBlockInfo->window.ekey + step : pBlockInfo->window.skey + step; -// pQuery->limit.offset = 0; +// if (pQueryAttr->limit.offset == pBlockInfo->rows) { // current block will ignore completed +// pTableQueryInfo->lastKey = QUERY_IS_ASC_QUERY(pQueryAttr) ? pBlockInfo->window.ekey + step : pBlockInfo->window.skey + step; +// pQueryAttr->limit.offset = 0; // return; // } // -// if (QUERY_IS_ASC_QUERY(pQuery)) { -// pQuery->pos = (int32_t)pQuery->limit.offset; +// if (QUERY_IS_ASC_QUERY(pQueryAttr)) { +// pQueryAttr->pos = (int32_t)pQueryAttr->limit.offset; // } else { -// pQuery->pos = pBlockInfo->rows - (int32_t)pQuery->limit.offset - 1; +// pQueryAttr->pos = pBlockInfo->rows - (int32_t)pQueryAttr->limit.offset - 1; // } // -// assert(pQuery->pos >= 0 && pQuery->pos <= pBlockInfo->rows - 1); +// assert(pQueryAttr->pos >= 0 && pQueryAttr->pos <= pBlockInfo->rows - 1); // // SArray * pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pQueryHandle, NULL); // SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0); // -// // update the pQuery->limit.offset value, and pQuery->pos value +// // update the pQueryAttr->limit.offset value, and pQueryAttr->pos value // TSKEY *keys = (TSKEY *) pColInfoData->pData; // // // update the offset value -// pTableQueryInfo->lastKey = keys[pQuery->pos]; -// pQuery->limit.offset = 0; +// pTableQueryInfo->lastKey = keys[pQueryAttr->pos]; +// pQueryAttr->limit.offset = 0; // // int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock); // -// qDebug("QInfo:%"PRIu64" check data block, brange:%" PRId64 "-%" PRId64 ", numOfRows:%d, numOfRes:%d, lastKey:%"PRId64, GET_QID(pRuntimeEnv), +// qDebug("QInfo:0x%"PRIx64" check data block, brange:%" PRId64 "-%" PRId64 ", numOfRows:%d, numOfRes:%d, lastKey:%"PRId64, GET_QID(pRuntimeEnv), // pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows, numOfRes, pQuery->current->lastKey); //} //void skipBlocks(SQueryRuntimeEnv *pRuntimeEnv) { -// SQuery *pQuery = pRuntimeEnv->pQuery; +// SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; // -// if (pQuery->limit.offset <= 0 || pQuery->numOfFilterCols > 0) { +// if (pQueryAttr->limit.offset <= 0 || pQueryAttr->numOfFilterCols > 0) { // return; // } // -// pQuery->pos = 0; -// int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); +// pQueryAttr->pos = 0; +// int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order); // -// STableQueryInfo* pTableQueryInfo = pQuery->current; +// STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current; // TsdbQueryHandleT pQueryHandle = pRuntimeEnv->pQueryHandle; // // SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER; @@ -3945,12 +3845,12 @@ void queryCostStatis(SQInfo *pQInfo) { // // tsdbRetrieveDataBlockInfo(pQueryHandle, &blockInfo); // -// if (pQuery->limit.offset > blockInfo.rows) { -// pQuery->limit.offset -= blockInfo.rows; -// pTableQueryInfo->lastKey = (QUERY_IS_ASC_QUERY(pQuery)) ? blockInfo.window.ekey : blockInfo.window.skey; +// if (pQueryAttr->limit.offset > blockInfo.rows) { +// pQueryAttr->limit.offset -= blockInfo.rows; +// pTableQueryInfo->lastKey = (QUERY_IS_ASC_QUERY(pQueryAttr)) ? blockInfo.window.ekey : blockInfo.window.skey; // pTableQueryInfo->lastKey += step; // -// qDebug("QInfo:%"PRIu64" skip rows:%d, offset:%" PRId64, GET_QID(pRuntimeEnv), blockInfo.rows, +// qDebug("QInfo:0x%"PRIx64" skip rows:%d, offset:%" PRId64, GET_QID(pRuntimeEnv), blockInfo.rows, // pQuery->limit.offset); // } else { // find the appropriated start position in current block // updateOffsetVal(pRuntimeEnv, &blockInfo); @@ -3964,15 +3864,15 @@ void queryCostStatis(SQInfo *pQInfo) { //} //static TSKEY doSkipIntervalProcess(SQueryRuntimeEnv* pRuntimeEnv, STimeWindow* win, SDataBlockInfo* pBlockInfo, STableQueryInfo* pTableQueryInfo) { -// SQuery *pQuery = pRuntimeEnv->pQuery; +// SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; // SResultRowInfo *pWindowResInfo = &pRuntimeEnv->resultRowInfo; // -// assert(pQuery->limit.offset == 0); +// assert(pQueryAttr->limit.offset == 0); // STimeWindow tw = *win; -// getNextTimeWindow(pQuery, &tw); +// getNextTimeWindow(pQueryAttr, &tw); // -// if ((tw.skey <= pBlockInfo->window.ekey && QUERY_IS_ASC_QUERY(pQuery)) || -// (tw.ekey >= pBlockInfo->window.skey && !QUERY_IS_ASC_QUERY(pQuery))) { +// if ((tw.skey <= pBlockInfo->window.ekey && QUERY_IS_ASC_QUERY(pQueryAttr)) || +// (tw.ekey >= pBlockInfo->window.skey && !QUERY_IS_ASC_QUERY(pQueryAttr))) { // // // load the data block and check data remaining in current data block // // TODO optimize performance @@ -3981,15 +3881,15 @@ void queryCostStatis(SQInfo *pQInfo) { // // tw = *win; // int32_t startPos = -// getNextQualifiedWindow(pQuery, &tw, pBlockInfo, pColInfoData->pData, binarySearchForKey, -1); +// getNextQualifiedWindow(pQueryAttr, &tw, pBlockInfo, pColInfoData->pData, binarySearchForKey, -1); // assert(startPos >= 0); // // // set the abort info -// pQuery->pos = startPos; +// pQueryAttr->pos = startPos; // // // reset the query start timestamp // pTableQueryInfo->win.skey = ((TSKEY *)pColInfoData->pData)[startPos]; -// pQuery->window.skey = pTableQueryInfo->win.skey; +// pQueryAttr->window.skey = pTableQueryInfo->win.skey; // TSKEY key = pTableQueryInfo->win.skey; // // pWindowResInfo->prevSKey = tw.skey; @@ -3998,13 +3898,13 @@ void queryCostStatis(SQInfo *pQInfo) { // int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock); // pRuntimeEnv->resultRowInfo.curIndex = index; // restore the window index // -// qDebug("QInfo:%"PRIu64" check data block, brange:%" PRId64 "-%" PRId64 ", numOfRows:%d, numOfRes:%d, lastKey:%" PRId64, +// qDebug("QInfo:0x%"PRIx64" check data block, brange:%" PRId64 "-%" PRId64 ", numOfRows:%d, numOfRes:%d, lastKey:%" PRId64, // GET_QID(pRuntimeEnv), pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows, numOfRes, -// pQuery->current->lastKey); +// pQueryAttr->current->lastKey); // // return key; // } else { // do nothing -// pQuery->window.skey = tw.skey; +// pQueryAttr->window.skey = tw.skey; // pWindowResInfo->prevSKey = tw.skey; // pTableQueryInfo->lastKey = tw.skey; // @@ -4015,53 +3915,53 @@ void queryCostStatis(SQInfo *pQInfo) { //} //static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv, TSKEY* start) { -// SQuery *pQuery = pRuntimeEnv->pQuery; -// if (QUERY_IS_ASC_QUERY(pQuery)) { -// assert(*start <= pQuery->current->lastKey); +// SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; +// if (QUERY_IS_ASC_QUERY(pQueryAttr)) { +// assert(*start <= pRuntimeEnv->current->lastKey); // } else { -// assert(*start >= pQuery->current->lastKey); +// assert(*start >= pRuntimeEnv->current->lastKey); // } // // // if queried with value filter, do NOT forward query start position -// if (pQuery->limit.offset <= 0 || pQuery->numOfFilterCols > 0 || pRuntimeEnv->pTsBuf != NULL || pRuntimeEnv->pFillInfo != NULL) { +// if (pQueryAttr->limit.offset <= 0 || pQueryAttr->numOfFilterCols > 0 || pRuntimeEnv->pTsBuf != NULL || pRuntimeEnv->pFillInfo != NULL) { // return true; // } // // /* -// * 1. for interval without interpolation query we forward pQuery->interval.interval at a time for -// * pQuery->limit.offset times. Since hole exists, pQuery->interval.interval*pQuery->limit.offset value is -// * not valid. otherwise, we only forward pQuery->limit.offset number of points +// * 1. for interval without interpolation query we forward pQueryAttr->interval.interval at a time for +// * pQueryAttr->limit.offset times. Since hole exists, pQueryAttr->interval.interval*pQueryAttr->limit.offset value is +// * not valid. otherwise, we only forward pQueryAttr->limit.offset number of points // */ // assert(pRuntimeEnv->resultRowInfo.prevSKey == TSKEY_INITIAL_VAL); // // STimeWindow w = TSWINDOW_INITIALIZER; -// bool ascQuery = QUERY_IS_ASC_QUERY(pQuery); +// bool ascQuery = QUERY_IS_ASC_QUERY(pQueryAttr); // // SResultRowInfo *pWindowResInfo = &pRuntimeEnv->resultRowInfo; -// STableQueryInfo *pTableQueryInfo = pQuery->current; +// STableQueryInfo *pTableQueryInfo = pRuntimeEnv->current; // // SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER; // while (tsdbNextDataBlock(pRuntimeEnv->pQueryHandle)) { // tsdbRetrieveDataBlockInfo(pRuntimeEnv->pQueryHandle, &blockInfo); // -// if (QUERY_IS_ASC_QUERY(pQuery)) { +// if (QUERY_IS_ASC_QUERY(pQueryAttr)) { // if (pWindowResInfo->prevSKey == TSKEY_INITIAL_VAL) { -// getAlignQueryTimeWindow(pQuery, blockInfo.window.skey, blockInfo.window.skey, pQuery->window.ekey, &w); +// getAlignQueryTimeWindow(pQueryAttr, blockInfo.window.skey, blockInfo.window.skey, pQueryAttr->window.ekey, &w); // pWindowResInfo->prevSKey = w.skey; // } // } else { -// getAlignQueryTimeWindow(pQuery, blockInfo.window.ekey, pQuery->window.ekey, blockInfo.window.ekey, &w); +// getAlignQueryTimeWindow(pQueryAttr, blockInfo.window.ekey, pQueryAttr->window.ekey, blockInfo.window.ekey, &w); // pWindowResInfo->prevSKey = w.skey; // } // // // the first time window -// STimeWindow win = getActiveTimeWindow(pWindowResInfo, pWindowResInfo->prevSKey, pQuery); +// STimeWindow win = getActiveTimeWindow(pWindowResInfo, pWindowResInfo->prevSKey, pQueryAttr); // -// while (pQuery->limit.offset > 0) { +// while (pQueryAttr->limit.offset > 0) { // STimeWindow tw = win; // // if ((win.ekey <= blockInfo.window.ekey && ascQuery) || (win.ekey >= blockInfo.window.skey && !ascQuery)) { -// pQuery->limit.offset -= 1; +// pQueryAttr->limit.offset -= 1; // pWindowResInfo->prevSKey = win.skey; // // // current time window is aligned with blockInfo.window.ekey @@ -4071,13 +3971,13 @@ void queryCostStatis(SQInfo *pQInfo) { // } // } // -// if (pQuery->limit.offset == 0) { +// if (pQueryAttr->limit.offset == 0) { // *start = doSkipIntervalProcess(pRuntimeEnv, &win, &blockInfo, pTableQueryInfo); // return true; // } // // // current window does not ended in current data block, try next data block -// getNextTimeWindow(pQuery, &tw); +// getNextTimeWindow(pQueryAttr, &tw); // // /* // * If the next time window still starts from current data block, @@ -4092,20 +3992,20 @@ void queryCostStatis(SQInfo *pQInfo) { // SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0); // // if ((win.ekey > blockInfo.window.ekey && ascQuery) || (win.ekey < blockInfo.window.skey && !ascQuery)) { -// pQuery->limit.offset -= 1; +// pQueryAttr->limit.offset -= 1; // } // -// if (pQuery->limit.offset == 0) { +// if (pQueryAttr->limit.offset == 0) { // *start = doSkipIntervalProcess(pRuntimeEnv, &win, &blockInfo, pTableQueryInfo); // return true; // } else { // tw = win; // int32_t startPos = -// getNextQualifiedWindow(pQuery, &tw, &blockInfo, pColInfoData->pData, binarySearchForKey, -1); +// getNextQualifiedWindow(pQueryAttr, &tw, &blockInfo, pColInfoData->pData, binarySearchForKey, -1); // assert(startPos >= 0); // // // set the abort info -// pQuery->pos = startPos; +// pQueryAttr->pos = startPos; // pTableQueryInfo->lastKey = ((TSKEY *)pColInfoData->pData)[startPos]; // pWindowResInfo->prevSKey = tw.skey; // win = tw; @@ -4126,26 +4026,25 @@ void queryCostStatis(SQInfo *pQInfo) { static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo); -static int32_t setupQueryHandle(void* tsdb, SQInfo* pQInfo, bool isSTableQuery) { - SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv; - SQuery *pQuery = pQInfo->runtimeEnv.pQuery; +static int32_t setupQueryHandle(void* tsdb, SQueryRuntimeEnv* pRuntimeEnv, int64_t qId, bool isSTableQuery) { + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; // TODO set the tags scan handle - if (onlyQueryTags(pQuery)) { + if (onlyQueryTags(pQueryAttr)) { return TSDB_CODE_SUCCESS; } - STsdbQueryCond cond = createTsdbQueryCond(pQuery, &pQuery->window); - if (isTsCompQuery(pQuery) || isPointInterpoQuery(pQuery)) { + STsdbQueryCond cond = createTsdbQueryCond(pQueryAttr, &pQueryAttr->window); + if (pQueryAttr->tsCompQuery || pQueryAttr->pointInterpQuery) { cond.type = BLOCK_LOAD_TABLE_SEQ_ORDER; } if (!isSTableQuery && (pRuntimeEnv->tableqinfoGroupInfo.numOfTables == 1) && (cond.order == TSDB_ORDER_ASC) - && (!QUERY_IS_INTERVAL_QUERY(pQuery)) - && (!isGroupbyColumn(pQuery->pGroupbyExpr)) - && (!isFixedOutputQuery(pRuntimeEnv)) + && (!QUERY_IS_INTERVAL_QUERY(pQueryAttr)) + && (!pQueryAttr->groupbyColumn) + && (!pQueryAttr->simpleAgg) ) { SArray* pa = GET_TABLEGROUP(pRuntimeEnv, 0); STableQueryInfo* pCheckInfo = taosArrayGetP(pa, 0); @@ -4153,12 +4052,12 @@ static int32_t setupQueryHandle(void* tsdb, SQInfo* pQInfo, bool isSTableQuery) } terrno = TSDB_CODE_SUCCESS; - if (isFirstLastRowQuery(pQuery)) { - pRuntimeEnv->pQueryHandle = tsdbQueryLastRow(tsdb, &cond, &pQuery->tableGroupInfo, pQInfo->qId, &pQuery->memRef); + if (isFirstLastRowQuery(pQueryAttr)) { + pRuntimeEnv->pQueryHandle = tsdbQueryLastRow(tsdb, &cond, &pQueryAttr->tableGroupInfo, qId, &pQueryAttr->memRef); // update the query time window - pQuery->window = cond.twindow; - if (pQuery->tableGroupInfo.numOfTables == 0) { + pQueryAttr->window = cond.twindow; + if (pQueryAttr->tableGroupInfo.numOfTables == 0) { pRuntimeEnv->tableqinfoGroupInfo.numOfTables = 0; } else { size_t numOfGroups = GET_NUM_OF_TABLEGROUP(pRuntimeEnv); @@ -4169,15 +4068,15 @@ static int32_t setupQueryHandle(void* tsdb, SQInfo* pQInfo, bool isSTableQuery) for (int32_t j = 0; j < t; ++j) { STableQueryInfo *pCheckInfo = taosArrayGetP(group, j); - pCheckInfo->win = pQuery->window; + pCheckInfo->win = pQueryAttr->window; pCheckInfo->lastKey = pCheckInfo->win.skey; } } } - } else if (isPointInterpoQuery(pQuery)) { - pRuntimeEnv->pQueryHandle = tsdbQueryRowsInExternalWindow(tsdb, &cond, &pQuery->tableGroupInfo, pQInfo->qId, &pQuery->memRef); + } else if (pQueryAttr->pointInterpQuery) { + pRuntimeEnv->pQueryHandle = tsdbQueryRowsInExternalWindow(tsdb, &cond, &pQueryAttr->tableGroupInfo, qId, &pQueryAttr->memRef); } else { - pRuntimeEnv->pQueryHandle = tsdbQueryTables(tsdb, &cond, &pQuery->tableGroupInfo, pQInfo->qId, &pQuery->memRef); + pRuntimeEnv->pQueryHandle = tsdbQueryTables(tsdb, &cond, &pQueryAttr->tableGroupInfo, qId, &pQueryAttr->memRef); } return terrno; @@ -4194,82 +4093,92 @@ static SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfOutput, in for(int32_t i = 0; i < numOfOutput; ++i) { SExprInfo* pExprInfo = &pExpr[i]; - pFillCol[i].col.bytes = pExprInfo->bytes; - pFillCol[i].col.type = (int8_t)pExprInfo->type; + pFillCol[i].col.bytes = pExprInfo->base.resBytes; + pFillCol[i].col.type = (int8_t)pExprInfo->base.resType; pFillCol[i].col.offset = offset; + pFillCol[i].col.colId = pExprInfo->base.resColId; pFillCol[i].tagIndex = -2; - pFillCol[i].flag = TSDB_COL_NORMAL; // always be ta normal column for table query + pFillCol[i].flag = pExprInfo->base.colInfo.flag; // always be the normal column for table query pFillCol[i].functionId = pExprInfo->base.functionId; pFillCol[i].fillVal.i = fillVal[i]; - offset += pExprInfo->bytes; + offset += pExprInfo->base.resBytes; } return pFillCol; } -int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bool isSTableQuery) { +int32_t doInitQInfo(SQInfo* pQInfo, STSBuf* pTsBuf, SArray* prevResult, void* tsdb, void* sourceOptr, int32_t tbScanner, + SArray* pOperator, void* param) { SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv; - SQuery *pQuery = pQInfo->runtimeEnv.pQuery; - pQuery->tsdb = tsdb; + SQueryAttr *pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; + pQueryAttr->tsdb = tsdb; - pQuery->topBotQuery = isTopBottomQuery(pQuery); - pQuery->hasTagResults = hasTagValOutput(pQuery); - pQuery->timeWindowInterpo = timeWindowInterpoRequired(pQuery); - pQuery->stabledev = isStabledev(pQuery); + pRuntimeEnv->prevResult = prevResult; - setScanLimitationByResultBuffer(pQuery); - - int32_t code = setupQueryHandle(tsdb, pQInfo, isSTableQuery); - if (code != TSDB_CODE_SUCCESS) { - return code; + if (tsdb != NULL) { + int32_t code = setupQueryHandle(tsdb, pRuntimeEnv, pQInfo->qId, pQueryAttr->stableQuery); + if (code != TSDB_CODE_SUCCESS) { + return code; + } } - pQuery->tsdb = tsdb; - pQuery->vgId = vgId; - pQuery->stableQuery = isSTableQuery; - pQuery->groupbyColumn = isGroupbyColumn(pQuery->pGroupbyExpr); - pQuery->interBufSize = getOutputInterResultBufSize(pQuery); + pQueryAttr->interBufSize = getOutputInterResultBufSize(pQueryAttr); - pRuntimeEnv->groupResInfo.totalGroup = (int32_t) (isSTableQuery? GET_NUM_OF_TABLEGROUP(pRuntimeEnv):0); + pRuntimeEnv->groupResInfo.totalGroup = (int32_t) (pQueryAttr->stableQuery? GET_NUM_OF_TABLEGROUP(pRuntimeEnv):0); - pRuntimeEnv->pQuery = pQuery; + pRuntimeEnv->pQueryAttr = pQueryAttr; pRuntimeEnv->pTsBuf = pTsBuf; pRuntimeEnv->cur.vgroupIndex = -1; - setResultBufSize(pQuery, &pRuntimeEnv->resultInfo); + setResultBufSize(pQueryAttr, &pRuntimeEnv->resultInfo); - if (onlyQueryTags(pQuery)) { - pRuntimeEnv->resultInfo.capacity = 4096; - pRuntimeEnv->proot = createTagScanOperatorInfo(pRuntimeEnv, pQuery->pExpr1, pQuery->numOfOutput); - } else if (pQuery->queryBlockDist) { - pRuntimeEnv->pTableScanner = createTableBlockInfoScanOperator(pRuntimeEnv->pQueryHandle, pRuntimeEnv); - } else if (isTsCompQuery(pQuery) || isPointInterpoQuery(pQuery)) { - pRuntimeEnv->pTableScanner = createTableSeqScanOperator(pRuntimeEnv->pQueryHandle, pRuntimeEnv); - } else if (needReverseScan(pQuery)) { - pRuntimeEnv->pTableScanner = createDataBlocksOptScanInfo(pRuntimeEnv->pQueryHandle, pRuntimeEnv, getNumOfScanTimes(pQuery), 1); - } else { - pRuntimeEnv->pTableScanner = createTableScanOperator(pRuntimeEnv->pQueryHandle, pRuntimeEnv, getNumOfScanTimes(pQuery)); + switch(tbScanner) { + case OP_TableBlockInfoScan: { + pRuntimeEnv->proot = createTableBlockInfoScanOperator(pRuntimeEnv->pQueryHandle, pRuntimeEnv); + break; + } + case OP_TableSeqScan: { + pRuntimeEnv->proot = createTableSeqScanOperator(pRuntimeEnv->pQueryHandle, pRuntimeEnv); + break; + } + case OP_DataBlocksOptScan: { + pRuntimeEnv->proot = createDataBlocksOptScanInfo(pRuntimeEnv->pQueryHandle, pRuntimeEnv, getNumOfScanTimes(pQueryAttr), 1); + break; + } + case OP_TableScan: { + pRuntimeEnv->proot = createTableScanOperator(pRuntimeEnv->pQueryHandle, pRuntimeEnv, getNumOfScanTimes(pQueryAttr)); + break; + } + default: { // do nothing + break; + } + } + + if (sourceOptr != NULL) { + assert(pRuntimeEnv->proot == NULL); + pRuntimeEnv->proot = sourceOptr; } if (pTsBuf != NULL) { - int16_t order = (pQuery->order.order == pRuntimeEnv->pTsBuf->tsOrder) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC; + int16_t order = (pQueryAttr->order.order == pRuntimeEnv->pTsBuf->tsOrder) ? TSDB_ORDER_ASC : TSDB_ORDER_DESC; tsBufSetTraverseOrder(pRuntimeEnv->pTsBuf, order); } int32_t ps = DEFAULT_PAGE_SIZE; - getIntermediateBufInfo(pRuntimeEnv, &ps, &pQuery->intermediateResultRowSize); + getIntermediateBufInfo(pRuntimeEnv, &ps, &pQueryAttr->intermediateResultRowSize); int32_t TENMB = 1024*1024*10; - code = createDiskbasedResultBuffer(&pRuntimeEnv->pResultBuf, ps, TENMB, pQInfo->qId); + int32_t code = createDiskbasedResultBuffer(&pRuntimeEnv->pResultBuf, ps, TENMB, pQInfo->qId); if (code != TSDB_CODE_SUCCESS) { return code; } // create runtime environment - int32_t numOfTables = (int32_t)pQuery->tableGroupInfo.numOfTables; + int32_t numOfTables = (int32_t)pQueryAttr->tableGroupInfo.numOfTables; pQInfo->summary.tableInfoSize += (numOfTables * sizeof(STableQueryInfo)); - code = setupQueryRuntimeEnv(pRuntimeEnv, (int32_t) pQuery->tableGroupInfo.numOfTables); + + code = setupQueryRuntimeEnv(pRuntimeEnv, (int32_t) pQueryAttr->tableGroupInfo.numOfTables, pOperator, param); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -4278,25 +4187,25 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo return TSDB_CODE_SUCCESS; } -static void doTableQueryInfoTimeWindowCheck(SQuery* pQuery, STableQueryInfo* pTableQueryInfo) { - if (QUERY_IS_ASC_QUERY(pQuery)) { +static void doTableQueryInfoTimeWindowCheck(SQueryAttr* pQueryAttr, STableQueryInfo* pTableQueryInfo) { + if (QUERY_IS_ASC_QUERY(pQueryAttr)) { assert( (pTableQueryInfo->win.skey <= pTableQueryInfo->win.ekey) && (pTableQueryInfo->lastKey >= pTableQueryInfo->win.skey) && - (pTableQueryInfo->win.skey >= pQuery->window.skey && pTableQueryInfo->win.ekey <= pQuery->window.ekey)); + (pTableQueryInfo->win.skey >= pQueryAttr->window.skey && pTableQueryInfo->win.ekey <= pQueryAttr->window.ekey)); } else { assert( (pTableQueryInfo->win.skey >= pTableQueryInfo->win.ekey) && (pTableQueryInfo->lastKey <= pTableQueryInfo->win.skey) && - (pTableQueryInfo->win.skey <= pQuery->window.skey && pTableQueryInfo->win.ekey >= pQuery->window.ekey)); + (pTableQueryInfo->win.skey <= pQueryAttr->window.skey && pTableQueryInfo->win.ekey >= pQueryAttr->window.ekey)); } } -STsdbQueryCond createTsdbQueryCond(SQuery* pQuery, STimeWindow* win) { +STsdbQueryCond createTsdbQueryCond(SQueryAttr* pQueryAttr, STimeWindow* win) { STsdbQueryCond cond = { - .colList = pQuery->colList, - .order = pQuery->order.order, - .numOfCols = pQuery->numOfCols, + .colList = pQueryAttr->tableCols, + .order = pQueryAttr->order.order, + .numOfCols = pQueryAttr->numOfCols, .type = BLOCK_LOAD_OFFSET_SEQ_ORDER, .loadExternalRows = false, }; @@ -4343,13 +4252,16 @@ static void doCloseAllTimeWindow(SQueryRuntimeEnv* pRuntimeEnv) { } } -static SSDataBlock* doTableScanImpl(void* param) { +static SSDataBlock* doTableScanImpl(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; STableScanInfo* pTableScanInfo = pOperator->info; - SSDataBlock* pBlock = &pTableScanInfo->block; - SQuery* pQuery = pOperator->pRuntimeEnv->pQuery; - STableGroupInfo* pTableGroupInfo = &pOperator->pRuntimeEnv->tableqinfoGroupInfo; + SSDataBlock* pBlock = &pTableScanInfo->block; + SQueryRuntimeEnv *pRuntimeEnv = pOperator->pRuntimeEnv; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + STableGroupInfo *pTableGroupInfo = &pOperator->pRuntimeEnv->tableqinfoGroupInfo; + + *newgroup = false; while (tsdbNextDataBlock(pTableScanInfo->pQueryHandle)) { if (isQueryKilled(pOperator->pRuntimeEnv->qinfo)) { @@ -4360,15 +4272,15 @@ static SSDataBlock* doTableScanImpl(void* param) { tsdbRetrieveDataBlockInfo(pTableScanInfo->pQueryHandle, &pBlock->info); // todo opt - if (pTableGroupInfo->numOfTables > 1 || (pQuery->current == NULL && pTableGroupInfo->numOfTables == 1)) { + if (pTableGroupInfo->numOfTables > 1 || (pRuntimeEnv->current == NULL && pTableGroupInfo->numOfTables == 1)) { STableQueryInfo** pTableQueryInfo = (STableQueryInfo**)taosHashGet(pTableGroupInfo->map, &pBlock->info.tid, sizeof(pBlock->info.tid)); if (pTableQueryInfo == NULL) { break; } - pQuery->current = *pTableQueryInfo; - doTableQueryInfoTimeWindowCheck(pQuery, *pTableQueryInfo); + pRuntimeEnv->current = *pTableQueryInfo; + doTableQueryInfoTimeWindowCheck(pQueryAttr, *pTableQueryInfo); } // this function never returns error? @@ -4389,17 +4301,18 @@ static SSDataBlock* doTableScanImpl(void* param) { return NULL; } -static SSDataBlock* doTableScan(void* param) { +static SSDataBlock* doTableScan(void* param, bool *newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; STableScanInfo *pTableScanInfo = pOperator->info; SQueryRuntimeEnv *pRuntimeEnv = pOperator->pRuntimeEnv; - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; SResultRowInfo* pResultRowInfo = pTableScanInfo->pResultRowInfo; + *newgroup = false; while (pTableScanInfo->current < pTableScanInfo->times) { - SSDataBlock* p = doTableScanImpl(pOperator); + SSDataBlock* p = doTableScanImpl(pOperator, newgroup); if (p != NULL) { return p; } @@ -4413,7 +4326,7 @@ static SSDataBlock* doTableScan(void* param) { } // do prepare for the next round table scan operation - STsdbQueryCond cond = createTsdbQueryCond(pQuery, &pQuery->window); + STsdbQueryCond cond = createTsdbQueryCond(pQueryAttr, &pQueryAttr->window); tsdbResetQueryHandle(pTableScanInfo->pQueryHandle, &cond); setQueryStatus(pRuntimeEnv, QUERY_NOT_COMPLETED); @@ -4429,17 +4342,18 @@ static SSDataBlock* doTableScan(void* param) { pResultRowInfo->prevSKey = pResultRowInfo->pResult[0]->win.skey; } - qDebug("QInfo:%"PRIu64" start to repeat scan data blocks due to query func required, qrange:%" PRId64 "-%" PRId64, + qDebug("QInfo:0x%"PRIx64" start to repeat scan data blocks due to query func required, qrange:%" PRId64 "-%" PRId64, GET_QID(pRuntimeEnv), cond.twindow.skey, cond.twindow.ekey); } + SSDataBlock *p = NULL; if (pTableScanInfo->reverseTimes > 0) { setupEnvForReverseScan(pRuntimeEnv, pTableScanInfo->pResultRowInfo, pTableScanInfo->pCtx, pTableScanInfo->numOfOutput); - STsdbQueryCond cond = createTsdbQueryCond(pQuery, &pQuery->window); + STsdbQueryCond cond = createTsdbQueryCond(pQueryAttr, &pQueryAttr->window); tsdbResetQueryHandle(pTableScanInfo->pQueryHandle, &cond); - qDebug("QInfo:%"PRIu64" start to reverse scan data blocks due to query func required, qrange:%" PRId64 "-%" PRId64, + qDebug("QInfo:0x%"PRIx64" start to reverse scan data blocks due to query func required, qrange:%" PRId64 "-%" PRId64, GET_QID(pRuntimeEnv), cond.twindow.skey, cond.twindow.ekey); pRuntimeEnv->scanFlag = REVERSE_SCAN; @@ -4454,22 +4368,20 @@ static SSDataBlock* doTableScan(void* param) { pResultRowInfo->prevSKey = pResultRowInfo->pResult[pResultRowInfo->size-1]->win.skey; } - SSDataBlock* p = doTableScanImpl(pOperator); - if (p != NULL) { - return p; - } + p = doTableScanImpl(pOperator, newgroup); } - return NULL; + return p; } -static SSDataBlock* doBlockInfoScan(void* param) { +static SSDataBlock* doBlockInfoScan(void* param, bool* newgroup) { SOperatorInfo *pOperator = (SOperatorInfo*)param; if (pOperator->status == OP_EXEC_DONE) { return NULL; } STableScanInfo *pTableScanInfo = pOperator->info; + *newgroup = false; STableBlockDist tableBlockDist = {0}; tableBlockDist.numOfTables = (int32_t)pOperator->pRuntimeEnv->tableqinfoGroupInfo.numOfTables; @@ -4495,7 +4407,7 @@ static SSDataBlock* doBlockInfoScan(void* param) { tbufCloseWriter(&bw); SArray* g = GET_TABLEGROUP(pOperator->pRuntimeEnv, 0); - pOperator->pRuntimeEnv->pQuery->current = taosArrayGetP(g, 0); + pOperator->pRuntimeEnv->current = taosArrayGetP(g, 0); pOperator->status = OP_EXEC_DONE; return pBlock; @@ -4508,15 +4420,16 @@ SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pInfo->pQueryHandle = pTsdbQueryHandle; pInfo->times = repeatTime; pInfo->reverseTimes = 0; - pInfo->order = pRuntimeEnv->pQuery->order.order; + pInfo->order = pRuntimeEnv->pQueryAttr->order.order; pInfo->current = 0; SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); pOperator->name = "TableScanOperator"; + pOperator->operatorType = OP_TableScan; pOperator->blockingOptr = false; pOperator->status = OP_IN_EXECUTING; pOperator->info = pInfo; - pOperator->numOfOutput = pRuntimeEnv->pQuery->numOfCols; + pOperator->numOfOutput = pRuntimeEnv->pQueryAttr->numOfCols; pOperator->pRuntimeEnv = pRuntimeEnv; pOperator->exec = doTableScan; @@ -4529,7 +4442,7 @@ SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, SQueryRuntimeE pInfo->pQueryHandle = pTsdbQueryHandle; pInfo->times = 1; pInfo->reverseTimes = 0; - pInfo->order = pRuntimeEnv->pQuery->order.order; + pInfo->order = pRuntimeEnv->pQueryAttr->order.order; pInfo->current = 0; SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); @@ -4538,7 +4451,7 @@ SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, SQueryRuntimeE pOperator->blockingOptr = false; pOperator->status = OP_IN_EXECUTING; pOperator->info = pInfo; - pOperator->numOfOutput = pRuntimeEnv->pQuery->numOfCols; + pOperator->numOfOutput = pRuntimeEnv->pQueryAttr->numOfCols; pOperator->pRuntimeEnv = pRuntimeEnv; pOperator->exec = doTableScanImpl; @@ -4564,7 +4477,7 @@ SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRu pOperator->status = OP_IN_EXECUTING; pOperator->info = pInfo; pOperator->pRuntimeEnv = pRuntimeEnv; - pOperator->numOfOutput = pRuntimeEnv->pQuery->numOfCols; + pOperator->numOfOutput = pRuntimeEnv->pQueryAttr->numOfCols; pOperator->exec = doBlockInfoScan; return pOperator; @@ -4620,7 +4533,7 @@ void setTableScanFilterOperatorInfo(STableScanInfo* pTableScanInfo, SOperatorInf } } -static SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime, int32_t reverseTime) { +SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime, int32_t reverseTime) { assert(repeatTime > 0); STableScanInfo* pInfo = calloc(1, sizeof(STableScanInfo)); @@ -4628,7 +4541,7 @@ static SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQuery pInfo->times = repeatTime; pInfo->reverseTimes = reverseTime; pInfo->current = 0; - pInfo->order = pRuntimeEnv->pQuery->order.order; + pInfo->order = pRuntimeEnv->pQueryAttr->order.order; SOperatorInfo* pOptr = calloc(1, sizeof(SOperatorInfo)); pOptr->name = "DataBlocksOptimizedScanOperator"; @@ -4641,12 +4554,206 @@ static SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQuery return pOptr; } +SArray* getOrderCheckColumns(SQueryAttr* pQuery) { + int32_t numOfCols = pQuery->pGroupbyExpr->numOfGroupCols; + + SArray* pOrderColumns = NULL; + if (numOfCols > 0) { + pOrderColumns = taosArrayDup(pQuery->pGroupbyExpr->columnInfo); + } else { + pOrderColumns = taosArrayInit(4, sizeof(SColIndex)); + } + + if (pQuery->interval.interval > 0) { + if (pOrderColumns == NULL) { + pOrderColumns = taosArrayInit(1, sizeof(SColIndex)); + } + + SColIndex colIndex = {.colIndex = 0, .colId = 0, .flag = TSDB_COL_NORMAL}; + taosArrayPush(pOrderColumns, &colIndex); + } + + { + numOfCols = (int32_t) taosArrayGetSize(pOrderColumns); + for(int32_t i = 0; i < numOfCols; ++i) { + SColIndex* index = taosArrayGet(pOrderColumns, i); + for(int32_t j = 0; j < pQuery->numOfOutput; ++j) { + if (index->colId == pQuery->pExpr1[j].base.colInfo.colId) { + index->colIndex = j; + index->colId = pQuery->pExpr1[j].base.resColId; + } + } + } + } + return pOrderColumns; +} + +SArray* getResultGroupCheckColumns(SQueryAttr* pQuery) { + int32_t numOfCols = pQuery->pGroupbyExpr->numOfGroupCols; + + SArray* pOrderColumns = NULL; + if (numOfCols > 0) { + pOrderColumns = taosArrayDup(pQuery->pGroupbyExpr->columnInfo); + } else { + pOrderColumns = taosArrayInit(4, sizeof(SColIndex)); + } + + for(int32_t i = 0; i < numOfCols; ++i) { + SColIndex* index = taosArrayGet(pOrderColumns, i); + + bool found = false; + for(int32_t j = 0; j < pQuery->numOfOutput; ++j) { + SSqlExpr* pExpr = &pQuery->pExpr1[j].base; + + // TSDB_FUNC_TAG_DUMMY function needs to be ignored + if (index->colId == pExpr->colInfo.colId && + ((TSDB_COL_IS_TAG(pExpr->colInfo.flag) && pExpr->functionId == TSDB_FUNC_TAG) || + (TSDB_COL_IS_NORMAL_COL(pExpr->colInfo.flag) && pExpr->functionId == TSDB_FUNC_PRJ))) { + index->colIndex = j; + index->colId = pExpr->resColId; + found = true; + break; + } + } + + assert(found && index->colIndex >= 0 && index->colIndex < pQuery->numOfOutput); + } + + return pOrderColumns; +} + +static void destroyGlobalAggOperatorInfo(void* param, int32_t numOfOutput) { + SMultiwayMergeInfo *pInfo = (SMultiwayMergeInfo*) param; + destroyBasicOperatorInfo(&pInfo->binfo, numOfOutput); + + taosArrayDestroy(pInfo->orderColumnList); + taosArrayDestroy(pInfo->groupColumnList); + tfree(pInfo->prevRow); + tfree(pInfo->currentGroupColData); +} + +static void destroySlimitOperatorInfo(void* param, int32_t numOfOutput) { + SSLimitOperatorInfo *pInfo = (SSLimitOperatorInfo*) param; + taosArrayDestroy(pInfo->orderColumnList); + tfree(pInfo->prevRow); +} + +SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, + SExprInfo* pExpr, int32_t numOfOutput, void* param) { + SMultiwayMergeInfo* pInfo = calloc(1, sizeof(SMultiwayMergeInfo)); + + pInfo->resultRowFactor = + (int32_t)(GET_ROW_PARAM_FOR_MULTIOUTPUT(pRuntimeEnv->pQueryAttr, pRuntimeEnv->pQueryAttr->topBotQuery, + false)); + + pRuntimeEnv->scanFlag = MERGE_STAGE; // TODO init when creating pCtx + + pInfo->pMerge = param; + pInfo->bufCapacity = 4096; + + pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, pInfo->bufCapacity * pInfo->resultRowFactor); + pInfo->binfo.pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset); + + pInfo->orderColumnList = getOrderCheckColumns(pRuntimeEnv->pQueryAttr); + pInfo->groupColumnList = getResultGroupCheckColumns(pRuntimeEnv->pQueryAttr); + + // TODO refactor + int32_t len = 0; + for(int32_t i = 0; i < numOfOutput; ++i) { + len += pExpr[i].base.colBytes; + } + + int32_t numOfCols = (pInfo->orderColumnList != NULL)? (int32_t) taosArrayGetSize(pInfo->orderColumnList):0; + pInfo->prevRow = calloc(1, (POINTER_BYTES * numOfCols + len)); + int32_t offset = POINTER_BYTES * numOfCols; + + for(int32_t i = 0; i < numOfCols; ++i) { + pInfo->prevRow[i] = (char*)pInfo->prevRow + offset; + + SColIndex* index = taosArrayGet(pInfo->orderColumnList, i); + offset += pExpr[index->colIndex].base.resBytes; + } + + numOfCols = (pInfo->groupColumnList != NULL)? (int32_t)taosArrayGetSize(pInfo->groupColumnList):0; + pInfo->currentGroupColData = calloc(1, (POINTER_BYTES * numOfCols + len)); + offset = POINTER_BYTES * numOfCols; + + for(int32_t i = 0; i < numOfCols; ++i) { + pInfo->currentGroupColData[i] = (char*)pInfo->currentGroupColData + offset; + + SColIndex* index = taosArrayGet(pInfo->groupColumnList, i); + offset += pExpr[index->colIndex].base.resBytes; + } + + initResultRowInfo(&pInfo->binfo.resultRowInfo, 8, TSDB_DATA_TYPE_INT); + + pInfo->seed = rand(); + setDefaultOutputBuf(pRuntimeEnv, &pInfo->binfo, pInfo->seed, MERGE_STAGE); + + SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); + pOperator->name = "GlobalAggregate"; + pOperator->operatorType = OP_GlobalAggregate; + pOperator->blockingOptr = true; + pOperator->status = OP_IN_EXECUTING; + pOperator->info = pInfo; + pOperator->upstream = upstream; + pOperator->pExpr = pExpr; + pOperator->numOfOutput = numOfOutput; + pOperator->pRuntimeEnv = pRuntimeEnv; + + pOperator->exec = doGlobalAggregate; + pOperator->cleanup = destroyGlobalAggOperatorInfo; + return pOperator; +} + +SOperatorInfo *createMultiwaySortOperatorInfo(SQueryRuntimeEnv *pRuntimeEnv, SExprInfo *pExpr, int32_t numOfOutput, + int32_t numOfRows, void *merger, bool groupMix) { + SMultiwayMergeInfo* pInfo = calloc(1, sizeof(SMultiwayMergeInfo)); + + pInfo->pMerge = merger; + pInfo->groupMix = groupMix; + pInfo->bufCapacity = numOfRows; + + pInfo->orderColumnList = getResultGroupCheckColumns(pRuntimeEnv->pQueryAttr); + pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, numOfRows); + + { + int32_t len = 0; + for(int32_t i = 0; i < numOfOutput; ++i) { + len += pExpr[i].base.colBytes; + } + + int32_t numOfCols = (pInfo->orderColumnList != NULL)? (int32_t) taosArrayGetSize(pInfo->orderColumnList):0; + pInfo->prevRow = calloc(1, (POINTER_BYTES * numOfCols + len)); + int32_t offset = POINTER_BYTES * numOfCols; + + for(int32_t i = 0; i < numOfCols; ++i) { + pInfo->prevRow[i] = (char*)pInfo->prevRow + offset; + + SColIndex* index = taosArrayGet(pInfo->orderColumnList, i); + offset += pExpr[index->colIndex].base.colBytes; + } + } + + SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); + pOperator->name = "MultiwaySortOperator"; + pOperator->operatorType = OP_MultiwayMergeSort; + pOperator->blockingOptr = false; + pOperator->status = OP_IN_EXECUTING; + pOperator->info = pInfo; + pOperator->pRuntimeEnv = pRuntimeEnv; + pOperator->numOfOutput = pRuntimeEnv->pQueryAttr->numOfCols; + pOperator->exec = doMultiwayMergeSort; + pOperator->cleanup = destroyGlobalAggOperatorInfo; + return pOperator; +} + static int32_t getTableScanOrder(STableScanInfo* pTableScanInfo) { return pTableScanInfo->order; } // this is a blocking operator -static SSDataBlock* doAggregate(void* param) { +static SSDataBlock* doAggregate(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; if (pOperator->status == OP_EXEC_DONE) { return NULL; @@ -4657,18 +4764,20 @@ static SSDataBlock* doAggregate(void* param) { SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; - SQuery* pQuery = pRuntimeEnv->pQuery; - int32_t order = pQuery->order.order; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int32_t order = pQueryAttr->order.order; SOperatorInfo* upstream = pOperator->upstream; while(1) { - SSDataBlock* pBlock = upstream->exec(upstream); + SSDataBlock* pBlock = upstream->exec(upstream, newgroup); if (pBlock == NULL) { break; } - setTagValue(pOperator, pQuery->current->pTable, pInfo->pCtx, pOperator->numOfOutput); + if (pRuntimeEnv->current != NULL) { + setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput); + } if (upstream->operatorType == OP_DataBlocksOptScan) { STableScanInfo* pScanInfo = upstream->info; @@ -4677,7 +4786,7 @@ static SSDataBlock* doAggregate(void* param) { // the pDataBlock are always the same one, no need to call this again setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order); - doAggregateImpl(pOperator, pQuery->window.skey, pInfo->pCtx, pBlock); + doAggregateImpl(pOperator, pQueryAttr->window.skey, pInfo->pCtx, pBlock); } pOperator->status = OP_EXEC_DONE; @@ -4689,7 +4798,7 @@ static SSDataBlock* doAggregate(void* param) { return pInfo->pRes; } -static SSDataBlock* doSTableAggregate(void* param) { +static SSDataBlock* doSTableAggregate(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; if (pOperator->status == OP_EXEC_DONE) { return NULL; @@ -4710,18 +4819,18 @@ static SSDataBlock* doSTableAggregate(void* param) { return pInfo->pRes; } - SQuery* pQuery = pRuntimeEnv->pQuery; - int32_t order = pQuery->order.order; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int32_t order = pQueryAttr->order.order; SOperatorInfo* upstream = pOperator->upstream; while(1) { - SSDataBlock* pBlock = upstream->exec(upstream); + SSDataBlock* pBlock = upstream->exec(upstream, newgroup); if (pBlock == NULL) { break; } - setTagValue(pOperator, pRuntimeEnv->pQuery->current->pTable, pInfo->pCtx, pOperator->numOfOutput); + setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput); if (upstream->operatorType == OP_DataBlocksOptScan) { STableScanInfo* pScanInfo = upstream->info; @@ -4731,9 +4840,9 @@ static SSDataBlock* doSTableAggregate(void* param) { // the pDataBlock are always the same one, no need to call this again setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order); - TSKEY key = QUERY_IS_ASC_QUERY(pQuery)? pBlock->info.window.ekey + 1:pBlock->info.window.skey-1; - setExecutionContext(pRuntimeEnv, pInfo, pOperator->numOfOutput, pQuery->current->groupIndex, key); - doAggregateImpl(pOperator, pQuery->window.skey, pInfo->pCtx, pBlock); + TSKEY key = QUERY_IS_ASC_QUERY(pQueryAttr)? pBlock->info.window.ekey + 1:pBlock->info.window.skey-1; + setExecutionContext(pRuntimeEnv, pInfo, pOperator->numOfOutput, pRuntimeEnv->current->groupIndex, key); + doAggregateImpl(pOperator, pQueryAttr->window.skey, pInfo->pCtx, pBlock); } pOperator->status = OP_RES_TO_RETURN; @@ -4752,7 +4861,7 @@ static SSDataBlock* doSTableAggregate(void* param) { return pInfo->pRes; } -static SSDataBlock* doArithmeticOperation(void* param) { +static SSDataBlock* doArithmeticOperation(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; SArithOperatorInfo* pArithInfo = pOperator->info; @@ -4760,28 +4869,75 @@ static SSDataBlock* doArithmeticOperation(void* param) { SOptrBasicInfo *pInfo = &pArithInfo->binfo; SSDataBlock* pRes = pInfo->pRes; - int32_t order = pRuntimeEnv->pQuery->order.order; + int32_t order = pRuntimeEnv->pQueryAttr->order.order; pRes->info.rows = 0; + if (pArithInfo->existDataBlock) { // TODO refactor + STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current; + + SSDataBlock* pBlock = pArithInfo->existDataBlock; + pArithInfo->existDataBlock = NULL; + *newgroup = true; + + // todo dynamic set tags + if (pTableQueryInfo != NULL) { + setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput); + } + + // the pDataBlock are always the same one, no need to call this again + setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order); + updateOutputBuf(&pArithInfo->binfo, &pArithInfo->bufCapacity, pBlock->info.rows); + + arithmeticApplyFunctions(pRuntimeEnv, pInfo->pCtx, pOperator->numOfOutput); + + if (pTableQueryInfo != NULL) { // TODO refactor + updateTableIdInfo(pTableQueryInfo, pBlock, pRuntimeEnv->pTableRetrieveTsMap, order); + } + + pRes->info.rows = getNumOfResult(pRuntimeEnv, pInfo->pCtx, pOperator->numOfOutput); + if (pRes->info.rows >= pRuntimeEnv->resultInfo.threshold) { + clearNumOfRes(pInfo->pCtx, pOperator->numOfOutput); + return pRes; + } + } + while(1) { - SSDataBlock* pBlock = pOperator->upstream->exec(pOperator->upstream); + bool prevVal = *newgroup; + + // The upstream exec may change the value of the newgroup, so use a local variable instead. + SSDataBlock* pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); if (pBlock == NULL) { + assert(*newgroup == false); + + *newgroup = prevVal; setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); break; } - STableQueryInfo* pTableQueryInfo = pRuntimeEnv->pQuery->current; + // Return result of the previous group in the firstly. + if (newgroup && pRes->info.rows > 0) { + pArithInfo->existDataBlock = pBlock; + clearNumOfRes(pInfo->pCtx, pOperator->numOfOutput); + return pInfo->pRes; + } + + STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current; // todo dynamic set tags - setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput); + if (pTableQueryInfo != NULL) { + setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput); + } // the pDataBlock are always the same one, no need to call this again setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order); - updateOutputBuf(pArithInfo, pBlock->info.rows); + updateOutputBuf(&pArithInfo->binfo, &pArithInfo->bufCapacity, pBlock->info.rows); arithmeticApplyFunctions(pRuntimeEnv, pInfo->pCtx, pOperator->numOfOutput); - updateTableIdInfo(pTableQueryInfo, pBlock, pRuntimeEnv->pTableRetrieveTsMap, order); + + if (pTableQueryInfo != NULL) { // TODO refactor + updateTableIdInfo(pTableQueryInfo, pBlock, pRuntimeEnv->pTableRetrieveTsMap, order); + } pRes->info.rows = getNumOfResult(pRuntimeEnv, pInfo->pCtx, pOperator->numOfOutput); if (pRes->info.rows >= pRuntimeEnv->resultInfo.threshold) { @@ -4793,24 +4949,46 @@ static SSDataBlock* doArithmeticOperation(void* param) { return (pInfo->pRes->info.rows > 0)? pInfo->pRes:NULL; } -static SSDataBlock* doLimit(void* param) { - SOperatorInfo* pOperator = (SOperatorInfo*) param; +static SSDataBlock* doLimit(void* param, bool* newgroup) { + SOperatorInfo* pOperator = (SOperatorInfo*)param; if (pOperator->status == OP_EXEC_DONE) { return NULL; } SLimitOperatorInfo* pInfo = pOperator->info; + SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; - SSDataBlock* pBlock = pOperator->upstream->exec(pOperator->upstream); - if (pBlock == NULL) { - setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); - pOperator->status = OP_EXEC_DONE; - return NULL; + SSDataBlock* pBlock = NULL; + while (1) { + pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + if (pBlock == NULL) { + setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); + pOperator->status = OP_EXEC_DONE; + return NULL; + } + + if (pRuntimeEnv->currentOffset == 0) { + break; + } else if (pRuntimeEnv->currentOffset >= pBlock->info.rows) { + pRuntimeEnv->currentOffset -= pBlock->info.rows; + } else { + int32_t remain = (int32_t)(pBlock->info.rows - pRuntimeEnv->currentOffset); + pBlock->info.rows = remain; + + 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, pColInfoData->pData + bytes * pRuntimeEnv->currentOffset, remain * bytes); + } + + pRuntimeEnv->currentOffset = 0; + break; + } } if (pInfo->total + pBlock->info.rows >= pInfo->limit) { - pBlock->info.rows = (int32_t) (pInfo->limit - pInfo->total); - + pBlock->info.rows = (int32_t)(pInfo->limit - pInfo->total); pInfo->total = pInfo->limit; setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); @@ -4822,44 +5000,6 @@ static SSDataBlock* doLimit(void* param) { return pBlock; } -// TODO add log -static SSDataBlock* doOffset(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; - } - - if (pRuntimeEnv->currentOffset == 0) { - return pBlock; - } else if (pRuntimeEnv->currentOffset >= pBlock->info.rows) { - pRuntimeEnv->currentOffset -= pBlock->info.rows; - } else { - int32_t remain = (int32_t)(pBlock->info.rows - pRuntimeEnv->currentOffset); - pBlock->info.rows = remain; - - 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, pColInfoData->pData + bytes * pRuntimeEnv->currentOffset, remain * bytes); - } - - pRuntimeEnv->currentOffset = 0; - return pBlock; - } - } -} - bool doFilterData(SColumnInfoData* p, int32_t rid, SColumnFilterElem *filterElem, __filter_func_t fp) { char* input = p->pData + p->info.bytes * rid; @@ -4873,7 +5013,7 @@ bool doFilterData(SColumnInfoData* p, int32_t rid, SColumnFilterElem *filterElem return false; } } - + if (fp(filterElem, input, input, p->info.type)) { return true; } @@ -4881,91 +5021,36 @@ bool doFilterData(SColumnInfoData* p, int32_t rid, SColumnFilterElem *filterElem 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) { +static SSDataBlock* doFilter(void* param, bool* newgroup) { SOperatorInfo *pOperator = (SOperatorInfo *)param; if (pOperator->status == OP_EXEC_DONE) { return NULL; } + SFilterOperatorInfo* pCondInfo = pOperator->info; SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; while (1) { - SSDataBlock *pBlock = pOperator->upstream->exec(pOperator->upstream); + SSDataBlock *pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); if (pBlock == NULL) { - setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); - pOperator->status = OP_EXEC_DONE; - return NULL; + break; } - - doHavingImpl(pOperator, pBlock); - return pBlock; + doSetFilterColumnInfo(pCondInfo->pFilterInfo, pCondInfo->numOfFilterCols, pBlock); + assert(pRuntimeEnv->pTsBuf == NULL); + filterRowsInDataBlock(pRuntimeEnv, pCondInfo->pFilterInfo, pCondInfo->numOfFilterCols, pBlock, true); + + if (pBlock->info.rows > 0) { + return pBlock; + } } + + setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); + pOperator->status = OP_EXEC_DONE; + return NULL; } - -static SSDataBlock* doIntervalAgg(void* param) { +static SSDataBlock* doIntervalAgg(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; if (pOperator->status == OP_EXEC_DONE) { return NULL; @@ -4984,26 +5069,26 @@ static SSDataBlock* doIntervalAgg(void* param) { return pIntervalInfo->pRes; } - SQuery* pQuery = pRuntimeEnv->pQuery; - int32_t order = pQuery->order.order; - STimeWindow win = pQuery->window; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int32_t order = pQueryAttr->order.order; + STimeWindow win = pQueryAttr->window; SOperatorInfo* upstream = pOperator->upstream; while(1) { - SSDataBlock* pBlock = upstream->exec(upstream); + SSDataBlock* pBlock = upstream->exec(upstream, newgroup); if (pBlock == NULL) { break; } // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pOperator, pIntervalInfo->pCtx, pBlock, pQuery->order.order); + setInputDataBlock(pOperator, pIntervalInfo->pCtx, pBlock, pQueryAttr->order.order); hashIntervalAgg(pOperator, &pIntervalInfo->resultRowInfo, pBlock, 0); } // restore the value - pQuery->order.order = order; - pQuery->window = win; + pQueryAttr->order.order = order; + pQueryAttr->window = win; pOperator->status = OP_RES_TO_RETURN; closeAllResultRows(&pIntervalInfo->resultRowInfo); @@ -5020,7 +5105,7 @@ static SSDataBlock* doIntervalAgg(void* param) { return pIntervalInfo->pRes->info.rows == 0? NULL:pIntervalInfo->pRes; } -static SSDataBlock* doSTableIntervalAgg(void* param) { +static SSDataBlock* doSTableIntervalAgg(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; if (pOperator->status == OP_EXEC_DONE) { return NULL; @@ -5038,29 +5123,29 @@ static SSDataBlock* doSTableIntervalAgg(void* param) { return pIntervalInfo->pRes; } - SQuery* pQuery = pRuntimeEnv->pQuery; - int32_t order = pQuery->order.order; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int32_t order = pQueryAttr->order.order; SOperatorInfo* upstream = pOperator->upstream; while(1) { - SSDataBlock* pBlock = upstream->exec(upstream); + SSDataBlock* pBlock = upstream->exec(upstream, newgroup); if (pBlock == NULL) { break; } // the pDataBlock are always the same one, no need to call this again - STableQueryInfo* pTableQueryInfo = pRuntimeEnv->pQuery->current; + STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current; setTagValue(pOperator, pTableQueryInfo->pTable, pIntervalInfo->pCtx, pOperator->numOfOutput); - setInputDataBlock(pOperator, pIntervalInfo->pCtx, pBlock, pQuery->order.order); + setInputDataBlock(pOperator, pIntervalInfo->pCtx, pBlock, pQueryAttr->order.order); setIntervalQueryRange(pRuntimeEnv, pBlock->info.window.skey); hashIntervalAgg(pOperator, &pTableQueryInfo->resInfo, pBlock, pTableQueryInfo->groupIndex); } pOperator->status = OP_RES_TO_RETURN; - pQuery->order.order = order; // TODO : restore the order + pQueryAttr->order.order = order; // TODO : restore the order doCloseAllTimeWindow(pRuntimeEnv); setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); @@ -5072,7 +5157,7 @@ static SSDataBlock* doSTableIntervalAgg(void* param) { return pIntervalInfo->pRes; } -static SSDataBlock* doSessionWindowAgg(void* param) { +static SSDataBlock* doSessionWindowAgg(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; if (pOperator->status == OP_EXEC_DONE) { return NULL; @@ -5092,26 +5177,26 @@ static SSDataBlock* doSessionWindowAgg(void* param) { return pBInfo->pRes; } - SQuery* pQuery = pRuntimeEnv->pQuery; - int32_t order = pQuery->order.order; - STimeWindow win = pQuery->window; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int32_t order = pQueryAttr->order.order; + STimeWindow win = pQueryAttr->window; SOperatorInfo* upstream = pOperator->upstream; while(1) { - SSDataBlock* pBlock = upstream->exec(upstream); + SSDataBlock* pBlock = upstream->exec(upstream, newgroup); if (pBlock == NULL) { break; } // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, pQuery->order.order); + setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, pQueryAttr->order.order); doSessionWindowAggImpl(pOperator, pWindowInfo, pBlock); } // restore the value - pQuery->order.order = order; - pQuery->window = win; + pQueryAttr->order.order = order; + pQueryAttr->window = win; pOperator->status = OP_RES_TO_RETURN; closeAllResultRows(&pBInfo->resultRowInfo); @@ -5128,7 +5213,7 @@ static SSDataBlock* doSessionWindowAgg(void* param) { return pBInfo->pRes->info.rows == 0? NULL:pBInfo->pRes; } -static SSDataBlock* hashGroupbyAggregate(void* param) { +static SSDataBlock* hashGroupbyAggregate(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; if (pOperator->status == OP_EXEC_DONE) { return NULL; @@ -5150,16 +5235,16 @@ static SSDataBlock* hashGroupbyAggregate(void* param) { SOperatorInfo* upstream = pOperator->upstream; while(1) { - SSDataBlock* pBlock = upstream->exec(upstream); + SSDataBlock* pBlock = upstream->exec(upstream, newgroup); if (pBlock == NULL) { break; } // the pDataBlock are always the same one, no need to call this again - setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, pRuntimeEnv->pQuery->order.order); - setTagValue(pOperator, pRuntimeEnv->pQuery->current->pTable, pInfo->binfo.pCtx, pOperator->numOfOutput); + setInputDataBlock(pOperator, pInfo->binfo.pCtx, pBlock, pRuntimeEnv->pQueryAttr->order.order); + setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->binfo.pCtx, pOperator->numOfOutput); if (pInfo->colIndex == -1) { - pInfo->colIndex = getGroupbyColumnIndex(pRuntimeEnv->pQuery->pGroupbyExpr, pBlock); + pInfo->colIndex = getGroupbyColumnIndex(pRuntimeEnv->pQueryAttr->pGroupbyExpr, pBlock); } doHashGroupbyAgg(pOperator, pInfo, pBlock); @@ -5169,7 +5254,7 @@ static SSDataBlock* hashGroupbyAggregate(void* param) { closeAllResultRows(&pInfo->binfo.resultRowInfo); setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); - if (!pRuntimeEnv->pQuery->stableQuery) { // finalize include the update of result rows + if (!pRuntimeEnv->pQueryAttr->stableQuery) { // finalize include the update of result rows finalizeQueryResult(pOperator, pInfo->binfo.pCtx, &pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset); } else { updateNumOfRowsInResultRows(pRuntimeEnv, pInfo->binfo.pCtx, pOperator->numOfOutput, &pInfo->binfo.resultRowInfo, pInfo->binfo.rowCellInfoOffset); @@ -5185,47 +5270,96 @@ static SSDataBlock* hashGroupbyAggregate(void* param) { return pInfo->binfo.pRes; } -static SSDataBlock* doFill(void* param) { +static SSDataBlock* doFill(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; if (pOperator->status == OP_EXEC_DONE) { return NULL; } SFillOperatorInfo *pInfo = pOperator->info; - SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv; + SQueryRuntimeEnv *pRuntimeEnv = pOperator->pRuntimeEnv; if (taosFillHasMoreResults(pInfo->pFillInfo)) { + *newgroup = false; doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, (int32_t)pRuntimeEnv->resultInfo.capacity); return pInfo->pRes; } + // handle the cached new group data block + if (pInfo->existNewGroupBlock) { + pInfo->totalInputRows = pInfo->existNewGroupBlock->info.rows; + int64_t ekey = Q_STATUS_EQUAL(pRuntimeEnv->status, QUERY_COMPLETED)?pRuntimeEnv->pQueryAttr->window.ekey:pInfo->existNewGroupBlock->info.window.ekey; + taosResetFillInfo(pInfo->pFillInfo, pInfo->pFillInfo->start); + + taosFillSetStartInfo(pInfo->pFillInfo, pInfo->existNewGroupBlock->info.rows, ekey); + taosFillSetInputDataBlock(pInfo->pFillInfo, pInfo->existNewGroupBlock); + + doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, pRuntimeEnv->resultInfo.capacity); + pInfo->existNewGroupBlock = NULL; + *newgroup = true; + return (pInfo->pRes->info.rows > 0)? pInfo->pRes:NULL; + } + while(1) { - SSDataBlock *pBlock = pOperator->upstream->exec(pOperator->upstream); - if (pBlock == NULL) { - if (pInfo->totalInputRows == 0) { - pOperator->status = OP_EXEC_DONE; - return NULL; - } + SSDataBlock* pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + if (*newgroup) { + assert(pBlock != NULL); + } - taosFillSetStartInfo(pInfo->pFillInfo, 0, pRuntimeEnv->pQuery->window.ekey); + if (*newgroup && pInfo->totalInputRows > 0) { // there are already processed current group data block + pInfo->existNewGroupBlock = pBlock; + *newgroup = false; + + // fill the previous group data block + // before handle a new data block, close the fill operation for previous group data block + taosFillSetStartInfo(pInfo->pFillInfo, 0, pRuntimeEnv->pQueryAttr->window.ekey); } else { - pInfo->totalInputRows += pBlock->info.rows; + if (pBlock == NULL) { + if (pInfo->totalInputRows == 0) { + pOperator->status = OP_EXEC_DONE; + return NULL; + } - int64_t ekey = Q_STATUS_EQUAL(pRuntimeEnv->status, QUERY_COMPLETED)?pRuntimeEnv->pQuery->window.ekey:pBlock->info.window.ekey; + taosFillSetStartInfo(pInfo->pFillInfo, 0, pRuntimeEnv->pQueryAttr->window.ekey); + } else { + pInfo->totalInputRows += pBlock->info.rows; - taosFillSetStartInfo(pInfo->pFillInfo, pBlock->info.rows, ekey); - taosFillSetInputDataBlock(pInfo->pFillInfo, pBlock); + int64_t ekey = /*Q_STATUS_EQUAL(pRuntimeEnv->status, QUERY_COMPLETED) ? pRuntimeEnv->pQueryAttr->window.ekey + : */pBlock->info.window.ekey; + + taosFillSetStartInfo(pInfo->pFillInfo, pBlock->info.rows, ekey); + taosFillSetInputDataBlock(pInfo->pFillInfo, pBlock); + } } doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, pRuntimeEnv->resultInfo.capacity); - return (pInfo->pRes->info.rows > 0)? pInfo->pRes:NULL; + if (pInfo->pRes->info.rows > 0) { // current group has no more result to return + return pInfo->pRes; + } else if (pInfo->existNewGroupBlock) { // try next group + pInfo->totalInputRows = pInfo->existNewGroupBlock->info.rows; + int64_t ekey = /*Q_STATUS_EQUAL(pRuntimeEnv->status, QUERY_COMPLETED) ? pRuntimeEnv->pQueryAttr->window.ekey + :*/ pInfo->existNewGroupBlock->info.window.ekey; + taosResetFillInfo(pInfo->pFillInfo, pInfo->pFillInfo->start); + + taosFillSetStartInfo(pInfo->pFillInfo, pInfo->existNewGroupBlock->info.rows, ekey); + taosFillSetInputDataBlock(pInfo->pFillInfo, pInfo->existNewGroupBlock); + + doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, pRuntimeEnv->resultInfo.capacity); + pInfo->existNewGroupBlock = NULL; + *newgroup = true; + + return (pInfo->pRes->info.rows > 0) ? pInfo->pRes : NULL; + } else { + return NULL; + } + // return (pInfo->pRes->info.rows > 0)? pInfo->pRes:NULL; } } // todo set the attribute of query scan count -static int32_t getNumOfScanTimes(SQuery* pQuery) { - for(int32_t i = 0; i < pQuery->numOfOutput; ++i) { - int32_t functionId = pQuery->pExpr1[i].base.functionId; +static int32_t getNumOfScanTimes(SQueryAttr* pQueryAttr) { + for(int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { + int32_t functionId = pQueryAttr->pExpr1[i].base.functionId; if (functionId == TSDB_FUNC_STDDEV || functionId == TSDB_FUNC_PERCT) { return 2; } @@ -5248,11 +5382,11 @@ static void destroyOperatorInfo(SOperatorInfo* pOperator) { tfree(pOperator); } -static SOperatorInfo* createAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { +SOperatorInfo* createAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { SAggOperatorInfo* pInfo = calloc(1, sizeof(SAggOperatorInfo)); - SQuery* pQuery = pRuntimeEnv->pQuery; - int32_t numOfRows = (int32_t)(GET_ROW_PARAM_FOR_MULTIOUTPUT(pQuery, pQuery->topBotQuery, pQuery->stableQuery)); + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + int32_t numOfRows = (int32_t)(GET_ROW_PARAM_FOR_MULTIOUTPUT(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery)); pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, numOfRows); pInfo->binfo.pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset); @@ -5260,7 +5394,7 @@ static SOperatorInfo* createAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, initResultRowInfo(&pInfo->binfo.resultRowInfo, 8, TSDB_DATA_TYPE_INT); pInfo->seed = rand(); - setDefaultOutputBuf(pRuntimeEnv, &pInfo->binfo, pInfo->seed); + setDefaultOutputBuf(pRuntimeEnv, &pInfo->binfo, pInfo->seed, MASTER_SCAN); SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); pOperator->name = "TableAggregate"; @@ -5315,11 +5449,15 @@ 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); - } +static void destroyConditionOperatorInfo(void* param, int32_t numOfOutput) { + SFilterOperatorInfo* pInfo = (SFilterOperatorInfo*) param; + doDestroyFilterInfo(pInfo->pFilterInfo, pInfo->numOfFilterCols); +} + +static void destroyDistinctOperatorInfo(void* param, int32_t numOfOutput) { + SDistinctOperatorInfo* pInfo = (SDistinctOperatorInfo*) param; + taosHashCleanup(pInfo->pSet); + pInfo->pRes = destroyOutputBuf(pInfo->pRes); } SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { @@ -5359,7 +5497,7 @@ SOperatorInfo* createArithOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorI pBInfo->pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pBInfo->rowCellInfoOffset); initResultRowInfo(&pBInfo->resultRowInfo, 8, TSDB_DATA_TYPE_INT); - setDefaultOutputBuf(pRuntimeEnv, pBInfo, pInfo->seed); + setDefaultOutputBuf(pRuntimeEnv, pBInfo, pInfo->seed, MASTER_SCAN); SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); pOperator->name = "ArithmeticOperator"; @@ -5378,86 +5516,59 @@ SOperatorInfo* createArithOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorI return pOperator; } +SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, + int32_t numOfOutput) { + SFilterOperatorInfo* pInfo = calloc(1, sizeof(SFilterOperatorInfo)); -int32_t initFilterFp(SExprInfo* pExpr, int32_t numOfOutput, SArray** fps) { - __filter_func_t fp = NULL; + { + SColumnInfo* pCols = calloc(numOfOutput, sizeof(SColumnInfo)); - *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; + int32_t numOfFilter = 0; + for(int32_t i = 0; i < numOfOutput; ++i) { + if (pExpr[i].base.flist.numOfFilters > 0) { + numOfFilter += 1; } - __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; + pCols[i].type = pExpr[i].base.resType; + pCols[i].bytes = pExpr[i].base.resBytes; + pCols[i].colId = pExpr[i].base.resColId; + + pCols[i].flist.numOfFilters = pExpr[i].base.flist.numOfFilters; + pCols[i].flist.filterInfo = calloc(pCols[i].flist.numOfFilters, sizeof(SColumnFilterInfo)); + memcpy(pCols[i].flist.filterInfo, pExpr[i].base.flist.filterInfo, pCols[i].flist.numOfFilters * sizeof(SColumnFilterInfo)); } - taosArrayPush(*fps, &es); + assert(numOfFilter > 0); + doCreateFilterInfo(pCols, numOfOutput, numOfFilter, &pInfo->pFilterInfo, 0); + pInfo->numOfFilterCols = numOfFilter; + + for(int32_t i = 0; i < numOfOutput; ++i) { + tfree(pCols[i].flist.filterInfo); + } + + tfree(pCols); } - 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->name = "ConditionOperator"; + pOperator->operatorType = OP_Filter; pOperator->blockingOptr = false; pOperator->status = OP_IN_EXECUTING; pOperator->numOfOutput = numOfOutput; pOperator->pExpr = pExpr; pOperator->upstream = upstream; - pOperator->exec = doHaving; + pOperator->exec = doFilter; pOperator->info = pInfo; pOperator->pRuntimeEnv = pRuntimeEnv; - pOperator->cleanup = destroyHavingOperatorInfo; + pOperator->cleanup = destroyConditionOperatorInfo; return pOperator; } - - SOperatorInfo* createLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream) { SLimitOperatorInfo* pInfo = calloc(1, sizeof(SLimitOperatorInfo)); - pInfo->limit = pRuntimeEnv->pQuery->limit.limit; + pInfo->limit = pRuntimeEnv->pQueryAttr->limit.limit; SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); @@ -5473,24 +5584,6 @@ SOperatorInfo* createLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorI return pOperator; } -SOperatorInfo* createOffsetOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream) { - SOffsetOperatorInfo* pInfo = calloc(1, sizeof(SOffsetOperatorInfo)); - - pInfo->offset = pRuntimeEnv->pQuery->limit.offset; - SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); - - pOperator->name = "OffsetOperator"; - pOperator->operatorType = OP_Offset; - pOperator->blockingOptr = false; - pOperator->status = OP_IN_EXECUTING; - pOperator->upstream = upstream; - pOperator->exec = doOffset; - pOperator->info = pInfo; - pOperator->pRuntimeEnv = pRuntimeEnv; - - return pOperator; -} - SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { STableIntervalOperatorInfo* pInfo = calloc(1, sizeof(STableIntervalOperatorInfo)); @@ -5594,17 +5687,18 @@ SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorIn pInfo->pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity); { - SQuery* pQuery = pRuntimeEnv->pQuery; - SFillColInfo* pColInfo = createFillColInfo(pExpr, numOfOutput, pQuery->fillVal); + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + SFillColInfo* pColInfo = createFillColInfo(pExpr, numOfOutput, pQueryAttr->fillVal); STimeWindow w = TSWINDOW_INITIALIZER; - TSKEY sk = MIN(pQuery->window.skey, pQuery->window.ekey); - TSKEY ek = MAX(pQuery->window.skey, pQuery->window.ekey); - getAlignQueryTimeWindow(pQuery, pQuery->window.skey, sk, ek, &w); + TSKEY sk = MIN(pQueryAttr->window.skey, pQueryAttr->window.ekey); + TSKEY ek = MAX(pQueryAttr->window.skey, pQueryAttr->window.ekey); + getAlignQueryTimeWindow(pQueryAttr, pQueryAttr->window.skey, sk, ek, &w); - pInfo->pFillInfo = taosCreateFillInfo(pQuery->order.order, w.skey, 0, (int32_t)pRuntimeEnv->resultInfo.capacity, numOfOutput, - pQuery->interval.sliding, pQuery->interval.slidingUnit, (int8_t)pQuery->precision, - pQuery->fillType, pColInfo, pRuntimeEnv->qinfo); + pInfo->pFillInfo = + taosCreateFillInfo(pQueryAttr->order.order, w.skey, 0, (int32_t)pRuntimeEnv->resultInfo.capacity, numOfOutput, + pQueryAttr->interval.sliding, pQueryAttr->interval.slidingUnit, + (int8_t)pQueryAttr->precision, pQueryAttr->fillType, pColInfo, pRuntimeEnv->qinfo); } SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); @@ -5626,7 +5720,50 @@ SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorIn return pOperator; } -static SSDataBlock* doTagScan(void* param) { +SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* pMerger) { + SSLimitOperatorInfo* pInfo = calloc(1, sizeof(SSLimitOperatorInfo)); + + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + + pInfo->orderColumnList = getResultGroupCheckColumns(pQueryAttr); + pInfo->slimit = pQueryAttr->slimit; + pInfo->limit = pQueryAttr->limit; + + pInfo->currentGroupOffset = pQueryAttr->slimit.offset; + pInfo->currentOffset = pQueryAttr->limit.offset; + + // TODO refactor + int32_t len = 0; + for(int32_t i = 0; i < numOfOutput; ++i) { + len += pExpr[i].base.resBytes; + } + + int32_t numOfCols = pInfo->orderColumnList != NULL? (int32_t) taosArrayGetSize(pInfo->orderColumnList):0; + pInfo->prevRow = calloc(1, (POINTER_BYTES * numOfCols + len)); + int32_t offset = POINTER_BYTES * numOfCols; + + for(int32_t i = 0; i < numOfCols; ++i) { + pInfo->prevRow[i] = (char*)pInfo->prevRow + offset; + + SColIndex* index = taosArrayGet(pInfo->orderColumnList, i); + offset += pExpr[index->colIndex].base.resBytes; + } + + SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); + + pOperator->name = "SLimitOperator"; + pOperator->operatorType = OP_SLimit; + pOperator->blockingOptr = false; + pOperator->status = OP_IN_EXECUTING; + pOperator->upstream = upstream; + pOperator->exec = doSLimit; + pOperator->info = pInfo; + pOperator->pRuntimeEnv = pRuntimeEnv; + pOperator->cleanup = destroySlimitOperatorInfo; + return pOperator; +} + +static SSDataBlock* doTagScan(void* param, bool* newgroup) { SOperatorInfo* pOperator = (SOperatorInfo*) param; if (pOperator->status == OP_EXEC_DONE) { return NULL; @@ -5638,27 +5775,28 @@ static SSDataBlock* doTagScan(void* param) { STagScanInfo *pInfo = pOperator->info; SSDataBlock *pRes = pInfo->pRes; + *newgroup = false; int32_t count = 0; SArray* pa = GET_TABLEGROUP(pRuntimeEnv, 0); int32_t functionId = pOperator->pExpr[0].base.functionId; if (functionId == TSDB_FUNC_TID_TAG) { // return the tags & table Id - SQuery* pQuery = pRuntimeEnv->pQuery; - assert(pQuery->numOfOutput == 1); + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + assert(pQueryAttr->numOfOutput == 1); SExprInfo* pExprInfo = &pOperator->pExpr[0]; - int32_t rsize = pExprInfo->bytes; + int32_t rsize = pExprInfo->base.resBytes; count = 0; - int16_t bytes = pExprInfo->bytes; - int16_t type = pExprInfo->type; + int16_t bytes = pExprInfo->base.resBytes; + int16_t type = pExprInfo->base.resType; - for(int32_t i = 0; i < pQuery->numOfTags; ++i) { - if (pQuery->tagColList[i].colId == pExprInfo->base.colInfo.colId) { - bytes = pQuery->tagColList[i].bytes; - type = pQuery->tagColList[i].type; + for(int32_t i = 0; i < pQueryAttr->numOfTags; ++i) { + if (pQueryAttr->tagColList[i].colId == pExprInfo->base.colInfo.colId) { + bytes = pQueryAttr->tagColList[i].bytes; + type = pQueryAttr->tagColList[i].type; break; } } @@ -5684,8 +5822,8 @@ static SSDataBlock* doTagScan(void* param) { *(int32_t *)output = id->tid; output += sizeof(id->tid); - *(int32_t *)output = pQuery->vgId; - output += sizeof(pQuery->vgId); + *(int32_t *)output = pQueryAttr->vgId; + output += sizeof(pQueryAttr->vgId); char* data = NULL; if (pExprInfo->base.colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) { @@ -5698,14 +5836,14 @@ static SSDataBlock* doTagScan(void* param) { count += 1; } - qDebug("QInfo:%"PRIu64" create (tableId, tag) info completed, rows:%d", GET_QID(pRuntimeEnv), count); + qDebug("QInfo:0x%"PRIx64" create (tableId, tag) info completed, rows:%d", GET_QID(pRuntimeEnv), count); } else if (functionId == TSDB_FUNC_COUNT) {// handle the "count(tbname)" query SColumnInfoData* pColInfo = taosArrayGet(pRes->pDataBlock, 0); *(int64_t*)pColInfo->pData = pInfo->totalTables; count = 1; pOperator->status = OP_EXEC_DONE; - qDebug("QInfo:%"PRIu64" create count(tbname) query, res:%d rows:1", GET_QID(pRuntimeEnv), count); + qDebug("QInfo:0x%"PRIx64" create count(tbname) query, res:%d rows:1", GET_QID(pRuntimeEnv), count); } else { // return only the tags|table name etc. SExprInfo* pExprInfo = pOperator->pExpr; // todo use the column list instead of exprinfo @@ -5724,8 +5862,8 @@ static SSDataBlock* doTagScan(void* param) { } SColumnInfoData* pColInfo = taosArrayGet(pRes->pDataBlock, j); - type = pExprInfo[j].type; - bytes = pExprInfo[j].bytes; + type = pExprInfo[j].base.resType; + bytes = pExprInfo[j].base.resBytes; if (pExprInfo[j].base.colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) { data = tsdbGetTableName(item->pTable); @@ -5733,7 +5871,7 @@ static SSDataBlock* doTagScan(void* param) { data = tsdbGetTableTagVal(item->pTable, pExprInfo[j].base.colInfo.colId, type, bytes); } - dst = pColInfo->pData + count * pExprInfo[j].bytes; + dst = pColInfo->pData + count * pExprInfo[j].base.resBytes; doSetTagValueToResultBuf(dst, data, type, bytes); } @@ -5744,7 +5882,7 @@ static SSDataBlock* doTagScan(void* param) { pOperator->status = OP_EXEC_DONE; } - qDebug("QInfo:%"PRIu64" create tag values results completed, rows:%d", GET_QID(pRuntimeEnv), count); + qDebug("QInfo:0x%"PRIx64" create tag values results completed, rows:%d", GET_QID(pRuntimeEnv), count); } pRes->info.rows = count; @@ -5776,30 +5914,112 @@ SOperatorInfo* createTagScanOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInf return pOperator; } -static int32_t getColumnIndexInSource(SQueryTableMsg *pQueryMsg, SSqlFuncMsg *pExprMsg, SColumnInfo* pTagCols) { +static SSDataBlock* hashDistinct(void* param, bool* newgroup) { + SOperatorInfo* pOperator = (SOperatorInfo*) param; + if (pOperator->status == OP_EXEC_DONE) { + return NULL; + } + + SDistinctOperatorInfo* pInfo = pOperator->info; + SSDataBlock* pRes = pInfo->pRes; + + pRes->info.rows = 0; + SSDataBlock* pBlock = NULL; + while(1) { + pBlock = pOperator->upstream->exec(pOperator->upstream, newgroup); + if (pBlock == NULL) { + setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED); + pOperator->status = OP_EXEC_DONE; + return NULL; + } + + assert(pBlock->info.numOfCols == 1); + SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, 0); + + int16_t bytes = pColInfoData->info.bytes; + int16_t type = pColInfoData->info.type; + + // ensure the output buffer size + SColumnInfoData* pResultColInfoData = taosArrayGet(pRes->pDataBlock, 0); + if (pRes->info.rows + pBlock->info.rows > pInfo->outputCapacity) { + int32_t newSize = pRes->info.rows + pBlock->info.rows; + char* tmp = realloc(pResultColInfoData->pData, newSize * bytes); + if (tmp == NULL) { + return NULL; + } else { + pResultColInfoData->pData = tmp; + pInfo->outputCapacity = newSize; + } + } + + for(int32_t i = 0; i < pBlock->info.rows; ++i) { + char* val = ((char*)pColInfoData->pData) + bytes * i; + if (isNull(val, type)) { + continue; + } + + void* res = taosHashGet(pInfo->pSet, val, bytes); + if (res == NULL) { + taosHashPut(pInfo->pSet, val, bytes, NULL, 0); + char* start = pResultColInfoData->pData + bytes * pInfo->pRes->info.rows; + memcpy(start, val, bytes); + pRes->info.rows += 1; + } + } + + if (pRes->info.rows >= pInfo->threshold) { + break; + } + } + + return (pInfo->pRes->info.rows > 0)? pInfo->pRes:NULL; +} + +SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) { + SDistinctOperatorInfo* pInfo = calloc(1, sizeof(SDistinctOperatorInfo)); + + pInfo->outputCapacity = 4096; + pInfo->pSet = taosHashInit(64, taosGetDefaultHashFunction(pExpr->base.colType), false, HASH_NO_LOCK); + pInfo->pRes = createOutputBuf(pExpr, numOfOutput, (int32_t) pInfo->outputCapacity); + + SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo)); + pOperator->name = "DistinctOperator"; + pOperator->blockingOptr = false; + pOperator->status = OP_IN_EXECUTING; + pOperator->operatorType = OP_Distinct; + pOperator->upstream = upstream; + pOperator->numOfOutput = numOfOutput; + pOperator->info = pInfo; + pOperator->pRuntimeEnv = pRuntimeEnv; + pOperator->exec = hashDistinct; + pOperator->cleanup = destroyDistinctOperatorInfo; + return pOperator; +} + +static int32_t getColumnIndexInSource(SQueriedTableInfo *pTableInfo, SSqlExpr *pExpr, SColumnInfo* pTagCols) { int32_t j = 0; - if (TSDB_COL_IS_TAG(pExprMsg->colInfo.flag)) { - if (pExprMsg->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) { + if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) { + if (pExpr->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) { return TSDB_TBNAME_COLUMN_INDEX; - } else if (pExprMsg->colInfo.colId == TSDB_BLOCK_DIST_COLUMN_INDEX) { + } else if (pExpr->colInfo.colId == TSDB_BLOCK_DIST_COLUMN_INDEX) { return TSDB_BLOCK_DIST_COLUMN_INDEX; } - while(j < pQueryMsg->numOfTags) { - if (pExprMsg->colInfo.colId == pTagCols[j].colId) { + while(j < pTableInfo->numOfTags) { + if (pExpr->colInfo.colId == pTagCols[j].colId) { return j; } j += 1; } - } else if (TSDB_COL_IS_UD_COL(pExprMsg->colInfo.flag)) { // user specified column data + } else if (TSDB_COL_IS_UD_COL(pExpr->colInfo.flag)) { // user specified column data return TSDB_UD_COLUMN_INDEX; } else { - while (j < pQueryMsg->numOfCols) { - if (pExprMsg->colInfo.colId == pQueryMsg->colList[j].colId) { + while (j < pTableInfo->numOfCols) { + if (pExpr->colInfo.colId == pTableInfo->colList[j].colId) { return j; } @@ -5810,8 +6030,8 @@ static int32_t getColumnIndexInSource(SQueryTableMsg *pQueryMsg, SSqlFuncMsg *pE return INT32_MIN; // return a less than TSDB_TBNAME_COLUMN_INDEX value } -bool validateExprColumnInfo(SQueryTableMsg *pQueryMsg, SSqlFuncMsg *pExprMsg, SColumnInfo* pTagCols) { - int32_t j = getColumnIndexInSource(pQueryMsg, pExprMsg, pTagCols); +bool validateExprColumnInfo(SQueriedTableInfo *pTableInfo, SSqlExpr *pExpr, SColumnInfo* pTagCols) { + int32_t j = getColumnIndexInSource(pTableInfo, pExpr, pTagCols); return j != INT32_MIN; } @@ -5850,21 +6070,21 @@ static bool validateQueryMsg(SQueryTableMsg *pQueryMsg) { return true; } -static bool validateQuerySourceCols(SQueryTableMsg *pQueryMsg, SSqlFuncMsg** pExprMsg, SColumnInfo* pTagCols) { - int32_t numOfTotal = pQueryMsg->numOfCols + pQueryMsg->numOfTags; - if (pQueryMsg->numOfCols < 0 || pQueryMsg->numOfTags < 0 || numOfTotal > TSDB_MAX_COLUMNS) { - qError("qmsg:%p illegal value of numOfCols %d numOfTags:%d", pQueryMsg, pQueryMsg->numOfCols, pQueryMsg->numOfTags); +static UNUSED_FUNC bool validateQueryTableCols(SQueriedTableInfo* pTableInfo, SSqlExpr** pExpr, int32_t numOfOutput, + SColumnInfo* pTagCols, void* pMsg) { + int32_t numOfTotal = pTableInfo->numOfCols + pTableInfo->numOfTags; + if (pTableInfo->numOfCols < 0 || pTableInfo->numOfTags < 0 || numOfTotal > TSDB_MAX_COLUMNS) { + qError("qmsg:%p illegal value of numOfCols %d numOfTags:%d", pMsg, pTableInfo->numOfCols, pTableInfo->numOfTags); return false; } - if (numOfTotal == 0) { - for(int32_t i = 0; i < pQueryMsg->numOfOutput; ++i) { - SSqlFuncMsg* pFuncMsg = pExprMsg[i]; - - if ((pFuncMsg->functionId == TSDB_FUNC_TAGPRJ) || - (pFuncMsg->functionId == TSDB_FUNC_TID_TAG && pFuncMsg->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) || - (pFuncMsg->functionId == TSDB_FUNC_COUNT && pFuncMsg->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) || - (pFuncMsg->functionId == TSDB_FUNC_BLKINFO)) { + if (numOfTotal == 0) { // table total columns are not required. + for(int32_t i = 0; i < numOfOutput; ++i) { + SSqlExpr* p = pExpr[i]; + if ((p->functionId == TSDB_FUNC_TAGPRJ) || + (p->functionId == TSDB_FUNC_TID_TAG && p->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) || + (p->functionId == TSDB_FUNC_COUNT && p->colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) || + (p->functionId == TSDB_FUNC_BLKINFO)) { continue; } @@ -5872,8 +6092,8 @@ static bool validateQuerySourceCols(SQueryTableMsg *pQueryMsg, SSqlFuncMsg** pEx } } - for(int32_t i = 0; i < pQueryMsg->numOfOutput; ++i) { - if (!validateExprColumnInfo(pQueryMsg, pExprMsg[i], pTagCols)) { + for(int32_t i = 0; i < numOfOutput; ++i) { + if (!validateExprColumnInfo(pTableInfo, pExpr[i], pTagCols)) { return TSDB_CODE_QRY_INVALID_MSG; } } @@ -5900,6 +6120,37 @@ static char *createTableIdList(SQueryTableMsg *pQueryMsg, char *pMsg, SArray **p return pMsg; } +static int32_t deserializeColFilterInfo(SColumnFilterInfo* pColFilters, int16_t numOfFilters, char** pMsg) { + for (int32_t f = 0; f < numOfFilters; ++f) { + SColumnFilterInfo *pFilterMsg = (SColumnFilterInfo *)(*pMsg); + + SColumnFilterInfo *pColFilter = &pColFilters[f]; + pColFilter->filterstr = htons(pFilterMsg->filterstr); + + (*pMsg) += sizeof(SColumnFilterInfo); + + if (pColFilter->filterstr) { + pColFilter->len = htobe64(pFilterMsg->len); + + pColFilter->pz = (int64_t)calloc(1, (size_t)(pColFilter->len + 1 * TSDB_NCHAR_SIZE)); // note: null-terminator + if (pColFilter->pz == 0) { + return TSDB_CODE_QRY_OUT_OF_MEMORY; + } + + memcpy((void *)pColFilter->pz, (*pMsg), (size_t)pColFilter->len); + (*pMsg) += (pColFilter->len + 1); + } else { + pColFilter->lowerBndi = htobe64(pFilterMsg->lowerBndi); + pColFilter->upperBndi = htobe64(pFilterMsg->upperBndi); + } + + pColFilter->lowerRelOptr = htons(pFilterMsg->lowerRelOptr); + pColFilter->upperRelOptr = htons(pFilterMsg->upperRelOptr); + } + + return TSDB_CODE_SUCCESS; +} + /** * pQueryMsg->head has been converted before this function is called. * @@ -5916,7 +6167,6 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { } pQueryMsg->numOfTables = htonl(pQueryMsg->numOfTables); - pQueryMsg->window.skey = htobe64(pQueryMsg->window.skey); pQueryMsg->window.ekey = htobe64(pQueryMsg->window.ekey); pQueryMsg->interval.interval = htobe64(pQueryMsg->interval.interval); @@ -5935,10 +6185,10 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { pQueryMsg->numOfOutput = htons(pQueryMsg->numOfOutput); pQueryMsg->numOfGroupCols = htons(pQueryMsg->numOfGroupCols); pQueryMsg->tagCondLen = htons(pQueryMsg->tagCondLen); - pQueryMsg->tsOffset = htonl(pQueryMsg->tsOffset); - pQueryMsg->tsLen = htonl(pQueryMsg->tsLen); - pQueryMsg->tsNumOfBlocks = htonl(pQueryMsg->tsNumOfBlocks); - pQueryMsg->tsOrder = htonl(pQueryMsg->tsOrder); + pQueryMsg->tsBuf.tsOffset = htonl(pQueryMsg->tsBuf.tsOffset); + pQueryMsg->tsBuf.tsLen = htonl(pQueryMsg->tsBuf.tsLen); + pQueryMsg->tsBuf.tsNumOfBlocks = htonl(pQueryMsg->tsBuf.tsNumOfBlocks); + pQueryMsg->tsBuf.tsOrder = htonl(pQueryMsg->tsBuf.tsOrder); pQueryMsg->numOfTags = htonl(pQueryMsg->numOfTags); pQueryMsg->tbnameCondLen = htonl(pQueryMsg->tbnameCondLen); pQueryMsg->secondStageOutput = htonl(pQueryMsg->secondStageOutput); @@ -5946,6 +6196,8 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { pQueryMsg->prevResultLen = htonl(pQueryMsg->prevResultLen); pQueryMsg->sw.gap = htobe64(pQueryMsg->sw.gap); pQueryMsg->sw.primaryColId = htonl(pQueryMsg->sw.primaryColId); + pQueryMsg->tableScanOperator = htonl(pQueryMsg->tableScanOperator); + pQueryMsg->numOfOperator = htonl(pQueryMsg->numOfOperator); pQueryMsg->udfContentOffset = htonl(pQueryMsg->udfContentOffset); pQueryMsg->udfContentLen = htonl(pQueryMsg->udfContentLen); pQueryMsg->udfNum = htonl(pQueryMsg->udfNum); @@ -5956,14 +6208,14 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { goto _cleanup; } - char *pMsg = (char *)(pQueryMsg->colList) + sizeof(SColumnInfo) * pQueryMsg->numOfCols; + char *pMsg = (char *)(pQueryMsg->tableCols) + sizeof(SColumnInfo) * pQueryMsg->numOfCols; for (int32_t col = 0; col < pQueryMsg->numOfCols; ++col) { - SColumnInfo *pColInfo = &pQueryMsg->colList[col]; + SColumnInfo *pColInfo = &pQueryMsg->tableCols[col]; pColInfo->colId = htons(pColInfo->colId); pColInfo->type = htons(pColInfo->type); pColInfo->bytes = htons(pColInfo->bytes); - pColInfo->numOfFilters = htons(pColInfo->numOfFilters); + pColInfo->flist.numOfFilters = htons(pColInfo->flist.numOfFilters); if (!isValidDataType(pColInfo->type)) { qDebug("qmsg:%p, invalid data type in source column, index:%d, type:%d", pQueryMsg, col, pColInfo->type); @@ -5971,102 +6223,57 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { goto _cleanup; } - int32_t numOfFilters = pColInfo->numOfFilters; + int32_t numOfFilters = pColInfo->flist.numOfFilters; if (numOfFilters > 0) { - pColInfo->filters = calloc(numOfFilters, sizeof(SColumnFilterInfo)); - if (pColInfo->filters == NULL) { + pColInfo->flist.filterInfo = calloc(numOfFilters, sizeof(SColumnFilterInfo)); + if (pColInfo->flist.filterInfo == NULL) { code = TSDB_CODE_QRY_OUT_OF_MEMORY; goto _cleanup; } } - for (int32_t f = 0; f < numOfFilters; ++f) { - SColumnFilterInfo *pFilterMsg = (SColumnFilterInfo *)pMsg; - - SColumnFilterInfo *pColFilter = &pColInfo->filters[f]; - pColFilter->filterstr = htons(pFilterMsg->filterstr); - - pMsg += sizeof(SColumnFilterInfo); - - if (pColFilter->filterstr) { - pColFilter->len = htobe64(pFilterMsg->len); - - pColFilter->pz = (int64_t)calloc(1, (size_t)(pColFilter->len + 1 * TSDB_NCHAR_SIZE)); // note: null-terminator - if (pColFilter->pz == 0) { - code = TSDB_CODE_QRY_OUT_OF_MEMORY; - goto _cleanup; - } - - memcpy((void *)pColFilter->pz, pMsg, (size_t)pColFilter->len); - pMsg += (pColFilter->len + 1); - } else { - pColFilter->lowerBndi = htobe64(pFilterMsg->lowerBndi); - pColFilter->upperBndi = htobe64(pFilterMsg->upperBndi); - } - - pColFilter->lowerRelOptr = htons(pFilterMsg->lowerRelOptr); - pColFilter->upperRelOptr = htons(pFilterMsg->upperRelOptr); + code = deserializeColFilterInfo(pColInfo->flist.filterInfo, numOfFilters, &pMsg); + if (code != TSDB_CODE_SUCCESS) { + goto _cleanup; } } - param->pExprMsg = calloc(pQueryMsg->numOfOutput, POINTER_BYTES); - if (param->pExprMsg == NULL) { + param->tableScanOperator = pQueryMsg->tableScanOperator; + param->pExpr = calloc(pQueryMsg->numOfOutput, POINTER_BYTES); + if (param->pExpr == NULL) { code = TSDB_CODE_QRY_OUT_OF_MEMORY; goto _cleanup; } - SSqlFuncMsg *pExprMsg = (SSqlFuncMsg *)pMsg; + SSqlExpr *pExprMsg = (SSqlExpr *)pMsg; for (int32_t i = 0; i < pQueryMsg->numOfOutput; ++i) { - param->pExprMsg[i] = pExprMsg; + param->pExpr[i] = pExprMsg; pExprMsg->colInfo.colIndex = htons(pExprMsg->colInfo.colIndex); pExprMsg->colInfo.colId = htons(pExprMsg->colInfo.colId); pExprMsg->colInfo.flag = htons(pExprMsg->colInfo.flag); - pExprMsg->colType = htons(pExprMsg->colType); pExprMsg->colBytes = htons(pExprMsg->colBytes); + pExprMsg->colType = htons(pExprMsg->colType); + + pExprMsg->resType = htons(pExprMsg->resType); + pExprMsg->resBytes = htons(pExprMsg->resBytes); 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++; - } + pExprMsg->flist.numOfFilters = htons(pExprMsg->flist.numOfFilters); + pMsg += sizeof(SSqlExpr); 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); + pExprMsg->param[j].nType = htons(pExprMsg->param[j].nType); + pExprMsg->param[j].nLen = htons(pExprMsg->param[j].nLen); - if (pExprMsg->arg[j].argType == TSDB_DATA_TYPE_BINARY) { - pExprMsg->arg[j].argValue.pz = pMsg; - pMsg += pExprMsg->arg[j].argBytes; // one more for the string terminated char. + if (pExprMsg->param[j].nType == TSDB_DATA_TYPE_BINARY) { + pExprMsg->param[j].pz = pMsg; + pMsg += pExprMsg->param[j].nLen; // one more for the string terminated char. } else { - pExprMsg->arg[j].argValue.i64 = htobe64(pExprMsg->arg[j].argValue.i64); + pExprMsg->param[j].i64 = htobe64(pExprMsg->param[j].i64); } } @@ -6078,36 +6285,43 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { } } - pExprMsg = (SSqlFuncMsg *)pMsg; + if (pExprMsg->flist.numOfFilters > 0) { + pExprMsg->flist.filterInfo = calloc(pExprMsg->flist.numOfFilters, sizeof(SColumnFilterInfo)); + } + + deserializeColFilterInfo(pExprMsg->flist.filterInfo, pExprMsg->flist.numOfFilters, &pMsg); + pExprMsg = (SSqlExpr *)pMsg; } if (pQueryMsg->secondStageOutput) { - pExprMsg = (SSqlFuncMsg *)pMsg; - param->pSecExprMsg = calloc(pQueryMsg->secondStageOutput, POINTER_BYTES); + pExprMsg = (SSqlExpr *)pMsg; + param->pSecExpr = calloc(pQueryMsg->secondStageOutput, POINTER_BYTES); for (int32_t i = 0; i < pQueryMsg->secondStageOutput; ++i) { - param->pSecExprMsg[i] = pExprMsg; + param->pSecExpr[i] = pExprMsg; pExprMsg->colInfo.colIndex = htons(pExprMsg->colInfo.colIndex); pExprMsg->colInfo.colId = htons(pExprMsg->colInfo.colId); pExprMsg->colInfo.flag = htons(pExprMsg->colInfo.flag); - pExprMsg->colType = htons(pExprMsg->colType); + pExprMsg->resType = htons(pExprMsg->resType); + pExprMsg->resBytes = htons(pExprMsg->resBytes); pExprMsg->colBytes = htons(pExprMsg->colBytes); + pExprMsg->colType = htons(pExprMsg->colType); pExprMsg->functionId = htons(pExprMsg->functionId); pExprMsg->numOfParams = htons(pExprMsg->numOfParams); - pMsg += sizeof(SSqlFuncMsg); + pMsg += sizeof(SSqlExpr); 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); + pExprMsg->param[j].nType = htons(pExprMsg->param[j].nType); + pExprMsg->param[j].nLen = htons(pExprMsg->param[j].nLen); - if (pExprMsg->arg[j].argType == TSDB_DATA_TYPE_BINARY) { - pExprMsg->arg[j].argValue.pz = pMsg; - pMsg += pExprMsg->arg[j].argBytes; // one more for the string terminated char. + if (pExprMsg->param[j].nType == TSDB_DATA_TYPE_BINARY) { + pExprMsg->param[j].pz = pMsg; + pMsg += pExprMsg->param[j].nLen; // one more for the string terminated char. } else { - pExprMsg->arg[j].argValue.i64 = htobe64(pExprMsg->arg[j].argValue.i64); + pExprMsg->param[j].i64 = htobe64(pExprMsg->param[j].i64); } } @@ -6119,7 +6333,7 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { } } - pExprMsg = (SSqlFuncMsg *)pMsg; + pExprMsg = (SSqlExpr *)pMsg; } } @@ -6175,7 +6389,7 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { pTagCol->colId = htons(pTagCol->colId); pTagCol->bytes = htons(pTagCol->bytes); pTagCol->type = htons(pTagCol->type); - pTagCol->numOfFilters = 0; + pTagCol->flist.numOfFilters = 0; param->pTagColumnInfo[i] = *pTagCol; pMsg += sizeof(SColumnInfo); @@ -6217,8 +6431,16 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { } //skip ts buf - if ((pQueryMsg->tsOffset + pQueryMsg->tsLen) > 0) { - pMsg = (char *)pQueryMsg + pQueryMsg->tsOffset + pQueryMsg->tsLen; + if ((pQueryMsg->tsBuf.tsOffset + pQueryMsg->tsBuf.tsLen) > 0) { + pMsg = (char *)pQueryMsg + pQueryMsg->tsBuf.tsOffset + pQueryMsg->tsBuf.tsLen; + } + + param->pOperator = taosArrayInit(pQueryMsg->numOfOperator, sizeof(int32_t)); + for(int32_t i = 0; i < pQueryMsg->numOfOperator; ++i) { + int32_t op = htonl(*(int32_t*)pMsg); + taosArrayPush(param->pOperator, &op); + + pMsg += sizeof(int32_t); } if (pQueryMsg->udfContentLen > 0) { @@ -6241,7 +6463,7 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { param->pUdfInfo->bufSize = htonl(*(int32_t*)pMsg); pMsg += sizeof(int32_t); - + param->pUdfInfo->content = malloc(pQueryMsg->udfContentLen); memcpy(param->pUdfInfo->content, pMsg, pQueryMsg->udfContentLen); @@ -6250,7 +6472,8 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { param->sql = strndup(pMsg, pQueryMsg->sqlstrLen); - if (!validateQuerySourceCols(pQueryMsg, param->pExprMsg, param->pTagColumnInfo)) { + SQueriedTableInfo info = { .numOfTags = pQueryMsg->numOfTags, .numOfCols = pQueryMsg->numOfCols, .colList = pQueryMsg->tableCols}; + if (!validateQueryTableCols(&info, param->pExpr, pQueryMsg->numOfOutput, param->pTagColumnInfo, pQueryMsg)) { code = TSDB_CODE_QRY_INVALID_MSG; goto _cleanup; } @@ -6259,7 +6482,7 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) { "outputCols:%d, numOfCols:%d, interval:%" PRId64 ", fillType:%d, comptsLen:%d, compNumOfBlocks:%d, limit:%" PRId64 ", offset:%" PRId64, pQueryMsg, pQueryMsg->numOfTables, pQueryMsg->queryType, pQueryMsg->window.skey, pQueryMsg->window.ekey, pQueryMsg->numOfGroupCols, pQueryMsg->order, pQueryMsg->numOfOutput, pQueryMsg->numOfCols, pQueryMsg->interval.interval, - pQueryMsg->fillType, pQueryMsg->tsLen, pQueryMsg->tsNumOfBlocks, pQueryMsg->limit, pQueryMsg->offset); + pQueryMsg->fillType, pQueryMsg->tsBuf.tsLen, pQueryMsg->tsBuf.tsNumOfBlocks, pQueryMsg->limit, pQueryMsg->offset); qDebug("qmsg:%p, sql:%s", pQueryMsg, param->sql); return TSDB_CODE_SUCCESS; @@ -6269,75 +6492,75 @@ _cleanup: return code; } -int32_t cloneExprFilterInfo(SColumnFilterInfo **dst, SColumnFilterInfo* src, int32_t filterNum) { - if (filterNum <= 0) { + 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; } - *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) { +int32_t buildArithmeticExprFromMsg(SExprInfo *pExprInfo, void *pQueryMsg) { qDebug("qmsg:%p create arithmetic expr from binary", pQueryMsg); tExprNode* pExprNode = NULL; TRY(TSDB_MAX_TAG_CONDITIONS) { - pExprNode = exprTreeFromBinary(pArithExprInfo->base.arg[0].argValue.pz, pArithExprInfo->base.arg[0].argBytes); + pExprNode = exprTreeFromBinary(pExprInfo->base.param[0].pz, pExprInfo->base.param[0].nLen); } CATCH( code ) { CLEANUP_EXECUTE(); - qError("qmsg:%p failed to create arithmetic expression string from:%s, reason: %s", pQueryMsg, pArithExprInfo->base.arg[0].argValue.pz, tstrerror(code)); + qError("qmsg:%p failed to create arithmetic expression string from:%s, reason: %s", pQueryMsg, pExprInfo->base.param[0].pz, tstrerror(code)); return code; } END_TRY if (pExprNode == NULL) { - qError("qmsg:%p failed to create arithmetic expression string from:%s", pQueryMsg, pArithExprInfo->base.arg[0].argValue.pz); + qError("qmsg:%p failed to create arithmetic expression string from:%s", pQueryMsg, pExprInfo->base.param[0].pz); return TSDB_CODE_QRY_APP_ERROR; } - pArithExprInfo->pExpr = pExprNode; + pExprInfo->pExpr = pExprNode; return TSDB_CODE_SUCCESS; } -static int32_t updateOutputBufForTopBotQuery(SQueryTableMsg* pQueryMsg, SColumnInfo* pTagCols, SExprInfo* pExprs, int32_t numOfOutput, int32_t tagLen, bool superTable) { + +static int32_t updateOutputBufForTopBotQuery(SQueriedTableInfo* pTableInfo, SColumnInfo* pTagCols, SExprInfo* pExprs, int32_t numOfOutput, int32_t tagLen, bool superTable) { for (int32_t i = 0; i < numOfOutput; ++i) { int16_t functId = pExprs[i].base.functionId; if (functId == TSDB_FUNC_TOP || functId == TSDB_FUNC_BOTTOM) { - int32_t j = getColumnIndexInSource(pQueryMsg, &pExprs[i].base, pTagCols); - if (j < 0 || j >= pQueryMsg->numOfCols) { + int32_t j = getColumnIndexInSource(pTableInfo, &pExprs[i].base, pTagCols); + if (j < 0 || j >= pTableInfo->numOfCols) { return TSDB_CODE_QRY_INVALID_MSG; } else { - SColumnInfo* pCol = &pQueryMsg->colList[j]; - int32_t ret = getResultDataInfo(pCol->type, pCol->bytes, functId, (int32_t)pExprs[i].base.arg[0].argValue.i64, - &pExprs[i].type, &pExprs[i].bytes, &pExprs[i].interBytes, tagLen, superTable, NULL); + SColumnInfo* pCol = &pTableInfo->colList[j]; + int32_t ret = getResultDataInfo(pCol->type, pCol->bytes, functId, (int32_t)pExprs[i].base.param[0].i64, + &pExprs[i].base.resType, &pExprs[i].base.resBytes, &pExprs[i].base.interBytes, tagLen, superTable, NULL); assert(ret == TSDB_CODE_SUCCESS); } } @@ -6359,25 +6582,22 @@ void destroyUdfInfo(SUdfInfo* pUdfInfo) { (*(udfDestroyFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY])(&pUdfInfo->init); } } - + tfree(pUdfInfo->name); if (pUdfInfo->path) { unlink(pUdfInfo->path); } - + tfree(pUdfInfo->path); - tfree(pUdfInfo->content); - taosCloseDll(pUdfInfo->handle); - tfree(pUdfInfo); } static char* getUdfFuncName(char* name, int type) { char* funcname = calloc(1, TSDB_FUNCTIONS_NAME_MAX_LENGTH + 10); - + switch (type) { case TSDB_UDF_FUNC_NORMAL: strcpy(funcname, name); @@ -6390,7 +6610,7 @@ static char* getUdfFuncName(char* name, int type) { break; case TSDB_UDF_FUNC_MERGE: sprintf(funcname, "%s_merge", name); - break; + break; case TSDB_UDF_FUNC_DESTROY: sprintf(funcname, "%s_destroy", name); break; @@ -6427,7 +6647,7 @@ int32_t initUdfInfo(SUdfInfo* pUdfInfo) { pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE] = taosLoadScriptFinalize; } pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY] = taosLoadScriptDestroy; - + } else { char path[PATH_MAX] = {0}; taosGetTmpfilePath("script", path); @@ -6438,7 +6658,7 @@ int32_t initUdfInfo(SUdfInfo* pUdfInfo) { /*size_t t = */ fwrite(pUdfInfo->content, pUdfInfo->contLen, 1, file); fclose(file); tfree(pUdfInfo->content); - + pUdfInfo->path = strdup(path); pUdfInfo->handle = taosLoadDll(path); @@ -6453,7 +6673,7 @@ int32_t initUdfInfo(SUdfInfo* pUdfInfo) { } pUdfInfo->funcs[TSDB_UDF_FUNC_INIT] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(pUdfInfo->name, TSDB_UDF_FUNC_INIT)); - + if (pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE) { pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(pUdfInfo->name, TSDB_UDF_FUNC_FINALIZE)); pUdfInfo->funcs[TSDB_UDF_FUNC_MERGE] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(pUdfInfo->name, TSDB_UDF_FUNC_MERGE)); @@ -6465,13 +6685,13 @@ int32_t initUdfInfo(SUdfInfo* pUdfInfo) { return (*(udfInitFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_INIT])(&pUdfInfo->init); } } - + return TSDB_CODE_SUCCESS; } // TODO tag length should be passed from client -int32_t createQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t numOfOutput, SExprInfo** pExprInfo, - SSqlFuncMsg** pExprMsg, SColumnInfo* pTagCols, SUdfInfo* pUdfInfo) { +int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExprInfo** pExprInfo, + SSqlExpr** pExprMsg, SColumnInfo* pTagCols, int32_t queryType, void* pMsg, SUdfInfo* pUdfInfo) { *pExprInfo = NULL; int32_t code = TSDB_CODE_SUCCESS; @@ -6480,24 +6700,28 @@ int32_t createQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t numOfOutpu return code; } - SExprInfo *pExprs = (SExprInfo *)calloc(pQueryMsg->numOfOutput, sizeof(SExprInfo)); + SExprInfo *pExprs = (SExprInfo *)calloc(numOfOutput, sizeof(SExprInfo)); if (pExprs == NULL) { return TSDB_CODE_QRY_OUT_OF_MEMORY; } - bool isSuperTable = QUERY_IS_STABLE_QUERY(pQueryMsg->queryType); + bool isSuperTable = QUERY_IS_STABLE_QUERY(queryType); int16_t tagLen = 0; for (int32_t i = 0; i < numOfOutput; ++i) { pExprs[i].base = *pExprMsg[i]; - pExprs[i].bytes = 0; + memset(pExprs[i].base.param, 0, sizeof(tVariant) * tListLen(pExprs[i].base.param)); + + for (int32_t j = 0; j < pExprMsg[i]->numOfParams; ++j) { + tVariantAssign(&pExprs[i].base.param[j], &pExprMsg[i]->param[j]); + } int16_t type = 0; int16_t bytes = 0; // parse the arithmetic expression if (pExprs[i].base.functionId == TSDB_FUNC_ARITHM) { - code = buildArithmeticExprFromMsg(&pExprs[i], pQueryMsg); + code = buildArithmeticExprFromMsg(&pExprs[i], pMsg); if (code != TSDB_CODE_SUCCESS) { tfree(pExprs); @@ -6514,30 +6738,29 @@ int32_t createQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t numOfOutpu SSchema s = tGetBlockDistColumnSchema(); type = s.type; bytes = s.bytes; - } else if (pExprs[i].base.colInfo.colId <= TSDB_UD_COLUMN_INDEX) { + } else if (pExprs[i].base.colInfo.colId <= TSDB_UD_COLUMN_INDEX && pExprs[i].base.colInfo.colId > TSDB_RES_COL_ID) { // it is a user-defined constant value column assert(pExprs[i].base.functionId == TSDB_FUNC_PRJ); - type = pExprs[i].base.arg[1].argType; - bytes = pExprs[i].base.arg[1].argBytes; - + type = pExprs[i].base.param[1].nType; + bytes = pExprs[i].base.param[1].nLen; if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) { bytes += VARSTR_HEADER_SIZE; } } else { - int32_t j = getColumnIndexInSource(pQueryMsg, &pExprs[i].base, pTagCols); + int32_t j = getColumnIndexInSource(pTableInfo, &pExprs[i].base, pTagCols); if (TSDB_COL_IS_TAG(pExprs[i].base.colInfo.flag)) { - if (j < TSDB_BLOCK_DIST_COLUMN_INDEX || j >= pQueryMsg->numOfTags) { + if (j < TSDB_BLOCK_DIST_COLUMN_INDEX || j >= pTableInfo->numOfTags) { return TSDB_CODE_QRY_INVALID_MSG; } } else { - if (j < PRIMARYKEY_TIMESTAMP_COL_INDEX || j >= pQueryMsg->numOfCols) { + if (j < PRIMARYKEY_TIMESTAMP_COL_INDEX || j >= pTableInfo->numOfCols) { return TSDB_CODE_QRY_INVALID_MSG; } } if (pExprs[i].base.colInfo.colId != TSDB_TBNAME_COLUMN_INDEX && j >= 0) { - SColumnInfo* pCol = (TSDB_COL_IS_TAG(pExprs[i].base.colInfo.flag))? &pTagCols[j]:&pQueryMsg->colList[j]; + SColumnInfo* pCol = (TSDB_COL_IS_TAG(pExprs[i].base.colInfo.flag))? &pTagCols[j]:&pTableInfo->colList[j]; type = pCol->type; bytes = pCol->bytes; } else { @@ -6547,43 +6770,45 @@ int32_t createQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t numOfOutpu bytes = s->bytes; } - if (pExprs[i].base.filterNum > 0) { - int32_t ret = cloneExprFilterInfo(&pExprs[i].pFilter, pExprMsg[i]->filterInfo, pExprMsg[i]->filterNum); + if (pExprs[i].base.flist.numOfFilters > 0) { + int32_t ret = cloneExprFilterInfo(&pExprs[i].base.flist.filterInfo, pExprMsg[i]->flist.filterInfo, + pExprMsg[i]->flist.numOfFilters); if (ret) { return ret; } } } - int32_t param = (int32_t)pExprs[i].base.arg[0].argValue.i64; + int32_t param = (int32_t)pExprs[i].base.param[0].i64; if (pExprs[i].base.functionId != TSDB_FUNC_ARITHM && (type != pExprs[i].base.colType || bytes != pExprs[i].base.colBytes)) { tfree(pExprs); return TSDB_CODE_QRY_INVALID_MSG; } - if (getResultDataInfo(type, bytes, pExprs[i].base.functionId, param, &pExprs[i].type, &pExprs[i].bytes, - &pExprs[i].interBytes, 0, isSuperTable, pUdfInfo) != TSDB_CODE_SUCCESS) { + if (getResultDataInfo(type, bytes, pExprs[i].base.functionId, param, &pExprs[i].base.resType, &pExprs[i].base.resBytes, + &pExprs[i].base.interBytes, 0, isSuperTable, pUdfInfo) != TSDB_CODE_SUCCESS) { tfree(pExprs); return TSDB_CODE_QRY_INVALID_MSG; } if (pExprs[i].base.functionId == TSDB_FUNC_TAG_DUMMY || pExprs[i].base.functionId == TSDB_FUNC_TS_DUMMY) { - tagLen += pExprs[i].bytes; + tagLen += pExprs[i].base.resBytes; } - assert(isValidDataType(pExprs[i].type)); + assert(isValidDataType(pExprs[i].base.resType)); } // the tag length is affected by other tag columns, so this should be update. - updateOutputBufForTopBotQuery(pQueryMsg, pTagCols, pExprs, numOfOutput, tagLen, isSuperTable); + updateOutputBufForTopBotQuery(pTableInfo, pTagCols, pExprs, numOfOutput, tagLen, isSuperTable); *pExprInfo = pExprs; return TSDB_CODE_SUCCESS; } -int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t numOfOutput, SExprInfo **pExprInfo, - SSqlFuncMsg **pExprMsg, SExprInfo *prevExpr, SUdfInfo *pUdfInfo) { +// todo refactor +int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t numOfOutput, SExprInfo** pExprInfo, + SSqlExpr** pExpr, SExprInfo* prevExpr, SUdfInfo *pUdfInfo) { *pExprInfo = NULL; int32_t code = TSDB_CODE_SUCCESS; @@ -6595,8 +6820,14 @@ int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t nu bool isSuperTable = QUERY_IS_STABLE_QUERY(pQueryMsg->queryType); for (int32_t i = 0; i < numOfOutput; ++i) { - pExprs[i].base = *pExprMsg[i]; - pExprs[i].bytes = 0; + pExprs[i].base = *pExpr[i]; + memset(pExprs[i].base.param, 0, sizeof(tVariant) * tListLen(pExprs[i].base.param)); + + for (int32_t j = 0; j < pExpr[i]->numOfParams; ++j) { + tVariantAssign(&pExprs[i].base.param[j], &pExpr[i]->param[j]); + } + + pExprs[i].base.resType = 0; int16_t type = 0; int16_t bytes = 0; @@ -6616,18 +6847,18 @@ int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t nu int32_t index = pExprs[i].base.colInfo.colIndex; assert(prevExpr[index].base.resColId == pExprs[i].base.colInfo.colId); - type = prevExpr[index].type; - bytes = prevExpr[index].bytes; + type = prevExpr[index].base.resType; + bytes = prevExpr[index].base.resBytes; } - int32_t param = (int32_t)pExprs[i].base.arg[0].argValue.i64; - if (getResultDataInfo(type, bytes, pExprs[i].base.functionId, param, &pExprs[i].type, &pExprs[i].bytes, - &pExprs[i].interBytes, 0, isSuperTable, pUdfInfo) != TSDB_CODE_SUCCESS) { + int32_t param = (int32_t)pExprs[i].base.param[0].i64; + if (getResultDataInfo(type, bytes, pExprs[i].base.functionId, param, &pExprs[i].base.resType, &pExprs[i].base.resBytes, + &pExprs[i].base.interBytes, 0, isSuperTable, pUdfInfo) != TSDB_CODE_SUCCESS) { tfree(pExprs); return TSDB_CODE_QRY_INVALID_MSG; } - assert(isValidDataType(pExprs[i].type)); + assert(isValidDataType(pExprs[i].base.resType)); } *pExprInfo = pExprs; @@ -6658,53 +6889,44 @@ SSqlGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex * return pGroupbyExpr; } -static int32_t createFilterInfo(SQuery *pQuery, uint64_t qId) { - for (int32_t i = 0; i < pQuery->numOfCols; ++i) { - if (pQuery->colList[i].numOfFilters > 0) { - pQuery->numOfFilterCols++; - } - } - - if (pQuery->numOfFilterCols == 0) { - return TSDB_CODE_SUCCESS; - } - - pQuery->pFilterInfo = calloc(1, sizeof(SSingleColumnFilterInfo) * pQuery->numOfFilterCols); - if (pQuery->pFilterInfo == NULL) { +static int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfFilterCols, + SSingleColumnFilterInfo** pFilterInfo, uint64_t qId) { + *pFilterInfo = calloc(1, sizeof(SSingleColumnFilterInfo) * numOfFilterCols); + if (pFilterInfo == NULL) { return TSDB_CODE_QRY_OUT_OF_MEMORY; } - for (int32_t i = 0, j = 0; i < pQuery->numOfCols; ++i) { - if (pQuery->colList[i].numOfFilters > 0) { - SSingleColumnFilterInfo *pFilterInfo = &pQuery->pFilterInfo[j]; + for (int32_t i = 0, j = 0; i < numOfCols; ++i) { + if (pCols[i].flist.numOfFilters > 0) { + SSingleColumnFilterInfo* pFilter = &((*pFilterInfo)[j]); - memcpy(&pFilterInfo->info, &pQuery->colList[i], sizeof(SColumnInfo)); - pFilterInfo->info = pQuery->colList[i]; + memcpy(&pFilter->info, &pCols[i], sizeof(SColumnInfo)); + pFilter->info = pCols[i]; - pFilterInfo->numOfFilters = pQuery->colList[i].numOfFilters; - pFilterInfo->pFilters = calloc(pFilterInfo->numOfFilters, sizeof(SColumnFilterElem)); - if (pFilterInfo->pFilters == NULL) { + pFilter->numOfFilters = pCols[i].flist.numOfFilters; + pFilter->pFilters = calloc(pFilter->numOfFilters, sizeof(SColumnFilterElem)); + if (pFilter->pFilters == NULL) { return TSDB_CODE_QRY_OUT_OF_MEMORY; } - for (int32_t f = 0; f < pFilterInfo->numOfFilters; ++f) { - SColumnFilterElem *pSingleColFilter = &pFilterInfo->pFilters[f]; - pSingleColFilter->filterInfo = pQuery->colList[i].filters[f]; + for (int32_t f = 0; f < pFilter->numOfFilters; ++f) { + SColumnFilterElem* pSingleColFilter = &pFilter->pFilters[f]; + pSingleColFilter->filterInfo = pCols[i].flist.filterInfo[f]; int32_t lower = pSingleColFilter->filterInfo.lowerRelOptr; int32_t upper = pSingleColFilter->filterInfo.upperRelOptr; if (lower == TSDB_RELATION_INVALID && upper == TSDB_RELATION_INVALID) { - qError("QInfo:%"PRIu64" invalid filter info", qId); + qError("QInfo:0x%"PRIx64" invalid filter info", qId); return TSDB_CODE_QRY_INVALID_MSG; } pSingleColFilter->fp = getFilterOperator(lower, upper); if (pSingleColFilter->fp == NULL) { - qError("QInfo:%"PRIu64" invalid filter info", qId); + qError("QInfo:0x%"PRIx64" invalid filter info", qId); return TSDB_CODE_QRY_INVALID_MSG; } - pSingleColFilter->bytes = pQuery->colList[i].bytes; + pSingleColFilter->bytes = pCols[i].bytes; } j++; @@ -6714,11 +6936,39 @@ static int32_t createFilterInfo(SQuery *pQuery, uint64_t qId) { return TSDB_CODE_SUCCESS; } -static void doUpdateExprColumnIndex(SQuery *pQuery) { - assert(pQuery->pExpr1 != NULL && pQuery != NULL); +void* doDestroyFilterInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols) { + for (int32_t i = 0; i < numOfFilterCols; ++i) { + if (pFilterInfo[i].numOfFilters > 0) { + tfree(pFilterInfo[i].pFilters); + } + } - for (int32_t k = 0; k < pQuery->numOfOutput; ++k) { - SSqlFuncMsg *pSqlExprMsg = &pQuery->pExpr1[k].base; + tfree(pFilterInfo); + return NULL; +} + +static int32_t createFilterInfo(SQueryAttr* pQueryAttr, uint64_t qId) { + for (int32_t i = 0; i < pQueryAttr->numOfCols; ++i) { + if (pQueryAttr->tableCols[i].flist.numOfFilters > 0) { + pQueryAttr->numOfFilterCols++; + } + } + + if (pQueryAttr->numOfFilterCols == 0) { + return TSDB_CODE_SUCCESS; + } + + doCreateFilterInfo(pQueryAttr->tableCols, pQueryAttr->numOfCols, pQueryAttr->numOfFilterCols, + &pQueryAttr->pFilterInfo, qId); + + return TSDB_CODE_SUCCESS; +} + +static void doUpdateExprColumnIndex(SQueryAttr *pQueryAttr) { + assert(pQueryAttr->pExpr1 != NULL && pQueryAttr != NULL); + + for (int32_t k = 0; k < pQueryAttr->numOfOutput; ++k) { + SSqlExpr *pSqlExprMsg = &pQueryAttr->pExpr1[k].base; if (pSqlExprMsg->functionId == TSDB_FUNC_ARITHM) { continue; } @@ -6727,34 +6977,34 @@ static void doUpdateExprColumnIndex(SQuery *pQuery) { SColIndex *pColIndex = &pSqlExprMsg->colInfo; if (TSDB_COL_IS_NORMAL_COL(pColIndex->flag)) { int32_t f = 0; - for (f = 0; f < pQuery->numOfCols; ++f) { - if (pColIndex->colId == pQuery->colList[f].colId) { + for (f = 0; f < pQueryAttr->numOfCols; ++f) { + if (pColIndex->colId == pQueryAttr->tableCols[f].colId) { pColIndex->colIndex = f; break; } } - assert(f < pQuery->numOfCols); + assert(f < pQueryAttr->numOfCols); } else if (pColIndex->colId <= TSDB_UD_COLUMN_INDEX) { // do nothing for user-defined constant value result columns } else if (pColIndex->colId == TSDB_BLOCK_DIST_COLUMN_INDEX) { pColIndex->colIndex = 0;// only one source column, so it must be 0; - assert(pQuery->numOfOutput == 1); + assert(pQueryAttr->numOfOutput == 1); } else { int32_t f = 0; - for (f = 0; f < pQuery->numOfTags; ++f) { - if (pColIndex->colId == pQuery->tagColList[f].colId) { + for (f = 0; f < pQueryAttr->numOfTags; ++f) { + if (pColIndex->colId == pQueryAttr->tagColList[f].colId) { pColIndex->colIndex = f; break; } } - assert(f < pQuery->numOfTags || pColIndex->colId == TSDB_TBNAME_COLUMN_INDEX || pColIndex->colId == TSDB_BLOCK_DIST_COLUMN_INDEX); + assert(f < pQueryAttr->numOfTags || pColIndex->colId == TSDB_TBNAME_COLUMN_INDEX || pColIndex->colId == TSDB_BLOCK_DIST_COLUMN_INDEX); } } } -void setResultBufSize(SQuery* pQuery, SRspResultInfo* pResultInfo) { +void setResultBufSize(SQueryAttr* pQueryAttr, SRspResultInfo* pResultInfo) { const int32_t DEFAULT_RESULT_MSG_SIZE = 1024 * (1024 + 512); // the minimum number of rows for projection query @@ -6763,8 +7013,8 @@ void setResultBufSize(SQuery* pQuery, SRspResultInfo* pResultInfo) { const float THRESHOLD_RATIO = 0.85f; - if (isProjQuery(pQuery)) { - int32_t numOfRes = DEFAULT_RESULT_MSG_SIZE / pQuery->resultRowSize; + if (isProjQuery(pQueryAttr)) { + int32_t numOfRes = DEFAULT_RESULT_MSG_SIZE / pQueryAttr->resultRowSize; if (numOfRes < MIN_ROWS_FOR_PRJ_QUERY) { numOfRes = MIN_ROWS_FOR_PRJ_QUERY; } @@ -6795,90 +7045,103 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SSqlGroupbyExpr* pGroupbyExpr pQInfo->qId = *qId; - // to make sure third party won't overwrite this structure - pQInfo->signature = pQInfo; - SQuery* pQuery = &pQInfo->query; - pQInfo->runtimeEnv.pQuery = pQuery; - pQInfo->runtimeEnv.pUdfInfo = pUdfInfo; - pQuery->tableGroupInfo = *pTableGroupInfo; - pQuery->numOfCols = numOfCols; - pQuery->numOfOutput = numOfOutput; - pQuery->limit.limit = pQueryMsg->limit; - pQuery->limit.offset = pQueryMsg->offset; - pQuery->order.order = pQueryMsg->order; - pQuery->order.orderColId = pQueryMsg->orderColId; - pQuery->pExpr1 = pExprs; - pQuery->pExpr2 = pSecExprs; - pQuery->numOfExpr2 = pQueryMsg->secondStageOutput; - pQuery->pGroupbyExpr = pGroupbyExpr; - memcpy(&pQuery->interval, &pQueryMsg->interval, sizeof(pQuery->interval)); - pQuery->fillType = pQueryMsg->fillType; - pQuery->numOfTags = pQueryMsg->numOfTags; - pQuery->tagColList = pTagCols; - pQuery->prjInfo.vgroupLimit = pQueryMsg->vgroupLimit; - pQuery->prjInfo.ts = (pQueryMsg->order == TSDB_ORDER_ASC)? INT64_MIN:INT64_MAX; - pQuery->sw = pQueryMsg->sw; - pQuery->colList = calloc(numOfCols, sizeof(SSingleColumnFilterInfo)); - if (pQuery->colList == NULL) { + // to make sure third party won't overwrite this structure + pQInfo->signature = pQInfo; + SQueryAttr* pQueryAttr = &pQInfo->query; + pQInfo->runtimeEnv.pQueryAttr = pQueryAttr; + + pQueryAttr->tableGroupInfo = *pTableGroupInfo; + pQueryAttr->numOfCols = numOfCols; + pQueryAttr->numOfOutput = numOfOutput; + pQueryAttr->limit.limit = pQueryMsg->limit; + pQueryAttr->limit.offset = pQueryMsg->offset; + pQueryAttr->order.order = pQueryMsg->order; + pQueryAttr->order.orderColId = pQueryMsg->orderColId; + pQueryAttr->pExpr1 = pExprs; + pQueryAttr->pExpr2 = pSecExprs; + pQueryAttr->numOfExpr2 = pQueryMsg->secondStageOutput; + pQueryAttr->pGroupbyExpr = pGroupbyExpr; + memcpy(&pQueryAttr->interval, &pQueryMsg->interval, sizeof(pQueryAttr->interval)); + pQueryAttr->fillType = pQueryMsg->fillType; + pQueryAttr->numOfTags = pQueryMsg->numOfTags; + pQueryAttr->tagColList = pTagCols; + pQueryAttr->prjInfo.vgroupLimit = pQueryMsg->vgroupLimit; + pQueryAttr->prjInfo.ts = (pQueryMsg->order == TSDB_ORDER_ASC)? INT64_MIN:INT64_MAX; + pQueryAttr->sw = pQueryMsg->sw; + + pQueryAttr->stableQuery = pQueryMsg->stableQuery; + pQueryAttr->topBotQuery = pQueryMsg->topBotQuery; + pQueryAttr->groupbyColumn = pQueryMsg->groupbyColumn; + pQueryAttr->hasTagResults = pQueryMsg->hasTagResults; + pQueryAttr->timeWindowInterpo = pQueryMsg->timeWindowInterpo; + pQueryAttr->queryBlockDist = pQueryMsg->queryBlockDist; + pQueryAttr->stabledev = pQueryMsg->stabledev; + pQueryAttr->tsCompQuery = pQueryMsg->tsCompQuery; + pQueryAttr->simpleAgg = pQueryMsg->simpleAgg; + pQueryAttr->pointInterpQuery = pQueryMsg->pointInterpQuery; + pQueryAttr->needReverseScan = pQueryMsg->needReverseScan; + + pQueryAttr->tableCols = calloc(numOfCols, sizeof(SSingleColumnFilterInfo)); + if (pQueryAttr->tableCols == NULL) { goto _cleanup; } - pQuery->srcRowSize = 0; - pQuery->maxSrcColumnSize = 0; + pQueryAttr->srcRowSize = 0; + pQueryAttr->maxTableColumnWidth = 0; for (int16_t i = 0; i < numOfCols; ++i) { - pQuery->colList[i] = pQueryMsg->colList[i]; - pQuery->colList[i].filters = tFilterInfoDup(pQueryMsg->colList[i].filters, pQuery->colList[i].numOfFilters); + pQueryAttr->tableCols[i] = pQueryMsg->tableCols[i]; + pQueryAttr->tableCols[i].flist.filterInfo = tFilterInfoDup(pQueryMsg->tableCols[i].flist.filterInfo, pQueryAttr->tableCols[i].flist.numOfFilters); - pQuery->srcRowSize += pQuery->colList[i].bytes; - if (pQuery->maxSrcColumnSize < pQuery->colList[i].bytes) { - pQuery->maxSrcColumnSize = pQuery->colList[i].bytes; + pQueryAttr->srcRowSize += pQueryAttr->tableCols[i].bytes; + if (pQueryAttr->maxTableColumnWidth < pQueryAttr->tableCols[i].bytes) { + pQueryAttr->maxTableColumnWidth = pQueryAttr->tableCols[i].bytes; } } for (int16_t col = 0; col < numOfOutput; ++col) { - assert(pExprs[col].bytes > 0); - pQuery->resultRowSize += pExprs[col].bytes; - + assert(pExprs[col].base.resBytes > 0); + pQueryAttr->resultRowSize += pExprs[col].base.resBytes; + // keep the tag length if (TSDB_COL_IS_TAG(pExprs[col].base.colInfo.flag)) { - pQuery->tagLen += pExprs[col].bytes; + pQueryAttr->tagLen += pExprs[col].base.resBytes; } - if (pExprs[col].pFilter) { - ++pQuery->havingNum; + if (pExprs[col].base.flist.filterInfo) { + ++pQueryAttr->havingNum; } } - if (pSecExprs != NULL) { - int32_t resultRowSize = 0; - - // calculate the result row size - for (int16_t col = 0; col < pQuery->numOfExpr2; ++col) { - assert(pSecExprs[col].bytes > 0); - resultRowSize += pSecExprs[col].bytes; - } - - if (resultRowSize > pQuery->resultRowSize) { - pQuery->resultRowSize = resultRowSize; - } - } - - doUpdateExprColumnIndex(pQuery); - int32_t ret = createFilterInfo(pQuery, pQInfo->qId); + doUpdateExprColumnIndex(pQueryAttr); + int32_t ret = createFilterInfo(pQueryAttr, pQInfo->qId); if (ret != TSDB_CODE_SUCCESS) { goto _cleanup; } - if (pQuery->fillType != TSDB_FILL_NONE) { - pQuery->fillVal = malloc(sizeof(int64_t) * pQuery->numOfOutput); - if (pQuery->fillVal == NULL) { + if (pSecExprs != NULL) { + int32_t resultRowSize = 0; + + // calculate the result row size + for (int16_t col = 0; col < pQueryAttr->numOfExpr2; ++col) { + assert(pSecExprs[col].base.resBytes > 0); + resultRowSize += pSecExprs[col].base.resBytes; + } + + if (resultRowSize > pQueryAttr->resultRowSize) { + pQueryAttr->resultRowSize = resultRowSize; + } + } + + if (pQueryAttr->fillType != TSDB_FILL_NONE) { + pQueryAttr->fillVal = malloc(sizeof(int64_t) * pQueryAttr->numOfOutput); + if (pQueryAttr->fillVal == NULL) { goto _cleanup; } // the first column is the timestamp - memcpy(pQuery->fillVal, (char *)pQueryMsg->fillVal, pQuery->numOfOutput * sizeof(int64_t)); + memcpy(pQueryAttr->fillVal, (char *)pQueryMsg->fillVal, pQueryAttr->numOfOutput * sizeof(int64_t)); } size_t numOfGroups = 0; @@ -6902,17 +7165,15 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SSqlGroupbyExpr* pGroupbyExpr pthread_mutex_init(&pQInfo->lock, NULL); tsem_init(&pQInfo->ready, 0, 0); - pQuery->window = pQueryMsg->window; - changeExecuteScanOrder(pQInfo, pQueryMsg, stableQuery); + pQueryAttr->window = pQueryMsg->window; + changeExecuteScanOrder(pQInfo, pQueryMsg, pQueryAttr->stableQuery); SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; - bool groupByCol = isGroupbyColumn(pQuery->pGroupbyExpr); - - STimeWindow window = pQuery->window; + STimeWindow window = pQueryAttr->window; int32_t index = 0; for(int32_t i = 0; i < numOfGroups; ++i) { - SArray* pa = taosArrayGetP(pQuery->tableGroupInfo.pGroupList, i); + SArray* pa = taosArrayGetP(pQueryAttr->tableGroupInfo.pGroupList, i); size_t s = taosArrayGetSize(pa); SArray* p1 = taosArrayInit(s, POINTER_BYTES); @@ -6927,7 +7188,7 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SSqlGroupbyExpr* pGroupbyExpr window.skey = info->lastKey; void* buf = (char*) pQInfo->pBuf + index * sizeof(STableQueryInfo); - STableQueryInfo* item = createTableQueryInfo(pQuery, info->pTable, groupByCol, window, buf); + STableQueryInfo* item = createTableQueryInfo(pQueryAttr, info->pTable, pQueryAttr->groupbyColumn, window, buf); if (item == NULL) { goto _cleanup; } @@ -6941,12 +7202,12 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SSqlGroupbyExpr* pGroupbyExpr } } - colIdCheck(pQuery, pQInfo->qId); + colIdCheck(pQueryAttr, pQInfo->qId); // todo refactor pQInfo->query.queryBlockDist = (numOfOutput == 1 && pExprs[0].base.colInfo.colId == TSDB_BLOCK_DIST_COLUMN_INDEX); - qDebug("qmsg:%p QInfo:%" PRIu64 "-%p created", pQueryMsg, pQInfo->qId, pQInfo); + qDebug("qmsg:%p QInfo:0x%" PRIx64 "-%p created", pQueryMsg, pQInfo->qId, pQInfo); return pQInfo; _cleanup_qinfo: @@ -6965,8 +7226,8 @@ _cleanup_qinfo: pExprInfo->pExpr = NULL; } - if (pExprInfo->pFilter) { - freeColumnFilterInfo(pExprInfo->pFilter, pExprInfo->base.filterNum); + if (pExprInfo->base.flist.filterInfo) { + freeColumnFilterInfo(pExprInfo->base.flist.filterInfo, pExprInfo->base.flist.numOfFilters); } } @@ -6991,38 +7252,39 @@ bool isValidQInfo(void *param) { return (sig == (uint64_t)pQInfo); } -int32_t initQInfo(SQueryTableMsg *pQueryMsg, void *tsdb, int32_t vgId, SQInfo *pQInfo, SQueryParam* param, bool isSTable) { +int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* pQInfo, SQueryParam* param, char* start, + int32_t prevResultLen, void* merger) { int32_t code = TSDB_CODE_SUCCESS; SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; pRuntimeEnv->qinfo = pQInfo; - SQuery *pQuery = pRuntimeEnv->pQuery; + SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr; STSBuf *pTsBuf = NULL; - if (pQueryMsg->tsLen > 0) { // open new file to save the result - char *tsBlock = (char *) pQueryMsg + pQueryMsg->tsOffset; - pTsBuf = tsBufCreateFromCompBlocks(tsBlock, pQueryMsg->tsNumOfBlocks, pQueryMsg->tsLen, pQueryMsg->tsOrder, vgId); + if (pTsBufInfo->tsLen > 0) { // open new file to save the result + char *tsBlock = start + pTsBufInfo->tsOffset; + pTsBuf = tsBufCreateFromCompBlocks(tsBlock, pTsBufInfo->tsNumOfBlocks, pTsBufInfo->tsLen, pTsBufInfo->tsOrder, + pQueryAttr->vgId); tsBufResetPos(pTsBuf); bool ret = tsBufNextPos(pTsBuf); - UNUSED(ret); } SArray* prevResult = NULL; - if (pQueryMsg->prevResultLen > 0) { - prevResult = interResFromBinary(param->prevResult, pQueryMsg->prevResultLen); - - pRuntimeEnv->prevResult = prevResult; + if (prevResultLen > 0) { + prevResult = interResFromBinary(param->prevResult, prevResultLen); } - pQuery->precision = tsdbGetCfg(tsdb)->precision; + if (tsdb != NULL) { + pQueryAttr->precision = tsdbGetCfg(tsdb)->precision; + } - if ((QUERY_IS_ASC_QUERY(pQuery) && (pQuery->window.skey > pQuery->window.ekey)) || - (!QUERY_IS_ASC_QUERY(pQuery) && (pQuery->window.ekey > pQuery->window.skey))) { - qDebug("QInfo:%"PRIu64" no result in time range %" PRId64 "-%" PRId64 ", order %d", pQInfo->qId, pQuery->window.skey, - pQuery->window.ekey, pQuery->order.order); + if ((QUERY_IS_ASC_QUERY(pQueryAttr) && (pQueryAttr->window.skey > pQueryAttr->window.ekey)) || + (!QUERY_IS_ASC_QUERY(pQueryAttr) && (pQueryAttr->window.ekey > pQueryAttr->window.skey))) { + qDebug("QInfo:0x%"PRIx64" no result in time range %" PRId64 "-%" PRId64 ", order %d", pQInfo->qId, pQueryAttr->window.skey, + pQueryAttr->window.ekey, pQueryAttr->order.order); setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); pRuntimeEnv->tableqinfoGroupInfo.numOfTables = 0; // todo free memory @@ -7030,13 +7292,13 @@ int32_t initQInfo(SQueryTableMsg *pQueryMsg, void *tsdb, int32_t vgId, SQInfo *p } if (pRuntimeEnv->tableqinfoGroupInfo.numOfTables == 0) { - qDebug("QInfo:%"PRIu64" no table qualified for tag filter, abort query", pQInfo->qId); + qDebug("QInfo:0x%"PRIx64" no table qualified for tag filter, abort query", pQInfo->qId); setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); return TSDB_CODE_SUCCESS; } // filter the qualified - if ((code = doInitQInfo(pQInfo, pTsBuf, tsdb, vgId, isSTable)) != TSDB_CODE_SUCCESS) { + if ((code = doInitQInfo(pQInfo, pTsBuf, prevResult, tsdb, sourceOptr, param->tableScanOperator, param->pOperator, merger)) != TSDB_CODE_SUCCESS) { goto _error; } @@ -7048,6 +7310,7 @@ _error: return code; } +//TODO refactor void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters) { if (pFilter == NULL || numOfFilters == 0) { return; @@ -7097,8 +7360,12 @@ static void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr) { tExprTreeDestroy(pExprInfo[i].pExpr, NULL); } - if (pExprInfo[i].pFilter) { - freeColumnFilterInfo(pExprInfo[i].pFilter, pExprInfo[i].base.filterNum); + if (pExprInfo[i].base.flist.filterInfo) { + freeColumnFilterInfo(pExprInfo[i].base.flist.filterInfo, pExprInfo[i].base.flist.numOfFilters); + } + + for(int32_t j = 0; j < pExprInfo[i].base.numOfParams; ++j) { + tVariantDestroy(&pExprInfo[i].base.param[j]); } } @@ -7111,58 +7378,26 @@ void freeQInfo(SQInfo *pQInfo) { return; } - qDebug("QInfo:%"PRIu64" start to free QInfo", pQInfo->qId); + qDebug("QInfo:0x%"PRIx64" start to free QInfo", pQInfo->qId); SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; releaseQueryBuf(pRuntimeEnv->tableqinfoGroupInfo.numOfTables); doDestroyTableQueryInfo(&pRuntimeEnv->tableqinfoGroupInfo); - teardownQueryRuntimeEnv(&pQInfo->runtimeEnv); - SQuery *pQuery = pQInfo->runtimeEnv.pQuery; - if (pQuery != NULL) { - if (pQuery->fillVal != NULL) { - tfree(pQuery->fillVal); - } - - for (int32_t i = 0; i < pQuery->numOfFilterCols; ++i) { - SSingleColumnFilterInfo *pColFilter = &pQuery->pFilterInfo[i]; - if (pColFilter->numOfFilters > 0) { - tfree(pColFilter->pFilters); - } - } - - pQuery->pExpr1 = destroyQueryFuncExpr(pQuery->pExpr1, pQuery->numOfOutput); - pQuery->pExpr2 = destroyQueryFuncExpr(pQuery->pExpr2, pQuery->numOfExpr2); - - tfree(pQuery->tagColList); - tfree(pQuery->pFilterInfo); - - if (pQuery->colList != NULL) { - for (int32_t i = 0; i < pQuery->numOfCols; i++) { - SColumnInfo *column = pQuery->colList + i; - freeColumnFilterInfo(column->filters, column->numOfFilters); - } - tfree(pQuery->colList); - } - - if (pQuery->pGroupbyExpr != NULL) { - taosArrayDestroy(pQuery->pGroupbyExpr->columnInfo); - tfree(pQuery->pGroupbyExpr); - } - } + SQueryAttr *pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; + freeQueryAttr(pQueryAttr); + tsdbDestroyTableGroup(&pQueryAttr->tableGroupInfo); tfree(pQInfo->pBuf); tfree(pQInfo->sql); - tsdbDestroyTableGroup(&pQuery->tableGroupInfo); - taosArrayDestroy(pRuntimeEnv->groupResInfo.pRows); pQInfo->signature = 0; - qDebug("QInfo:%"PRIu64" QInfo is freed", pQInfo->qId); + qDebug("QInfo:0x%"PRIx64" QInfo is freed", pQInfo->qId); tfree(pQInfo); } @@ -7170,10 +7405,10 @@ void freeQInfo(SQInfo *pQInfo) { int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) { // the remained number of retrieved rows, not the interpolated result SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; - SQuery *pQuery = pQInfo->runtimeEnv.pQuery; + SQueryAttr *pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; // load data from file to msg buffer - if (isTsCompQuery(pQuery)) { + if (pQueryAttr->tsCompQuery) { SColumnInfoData* pColInfoData = taosArrayGet(pRuntimeEnv->outputBuf->pDataBlock, 0); FILE *f = *(FILE **)pColInfoData->pData; // TODO refactor @@ -7182,7 +7417,7 @@ int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) { off_t s = lseek(fileno(f), 0, SEEK_END); assert(s == pRuntimeEnv->outputBuf->info.rows); - qDebug("QInfo:%"PRIu64" ts comp data return, file:%p, size:%"PRId64, pQInfo->qId, f, (uint64_t)s); + qDebug("QInfo:0x%"PRIx64" ts comp data return, file:%p, size:%"PRId64, pQInfo->qId, f, (uint64_t)s); if (fseek(f, 0, SEEK_SET) >= 0) { size_t sz = fread(data, 1, s, f); if(sz < s) { // todo handle error @@ -7214,11 +7449,11 @@ int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) { } pRuntimeEnv->resultInfo.total += pRuntimeEnv->outputBuf->info.rows; - qDebug("QInfo:%"PRIu64" current numOfRes rows:%d, total:%" PRId64, pQInfo->qId, + qDebug("QInfo:0x%"PRIx64" current numOfRes rows:%d, total:%" PRId64, pQInfo->qId, pRuntimeEnv->outputBuf->info.rows, pRuntimeEnv->resultInfo.total); - if (pQuery->limit.limit > 0 && pQuery->limit.limit == pRuntimeEnv->resultInfo.total) { - qDebug("QInfo:%"PRIu64" results limitation reached, limitation:%"PRId64, pQInfo->qId, pQuery->limit.limit); + if (pQueryAttr->limit.limit > 0 && pQueryAttr->limit.limit == pRuntimeEnv->resultInfo.total) { + qDebug("QInfo:0x%"PRIx64" results limitation reached, limitation:%"PRId64, pQInfo->qId, pQueryAttr->limit.limit); setQueryStatus(pRuntimeEnv, QUERY_OVER); } @@ -7306,3 +7541,34 @@ void releaseQueryBuf(size_t numOfTables) { // restore value is not enough buffer available atomic_add_fetch_64(&tsQueryBufferSizeBytes, t); } + +void freeQueryAttr(SQueryAttr* pQueryAttr) { + if (pQueryAttr != NULL) { + if (pQueryAttr->fillVal != NULL) { + tfree(pQueryAttr->fillVal); + } + + pQueryAttr->pFilterInfo = doDestroyFilterInfo(pQueryAttr->pFilterInfo, pQueryAttr->numOfFilterCols); + + pQueryAttr->pExpr1 = destroyQueryFuncExpr(pQueryAttr->pExpr1, pQueryAttr->numOfOutput); + pQueryAttr->pExpr2 = destroyQueryFuncExpr(pQueryAttr->pExpr2, pQueryAttr->numOfExpr2); + pQueryAttr->pExpr3 = destroyQueryFuncExpr(pQueryAttr->pExpr3, pQueryAttr->numOfExpr3); + + tfree(pQueryAttr->tagColList); + tfree(pQueryAttr->pFilterInfo); + + if (pQueryAttr->tableCols != NULL) { + for (int32_t i = 0; i < pQueryAttr->numOfCols; i++) { + SColumnInfo* column = pQueryAttr->tableCols + i; + freeColumnFilterInfo(column->flist.filterInfo, column->flist.numOfFilters); + } + tfree(pQueryAttr->tableCols); + } + + if (pQueryAttr->pGroupbyExpr != NULL) { + taosArrayDestroy(pQueryAttr->pGroupbyExpr->columnInfo); + tfree(pQueryAttr->pGroupbyExpr); + } + } +} + diff --git a/src/query/src/qExtbuffer.c b/src/query/src/qExtbuffer.c index 73b5b81e52..1fe2819ea2 100644 --- a/src/query/src/qExtbuffer.c +++ b/src/query/src/qExtbuffer.c @@ -20,6 +20,7 @@ #include "taosdef.h" #include "taosmsg.h" #include "tulog.h" +#include "qExecutor.h" #define COLMODEL_GET_VAL(data, schema, allrow, rowId, colId) \ (data + (schema)->pFields[colId].offset * (allrow) + (rowId) * (schema)->pFields[colId].field.bytes) @@ -352,47 +353,28 @@ static FORCE_INLINE int32_t primaryKeyComparator(int64_t f1, int64_t f2, int32_t } } -static FORCE_INLINE int32_t columnValueAscendingComparator(char *f1, char *f2, int32_t type, int32_t bytes) { +static int32_t tsCompareFunc(TSKEY k1, TSKEY k2, int32_t order) { + if (k1 == k2) { + return 0; + } + + if (order == TSDB_ORDER_DESC) { + return (k1 < k2)? 1:-1; + } else { + return (k1 < k2)? -1:1; + } +} + +int32_t columnValueAscendingComparator(char *f1, char *f2, int32_t type, int32_t bytes) { switch (type) { - case TSDB_DATA_TYPE_INT: { - int32_t first = *(int32_t *) f1; - int32_t second = *(int32_t *) f2; - if (first == second) { - return 0; - } - return (first < second) ? -1 : 1; - }; - case TSDB_DATA_TYPE_DOUBLE: { - DEFAULT_DOUBLE_COMP(GET_DOUBLE_VAL(f1), GET_DOUBLE_VAL(f2)); - }; - case TSDB_DATA_TYPE_FLOAT: { - DEFAULT_FLOAT_COMP(GET_FLOAT_VAL(f1), GET_FLOAT_VAL(f2)); - }; - case TSDB_DATA_TYPE_BIGINT: { - int64_t first = *(int64_t *)f1; - int64_t second = *(int64_t *)f2; - if (first == second) { - return 0; - } - return (first < second) ? -1 : 1; - }; - case TSDB_DATA_TYPE_SMALLINT: { - int16_t first = *(int16_t *)f1; - int16_t second = *(int16_t *)f2; - if (first == second) { - return 0; - } - return (first < second) ? -1 : 1; - }; + case TSDB_DATA_TYPE_INT: DEFAULT_COMP(GET_INT32_VAL(f1), GET_INT32_VAL(f2)); + case TSDB_DATA_TYPE_DOUBLE: DEFAULT_DOUBLE_COMP(GET_DOUBLE_VAL(f1), GET_DOUBLE_VAL(f2)); + case TSDB_DATA_TYPE_FLOAT: DEFAULT_FLOAT_COMP(GET_FLOAT_VAL(f1), GET_FLOAT_VAL(f2)); + case TSDB_DATA_TYPE_BIGINT: DEFAULT_COMP(GET_INT64_VAL(f1), GET_INT64_VAL(f2)); + case TSDB_DATA_TYPE_SMALLINT:DEFAULT_COMP(GET_INT16_VAL(f1), GET_INT16_VAL(f2)); case TSDB_DATA_TYPE_BOOL: - case TSDB_DATA_TYPE_TINYINT: { - int8_t first = *(int8_t *)f1; - int8_t second = *(int8_t *)f2; - if (first == second) { - return 0; - } - return (first < second) ? -1 : 1; - }; + case TSDB_DATA_TYPE_TINYINT: DEFAULT_COMP(GET_INT8_VAL(f1), GET_INT8_VAL(f2)); + case TSDB_DATA_TYPE_BINARY: { int32_t len1 = varDataLen(f1); int32_t len2 = varDataLen(f2); @@ -415,6 +397,10 @@ static FORCE_INLINE int32_t columnValueAscendingComparator(char *f1, char *f2, i } return (ret < 0) ? -1 : 1; }; + case TSDB_DATA_TYPE_UTINYINT: DEFAULT_COMP(GET_UINT8_VAL(f1), GET_UINT8_VAL(f2)); + case TSDB_DATA_TYPE_USMALLINT: DEFAULT_COMP(GET_UINT16_VAL(f1), GET_UINT16_VAL(f2)); + case TSDB_DATA_TYPE_UINT: DEFAULT_COMP(GET_UINT32_VAL(f1), GET_UINT32_VAL(f2)); + case TSDB_DATA_TYPE_UBIGINT: DEFAULT_COMP(GET_UINT64_VAL(f1), GET_UINT64_VAL(f2)); } return 0; @@ -452,6 +438,35 @@ int32_t compare_a(tOrderDescriptor *pDescriptor, int32_t numOfRows1, int32_t s1, return 0; } +int32_t compare_aRv(SSDataBlock* pBlock, SArray* colIndex, int32_t numOfCols, int32_t rowIndex, char** buffer, int32_t order) { + for (int32_t i = 0; i < numOfCols; ++i) { + SColIndex* pColIndex = taosArrayGet(colIndex, i); + int32_t index = pColIndex->colIndex; + + SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, index); + assert(pColIndex->colId == pColInfo->info.colId); + + char* data = pColInfo->pData + rowIndex * pColInfo->info.bytes; + if (pColInfo->info.type == TSDB_DATA_TYPE_TIMESTAMP) { + int32_t ret = tsCompareFunc(GET_INT64_VAL(data), GET_INT64_VAL(buffer[i]), order); + if (ret == 0) { + continue; // The timestamps are identical + } else { + return ret; + } + } else { + int32_t ret = columnValueAscendingComparator(data, buffer[i], pColInfo->info.type, pColInfo->info.bytes); + if (ret == 0) { + continue; + } else { + return ret; + } + } + } + + return 0; +} + int32_t compare_d(tOrderDescriptor *pDescriptor, int32_t numOfRows1, int32_t s1, char *data1, int32_t numOfRows2, int32_t s2, char *data2) { assert(numOfRows1 == numOfRows2); diff --git a/src/query/src/qFill.c b/src/query/src/qFill.c index 2de1029396..fa572029fc 100644 --- a/src/query/src/qFill.c +++ b/src/query/src/qFill.c @@ -31,7 +31,7 @@ static void setTagsValue(SFillInfo* pFillInfo, void** data, int32_t genRows) { for(int32_t j = 0; j < pFillInfo->numOfCols; ++j) { SFillColInfo* pCol = &pFillInfo->pFillCol[j]; - if (TSDB_COL_IS_NORMAL_COL(pCol->flag)) { + if (TSDB_COL_IS_NORMAL_COL(pCol->flag) || TSDB_COL_IS_UD_COL(pCol->flag)) { continue; } @@ -126,10 +126,10 @@ static void doFillOneRowResult(SFillInfo* pFillInfo, void** data, char** srcData } else { setNullValueForRow(pFillInfo, data, pFillInfo->numOfCols, index); } - } else { /* fill the default value */ + } else { // fill the default value */ for (int32_t i = 1; i < pFillInfo->numOfCols; ++i) { SFillColInfo* pCol = &pFillInfo->pFillCol[i]; - if (TSDB_COL_IS_TAG(pCol->flag)) { + if (TSDB_COL_IS_TAG(pCol->flag)/* || IS_VAR_DATA_TYPE(pCol->col.type)*/) { continue; } @@ -210,7 +210,7 @@ static int32_t fillResultImpl(SFillInfo* pFillInfo, void** data, int32_t outputR // assign rows to dst buffer for (int32_t i = 0; i < pFillInfo->numOfCols; ++i) { SFillColInfo* pCol = &pFillInfo->pFillCol[i]; - if (TSDB_COL_IS_TAG(pCol->flag)) { + if (TSDB_COL_IS_TAG(pCol->flag)/* || IS_VAR_DATA_TYPE(pCol->col.type)*/) { continue; } @@ -275,13 +275,16 @@ static int64_t appendFilledResult(SFillInfo* pFillInfo, void** output, int64_t r // there are no duplicated tags in the SFillTagColInfo list static int32_t setTagColumnInfo(SFillInfo* pFillInfo, int32_t numOfCols, int32_t capacity) { int32_t rowsize = 0; + int32_t numOfTags = 0; int32_t k = 0; for (int32_t i = 0; i < numOfCols; ++i) { SFillColInfo* pColInfo = &pFillInfo->pFillCol[i]; pFillInfo->pData[i] = NULL; - if (TSDB_COL_IS_TAG(pColInfo->flag)) { + if (TSDB_COL_IS_TAG(pColInfo->flag) || pColInfo->col.type == TSDB_DATA_TYPE_BINARY) { + numOfTags += 1; + bool exists = false; int32_t index = -1; for (int32_t j = 0; j < k; ++j) { @@ -310,6 +313,8 @@ static int32_t setTagColumnInfo(SFillInfo* pFillInfo, int32_t numOfCols, int32_t rowsize += pColInfo->col.bytes; } + pFillInfo->numOfTags = numOfTags; + assert(k <= pFillInfo->numOfTags); return rowsize; } @@ -347,12 +352,13 @@ SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int3 pFillInfo->interval.slidingUnit = slidingUnit; pFillInfo->pData = malloc(POINTER_BYTES * numOfCols); - if (numOfTags > 0) { - pFillInfo->pTags = calloc(pFillInfo->numOfTags, sizeof(SFillTagColInfo)); - for (int32_t i = 0; i < numOfTags; ++i) { + +// if (numOfTags > 0) { + pFillInfo->pTags = calloc(numOfCols, sizeof(SFillTagColInfo)); + for (int32_t i = 0; i < numOfCols; ++i) { pFillInfo->pTags[i].col.colId = -2; // TODO } - } +// } pFillInfo->rowSize = setTagColumnInfo(pFillInfo, pFillInfo->numOfCols, pFillInfo->alloc); assert(pFillInfo->rowSize > 0); @@ -367,6 +373,7 @@ SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int3 void taosResetFillInfo(SFillInfo* pFillInfo, TSKEY startTimestamp) { pFillInfo->start = startTimestamp; pFillInfo->currentKey = startTimestamp; + pFillInfo->end = startTimestamp; pFillInfo->index = -1; pFillInfo->numOfRows = 0; pFillInfo->numOfCurrent = 0; @@ -425,6 +432,8 @@ void taosFillSetStartInfo(SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey) void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const SSDataBlock* pInput) { for (int32_t i = 0; i < pFillInfo->numOfCols; ++i) { + SFillColInfo* pCol = &pFillInfo->pFillCol[i]; + SColumnInfoData* pColData = taosArrayGet(pInput->pDataBlock, i); // pFillInfo->pData[i] = pColData->pData; if (pInput->info.rows > pFillInfo->alloc) { @@ -436,6 +445,12 @@ void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const SSDataBlock* pInput) } memcpy(pFillInfo->pData[i], pColData->pData, pColData->info.bytes * pInput->info.rows); + + if (TSDB_COL_IS_TAG(pCol->flag)/* || IS_VAR_DATA_TYPE(pCol->col.type)*/) { // copy the tag value to tag value buffer + SFillTagColInfo* pTag = &pFillInfo->pTags[pCol->tagIndex]; + assert (pTag->col.colId == pCol->col.colId); + memcpy(pTag->tagVal, pColData->pData, pCol->col.bytes); // TODO not memcpy?? + } } } @@ -456,7 +471,7 @@ void taosFillCopyInputDataFromOneFilePage(SFillInfo* pFillInfo, const tFilePage* memcpy(pFillInfo->pData[i], data, (size_t)(pCol->col.bytes * pInput->num)); - if (TSDB_COL_IS_TAG(pCol->flag)) { // copy the tag value to tag value buffer + if (TSDB_COL_IS_TAG(pCol->flag)/* || IS_VAR_DATA_TYPE(pCol->col.type)*/) { // copy the tag value to tag value buffer SFillTagColInfo* pTag = &pFillInfo->pTags[pCol->tagIndex]; assert (pTag->col.colId == pCol->col.colId); memcpy(pTag->tagVal, data, pCol->col.bytes); // TODO not memcpy?? @@ -465,7 +480,17 @@ void taosFillCopyInputDataFromOneFilePage(SFillInfo* pFillInfo, const tFilePage* } bool taosFillHasMoreResults(SFillInfo* pFillInfo) { - return taosNumOfRemainRows(pFillInfo) > 0; + int32_t remain = taosNumOfRemainRows(pFillInfo); + if (remain > 0) { + return true; + } + + if (pFillInfo->numOfTotal > 0 && (((pFillInfo->end > pFillInfo->start) && FILL_IS_ASC_FILL(pFillInfo)) || + (pFillInfo->end < pFillInfo->start && !FILL_IS_ASC_FILL(pFillInfo)))) { + return getNumOfResultsAfterFillGap(pFillInfo, pFillInfo->end, 4096) > 0; + } + + return false; } int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, TSKEY ekey, int32_t maxNumOfRows) { diff --git a/src/query/src/qPlan.c b/src/query/src/qPlan.c new file mode 100644 index 0000000000..0554a887ec --- /dev/null +++ b/src/query/src/qPlan.c @@ -0,0 +1,195 @@ +#include "os.h" +#include "tsclient.h" +#include "qUtil.h" +#include "texpr.h" + +#define QNODE_PROJECT 1 +#define QNODE_FILTER 2 +#define QNODE_RELATION 3 +#define QNODE_AGGREGATE 4 +#define QNODE_GROUPBY 5 +#define QNODE_LIMIT 6 +#define QNODE_JOIN 7 +#define QNODE_DIST 8 +#define QNODE_SORT 9 +#define QNODE_UNIONALL 10 +#define QNODE_TIMEWINDOW 11 + +typedef struct SQueryNode { + int32_t type; // the type of logic node + char *name; // the name of logic node + + SSchema *pSchema; // the schema of the input SSDatablock + int32_t numOfCols; // number of input columns + SExprInfo *pExpr; // the query functions or sql aggregations + int32_t numOfOutput; // number of result columns, which is also the number of pExprs + + // previous operator to generated result for current node to process + // in case of join, multiple prev nodes exist. + struct SQueryNode* prevNode; + struct SQueryNode* nextNode; +} SQueryNode; + +// TODO create the query plan +SQueryNode* qCreateQueryPlan(SQueryInfo* pQueryInfo) { + return NULL; +} + +char* queryPlanToString() { + return NULL; +} + +SQueryNode* queryPlanFromString() { + return NULL; +} + +SArray* createTableScanPlan(SQueryAttr* pQueryAttr) { + SArray* plan = taosArrayInit(4, sizeof(int32_t)); + + int32_t op = 0; + if (onlyQueryTags(pQueryAttr)) { +// op = OP_TagScan; + } else { + if (pQueryAttr->queryBlockDist) { + op = OP_TableBlockInfoScan; + } else if (pQueryAttr->tsCompQuery || pQueryAttr->pointInterpQuery) { + op = OP_TableSeqScan; + } else if (pQueryAttr->needReverseScan) { + op = OP_DataBlocksOptScan; + } else { + op = OP_TableScan; + } + + taosArrayPush(plan, &op); + } + + return plan; +} + +SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) { + SArray* plan = taosArrayInit(4, sizeof(int32_t)); + int32_t op = 0; + + if (onlyQueryTags(pQueryAttr)) { // do nothing for tags query + op = OP_TagScan; + taosArrayPush(plan, &op); + if (pQueryAttr->distinctTag) { + op = OP_Distinct; + taosArrayPush(plan, &op); + } + } else if (pQueryAttr->interval.interval > 0) { + if (pQueryAttr->stableQuery) { + op = OP_MultiTableTimeInterval; + taosArrayPush(plan, &op); + } else { + op = OP_TimeWindow; + taosArrayPush(plan, &op); + + if (pQueryAttr->pExpr2 != NULL) { + op = OP_Arithmetic; + taosArrayPush(plan, &op); + } + + if (pQueryAttr->fillType != TSDB_FILL_NONE && (!pQueryAttr->pointInterpQuery)) { + op = OP_Fill; + taosArrayPush(plan, &op); + } + } + + } else if (pQueryAttr->groupbyColumn) { + op = OP_Groupby; + taosArrayPush(plan, &op); + + if (!pQueryAttr->stableQuery && pQueryAttr->havingNum > 0) { + op = OP_Filter; + taosArrayPush(plan, &op); + } + + if (pQueryAttr->pExpr2 != NULL) { + op = OP_Arithmetic; + taosArrayPush(plan, &op); + } + } else if (pQueryAttr->sw.gap > 0) { + op = OP_SessionWindow; + taosArrayPush(plan, &op); + + if (pQueryAttr->pExpr2 != NULL) { + op = OP_Arithmetic; + taosArrayPush(plan, &op); + } + } else if (pQueryAttr->simpleAgg) { + if (pQueryAttr->stableQuery && !pQueryAttr->tsCompQuery) { + op = OP_MultiTableAggregate; + } else { + op = OP_Aggregate; + } + + taosArrayPush(plan, &op); + + if (!pQueryAttr->stableQuery && pQueryAttr->havingNum > 0) { + op = OP_Filter; + taosArrayPush(plan, &op); + } + + if (pQueryAttr->pExpr2 != NULL && !pQueryAttr->stableQuery) { + op = OP_Arithmetic; + taosArrayPush(plan, &op); + } + } else { // diff/add/multiply/subtract/division + op = OP_Arithmetic; + taosArrayPush(plan, &op); + } + + if (pQueryAttr->limit.limit > 0 || pQueryAttr->limit.offset > 0) { + op = OP_Limit; + taosArrayPush(plan, &op); + } + + return plan; +} + +SArray* createGlobalMergePlan(SQueryAttr* pQueryAttr) { + SArray* plan = taosArrayInit(4, sizeof(int32_t)); + + if (!pQueryAttr->stableQuery) { + return plan; + } + + int32_t op = OP_MultiwayMergeSort; + taosArrayPush(plan, &op); + + if (pQueryAttr->distinctTag) { + op = OP_Distinct; + taosArrayPush(plan, &op); + } + + if (pQueryAttr->simpleAgg || (pQueryAttr->interval.interval > 0 || pQueryAttr->sw.gap > 0)) { + op = OP_GlobalAggregate; + taosArrayPush(plan, &op); + + if (pQueryAttr->havingNum > 0) { + op = OP_Filter; + taosArrayPush(plan, &op); + } + + if (pQueryAttr->pExpr2 != NULL) { + op = OP_Arithmetic; + taosArrayPush(plan, &op); + } + } + + // fill operator + if (pQueryAttr->fillType != TSDB_FILL_NONE && (!pQueryAttr->pointInterpQuery)) { + op = OP_Fill; + taosArrayPush(plan, &op); + } + + // limit/offset operator + if (pQueryAttr->limit.limit > 0 || pQueryAttr->limit.offset > 0 || + pQueryAttr->slimit.limit > 0 || pQueryAttr->slimit.offset > 0) { + op = OP_SLimit; + taosArrayPush(plan, &op); + } + + return plan; +} diff --git a/src/query/src/qResultbuf.c b/src/query/src/qResultbuf.c index f83caf2d8f..05ecf2e9b1 100644 --- a/src/query/src/qResultbuf.c +++ b/src/query/src/qResultbuf.c @@ -43,7 +43,7 @@ int32_t createDiskbasedResultBuffer(SDiskbasedResultBuf** pResultBuf, int32_t pa pResBuf->emptyDummyIdList = taosArrayInit(1, sizeof(int32_t)); - qDebug("QInfo:%"PRIu64" create resBuf for output, page size:%d, inmem buf pages:%d, file:%s", qId, pResBuf->pageSize, + qDebug("QInfo:0x%"PRIx64" create resBuf for output, page size:%d, inmem buf pages:%d, file:%s", qId, pResBuf->pageSize, pResBuf->inMemPages, pResBuf->path); return TSDB_CODE_SUCCESS; @@ -410,13 +410,13 @@ void destroyResultBuf(SDiskbasedResultBuf* pResultBuf) { } if (pResultBuf->file != NULL) { - qDebug("QInfo:%"PRIu64" res output buffer closed, total:%.2f Kb, inmem size:%.2f Kb, file size:%.2f Kb", + qDebug("QInfo:0x%"PRIx64" res output buffer closed, total:%.2f Kb, inmem size:%.2f Kb, file size:%.2f Kb", pResultBuf->qId, pResultBuf->totalBufSize/1024.0, listNEles(pResultBuf->lruList) * pResultBuf->pageSize / 1024.0, pResultBuf->fileSize/1024.0); fclose(pResultBuf->file); } else { - qDebug("QInfo:%"PRIu64" res output buffer closed, total:%.2f Kb, no file created", pResultBuf->qId, + qDebug("QInfo:0x%"PRIx64" res output buffer closed, total:%.2f Kb, no file created", pResultBuf->qId, pResultBuf->totalBufSize/1024.0); } diff --git a/src/query/src/qSqlParser.c b/src/query/src/qSqlParser.c index 7ffd135ba4..43e13caf4b 100644 --- a/src/query/src/qSqlParser.c +++ b/src/query/src/qSqlParser.c @@ -144,12 +144,15 @@ tSqlExpr *tSqlExprCreateIdValue(SStrToken *pToken, int32_t optrType) { pSqlExpr->value.nType = TSDB_DATA_TYPE_BIGINT; pSqlExpr->tokenId = TK_TIMESTAMP; // TK_TIMESTAMP used to denote the time value is in microsecond pSqlExpr->type = SQL_NODE_VALUE; + pSqlExpr->flags |= 1 << EXPR_FLAG_US_TIMESTAMP; } else if (optrType == TK_VARIABLE) { int32_t ret = parseAbsoluteDuration(pToken->z, pToken->n, &pSqlExpr->value.i64); if (ret != TSDB_CODE_SUCCESS) { terrno = TSDB_CODE_TSC_SQL_SYNTAX_ERROR; } + pSqlExpr->flags |= 1 << EXPR_FLAG_US_TIMESTAMP; + pSqlExpr->flags |= 1 << EXPR_FLAG_TIMESTAMP_VAR; pSqlExpr->value.nType = TSDB_DATA_TYPE_BIGINT; pSqlExpr->tokenId = TK_TIMESTAMP; pSqlExpr->type = SQL_NODE_VALUE; @@ -217,6 +220,15 @@ tSqlExpr *tSqlExprCreate(tSqlExpr *pLeft, tSqlExpr *pRight, int32_t optrType) { pExpr->value.nType = TSDB_DATA_TYPE_BIGINT; pExpr->tokenId = pLeft->tokenId; pExpr->type = SQL_NODE_VALUE; + pExpr->flags = pLeft->flags | pRight->flags; + + if ((pLeft->flags & (1 << EXPR_FLAG_TIMESTAMP_VAR)) && (pRight->flags & (1 << EXPR_FLAG_TIMESTAMP_VAR))) { + pExpr->flags |= 1 << EXPR_FLAG_TS_ERROR; + } else { + pExpr->flags &= ~(1 << EXPR_FLAG_TIMESTAMP_VAR); + pExpr->flags &= ~(1 << EXPR_FLAG_TS_ERROR); + } + switch (optrType) { case TK_PLUS: { @@ -245,7 +257,6 @@ tSqlExpr *tSqlExprCreate(tSqlExpr *pLeft, tSqlExpr *pRight, int32_t optrType) { tSqlExprDestroy(pLeft); tSqlExprDestroy(pRight); - } else if ((pLeft->tokenId == TK_FLOAT && pRight->tokenId == TK_INTEGER) || (pLeft->tokenId == TK_INTEGER && pRight->tokenId == TK_FLOAT) || (pLeft->tokenId == TK_FLOAT && pRight->tokenId == TK_FLOAT)) { @@ -319,7 +330,7 @@ int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right) { if ((left == NULL && right) || (left && right == NULL)) { return 1; } - + if (left->type != right->type) { return 1; } @@ -332,11 +343,11 @@ int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right) { return 1; } - if ((left->pLeft && right->pLeft == NULL) + if ((left->pLeft && right->pLeft == NULL) || (left->pLeft == NULL && right->pLeft) - || (left->pRight && right->pRight == NULL) + || (left->pRight && right->pRight == NULL) || (left->pRight == NULL && right->pRight) - || (left->pParam && right->pParam == NULL) + || (left->pParam && right->pParam == NULL) || (left->pParam == NULL && right->pParam)) { return 1; } @@ -349,19 +360,18 @@ int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right) { 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++) { + for (int32_t i = 0; i < size; i++) { tSqlExprItem* pLeftElem = taosArrayGet(left->pParam, i); tSqlExpr* pSubLeft = pLeftElem->pNode; - tSqlExprItem* pRightElem = taosArrayGet(left->pParam, i); + tSqlExprItem* pRightElem = taosArrayGet(right->pParam, i); tSqlExpr* pSubRight = pRightElem->pNode; - + if (tSqlExprCompare(pSubLeft, pSubRight)) { return 1; } @@ -523,13 +533,13 @@ SArray *tVariantListInsert(SArray *pList, tVariant *pVar, uint8_t sortOrder, int return pList; } -SFromInfo *setTableNameList(SFromInfo* pFromInfo, SStrToken *pName, SStrToken* pAlias) { - if (pFromInfo == NULL) { - pFromInfo = calloc(1, sizeof(SFromInfo)); - pFromInfo->tableList = taosArrayInit(4, sizeof(STableNamePair)); +SRelationInfo *setTableNameList(SRelationInfo* pRelationInfo, SStrToken *pName, SStrToken* pAlias) { + if (pRelationInfo == NULL) { + pRelationInfo = calloc(1, sizeof(SRelationInfo)); + pRelationInfo->list = taosArrayInit(4, sizeof(STableNamePair)); } - pFromInfo->type = SQL_NODE_FROM_NAMELIST; + pRelationInfo->type = SQL_NODE_FROM_TABLELIST; STableNamePair p = {.name = *pName}; if (pAlias != NULL) { p.aliasName = *pAlias; @@ -537,34 +547,39 @@ SFromInfo *setTableNameList(SFromInfo* pFromInfo, SStrToken *pName, SStrToken* p TPARSER_SET_NONE_TOKEN(p.aliasName); } - taosArrayPush(pFromInfo->tableList, &p); - - return pFromInfo; + taosArrayPush(pRelationInfo->list, &p); + return pRelationInfo; } -SFromInfo *setSubquery(SFromInfo* pFromInfo, SQuerySqlNode* pSqlNode) { - if (pFromInfo == NULL) { - pFromInfo = calloc(1, sizeof(SFromInfo)); +SRelationInfo* setSubquery(SRelationInfo* pRelationInfo, SArray* pList) { + if (pRelationInfo == NULL) { + pRelationInfo = calloc(1, sizeof(SRelationInfo)); + pRelationInfo->list = taosArrayInit(4, POINTER_BYTES); } - pFromInfo->type = SQL_NODE_FROM_SUBQUERY; - pFromInfo->pNode->pClause[pFromInfo->pNode->numOfClause - 1] = pSqlNode; + pRelationInfo->type = SQL_NODE_FROM_SUBQUERY; + taosArrayPush(pRelationInfo->list, &pList); - return pFromInfo; + return pRelationInfo; } -void* destroyFromInfo(SFromInfo* pFromInfo) { - if (pFromInfo == NULL) { +void* destroyRelationInfo(SRelationInfo* pRelationInfo) { + if (pRelationInfo == NULL) { return NULL; } - if (pFromInfo->type == SQL_NODE_FROM_NAMELIST) { - taosArrayDestroy(pFromInfo->tableList); + if (pRelationInfo->type == SQL_NODE_FROM_TABLELIST) { + taosArrayDestroy(pRelationInfo->list); } else { - destroyAllSelectClause(pFromInfo->pNode); + size_t size = taosArrayGetSize(pRelationInfo->list); + for(int32_t i = 0; i < size; ++i) { + SArray* pa = taosArrayGetP(pRelationInfo->list, 0); + destroyAllSqlNode(pa); + } + taosArrayDestroy(pRelationInfo->list); } - tfree(pFromInfo); + tfree(pRelationInfo); return NULL; } @@ -708,19 +723,19 @@ void tSetColumnType(TAOS_FIELD *pField, SStrToken *type) { /* * extract the select info out of sql string */ -SQuerySqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelectList, SFromInfo *pFrom, tSqlExpr *pWhere, +SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelationInfo *pFrom, tSqlExpr *pWhere, SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval, SSessionWindowVal *pSession, SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *psLimit, tSqlExpr *pHaving) { - assert(pSelectList != NULL); + assert(pSelNodeList != NULL); - SQuerySqlNode *pSqlNode = calloc(1, sizeof(SQuerySqlNode)); + SSqlNode *pSqlNode = calloc(1, sizeof(SSqlNode)); // all later sql string are belonged to the stream sql pSqlNode->sqlstr = *pSelectToken; pSqlNode->sqlstr.n = (uint32_t)strlen(pSqlNode->sqlstr.z); - pSqlNode->pSelectList = pSelectList; + pSqlNode->pSelNodeList = pSelNodeList; pSqlNode->from = pFrom; pSqlNode->pGroupby = pGroupby; pSqlNode->pSortOrder = pSortOrder; @@ -778,49 +793,47 @@ void freeCreateTableInfo(void* p) { tfree(pInfo->tagdata.data); } -void destroyQuerySqlNode(SQuerySqlNode *pQuerySql) { - if (pQuerySql == NULL) { +void destroySqlNode(SSqlNode *pSqlNode) { + if (pSqlNode == NULL) { return; } - tSqlExprListDestroy(pQuerySql->pSelectList); + tSqlExprListDestroy(pSqlNode->pSelNodeList); + pSqlNode->pSelNodeList = NULL; + + tSqlExprDestroy(pSqlNode->pWhere); + pSqlNode->pWhere = NULL; - pQuerySql->pSelectList = NULL; + taosArrayDestroyEx(pSqlNode->pSortOrder, freeVariant); + pSqlNode->pSortOrder = NULL; - tSqlExprDestroy(pQuerySql->pWhere); - pQuerySql->pWhere = NULL; + taosArrayDestroyEx(pSqlNode->pGroupby, freeVariant); + pSqlNode->pGroupby = NULL; - tSqlExprDestroy(pQuerySql->pHaving); - pQuerySql->pHaving = NULL; - - taosArrayDestroyEx(pQuerySql->pSortOrder, freeVariant); - pQuerySql->pSortOrder = NULL; + pSqlNode->from = destroyRelationInfo(pSqlNode->from); - taosArrayDestroyEx(pQuerySql->pGroupby, freeVariant); - pQuerySql->pGroupby = NULL; + taosArrayDestroyEx(pSqlNode->fillType, freeVariant); + pSqlNode->fillType = NULL; - pQuerySql->from = destroyFromInfo(pQuerySql->from); - - taosArrayDestroyEx(pQuerySql->fillType, freeVariant); - pQuerySql->fillType = NULL; - - free(pQuerySql); + tSqlExprDestroy(pSqlNode->pHaving); + free(pSqlNode); } -void destroyAllSelectClause(SSubclauseInfo *pClause) { - if (pClause == NULL || pClause->numOfClause == 0) { +void destroyAllSqlNode(SArray *pList) { + if (pList == NULL) { return; } - for(int32_t i = 0; i < pClause->numOfClause; ++i) { - SQuerySqlNode *pQuerySql = pClause->pClause[i]; - destroyQuerySqlNode(pQuerySql); + size_t size = taosArrayGetSize(pList); + for(int32_t i = 0; i < size; ++i) { + SSqlNode *pNode = taosArrayGetP(pList, i); + destroySqlNode(pNode); } - - tfree(pClause->pClause); + + taosArrayDestroy(pList); } -SCreateTableSql *tSetCreateTableInfo(SArray *pCols, SArray *pTags, SQuerySqlNode *pSelect, int32_t type) { +SCreateTableSql *tSetCreateTableInfo(SArray *pCols, SArray *pTags, SSqlNode *pSelect, int32_t type) { SCreateTableSql *pCreate = calloc(1, sizeof(SCreateTableSql)); switch (type) { @@ -888,7 +901,7 @@ SAlterTableInfo *tSetAlterTableInfo(SStrToken *pTableName, SArray *pCols, SArray } void* destroyCreateTableSql(SCreateTableSql* pCreate) { - destroyQuerySqlNode(pCreate->pSelect); + destroySqlNode(pCreate->pSelect); taosArrayDestroy(pCreate->colInfo.pColumns); taosArrayDestroy(pCreate->colInfo.pTagColumns); @@ -903,7 +916,7 @@ void SqlInfoDestroy(SSqlInfo *pInfo) { if (pInfo == NULL) return; if (pInfo->type == TSDB_SQL_SELECT) { - destroyAllSelectClause(&pInfo->subclauseInfo); + destroyAllSqlNode(pInfo->list); } else if (pInfo->type == TSDB_SQL_CREATE_TABLE) { pInfo->pCreateTableInfo = destroyCreateTableSql(pInfo->pCreateTableInfo); } else if (pInfo->type == TSDB_SQL_ALTER_TABLE) { @@ -924,31 +937,20 @@ void SqlInfoDestroy(SSqlInfo *pInfo) { } } -SSubclauseInfo* setSubclause(SSubclauseInfo* pSubclause, void *pSqlExprInfo) { - if (pSubclause == NULL) { - pSubclause = calloc(1, sizeof(SSubclauseInfo)); +SArray* setSubclause(SArray* pList, void *pSqlNode) { + if (pList == NULL) { + pList = taosArrayInit(1, POINTER_BYTES); } - int32_t newSize = pSubclause->numOfClause + 1; - char* tmp = realloc(pSubclause->pClause, newSize * POINTER_BYTES); - if (tmp == NULL) { - return pSubclause; - } - - pSubclause->pClause = (SQuerySqlNode**) tmp; - - pSubclause->pClause[newSize - 1] = pSqlExprInfo; - pSubclause->numOfClause++; - - return pSubclause; + taosArrayPush(pList, &pSqlNode); + return pList; } SSqlInfo* setSqlInfo(SSqlInfo *pInfo, void *pSqlExprInfo, SStrToken *pTableName, int32_t type) { pInfo->type = type; if (type == TSDB_SQL_SELECT) { - pInfo->subclauseInfo = *(SSubclauseInfo*) pSqlExprInfo; - free(pSqlExprInfo); + pInfo->list = (SArray*) pSqlExprInfo; } else { pInfo->pCreateTableInfo = pSqlExprInfo; } @@ -960,16 +962,9 @@ SSqlInfo* setSqlInfo(SSqlInfo *pInfo, void *pSqlExprInfo, SStrToken *pTableName, return pInfo; } -SSubclauseInfo* appendSelectClause(SSubclauseInfo *pQueryInfo, void *pSubclause) { - char* tmp = realloc(pQueryInfo->pClause, (pQueryInfo->numOfClause + 1) * POINTER_BYTES); - if (tmp == NULL) { // out of memory - return pQueryInfo; - } - - pQueryInfo->pClause = (SQuerySqlNode**) tmp; - pQueryInfo->pClause[pQueryInfo->numOfClause++] = pSubclause; - - return pQueryInfo; +SArray* appendSelectClause(SArray *pList, void *pSubclause) { + taosArrayPush(pList, &pSubclause); + return pList; } void setCreatedTableName(SSqlInfo *pInfo, SStrToken *pTableNameToken, SStrToken *pIfNotExists) { diff --git a/src/query/src/qUtil.c b/src/query/src/qUtil.c index aa793add84..41eec68cdc 100644 --- a/src/query/src/qUtil.c +++ b/src/query/src/qUtil.c @@ -30,11 +30,11 @@ typedef struct SCompSupporter { int32_t order; } SCompSupporter; -int32_t getOutputInterResultBufSize(SQuery* pQuery) { +int32_t getOutputInterResultBufSize(SQueryAttr* pQueryAttr) { int32_t size = 0; - for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { - size += pQuery->pExpr1[i].interBytes; + for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { + size += pQueryAttr->pExpr1[i].base.interBytes; } assert(size >= 0); @@ -136,11 +136,11 @@ void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResultRow, int16 tFilePage *page = getResBufPage(pRuntimeEnv->pResultBuf, pResultRow->pageId); int16_t offset = 0; - for (int32_t i = 0; i < pRuntimeEnv->pQuery->numOfOutput; ++i) { + for (int32_t i = 0; i < pRuntimeEnv->pQueryAttr->numOfOutput; ++i) { SResultRowCellInfo *pResultInfo = &pResultRow->pCellInfo[i]; - int16_t size = pRuntimeEnv->pQuery->pExpr1[i].bytes; - char * s = getPosInResultPage(pRuntimeEnv, page, pResultRow->offset, offset, size); + int16_t size = pRuntimeEnv->pQueryAttr->pExpr1[i].base.resType; + char * s = getPosInResultPage(pRuntimeEnv->pQueryAttr, page, pResultRow->offset, offset); memset(s, 0, size); offset += size; @@ -164,8 +164,8 @@ SResultRowCellInfo* getResultCell(const SResultRow* pRow, int32_t index, int32_t } size_t getResultRowSize(SQueryRuntimeEnv* pRuntimeEnv) { - SQuery* pQuery = pRuntimeEnv->pQuery; - return (pQuery->numOfOutput * sizeof(SResultRowCellInfo)) + pQuery->interBufSize + sizeof(SResultRow); + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; + return (pQueryAttr->numOfOutput * sizeof(SResultRowCellInfo)) + pQueryAttr->interBufSize + sizeof(SResultRow); } SResultRowPool* initResultRowPool(size_t size) { @@ -382,10 +382,10 @@ int32_t getNumOfTotalRes(SGroupResInfo* pGroupResInfo) { } static int64_t getNumOfResultWindowRes(SQueryRuntimeEnv* pRuntimeEnv, SResultRow *pResultRow, int32_t* rowCellInfoOffset) { - SQuery* pQuery = pRuntimeEnv->pQuery; + SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; - for (int32_t j = 0; j < pQuery->numOfOutput; ++j) { - int32_t functionId = pQuery->pExpr1[j].base.functionId; + for (int32_t j = 0; j < pQueryAttr->numOfOutput; ++j) { + int32_t functionId = pQueryAttr->pExpr1[j].base.functionId; /* * ts, tag, tagprj function can not decide the output number of current query @@ -448,7 +448,7 @@ static int32_t tableResultComparFn(const void *pLeft, const void *pRight, void * static int32_t mergeIntoGroupResultImpl(SQueryRuntimeEnv *pRuntimeEnv, SGroupResInfo* pGroupResInfo, SArray *pTableList, int32_t* rowCellInfoOffset) { - bool ascQuery = QUERY_IS_ASC_QUERY(pRuntimeEnv->pQuery); + bool ascQuery = QUERY_IS_ASC_QUERY(pRuntimeEnv->pQueryAttr); int32_t code = TSDB_CODE_SUCCESS; @@ -484,7 +484,7 @@ static int32_t mergeIntoGroupResultImpl(SQueryRuntimeEnv *pRuntimeEnv, SGroupRes goto _end; } - SCompSupporter cs = {pTableQueryInfoList, posList, pRuntimeEnv->pQuery->order.order}; + SCompSupporter cs = {pTableQueryInfoList, posList, pRuntimeEnv->pQueryAttr->order.order}; int32_t ret = tLoserTreeCreate(&pTree, numOfTables, &cs, tableResultComparFn); if (ret != TSDB_CODE_SUCCESS) { diff --git a/src/query/src/queryMain.c b/src/query/src/queryMain.c index f4810c3f8a..562f7b8415 100644 --- a/src/query/src/queryMain.c +++ b/src/query/src/queryMain.c @@ -14,7 +14,6 @@ */ #include "os.h" -#include "qFill.h" #include "taosmsg.h" #include "tcache.h" #include "tglobal.h" @@ -23,13 +22,11 @@ #include "hash.h" #include "texpr.h" #include "qExecutor.h" -#include "qResultbuf.h" #include "qUtil.h" #include "query.h" #include "queryLog.h" #include "tlosertree.h" #include "ttype.h" -#include "tcompare.h" typedef struct SQueryMgmt { pthread_mutex_t lock; @@ -58,10 +55,13 @@ void freeParam(SQueryParam *param) { tfree(param->tagCond); tfree(param->tbnameCond); tfree(param->pTableIdList); - tfree(param->pExprMsg); - tfree(param->pSecExprMsg); + taosArrayDestroy(param->pOperator); tfree(param->pExprs); tfree(param->pSecExprs); + + tfree(param->pExpr); + tfree(param->pSecExpr); + tfree(param->pGroupColIndex); tfree(param->pTagColumnInfo); tfree(param->pGroupbyExpr); @@ -91,12 +91,14 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi goto _over; } - if ((code = createQueryFuncExprFromMsg(pQueryMsg, pQueryMsg->numOfOutput, ¶m.pExprs, param.pExprMsg, param.pTagColumnInfo, param.pUdfInfo)) != TSDB_CODE_SUCCESS) { + SQueriedTableInfo info = { .numOfTags = pQueryMsg->numOfTags, .numOfCols = pQueryMsg->numOfCols, .colList = pQueryMsg->tableCols}; + if ((code = createQueryFunc(&info, pQueryMsg->numOfOutput, ¶m.pExprs, param.pExpr, param.pTagColumnInfo, + pQueryMsg->queryType, pQueryMsg, param.pUdfInfo)) != TSDB_CODE_SUCCESS) { goto _over; } - if (param.pSecExprMsg != NULL) { - if ((code = createIndirectQueryFuncExprFromMsg(pQueryMsg, pQueryMsg->secondStageOutput, ¶m.pSecExprs, param.pSecExprMsg, param.pExprs, param.pUdfInfo)) != TSDB_CODE_SUCCESS) { + if (param.pSecExpr != NULL) { + if ((code = createIndirectQueryFuncExprFromMsg(pQueryMsg, pQueryMsg->secondStageOutput, ¶m.pSecExprs, param.pSecExpr, param.pExprs, param.pUdfInfo)) != TSDB_CODE_SUCCESS) { goto _over; } } @@ -158,7 +160,9 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi goto _over; } - (*pQInfo) = createQInfoImpl(pQueryMsg, param.pGroupbyExpr, param.pExprs, param.pSecExprs, &tableGroupInfo, param.pTagColumnInfo, isSTableQuery, param.sql, qId, param.pUdfInfo); + assert(pQueryMsg->stableQuery == isSTableQuery); + (*pQInfo) = createQInfoImpl(pQueryMsg, param.pGroupbyExpr, param.pExprs, param.pSecExprs, &tableGroupInfo, + param.pTagColumnInfo, vgId, param.sql, qId, param.pUdfInfo); if ((*pQInfo) == NULL) { code = TSDB_CODE_QRY_OUT_OF_MEMORY; @@ -172,7 +176,7 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi param.pTagColumnInfo = NULL; param.pUdfInfo = NULL; - code = initQInfo(pQueryMsg, tsdb, vgId, *pQInfo, ¶m, isSTableQuery); + code = initQInfo(&pQueryMsg->tsBuf, tsdb, NULL, *pQInfo, ¶m, (char*)pQueryMsg, pQueryMsg->prevResultLen, NULL); _over: if (param.pGroupbyExpr != NULL) { @@ -187,8 +191,8 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryMsg, qi freeParam(¶m); for (int32_t i = 0; i < pQueryMsg->numOfCols; i++) { - SColumnInfo* column = pQueryMsg->colList + i; - freeColumnFilterInfo(column->filters, column->numOfFilters); + SColumnInfo* column = pQueryMsg->tableCols + i; + freeColumnFilterInfo(column->flist.filterInfo, column->flist.numOfFilters); } //pQInfo already freed in initQInfo, but *pQInfo may not pointer to null; @@ -208,23 +212,22 @@ bool qTableQuery(qinfo_t qinfo, uint64_t *qId) { int64_t curOwner = 0; if ((curOwner = atomic_val_compare_exchange_64(&pQInfo->owner, 0, threadId)) != 0) { - qError("QInfo:%"PRIu64"-%p qhandle is now executed by thread:%p", pQInfo->qId, pQInfo, (void*) curOwner); + qError("QInfo:0x%"PRIx64"-%p qhandle is now executed by thread:%p", pQInfo->qId, pQInfo, (void*) curOwner); pQInfo->code = TSDB_CODE_QRY_IN_EXEC; return false; } - *qId = pQInfo->qId; pQInfo->startExecTs = taosGetTimestampSec(); if (isQueryKilled(pQInfo)) { - qDebug("QInfo:%"PRIu64" it is already killed, abort", pQInfo->qId); + qDebug("QInfo:0x%"PRIx64" it is already killed, abort", pQInfo->qId); return doBuildResCheck(pQInfo); } SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; if (pRuntimeEnv->tableqinfoGroupInfo.numOfTables == 0) { - qDebug("QInfo:%"PRIu64" no table exists for query, abort", pQInfo->qId); + qDebug("QInfo:0x%"PRIx64" no table exists for query, abort", pQInfo->qId); setQueryStatus(pRuntimeEnv, QUERY_COMPLETED); return doBuildResCheck(pQInfo); } @@ -233,21 +236,22 @@ bool qTableQuery(qinfo_t qinfo, uint64_t *qId) { int32_t ret = setjmp(pQInfo->runtimeEnv.env); if (ret != TSDB_CODE_SUCCESS) { pQInfo->code = ret; - qDebug("QInfo:%"PRIu64" query abort due to error/cancel occurs, code:%s", pQInfo->qId, tstrerror(pQInfo->code)); + qDebug("QInfo:0x%"PRIx64" query abort due to error/cancel occurs, code:%s", pQInfo->qId, tstrerror(pQInfo->code)); return doBuildResCheck(pQInfo); } - qDebug("QInfo:%"PRIu64" query task is launched", pQInfo->qId); + qDebug("QInfo:0x%"PRIx64" query task is launched", pQInfo->qId); - pRuntimeEnv->outputBuf = pRuntimeEnv->proot->exec(pRuntimeEnv->proot); + bool newgroup = false; + pRuntimeEnv->outputBuf = pRuntimeEnv->proot->exec(pRuntimeEnv->proot, &newgroup); if (isQueryKilled(pQInfo)) { - qDebug("QInfo:%"PRIu64" query is killed", pQInfo->qId); + qDebug("QInfo:0x%"PRIx64" query is killed", pQInfo->qId); } else if (GET_NUM_OF_RESULTS(pRuntimeEnv) == 0) { - qDebug("QInfo:%"PRIu64" over, %u tables queried, %"PRId64" rows are returned", pQInfo->qId, pRuntimeEnv->tableqinfoGroupInfo.numOfTables, + qDebug("QInfo:0x%"PRIx64" over, %u tables queried, %"PRId64" rows are returned", pQInfo->qId, pRuntimeEnv->tableqinfoGroupInfo.numOfTables, pRuntimeEnv->resultInfo.total); } else { - qDebug("QInfo:%"PRIu64" query paused, %d rows returned, numOfTotal:%" PRId64 " rows", + qDebug("QInfo:0x%"PRIx64" query paused, %d rows returned, numOfTotal:%" PRId64 " rows", pQInfo->qId, GET_NUM_OF_RESULTS(pRuntimeEnv), pRuntimeEnv->resultInfo.total + GET_NUM_OF_RESULTS(pRuntimeEnv)); } @@ -258,13 +262,13 @@ int32_t qRetrieveQueryResultInfo(qinfo_t qinfo, bool* buildRes, void* pRspContex SQInfo *pQInfo = (SQInfo *)qinfo; if (pQInfo == NULL || !isValidQInfo(pQInfo)) { - qError("QInfo:%"PRIu64" invalid qhandle", pQInfo->qId); + qError("QInfo:0x%"PRIx64" invalid qhandle", pQInfo->qId); return TSDB_CODE_QRY_INVALID_QHANDLE; } *buildRes = false; if (IS_QUERY_KILLED(pQInfo)) { - qDebug("QInfo:%"PRIu64" query is killed, code:0x%08x", pQInfo->qId, pQInfo->code); + qDebug("QInfo:0x%"PRIx64" query is killed, code:0x%08x", pQInfo->qId, pQInfo->code); return pQInfo->code; } @@ -277,18 +281,18 @@ int32_t qRetrieveQueryResultInfo(qinfo_t qinfo, bool* buildRes, void* pRspContex code = pQInfo->code; } else { SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; - SQuery *pQuery = pQInfo->runtimeEnv.pQuery; + SQueryAttr *pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; pthread_mutex_lock(&pQInfo->lock); assert(pQInfo->rspContext == NULL); if (pQInfo->dataReady == QUERY_RESULT_READY) { *buildRes = true; - qDebug("QInfo:%"PRIu64" retrieve result info, rowsize:%d, rows:%d, code:%s", pQInfo->qId, pQuery->resultRowSize, + qDebug("QInfo:0x%"PRIx64" retrieve result info, rowsize:%d, rows:%d, code:%s", pQInfo->qId, pQueryAttr->resultRowSize, GET_NUM_OF_RESULTS(pRuntimeEnv), tstrerror(pQInfo->code)); } else { *buildRes = false; - qDebug("QInfo:%"PRIu64" retrieve req set query return result after paused", pQInfo->qId); + qDebug("QInfo:0x%"PRIx64" retrieve req set query return result after paused", pQInfo->qId); pQInfo->rspContext = pRspContext; assert(pQInfo->rspContext != NULL); } @@ -307,11 +311,11 @@ int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp **pRsp, int32_t *co return TSDB_CODE_QRY_INVALID_QHANDLE; } - SQuery *pQuery = pQInfo->runtimeEnv.pQuery; + SQueryAttr *pQueryAttr = pQInfo->runtimeEnv.pQueryAttr; SQueryRuntimeEnv* pRuntimeEnv = &pQInfo->runtimeEnv; int32_t s = GET_NUM_OF_RESULTS(pRuntimeEnv); - size_t size = pQuery->resultRowSize * s; + size_t size = pQueryAttr->resultRowSize * s; size += sizeof(int32_t); size += sizeof(STableIdInfo) * taosHashGetSize(pRuntimeEnv->pTableRetrieveTsMap); @@ -333,7 +337,7 @@ int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp **pRsp, int32_t *co (*pRsp)->useconds = htobe64(pQInfo->summary.elapsedTime); } - (*pRsp)->precision = htons(pQuery->precision); + (*pRsp)->precision = htons(pQueryAttr->precision); if (GET_NUM_OF_RESULTS(&(pQInfo->runtimeEnv)) > 0 && pQInfo->code == TSDB_CODE_SUCCESS) { doDumpQueryResult(pQInfo, (*pRsp)->data); } else { @@ -347,10 +351,10 @@ int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp **pRsp, int32_t *co // here current thread hold the refcount, so it is safe to free tsdbQueryHandle. *continueExec = false; (*pRsp)->completed = 1; // notify no more result to client - qDebug("QInfo:%"PRIu64" no more results to retrieve", pQInfo->qId); + qDebug("QInfo:0x%"PRIx64" no more results to retrieve", pQInfo->qId); } else { *continueExec = true; - qDebug("QInfo:%"PRIu64" has more results to retrieve", pQInfo->qId); + qDebug("QInfo:0x%"PRIx64" has more results to retrieve", pQInfo->qId); } // the memory should be freed if the code of pQInfo is not TSDB_CODE_SUCCESS @@ -376,7 +380,7 @@ int32_t qKillQuery(qinfo_t qinfo) { return TSDB_CODE_QRY_INVALID_QHANDLE; } - qDebug("QInfo:%"PRIu64" query killed", pQInfo->qId); + qDebug("QInfo:0x%"PRIx64" query killed", pQInfo->qId); setQueryKilled(pQInfo); // Wait for the query executing thread being stopped/ @@ -404,7 +408,7 @@ void qDestroyQueryInfo(qinfo_t qHandle) { return; } - qDebug("QInfo:%"PRIu64" query completed", pQInfo->qId); + qDebug("QInfo:0x%"PRIx64" query completed", pQInfo->qId); queryCostStatis(pQInfo); // print the query cost summary freeQInfo(pQInfo); } @@ -487,7 +491,7 @@ void** qRegisterQInfo(void* pMgmt, uint64_t qId, void *qInfo) { SQueryMgmt *pQueryMgmt = pMgmt; if (pQueryMgmt->qinfoPool == NULL) { - qError("QInfo:%"PRIu64"-%p failed to add qhandle into qMgmt, since qMgmt is closed", qId, (void*)qInfo); + qError("QInfo:0x%"PRIx64"-%p failed to add qhandle into qMgmt, since qMgmt is closed", qId, (void*)qInfo); terrno = TSDB_CODE_VND_INVALID_VGROUP_ID; return NULL; } @@ -495,7 +499,7 @@ void** qRegisterQInfo(void* pMgmt, uint64_t qId, void *qInfo) { pthread_mutex_lock(&pQueryMgmt->lock); if (pQueryMgmt->closed) { pthread_mutex_unlock(&pQueryMgmt->lock); - qError("QInfo:%"PRIu64"-%p failed to add qhandle into cache, since qMgmt is colsing", qId, (void*)qInfo); + qError("QInfo:0x%"PRIx64"-%p failed to add qhandle into cache, since qMgmt is colsing", qId, (void*)qInfo); terrno = TSDB_CODE_VND_INVALID_VGROUP_ID; return NULL; } else { diff --git a/src/query/src/sql.c b/src/query/src/sql.c index a6070af416..691c5b5dcd 100644 --- a/src/query/src/sql.c +++ b/src/query/src/sql.c @@ -23,7 +23,6 @@ ** input grammar file: */ #include -#include /************ Begin %include sections from the grammar ************************/ #include @@ -77,10 +76,8 @@ ** 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. @@ -100,57 +97,48 @@ #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int -#define YYNOCODE 268 +#define YYNOCODE 270 #define YYACTIONTYPE unsigned short int #define ParseTOKENTYPE SStrToken typedef union { int yyinit; ParseTOKENTYPE yy0; - SCreateDbInfo yy22; - TAOS_FIELD yy47; - SCreateAcctInfo yy83; - SSessionWindowVal yy84; - SSubclauseInfo* yy145; - tSqlExpr* yy162; - int yy196; - SLimitVal yy230; - SArray* yy325; - SIntervalVal yy328; - int64_t yy373; - SCreateTableSql* yy422; - tVariant yy442; - SQuerySqlNode* yy494; - SCreatedTableInfo yy504; - SFromInfo* yy506; + SSessionWindowVal yy15; + SIntervalVal yy42; + tSqlExpr* yy68; + SCreateAcctInfo yy77; + SArray* yy93; + int yy150; + SSqlNode* yy224; + int64_t yy279; + SLimitVal yy284; + TAOS_FIELD yy325; + SRelationInfo* yy330; + SCreateDbInfo yy372; + tVariant yy518; + SCreatedTableInfo yy528; + SCreateTableSql* yy532; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 #endif #define ParseARG_SDECL SSqlInfo* pInfo; #define ParseARG_PDECL ,SSqlInfo* 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 ParseARG_FETCH SSqlInfo* pInfo = yypParser->pInfo +#define ParseARG_STORE yypParser->pInfo = pInfo #define YYFALLBACK 1 #define YYNSTATE 330 -#define YYNRULE 273 -#define YYNRULE_WITH_ACTION 273 +#define YYNRULE 275 #define YYNTOKEN 192 #define YY_MAX_SHIFT 329 -#define YY_MIN_SHIFTREDUCE 526 -#define YY_MAX_SHIFTREDUCE 798 -#define YY_ERROR_ACTION 799 -#define YY_ACCEPT_ACTION 800 -#define YY_NO_ACTION 801 -#define YY_MIN_REDUCE 802 -#define YY_MAX_REDUCE 1074 +#define YY_MIN_SHIFTREDUCE 528 +#define YY_MAX_SHIFTREDUCE 802 +#define YY_ERROR_ACTION 803 +#define YY_ACCEPT_ACTION 804 +#define YY_NO_ACTION 805 +#define YY_MIN_REDUCE 806 +#define YY_MAX_REDUCE 1080 /************* 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. @@ -215,266 +203,266 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (694) +#define YY_ACTTAB_COUNT (696) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 975, 575, 190, 575, 211, 327, 235, 17, 84, 576, - /* 10 */ 575, 576, 1055, 49, 50, 161, 53, 54, 576, 215, + /* 0 */ 979, 577, 190, 577, 213, 327, 235, 17, 84, 578, + /* 10 */ 577, 578, 1061, 49, 50, 161, 53, 54, 578, 188, /* 20 */ 223, 43, 190, 52, 271, 57, 55, 59, 56, 32, - /* 30 */ 140, 218, 1056, 48, 47, 800, 329, 46, 45, 44, - /* 40 */ 937, 938, 29, 941, 954, 948, 87, 527, 528, 529, - /* 50 */ 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, - /* 60 */ 540, 328, 228, 972, 240, 49, 50, 147, 53, 54, - /* 70 */ 147, 212, 223, 43, 951, 52, 271, 57, 55, 59, - /* 80 */ 56, 942, 966, 72, 293, 48, 47, 954, 229, 46, + /* 30 */ 140, 220, 1062, 48, 47, 804, 329, 46, 45, 44, + /* 40 */ 941, 942, 29, 945, 752, 952, 755, 529, 530, 531, + /* 50 */ 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, + /* 60 */ 542, 328, 217, 976, 240, 49, 50, 147, 53, 54, + /* 70 */ 147, 214, 223, 43, 955, 52, 271, 57, 55, 59, + /* 80 */ 56, 194, 970, 72, 293, 48, 47, 958, 229, 46, /* 90 */ 45, 44, 49, 50, 256, 53, 54, 251, 313, 223, /* 100 */ 43, 190, 52, 271, 57, 55, 59, 56, 71, 32, - /* 110 */ 217, 1056, 48, 47, 76, 235, 46, 45, 44, 49, - /* 120 */ 51, 38, 53, 54, 162, 230, 223, 43, 188, 52, - /* 130 */ 271, 57, 55, 59, 56, 1007, 268, 266, 80, 48, - /* 140 */ 47, 939, 232, 46, 45, 44, 50, 966, 53, 54, - /* 150 */ 954, 226, 223, 43, 951, 52, 271, 57, 55, 59, - /* 160 */ 56, 849, 213, 744, 32, 48, 47, 175, 194, 46, + /* 110 */ 219, 1062, 48, 47, 76, 235, 46, 45, 44, 49, + /* 120 */ 51, 38, 53, 54, 162, 28, 223, 43, 277, 52, + /* 130 */ 271, 57, 55, 59, 56, 1011, 268, 266, 80, 48, + /* 140 */ 47, 943, 577, 46, 45, 44, 50, 970, 53, 54, + /* 150 */ 578, 226, 223, 43, 955, 52, 271, 57, 55, 59, + /* 160 */ 56, 759, 215, 746, 32, 48, 47, 1, 163, 46, /* 170 */ 45, 44, 23, 291, 322, 321, 290, 289, 288, 320, - /* 180 */ 287, 319, 318, 317, 286, 316, 315, 914, 1052, 902, - /* 190 */ 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, - /* 200 */ 913, 915, 916, 53, 54, 18, 227, 223, 43, 951, - /* 210 */ 52, 271, 57, 55, 59, 56, 233, 234, 940, 295, - /* 220 */ 48, 47, 147, 198, 46, 45, 44, 222, 757, 200, - /* 230 */ 32, 748, 82, 751, 1051, 754, 124, 123, 199, 922, - /* 240 */ 222, 757, 920, 921, 748, 73, 751, 923, 754, 925, - /* 250 */ 926, 924, 1050, 927, 928, 83, 32, 1066, 147, 219, - /* 260 */ 220, 48, 47, 270, 697, 46, 45, 44, 326, 325, - /* 270 */ 133, 76, 219, 220, 23, 950, 322, 321, 38, 1, - /* 280 */ 163, 320, 12, 319, 318, 317, 86, 316, 315, 32, - /* 290 */ 1006, 236, 725, 726, 300, 299, 32, 207, 296, 293, - /* 300 */ 250, 951, 70, 57, 55, 59, 56, 208, 206, 32, - /* 310 */ 575, 48, 47, 5, 165, 46, 45, 44, 576, 35, - /* 320 */ 164, 93, 98, 89, 97, 682, 81, 750, 679, 753, - /* 330 */ 680, 297, 681, 858, 951, 282, 58, 658, 301, 175, - /* 340 */ 850, 951, 758, 323, 243, 272, 175, 701, 756, 58, - /* 350 */ 192, 305, 247, 246, 951, 758, 237, 238, 46, 45, - /* 360 */ 44, 756, 235, 111, 755, 303, 302, 193, 954, 109, - /* 370 */ 114, 952, 313, 3, 176, 103, 113, 755, 119, 122, - /* 380 */ 112, 183, 179, 749, 746, 752, 116, 181, 178, 128, - /* 390 */ 127, 126, 125, 252, 694, 704, 221, 33, 66, 710, - /* 400 */ 24, 716, 254, 142, 717, 62, 778, 759, 20, 63, - /* 410 */ 19, 19, 668, 686, 274, 687, 33, 67, 33, 25, - /* 420 */ 747, 670, 276, 669, 953, 62, 85, 62, 195, 28, - /* 430 */ 64, 684, 277, 685, 102, 101, 69, 248, 657, 683, - /* 440 */ 14, 13, 108, 107, 1017, 6, 761, 16, 15, 121, - /* 450 */ 120, 138, 136, 189, 196, 197, 203, 204, 202, 187, - /* 460 */ 139, 1016, 201, 191, 224, 1013, 1012, 225, 304, 974, - /* 470 */ 41, 982, 984, 999, 998, 141, 967, 255, 137, 257, - /* 480 */ 949, 145, 158, 157, 947, 214, 283, 159, 918, 156, - /* 490 */ 259, 264, 152, 160, 709, 863, 964, 279, 148, 149, - /* 500 */ 280, 150, 281, 284, 269, 151, 263, 60, 285, 39, - /* 510 */ 185, 36, 294, 68, 65, 857, 267, 265, 153, 1071, - /* 520 */ 99, 261, 1070, 1068, 166, 258, 298, 154, 1065, 105, - /* 530 */ 42, 1064, 1062, 167, 883, 37, 34, 40, 186, 846, - /* 540 */ 115, 844, 117, 118, 842, 841, 239, 177, 839, 838, - /* 550 */ 837, 836, 835, 834, 833, 180, 182, 830, 828, 826, - /* 560 */ 824, 822, 184, 314, 253, 74, 77, 110, 306, 260, - /* 570 */ 1000, 307, 308, 309, 310, 311, 312, 324, 209, 798, - /* 580 */ 231, 241, 278, 242, 797, 244, 245, 796, 784, 783, - /* 590 */ 210, 94, 862, 95, 861, 205, 249, 254, 689, 273, - /* 600 */ 8, 216, 711, 75, 78, 840, 714, 129, 169, 884, - /* 610 */ 172, 168, 170, 174, 171, 173, 130, 832, 2, 131, - /* 620 */ 831, 155, 132, 823, 143, 144, 4, 79, 262, 9, - /* 630 */ 26, 27, 718, 146, 10, 760, 7, 11, 930, 21, - /* 640 */ 88, 762, 22, 275, 30, 86, 90, 91, 589, 31, - /* 650 */ 92, 621, 617, 615, 614, 613, 610, 579, 96, 292, - /* 660 */ 33, 61, 660, 659, 656, 605, 100, 603, 595, 601, - /* 670 */ 597, 599, 104, 593, 591, 624, 623, 106, 622, 620, - /* 680 */ 619, 618, 616, 612, 611, 62, 577, 544, 134, 542, - /* 690 */ 802, 801, 801, 135, + /* 180 */ 287, 319, 318, 317, 286, 316, 315, 918, 660, 906, + /* 190 */ 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, + /* 200 */ 917, 919, 920, 53, 54, 18, 227, 223, 43, 955, + /* 210 */ 52, 271, 57, 55, 59, 56, 303, 302, 3, 176, + /* 220 */ 48, 47, 32, 198, 46, 45, 44, 222, 761, 200, + /* 230 */ 228, 750, 944, 753, 243, 756, 124, 123, 199, 147, + /* 240 */ 222, 761, 247, 246, 750, 230, 753, 32, 756, 32, + /* 250 */ 323, 25, 147, 272, 926, 958, 234, 924, 925, 209, + /* 260 */ 210, 248, 927, 270, 929, 930, 928, 954, 931, 932, + /* 270 */ 958, 76, 209, 210, 23, 958, 322, 321, 38, 1058, + /* 280 */ 751, 320, 754, 319, 318, 317, 232, 316, 315, 296, + /* 290 */ 684, 297, 955, 681, 955, 682, 32, 683, 727, 728, + /* 300 */ 250, 235, 70, 57, 55, 59, 56, 1010, 206, 87, + /* 310 */ 956, 48, 47, 293, 32, 46, 45, 44, 5, 165, + /* 320 */ 81, 237, 238, 111, 35, 164, 93, 98, 89, 97, + /* 330 */ 236, 83, 313, 300, 299, 699, 58, 853, 301, 862, + /* 340 */ 282, 955, 762, 175, 946, 175, 48, 47, 758, 58, + /* 350 */ 46, 45, 44, 252, 765, 762, 305, 33, 12, 955, + /* 360 */ 233, 758, 86, 295, 757, 46, 45, 44, 1057, 109, + /* 370 */ 114, 82, 326, 325, 133, 103, 113, 757, 119, 122, + /* 380 */ 112, 183, 179, 748, 73, 221, 116, 181, 178, 128, + /* 390 */ 127, 126, 125, 854, 696, 706, 63, 760, 1056, 175, + /* 400 */ 24, 712, 254, 718, 685, 142, 719, 62, 782, 66, + /* 410 */ 20, 763, 19, 102, 101, 19, 670, 64, 703, 749, + /* 420 */ 33, 274, 672, 276, 207, 33, 62, 85, 67, 14, + /* 430 */ 13, 671, 108, 107, 6, 62, 69, 208, 659, 16, + /* 440 */ 15, 688, 686, 689, 687, 121, 120, 138, 136, 192, + /* 450 */ 1072, 193, 195, 189, 196, 197, 203, 204, 202, 187, + /* 460 */ 201, 191, 957, 1021, 1020, 139, 224, 1017, 1016, 225, + /* 470 */ 304, 41, 978, 986, 1003, 1002, 988, 137, 141, 145, + /* 480 */ 971, 255, 253, 158, 953, 257, 216, 157, 74, 951, + /* 490 */ 711, 283, 922, 110, 314, 159, 261, 160, 867, 279, + /* 500 */ 280, 150, 148, 68, 281, 284, 968, 259, 264, 65, + /* 510 */ 285, 39, 185, 36, 149, 294, 269, 861, 1077, 99, + /* 520 */ 60, 1076, 267, 1074, 151, 166, 298, 1071, 105, 1070, + /* 530 */ 1068, 167, 887, 37, 34, 40, 186, 850, 115, 848, + /* 540 */ 117, 118, 846, 845, 239, 177, 843, 842, 841, 840, + /* 550 */ 839, 838, 837, 180, 182, 834, 832, 830, 828, 826, + /* 560 */ 184, 265, 77, 260, 263, 258, 1004, 42, 306, 307, + /* 570 */ 308, 309, 310, 211, 311, 231, 312, 278, 324, 802, + /* 580 */ 242, 241, 801, 244, 212, 245, 800, 866, 94, 865, + /* 590 */ 205, 788, 95, 787, 249, 254, 273, 8, 75, 143, + /* 600 */ 844, 691, 129, 836, 170, 174, 130, 888, 168, 169, + /* 610 */ 171, 172, 131, 173, 835, 2, 132, 827, 4, 78, + /* 620 */ 152, 153, 154, 155, 156, 713, 716, 144, 218, 79, + /* 630 */ 262, 934, 720, 146, 9, 10, 764, 26, 7, 27, + /* 640 */ 11, 21, 766, 22, 88, 275, 30, 90, 86, 91, + /* 650 */ 591, 31, 92, 623, 619, 617, 616, 615, 612, 33, + /* 660 */ 96, 581, 292, 662, 61, 661, 658, 607, 605, 597, + /* 670 */ 603, 100, 599, 104, 601, 595, 593, 626, 625, 106, + /* 680 */ 624, 622, 621, 620, 618, 614, 613, 62, 579, 134, + /* 690 */ 546, 544, 806, 805, 805, 135, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 195, 1, 257, 1, 194, 195, 195, 257, 201, 9, - /* 10 */ 1, 9, 267, 13, 14, 204, 16, 17, 9, 216, - /* 20 */ 20, 21, 257, 23, 24, 25, 26, 27, 28, 195, - /* 30 */ 195, 266, 267, 33, 34, 192, 193, 37, 38, 39, - /* 40 */ 233, 234, 235, 236, 241, 195, 201, 45, 46, 47, + /* 0 */ 196, 1, 258, 1, 195, 196, 196, 258, 202, 9, + /* 10 */ 1, 9, 268, 13, 14, 205, 16, 17, 9, 258, + /* 20 */ 20, 21, 258, 23, 24, 25, 26, 27, 28, 196, + /* 30 */ 196, 267, 268, 33, 34, 193, 194, 37, 38, 39, + /* 40 */ 234, 235, 236, 237, 5, 196, 7, 45, 46, 47, /* 50 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 60 */ 58, 59, 216, 258, 62, 13, 14, 195, 16, 17, - /* 70 */ 195, 237, 20, 21, 240, 23, 24, 25, 26, 27, - /* 80 */ 28, 236, 239, 83, 81, 33, 34, 241, 238, 37, - /* 90 */ 38, 39, 13, 14, 259, 16, 17, 254, 87, 20, - /* 100 */ 21, 257, 23, 24, 25, 26, 27, 28, 201, 195, - /* 110 */ 266, 267, 33, 34, 110, 195, 37, 38, 39, 13, - /* 120 */ 14, 117, 16, 17, 204, 216, 20, 21, 257, 23, - /* 130 */ 24, 25, 26, 27, 28, 263, 261, 265, 263, 33, - /* 140 */ 34, 234, 68, 37, 38, 39, 14, 239, 16, 17, - /* 150 */ 241, 237, 20, 21, 240, 23, 24, 25, 26, 27, - /* 160 */ 28, 200, 254, 111, 195, 33, 34, 206, 257, 37, + /* 60 */ 58, 59, 217, 259, 62, 13, 14, 196, 16, 17, + /* 70 */ 196, 238, 20, 21, 241, 23, 24, 25, 26, 27, + /* 80 */ 28, 258, 240, 83, 81, 33, 34, 242, 239, 37, + /* 90 */ 38, 39, 13, 14, 260, 16, 17, 255, 87, 20, + /* 100 */ 21, 258, 23, 24, 25, 26, 27, 28, 202, 196, + /* 110 */ 267, 268, 33, 34, 110, 196, 37, 38, 39, 13, + /* 120 */ 14, 117, 16, 17, 205, 110, 20, 21, 113, 23, + /* 130 */ 24, 25, 26, 27, 28, 264, 262, 266, 264, 33, + /* 140 */ 34, 235, 1, 37, 38, 39, 14, 240, 16, 17, + /* 150 */ 9, 238, 20, 21, 241, 23, 24, 25, 26, 27, + /* 160 */ 28, 122, 255, 111, 196, 33, 34, 203, 204, 37, /* 170 */ 38, 39, 94, 95, 96, 97, 98, 99, 100, 101, - /* 180 */ 102, 103, 104, 105, 106, 107, 108, 215, 257, 217, - /* 190 */ 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, - /* 200 */ 228, 229, 230, 16, 17, 44, 237, 20, 21, 240, - /* 210 */ 23, 24, 25, 26, 27, 28, 142, 68, 0, 145, - /* 220 */ 33, 34, 195, 62, 37, 38, 39, 1, 2, 68, - /* 230 */ 195, 5, 242, 7, 257, 9, 75, 76, 77, 215, - /* 240 */ 1, 2, 218, 219, 5, 255, 7, 223, 9, 225, - /* 250 */ 226, 227, 257, 229, 230, 83, 195, 241, 195, 33, - /* 260 */ 34, 33, 34, 37, 37, 37, 38, 39, 65, 66, - /* 270 */ 67, 110, 33, 34, 94, 240, 96, 97, 117, 202, - /* 280 */ 203, 101, 110, 103, 104, 105, 114, 107, 108, 195, - /* 290 */ 263, 142, 129, 130, 145, 146, 195, 257, 237, 81, - /* 300 */ 139, 240, 141, 25, 26, 27, 28, 257, 147, 195, - /* 310 */ 1, 33, 34, 63, 64, 37, 38, 39, 9, 69, - /* 320 */ 70, 71, 72, 73, 74, 2, 263, 5, 5, 7, - /* 330 */ 7, 237, 9, 200, 240, 85, 110, 5, 237, 206, - /* 340 */ 200, 240, 116, 216, 140, 15, 206, 120, 122, 110, - /* 350 */ 257, 237, 148, 149, 240, 116, 33, 34, 37, 38, - /* 360 */ 39, 122, 195, 78, 138, 33, 34, 257, 241, 63, - /* 370 */ 64, 204, 87, 198, 199, 69, 70, 138, 72, 73, - /* 380 */ 74, 63, 64, 5, 1, 7, 80, 69, 70, 71, - /* 390 */ 72, 73, 74, 111, 115, 111, 61, 115, 115, 111, - /* 400 */ 121, 111, 118, 115, 111, 115, 111, 111, 115, 115, - /* 410 */ 115, 115, 111, 5, 111, 7, 115, 134, 115, 110, - /* 420 */ 37, 111, 111, 111, 241, 115, 115, 115, 257, 110, - /* 430 */ 136, 5, 113, 7, 143, 144, 110, 195, 112, 116, - /* 440 */ 143, 144, 143, 144, 232, 110, 116, 143, 144, 78, - /* 450 */ 79, 63, 64, 257, 257, 257, 257, 257, 257, 257, - /* 460 */ 195, 232, 257, 257, 232, 232, 232, 232, 232, 195, - /* 470 */ 256, 195, 195, 264, 264, 195, 239, 239, 61, 260, - /* 480 */ 239, 195, 195, 243, 195, 260, 86, 195, 231, 244, - /* 490 */ 260, 260, 248, 195, 122, 195, 253, 195, 252, 251, - /* 500 */ 195, 250, 195, 195, 127, 249, 125, 132, 195, 195, - /* 510 */ 195, 195, 195, 133, 135, 195, 131, 126, 247, 195, - /* 520 */ 195, 124, 195, 195, 195, 123, 195, 246, 195, 195, - /* 530 */ 137, 195, 195, 195, 195, 195, 195, 195, 195, 195, - /* 540 */ 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, - /* 550 */ 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, - /* 560 */ 195, 195, 195, 109, 196, 196, 196, 93, 92, 196, - /* 570 */ 196, 51, 89, 91, 55, 90, 88, 81, 196, 5, - /* 580 */ 196, 150, 196, 5, 5, 150, 5, 5, 96, 95, - /* 590 */ 196, 201, 205, 201, 205, 196, 140, 118, 111, 113, - /* 600 */ 110, 1, 111, 119, 115, 196, 111, 197, 212, 214, - /* 610 */ 209, 213, 208, 207, 211, 210, 197, 196, 202, 197, - /* 620 */ 196, 245, 197, 196, 110, 115, 198, 110, 110, 128, - /* 630 */ 115, 115, 111, 110, 128, 111, 110, 110, 231, 110, - /* 640 */ 78, 116, 110, 113, 84, 114, 83, 71, 5, 84, - /* 650 */ 83, 9, 5, 5, 5, 5, 5, 82, 78, 15, - /* 660 */ 115, 16, 5, 5, 111, 5, 144, 5, 5, 5, - /* 670 */ 5, 5, 144, 5, 5, 5, 5, 144, 5, 5, - /* 680 */ 5, 5, 5, 5, 5, 115, 82, 61, 21, 60, - /* 690 */ 0, 268, 268, 21, 268, 268, 268, 268, 268, 268, - /* 700 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - /* 710 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - /* 720 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - /* 730 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - /* 740 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - /* 750 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - /* 760 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - /* 770 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - /* 780 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - /* 790 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - /* 800 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - /* 810 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - /* 820 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - /* 830 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - /* 840 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - /* 850 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - /* 860 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - /* 870 */ 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - /* 880 */ 268, 268, 268, 268, 268, 268, + /* 180 */ 102, 103, 104, 105, 106, 107, 108, 216, 5, 218, + /* 190 */ 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + /* 200 */ 229, 230, 231, 16, 17, 44, 238, 20, 21, 241, + /* 210 */ 23, 24, 25, 26, 27, 28, 33, 34, 199, 200, + /* 220 */ 33, 34, 196, 62, 37, 38, 39, 1, 2, 68, + /* 230 */ 217, 5, 0, 7, 140, 9, 75, 76, 77, 196, + /* 240 */ 1, 2, 148, 149, 5, 217, 7, 196, 9, 196, + /* 250 */ 217, 110, 196, 15, 216, 242, 68, 219, 220, 33, + /* 260 */ 34, 196, 224, 37, 226, 227, 228, 241, 230, 231, + /* 270 */ 242, 110, 33, 34, 94, 242, 96, 97, 117, 258, + /* 280 */ 5, 101, 7, 103, 104, 105, 68, 107, 108, 238, + /* 290 */ 2, 238, 241, 5, 241, 7, 196, 9, 129, 130, + /* 300 */ 139, 196, 141, 25, 26, 27, 28, 264, 147, 202, + /* 310 */ 205, 33, 34, 81, 196, 37, 38, 39, 63, 64, + /* 320 */ 264, 33, 34, 78, 69, 70, 71, 72, 73, 74, + /* 330 */ 142, 83, 87, 145, 146, 37, 110, 201, 238, 201, + /* 340 */ 85, 241, 116, 207, 237, 207, 33, 34, 122, 110, + /* 350 */ 37, 38, 39, 111, 116, 116, 238, 115, 110, 241, + /* 360 */ 142, 122, 114, 145, 138, 37, 38, 39, 258, 63, + /* 370 */ 64, 243, 65, 66, 67, 69, 70, 138, 72, 73, + /* 380 */ 74, 63, 64, 1, 256, 61, 80, 69, 70, 71, + /* 390 */ 72, 73, 74, 201, 115, 111, 115, 122, 258, 207, + /* 400 */ 121, 111, 118, 111, 116, 115, 111, 115, 111, 115, + /* 410 */ 115, 111, 115, 143, 144, 115, 111, 136, 120, 37, + /* 420 */ 115, 111, 111, 111, 258, 115, 115, 115, 134, 143, + /* 430 */ 144, 111, 143, 144, 110, 115, 110, 258, 112, 143, + /* 440 */ 144, 5, 5, 7, 7, 78, 79, 63, 64, 258, + /* 450 */ 242, 258, 258, 258, 258, 258, 258, 258, 258, 258, + /* 460 */ 258, 258, 242, 233, 233, 196, 233, 233, 233, 233, + /* 470 */ 233, 257, 196, 196, 265, 265, 196, 61, 196, 196, + /* 480 */ 240, 240, 197, 196, 240, 261, 261, 244, 197, 196, + /* 490 */ 122, 86, 232, 93, 109, 196, 124, 196, 196, 196, + /* 500 */ 196, 251, 253, 133, 196, 196, 254, 261, 261, 135, + /* 510 */ 196, 196, 196, 196, 252, 196, 127, 196, 196, 196, + /* 520 */ 132, 196, 131, 196, 250, 196, 196, 196, 196, 196, + /* 530 */ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + /* 540 */ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + /* 550 */ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + /* 560 */ 196, 126, 197, 197, 125, 123, 197, 137, 92, 51, + /* 570 */ 89, 91, 55, 197, 90, 197, 88, 197, 81, 5, + /* 580 */ 5, 150, 5, 150, 197, 5, 5, 206, 202, 206, + /* 590 */ 197, 96, 202, 95, 140, 118, 113, 110, 119, 110, + /* 600 */ 197, 111, 198, 197, 209, 208, 198, 215, 214, 213, + /* 610 */ 212, 210, 198, 211, 197, 203, 198, 197, 199, 115, + /* 620 */ 249, 248, 247, 246, 245, 111, 111, 115, 1, 110, + /* 630 */ 110, 232, 111, 110, 128, 128, 111, 115, 110, 115, + /* 640 */ 110, 110, 116, 110, 78, 113, 84, 83, 114, 71, + /* 650 */ 5, 84, 83, 9, 5, 5, 5, 5, 5, 115, + /* 660 */ 78, 82, 15, 5, 16, 5, 111, 5, 5, 5, + /* 670 */ 5, 144, 5, 144, 5, 5, 5, 5, 5, 144, + /* 680 */ 5, 5, 5, 5, 5, 5, 5, 115, 82, 21, + /* 690 */ 61, 60, 0, 269, 269, 21, 269, 269, 269, 269, + /* 700 */ 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + /* 710 */ 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + /* 720 */ 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + /* 730 */ 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + /* 740 */ 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + /* 750 */ 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + /* 760 */ 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + /* 770 */ 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + /* 780 */ 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + /* 790 */ 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + /* 800 */ 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + /* 810 */ 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + /* 820 */ 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + /* 830 */ 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + /* 840 */ 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + /* 850 */ 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + /* 860 */ 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + /* 870 */ 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + /* 880 */ 269, 269, 269, 269, 269, 269, 269, 269, }; #define YY_SHIFT_COUNT (329) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (690) +#define YY_SHIFT_MAX (692) static const unsigned short int yy_shift_ofst[] = { /* 0 */ 161, 78, 78, 180, 180, 3, 226, 239, 9, 9, /* 10 */ 9, 9, 9, 9, 9, 9, 9, 0, 2, 239, - /* 20 */ 323, 323, 323, 323, 309, 4, 9, 9, 9, 218, - /* 30 */ 9, 9, 9, 9, 285, 3, 11, 11, 694, 694, - /* 40 */ 694, 239, 239, 239, 239, 239, 239, 239, 239, 239, + /* 20 */ 288, 288, 288, 288, 141, 4, 9, 9, 9, 232, + /* 30 */ 9, 9, 9, 9, 245, 3, 11, 11, 696, 696, + /* 40 */ 696, 239, 239, 239, 239, 239, 239, 239, 239, 239, /* 50 */ 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, - /* 60 */ 239, 323, 323, 332, 332, 332, 332, 332, 332, 332, - /* 70 */ 9, 9, 9, 227, 9, 4, 4, 9, 9, 9, - /* 80 */ 163, 163, 279, 4, 9, 9, 9, 9, 9, 9, + /* 60 */ 239, 288, 288, 183, 183, 183, 183, 183, 183, 183, + /* 70 */ 9, 9, 9, 298, 9, 4, 4, 9, 9, 9, + /* 80 */ 169, 169, 279, 4, 9, 9, 9, 9, 9, 9, /* 90 */ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, /* 100 */ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, /* 110 */ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, /* 120 */ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - /* 130 */ 9, 9, 9, 9, 9, 9, 9, 9, 9, 417, - /* 140 */ 417, 417, 372, 372, 372, 417, 372, 417, 380, 379, - /* 150 */ 375, 377, 385, 391, 381, 397, 402, 393, 417, 417, - /* 160 */ 417, 400, 400, 454, 3, 3, 417, 417, 474, 476, - /* 170 */ 520, 483, 482, 519, 485, 488, 454, 417, 496, 496, - /* 180 */ 417, 496, 417, 496, 417, 694, 694, 52, 79, 106, - /* 190 */ 79, 79, 132, 187, 278, 278, 278, 278, 250, 306, - /* 200 */ 318, 228, 228, 228, 228, 149, 204, 321, 321, 172, - /* 210 */ 74, 203, 282, 284, 288, 290, 293, 295, 296, 322, - /* 220 */ 378, 383, 335, 330, 294, 283, 301, 303, 310, 311, - /* 230 */ 312, 319, 291, 297, 299, 326, 304, 408, 426, 371, - /* 240 */ 388, 574, 431, 578, 579, 435, 581, 582, 492, 494, - /* 250 */ 456, 479, 486, 490, 484, 487, 489, 491, 514, 495, - /* 260 */ 510, 517, 600, 518, 521, 523, 515, 501, 516, 506, - /* 270 */ 524, 526, 525, 527, 486, 529, 530, 532, 531, 562, - /* 280 */ 560, 563, 576, 643, 565, 567, 642, 647, 648, 649, - /* 290 */ 650, 651, 575, 644, 580, 522, 545, 545, 645, 528, - /* 300 */ 533, 545, 657, 658, 553, 545, 660, 662, 663, 664, - /* 310 */ 665, 666, 668, 669, 670, 671, 673, 674, 675, 676, - /* 320 */ 677, 678, 679, 570, 604, 667, 672, 626, 629, 690, + /* 130 */ 9, 9, 9, 9, 9, 9, 9, 9, 9, 416, + /* 140 */ 416, 416, 368, 368, 368, 416, 368, 416, 370, 374, + /* 150 */ 388, 389, 391, 435, 439, 372, 442, 430, 416, 416, + /* 160 */ 416, 405, 405, 385, 3, 3, 416, 416, 400, 476, + /* 170 */ 518, 481, 480, 517, 484, 488, 385, 416, 497, 497, + /* 180 */ 416, 497, 416, 497, 416, 696, 696, 52, 79, 106, + /* 190 */ 79, 79, 132, 187, 278, 278, 278, 278, 255, 306, + /* 200 */ 318, 313, 313, 313, 313, 188, 94, 328, 328, 39, + /* 210 */ 275, 248, 218, 307, 242, 284, 290, 292, 295, 297, + /* 220 */ 300, 382, 324, 238, 281, 294, 305, 310, 311, 312, + /* 230 */ 320, 15, 270, 286, 289, 326, 296, 436, 437, 367, + /* 240 */ 384, 574, 431, 575, 577, 433, 580, 581, 495, 498, + /* 250 */ 454, 477, 483, 487, 479, 490, 504, 514, 489, 515, + /* 260 */ 512, 519, 627, 520, 521, 523, 522, 506, 524, 507, + /* 270 */ 525, 528, 526, 530, 483, 531, 532, 533, 534, 566, + /* 280 */ 562, 564, 578, 645, 567, 569, 644, 649, 650, 651, + /* 290 */ 652, 653, 579, 647, 582, 527, 544, 544, 648, 529, + /* 300 */ 535, 544, 658, 660, 555, 544, 662, 663, 664, 665, + /* 310 */ 667, 669, 670, 671, 672, 673, 675, 676, 677, 678, + /* 320 */ 679, 680, 681, 572, 606, 668, 674, 629, 631, 692, }; #define YY_REDUCE_COUNT (186) -#define YY_REDUCE_MIN (-255) -#define YY_REDUCE_MAX (428) +#define YY_REDUCE_MIN (-256) +#define YY_REDUCE_MAX (420) static const short yy_reduce_ofst[] = { - /* 0 */ -157, -28, -28, 24, 24, -193, -235, -156, -166, -128, - /* 10 */ -125, -86, -31, 61, 94, 101, 114, -195, -190, -255, - /* 20 */ -197, -154, -91, 127, -165, -92, 27, 63, -150, -155, - /* 30 */ -189, -80, 167, 35, -39, -93, 133, 140, -10, 77, - /* 40 */ 175, -250, -129, -89, -69, -23, -5, 40, 50, 93, - /* 50 */ 110, 171, 196, 197, 198, 199, 200, 201, 202, 205, - /* 60 */ 206, 16, 183, 212, 229, 232, 233, 234, 235, 236, - /* 70 */ 242, 265, 274, 214, 276, 237, 238, 277, 280, 286, - /* 80 */ 209, 210, 240, 241, 287, 289, 292, 298, 300, 302, - /* 90 */ 305, 307, 308, 313, 314, 315, 316, 317, 320, 324, - /* 100 */ 325, 327, 328, 329, 331, 333, 334, 336, 337, 338, - /* 110 */ 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - /* 120 */ 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, - /* 130 */ 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, - /* 140 */ 369, 370, 219, 225, 230, 373, 231, 374, 243, 246, - /* 150 */ 248, 251, 256, 244, 271, 281, 376, 245, 382, 384, - /* 160 */ 386, 387, 389, 257, 390, 392, 394, 399, 395, 398, - /* 170 */ 396, 404, 403, 401, 405, 406, 407, 409, 410, 419, - /* 180 */ 421, 422, 424, 425, 427, 416, 428, + /* 0 */ -158, -29, -29, 38, 38, -194, -236, -157, -167, -129, + /* 10 */ -126, -87, -32, 51, 53, 100, 118, -196, -191, -256, + /* 20 */ -155, 13, 28, 33, -166, -93, 43, 56, -151, 107, + /* 30 */ -190, -81, 105, 26, 136, -94, 138, 192, 128, -36, + /* 40 */ 19, -251, -239, -177, 21, 110, 140, 166, 179, 191, + /* 50 */ 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + /* 60 */ 203, 208, 220, 230, 231, 233, 234, 235, 236, 237, + /* 70 */ 65, 269, 276, 214, 277, 240, 241, 280, 282, 283, + /* 80 */ 209, 210, 243, 244, 287, 293, 299, 301, 302, 303, + /* 90 */ 304, 308, 309, 314, 315, 316, 317, 319, 321, 322, + /* 100 */ 323, 325, 327, 329, 330, 331, 332, 333, 334, 335, + /* 110 */ 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, + /* 120 */ 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, + /* 130 */ 356, 357, 358, 359, 360, 361, 362, 363, 364, 285, + /* 140 */ 291, 365, 224, 225, 246, 366, 247, 369, 252, 249, + /* 150 */ 262, 250, 274, 371, 373, 375, 377, 379, 376, 378, + /* 160 */ 380, 381, 383, 260, 386, 390, 387, 393, 392, 394, + /* 170 */ 396, 395, 398, 401, 402, 397, 399, 403, 404, 408, + /* 180 */ 406, 414, 417, 418, 420, 412, 419, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 799, 917, 859, 929, 847, 856, 1058, 1058, 799, 799, - /* 10 */ 799, 799, 799, 799, 799, 799, 799, 976, 819, 1058, - /* 20 */ 799, 799, 799, 799, 799, 799, 799, 799, 799, 856, - /* 30 */ 799, 799, 799, 799, 866, 856, 866, 866, 971, 901, - /* 40 */ 919, 799, 799, 799, 799, 799, 799, 799, 799, 799, - /* 50 */ 799, 799, 799, 799, 799, 799, 799, 799, 799, 799, - /* 60 */ 799, 799, 799, 799, 799, 799, 799, 799, 799, 799, - /* 70 */ 799, 799, 799, 978, 981, 799, 799, 983, 799, 799, - /* 80 */ 1003, 1003, 969, 799, 799, 799, 799, 799, 799, 799, - /* 90 */ 799, 799, 799, 799, 799, 799, 799, 799, 799, 799, - /* 100 */ 799, 799, 799, 799, 799, 799, 799, 799, 799, 799, - /* 110 */ 799, 799, 799, 799, 799, 845, 799, 843, 799, 799, - /* 120 */ 799, 799, 799, 799, 799, 799, 799, 799, 799, 799, - /* 130 */ 799, 799, 799, 829, 799, 799, 799, 799, 799, 821, - /* 140 */ 821, 821, 799, 799, 799, 821, 799, 821, 1010, 1014, - /* 150 */ 1008, 996, 1004, 995, 991, 989, 988, 1018, 821, 821, - /* 160 */ 821, 864, 864, 860, 856, 856, 821, 821, 882, 880, - /* 170 */ 878, 870, 876, 872, 874, 868, 848, 821, 854, 854, - /* 180 */ 821, 854, 821, 854, 821, 901, 919, 799, 1019, 799, - /* 190 */ 1057, 1009, 1047, 1046, 1053, 1045, 1044, 1043, 799, 799, - /* 200 */ 799, 1039, 1040, 1042, 1041, 799, 799, 1049, 1048, 799, - /* 210 */ 799, 799, 799, 799, 799, 799, 799, 799, 799, 799, - /* 220 */ 799, 799, 1021, 799, 1015, 1011, 799, 799, 799, 799, - /* 230 */ 799, 799, 799, 799, 799, 931, 799, 799, 799, 799, - /* 240 */ 799, 799, 799, 799, 799, 799, 799, 799, 799, 799, - /* 250 */ 799, 968, 799, 799, 799, 799, 979, 799, 799, 799, - /* 260 */ 799, 799, 799, 799, 799, 799, 1005, 799, 997, 799, - /* 270 */ 799, 799, 799, 799, 943, 799, 799, 799, 799, 799, - /* 280 */ 799, 799, 799, 799, 799, 799, 799, 799, 799, 799, - /* 290 */ 799, 799, 799, 799, 799, 799, 1069, 1067, 799, 799, - /* 300 */ 799, 1063, 799, 799, 799, 1061, 799, 799, 799, 799, - /* 310 */ 799, 799, 799, 799, 799, 799, 799, 799, 799, 799, - /* 320 */ 799, 799, 799, 885, 799, 827, 825, 799, 817, 799, + /* 0 */ 803, 921, 863, 933, 851, 860, 1064, 1064, 803, 803, + /* 10 */ 803, 803, 803, 803, 803, 803, 803, 980, 823, 1064, + /* 20 */ 803, 803, 803, 803, 803, 803, 803, 803, 803, 860, + /* 30 */ 803, 803, 803, 803, 870, 860, 870, 870, 975, 905, + /* 40 */ 923, 803, 803, 803, 803, 803, 803, 803, 803, 803, + /* 50 */ 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, + /* 60 */ 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, + /* 70 */ 803, 803, 803, 982, 985, 803, 803, 987, 803, 803, + /* 80 */ 1007, 1007, 973, 803, 803, 803, 803, 803, 803, 803, + /* 90 */ 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, + /* 100 */ 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, + /* 110 */ 803, 803, 803, 803, 803, 849, 803, 847, 803, 803, + /* 120 */ 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, + /* 130 */ 803, 803, 803, 833, 803, 803, 803, 803, 803, 825, + /* 140 */ 825, 825, 803, 803, 803, 825, 803, 825, 1014, 1018, + /* 150 */ 1012, 1000, 1008, 999, 995, 993, 992, 1022, 825, 825, + /* 160 */ 825, 868, 868, 864, 860, 860, 825, 825, 886, 884, + /* 170 */ 882, 874, 880, 876, 878, 872, 852, 825, 858, 858, + /* 180 */ 825, 858, 825, 858, 825, 905, 923, 803, 1023, 803, + /* 190 */ 1063, 1013, 1053, 1052, 1059, 1051, 1050, 1049, 803, 803, + /* 200 */ 803, 1045, 1046, 1048, 1047, 803, 803, 1055, 1054, 803, + /* 210 */ 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, + /* 220 */ 803, 803, 1025, 803, 1019, 1015, 803, 803, 803, 803, + /* 230 */ 803, 803, 803, 803, 803, 935, 803, 803, 803, 803, + /* 240 */ 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, + /* 250 */ 803, 972, 803, 803, 803, 803, 983, 803, 803, 803, + /* 260 */ 803, 803, 803, 803, 803, 803, 1009, 803, 1001, 803, + /* 270 */ 803, 803, 803, 803, 947, 803, 803, 803, 803, 803, + /* 280 */ 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, + /* 290 */ 803, 803, 803, 803, 803, 803, 1075, 1073, 803, 803, + /* 300 */ 803, 1069, 803, 803, 803, 1067, 803, 803, 803, 803, + /* 310 */ 803, 803, 803, 803, 803, 803, 803, 803, 803, 803, + /* 320 */ 803, 803, 803, 889, 803, 831, 829, 803, 821, 803, }; /********** End of lemon-generated parsing tables *****************************/ @@ -725,7 +713,6 @@ 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 */ @@ -965,82 +952,83 @@ static const char *const yyTokenName[] = { /* 189 */ "INSERT", /* 190 */ "INTO", /* 191 */ "VALUES", - /* 192 */ "program", - /* 193 */ "cmd", - /* 194 */ "dbPrefix", - /* 195 */ "ids", - /* 196 */ "cpxName", - /* 197 */ "ifexists", - /* 198 */ "alter_db_optr", - /* 199 */ "alter_topic_optr", - /* 200 */ "acct_optr", - /* 201 */ "ifnotexists", - /* 202 */ "db_optr", - /* 203 */ "topic_optr", - /* 204 */ "typename", - /* 205 */ "bufsize", - /* 206 */ "pps", - /* 207 */ "tseries", - /* 208 */ "dbs", - /* 209 */ "streams", - /* 210 */ "storage", - /* 211 */ "qtime", - /* 212 */ "users", - /* 213 */ "conns", - /* 214 */ "state", - /* 215 */ "keep", - /* 216 */ "tagitemlist", - /* 217 */ "cache", - /* 218 */ "replica", - /* 219 */ "quorum", - /* 220 */ "days", - /* 221 */ "minrows", - /* 222 */ "maxrows", - /* 223 */ "blocks", - /* 224 */ "ctime", - /* 225 */ "wal", - /* 226 */ "fsync", - /* 227 */ "comp", - /* 228 */ "prec", - /* 229 */ "update", - /* 230 */ "cachelast", - /* 231 */ "partitions", - /* 232 */ "signed", - /* 233 */ "create_table_args", - /* 234 */ "create_stable_args", - /* 235 */ "create_table_list", - /* 236 */ "create_from_stable", - /* 237 */ "columnlist", - /* 238 */ "tagNamelist", - /* 239 */ "select", - /* 240 */ "column", - /* 241 */ "tagitem", - /* 242 */ "selcollist", - /* 243 */ "from", - /* 244 */ "where_opt", - /* 245 */ "interval_opt", - /* 246 */ "session_option", - /* 247 */ "fill_opt", - /* 248 */ "sliding_opt", - /* 249 */ "groupby_opt", - /* 250 */ "orderby_opt", - /* 251 */ "having_opt", - /* 252 */ "slimit_opt", - /* 253 */ "limit_opt", - /* 254 */ "union", - /* 255 */ "sclp", - /* 256 */ "distinct", - /* 257 */ "expr", - /* 258 */ "as", - /* 259 */ "tablelist", - /* 260 */ "tmvar", - /* 261 */ "sortlist", - /* 262 */ "sortitem", - /* 263 */ "item", - /* 264 */ "sortorder", - /* 265 */ "grouplist", - /* 266 */ "exprlist", - /* 267 */ "expritem", + /* 192 */ "error", + /* 193 */ "program", + /* 194 */ "cmd", + /* 195 */ "dbPrefix", + /* 196 */ "ids", + /* 197 */ "cpxName", + /* 198 */ "ifexists", + /* 199 */ "alter_db_optr", + /* 200 */ "alter_topic_optr", + /* 201 */ "acct_optr", + /* 202 */ "ifnotexists", + /* 203 */ "db_optr", + /* 204 */ "topic_optr", + /* 205 */ "typename", + /* 206 */ "bufsize", + /* 207 */ "pps", + /* 208 */ "tseries", + /* 209 */ "dbs", + /* 210 */ "streams", + /* 211 */ "storage", + /* 212 */ "qtime", + /* 213 */ "users", + /* 214 */ "conns", + /* 215 */ "state", + /* 216 */ "keep", + /* 217 */ "tagitemlist", + /* 218 */ "cache", + /* 219 */ "replica", + /* 220 */ "quorum", + /* 221 */ "days", + /* 222 */ "minrows", + /* 223 */ "maxrows", + /* 224 */ "blocks", + /* 225 */ "ctime", + /* 226 */ "wal", + /* 227 */ "fsync", + /* 228 */ "comp", + /* 229 */ "prec", + /* 230 */ "update", + /* 231 */ "cachelast", + /* 232 */ "partitions", + /* 233 */ "signed", + /* 234 */ "create_table_args", + /* 235 */ "create_stable_args", + /* 236 */ "create_table_list", + /* 237 */ "create_from_stable", + /* 238 */ "columnlist", + /* 239 */ "tagNamelist", + /* 240 */ "select", + /* 241 */ "column", + /* 242 */ "tagitem", + /* 243 */ "selcollist", + /* 244 */ "from", + /* 245 */ "where_opt", + /* 246 */ "interval_opt", + /* 247 */ "session_option", + /* 248 */ "fill_opt", + /* 249 */ "sliding_opt", + /* 250 */ "groupby_opt", + /* 251 */ "orderby_opt", + /* 252 */ "having_opt", + /* 253 */ "slimit_opt", + /* 254 */ "limit_opt", + /* 255 */ "union", + /* 256 */ "sclp", + /* 257 */ "distinct", + /* 258 */ "expr", + /* 259 */ "as", + /* 260 */ "tablelist", + /* 261 */ "tmvar", + /* 262 */ "sortlist", + /* 263 */ "sortitem", + /* 264 */ "item", + /* 265 */ "sortorder", + /* 266 */ "grouplist", + /* 267 */ "exprlist", + /* 268 */ "expritem", }; #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ @@ -1279,48 +1267,50 @@ static const char *const yyRuleName[] = { /* 228 */ "expr ::= STRING", /* 229 */ "expr ::= NOW", /* 230 */ "expr ::= VARIABLE", - /* 231 */ "expr ::= BOOL", - /* 232 */ "expr ::= NULL", - /* 233 */ "expr ::= ID LP exprlist RP", - /* 234 */ "expr ::= ID LP STAR RP", - /* 235 */ "expr ::= expr IS NULL", - /* 236 */ "expr ::= expr IS NOT NULL", - /* 237 */ "expr ::= expr LT expr", - /* 238 */ "expr ::= expr GT expr", - /* 239 */ "expr ::= expr LE expr", - /* 240 */ "expr ::= expr GE expr", - /* 241 */ "expr ::= expr NE expr", - /* 242 */ "expr ::= expr EQ expr", - /* 243 */ "expr ::= expr BETWEEN expr AND expr", - /* 244 */ "expr ::= expr AND expr", - /* 245 */ "expr ::= expr OR expr", - /* 246 */ "expr ::= expr PLUS expr", - /* 247 */ "expr ::= expr MINUS expr", - /* 248 */ "expr ::= expr STAR expr", - /* 249 */ "expr ::= expr SLASH expr", - /* 250 */ "expr ::= expr REM expr", - /* 251 */ "expr ::= expr LIKE expr", - /* 252 */ "expr ::= expr IN LP exprlist RP", - /* 253 */ "exprlist ::= exprlist COMMA expritem", - /* 254 */ "exprlist ::= expritem", - /* 255 */ "expritem ::= expr", - /* 256 */ "expritem ::=", - /* 257 */ "cmd ::= RESET QUERY CACHE", - /* 258 */ "cmd ::= SYNCDB ids REPLICA", - /* 259 */ "cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist", - /* 260 */ "cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids", - /* 261 */ "cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist", - /* 262 */ "cmd ::= ALTER TABLE ids cpxName DROP TAG ids", - /* 263 */ "cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids", - /* 264 */ "cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem", - /* 265 */ "cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist", - /* 266 */ "cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids", - /* 267 */ "cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist", - /* 268 */ "cmd ::= ALTER STABLE ids cpxName DROP TAG ids", - /* 269 */ "cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids", - /* 270 */ "cmd ::= KILL CONNECTION INTEGER", - /* 271 */ "cmd ::= KILL STREAM INTEGER COLON INTEGER", - /* 272 */ "cmd ::= KILL QUERY INTEGER COLON INTEGER", + /* 231 */ "expr ::= PLUS VARIABLE", + /* 232 */ "expr ::= MINUS VARIABLE", + /* 233 */ "expr ::= BOOL", + /* 234 */ "expr ::= NULL", + /* 235 */ "expr ::= ID LP exprlist RP", + /* 236 */ "expr ::= ID LP STAR RP", + /* 237 */ "expr ::= expr IS NULL", + /* 238 */ "expr ::= expr IS NOT NULL", + /* 239 */ "expr ::= expr LT expr", + /* 240 */ "expr ::= expr GT expr", + /* 241 */ "expr ::= expr LE expr", + /* 242 */ "expr ::= expr GE expr", + /* 243 */ "expr ::= expr NE expr", + /* 244 */ "expr ::= expr EQ expr", + /* 245 */ "expr ::= expr BETWEEN expr AND expr", + /* 246 */ "expr ::= expr AND expr", + /* 247 */ "expr ::= expr OR expr", + /* 248 */ "expr ::= expr PLUS expr", + /* 249 */ "expr ::= expr MINUS expr", + /* 250 */ "expr ::= expr STAR expr", + /* 251 */ "expr ::= expr SLASH expr", + /* 252 */ "expr ::= expr REM expr", + /* 253 */ "expr ::= expr LIKE expr", + /* 254 */ "expr ::= expr IN LP exprlist RP", + /* 255 */ "exprlist ::= exprlist COMMA expritem", + /* 256 */ "exprlist ::= expritem", + /* 257 */ "expritem ::= expr", + /* 258 */ "expritem ::=", + /* 259 */ "cmd ::= RESET QUERY CACHE", + /* 260 */ "cmd ::= SYNCDB ids REPLICA", + /* 261 */ "cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist", + /* 262 */ "cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids", + /* 263 */ "cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist", + /* 264 */ "cmd ::= ALTER TABLE ids cpxName DROP TAG ids", + /* 265 */ "cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids", + /* 266 */ "cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem", + /* 267 */ "cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist", + /* 268 */ "cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids", + /* 269 */ "cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist", + /* 270 */ "cmd ::= ALTER STABLE ids cpxName DROP TAG ids", + /* 271 */ "cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids", + /* 272 */ "cmd ::= KILL CONNECTION INTEGER", + /* 273 */ "cmd ::= KILL STREAM INTEGER COLON INTEGER", + /* 274 */ "cmd ::= KILL QUERY INTEGER COLON INTEGER", }; #endif /* NDEBUG */ @@ -1369,29 +1359,28 @@ static int yyGrowStack(yyParser *p){ /* Initialize a new parser that has already been allocated. */ -void ParseInit(void *yypRawParser ParseCTX_PDECL){ - yyParser *yypParser = (yyParser*)yypRawParser; - ParseCTX_STORE +void ParseInit(void *yypParser){ + yyParser *pParser = (yyParser*)yypParser; #ifdef YYTRACKMAXSTACKDEPTH - yypParser->yyhwm = 0; + pParser->yyhwm = 0; #endif #if YYSTACKDEPTH<=0 - yypParser->yytos = NULL; - yypParser->yystack = NULL; - yypParser->yystksz = 0; - if( yyGrowStack(yypParser) ){ - yypParser->yystack = &yypParser->yystk0; - yypParser->yystksz = 1; + pParser->yytos = NULL; + pParser->yystack = NULL; + pParser->yystksz = 0; + if( yyGrowStack(pParser) ){ + pParser->yystack = &pParser->yystk0; + pParser->yystksz = 1; } #endif #ifndef YYNOERRORRECOVERY - yypParser->yyerrcnt = -1; + pParser->yyerrcnt = -1; #endif - yypParser->yytos = yypParser->yystack; - yypParser->yystack[0].stateno = 0; - yypParser->yystack[0].major = 0; + pParser->yytos = pParser->yystack; + pParser->yystack[0].stateno = 0; + pParser->yystack[0].major = 0; #if YYSTACKDEPTH>0 - yypParser->yystackEnd = &yypParser->yystack[YYSTACKDEPTH-1]; + pParser->yystackEnd = &pParser->yystack[YYSTACKDEPTH-1]; #endif } @@ -1408,14 +1397,11 @@ void ParseInit(void *yypRawParser ParseCTX_PDECL){ ** A pointer to a parser. This pointer is used in subsequent calls ** to Parse and ParseFree. */ -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; +void *ParseAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){ + yyParser *pParser; + pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) ); + if( pParser ) ParseInit(pParser); + return pParser; } #endif /* Parse_ENGINEALWAYSONSTACK */ @@ -1432,8 +1418,7 @@ static void yy_destructor( YYCODETYPE yymajor, /* Type code for object to destroy */ YYMINORTYPE *yypminor /* The object to be destroyed */ ){ - ParseARG_FETCH - ParseCTX_FETCH + ParseARG_FETCH; switch( yymajor ){ /* Here is inserted the actions which take place when a ** terminal or non-terminal is destroyed. This can happen @@ -1446,52 +1431,58 @@ static void yy_destructor( ** inside the C code. */ /********* Begin destructor definitions ***************************************/ - case 215: /* keep */ - case 216: /* tagitemlist */ - case 237: /* columnlist */ - case 238: /* tagNamelist */ - case 247: /* fill_opt */ - case 249: /* groupby_opt */ - case 250: /* orderby_opt */ - case 261: /* sortlist */ - case 265: /* grouplist */ + case 216: /* keep */ + case 217: /* tagitemlist */ + case 238: /* columnlist */ + case 239: /* tagNamelist */ + case 248: /* fill_opt */ + case 250: /* groupby_opt */ + case 251: /* orderby_opt */ + case 262: /* sortlist */ + case 266: /* grouplist */ { -taosArrayDestroy((yypminor->yy325)); +taosArrayDestroy((yypminor->yy93)); } break; - case 235: /* create_table_list */ + case 236: /* create_table_list */ { -destroyCreateTableSql((yypminor->yy422)); +destroyCreateTableSql((yypminor->yy532)); } break; - case 239: /* select */ + case 240: /* select */ { -destroyQuerySqlNode((yypminor->yy494)); +destroySqlNode((yypminor->yy224)); } break; - case 242: /* selcollist */ - case 255: /* sclp */ - case 266: /* exprlist */ + case 243: /* selcollist */ + case 256: /* sclp */ + case 267: /* exprlist */ { -tSqlExprListDestroy((yypminor->yy325)); +tSqlExprListDestroy((yypminor->yy93)); } break; - case 244: /* where_opt */ - case 251: /* having_opt */ - case 257: /* expr */ - case 267: /* expritem */ + case 244: /* from */ + case 260: /* tablelist */ { -tSqlExprDestroy((yypminor->yy162)); +destroyRelationInfo((yypminor->yy330)); } break; - case 254: /* union */ + case 245: /* where_opt */ + case 252: /* having_opt */ + case 258: /* expr */ + case 268: /* expritem */ { -destroyAllSelectClause((yypminor->yy145)); +tSqlExprDestroy((yypminor->yy68)); } break; - case 262: /* sortitem */ + case 255: /* union */ { -tVariantDestroy(&(yypminor->yy442)); +destroyAllSqlNode((yypminor->yy93)); +} + break; + case 263: /* sortitem */ +{ +tVariantDestroy(&(yypminor->yy518)); } break; /********* End destructor definitions *****************************************/ @@ -1603,12 +1594,13 @@ int ParseCoverage(FILE *out){ ** Find the appropriate action for a parser given the terminal ** look-ahead token iLookAhead. */ -static YYACTIONTYPE yy_find_shift_action( - YYCODETYPE iLookAhead, /* The look-ahead token */ - YYACTIONTYPE stateno /* Current state number */ +static unsigned int yy_find_shift_action( + yyParser *pParser, /* The parser */ + YYCODETYPE iLookAhead /* The look-ahead token */ ){ int i; - + int stateno = pParser->yytos->stateno; + if( stateno>YY_MAX_SHIFT ) return stateno; assert( stateno <= YY_SHIFT_COUNT ); #if defined(YYCOVERAGE) @@ -1616,19 +1608,15 @@ static YYACTIONTYPE yy_find_shift_action( #endif do{ i = yy_shift_ofst[stateno]; - assert( i>=0 ); - assert( i<=YY_ACTTAB_COUNT ); - assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); + assert( i>=0 && i+YYNTOKEN<=sizeof(yy_lookahead)/sizeof(yy_lookahead[0]) ); assert( iLookAhead!=YYNOCODE ); assert( iLookAhead < YYNTOKEN ); i += iLookAhead; - assert( i<(int)YY_NLOOKAHEAD ); if( yy_lookahead[i]!=iLookAhead ){ #ifdef YYFALLBACK YYCODETYPE iFallback; /* Fallback token */ - assert( iLookAhead %s\n", @@ -1643,8 +1631,15 @@ static YYACTIONTYPE yy_find_shift_action( #ifdef YYWILDCARD { int j = i - iLookAhead + YYWILDCARD; - assert( j<(int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])) ); - if( yy_lookahead[j]==YYWILDCARD && iLookAhead>0 ){ + if( +#if YY_SHIFT_MIN+YYWILDCARD<0 + j>=0 && +#endif +#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT + j0 + ){ #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n", @@ -1658,7 +1653,6 @@ static YYACTIONTYPE yy_find_shift_action( #endif /* YYWILDCARD */ return yy_default[stateno]; }else{ - assert( i>=0 && iyytos; - yytos->stateno = yyNewState; - yytos->major = yyMajor; + yytos->stateno = (YYACTIONTYPE)yyNewState; + yytos->major = (YYCODETYPE)yyMajor; yytos->minor.yy0 = yyMinor; yyTraceShift(yypParser, yyNewState, "Shift"); } -/* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side -** of that rule */ -static const YYCODETYPE yyRuleInfoLhs[] = { - 192, /* (0) program ::= cmd */ - 193, /* (1) cmd ::= SHOW DATABASES */ - 193, /* (2) cmd ::= SHOW TOPICS */ - 193, /* (3) cmd ::= SHOW FUNCTIONS */ - 193, /* (4) cmd ::= SHOW MNODES */ - 193, /* (5) cmd ::= SHOW DNODES */ - 193, /* (6) cmd ::= SHOW ACCOUNTS */ - 193, /* (7) cmd ::= SHOW USERS */ - 193, /* (8) cmd ::= SHOW MODULES */ - 193, /* (9) cmd ::= SHOW QUERIES */ - 193, /* (10) cmd ::= SHOW CONNECTIONS */ - 193, /* (11) cmd ::= SHOW STREAMS */ - 193, /* (12) cmd ::= SHOW VARIABLES */ - 193, /* (13) cmd ::= SHOW SCORES */ - 193, /* (14) cmd ::= SHOW GRANTS */ - 193, /* (15) cmd ::= SHOW VNODES */ - 193, /* (16) cmd ::= SHOW VNODES IPTOKEN */ - 194, /* (17) dbPrefix ::= */ - 194, /* (18) dbPrefix ::= ids DOT */ - 196, /* (19) cpxName ::= */ - 196, /* (20) cpxName ::= DOT ids */ - 193, /* (21) cmd ::= SHOW CREATE TABLE ids cpxName */ - 193, /* (22) cmd ::= SHOW CREATE DATABASE ids */ - 193, /* (23) cmd ::= SHOW dbPrefix TABLES */ - 193, /* (24) cmd ::= SHOW dbPrefix TABLES LIKE ids */ - 193, /* (25) cmd ::= SHOW dbPrefix STABLES */ - 193, /* (26) cmd ::= SHOW dbPrefix STABLES LIKE ids */ - 193, /* (27) cmd ::= SHOW dbPrefix VGROUPS */ - 193, /* (28) cmd ::= SHOW dbPrefix VGROUPS ids */ - 193, /* (29) cmd ::= DROP TABLE ifexists ids cpxName */ - 193, /* (30) cmd ::= DROP STABLE ifexists ids cpxName */ - 193, /* (31) cmd ::= DROP DATABASE ifexists ids */ - 193, /* (32) cmd ::= DROP TOPIC ifexists ids */ - 193, /* (33) cmd ::= DROP FUNCTION ids */ - 193, /* (34) cmd ::= DROP DNODE ids */ - 193, /* (35) cmd ::= DROP USER ids */ - 193, /* (36) cmd ::= DROP ACCOUNT ids */ - 193, /* (37) cmd ::= USE ids */ - 193, /* (38) cmd ::= DESCRIBE ids cpxName */ - 193, /* (39) cmd ::= ALTER USER ids PASS ids */ - 193, /* (40) cmd ::= ALTER USER ids PRIVILEGE ids */ - 193, /* (41) cmd ::= ALTER DNODE ids ids */ - 193, /* (42) cmd ::= ALTER DNODE ids ids ids */ - 193, /* (43) cmd ::= ALTER LOCAL ids */ - 193, /* (44) cmd ::= ALTER LOCAL ids ids */ - 193, /* (45) cmd ::= ALTER DATABASE ids alter_db_optr */ - 193, /* (46) cmd ::= ALTER TOPIC ids alter_topic_optr */ - 193, /* (47) cmd ::= ALTER ACCOUNT ids acct_optr */ - 193, /* (48) cmd ::= ALTER ACCOUNT ids PASS ids acct_optr */ - 195, /* (49) ids ::= ID */ - 195, /* (50) ids ::= STRING */ - 197, /* (51) ifexists ::= IF EXISTS */ - 197, /* (52) ifexists ::= */ - 201, /* (53) ifnotexists ::= IF NOT EXISTS */ - 201, /* (54) ifnotexists ::= */ - 193, /* (55) cmd ::= CREATE DNODE ids */ - 193, /* (56) cmd ::= CREATE ACCOUNT ids PASS ids acct_optr */ - 193, /* (57) cmd ::= CREATE DATABASE ifnotexists ids db_optr */ - 193, /* (58) cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ - 193, /* (59) cmd ::= CREATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ - 193, /* (60) cmd ::= CREATE AGGREGATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ - 193, /* (61) cmd ::= CREATE USER ids PASS ids */ - 205, /* (62) bufsize ::= */ - 205, /* (63) bufsize ::= BUFSIZE INTEGER */ - 206, /* (64) pps ::= */ - 206, /* (65) pps ::= PPS INTEGER */ - 207, /* (66) tseries ::= */ - 207, /* (67) tseries ::= TSERIES INTEGER */ - 208, /* (68) dbs ::= */ - 208, /* (69) dbs ::= DBS INTEGER */ - 209, /* (70) streams ::= */ - 209, /* (71) streams ::= STREAMS INTEGER */ - 210, /* (72) storage ::= */ - 210, /* (73) storage ::= STORAGE INTEGER */ - 211, /* (74) qtime ::= */ - 211, /* (75) qtime ::= QTIME INTEGER */ - 212, /* (76) users ::= */ - 212, /* (77) users ::= USERS INTEGER */ - 213, /* (78) conns ::= */ - 213, /* (79) conns ::= CONNS INTEGER */ - 214, /* (80) state ::= */ - 214, /* (81) state ::= STATE ids */ - 200, /* (82) acct_optr ::= pps tseries storage streams qtime dbs users conns state */ - 215, /* (83) keep ::= KEEP tagitemlist */ - 217, /* (84) cache ::= CACHE INTEGER */ - 218, /* (85) replica ::= REPLICA INTEGER */ - 219, /* (86) quorum ::= QUORUM INTEGER */ - 220, /* (87) days ::= DAYS INTEGER */ - 221, /* (88) minrows ::= MINROWS INTEGER */ - 222, /* (89) maxrows ::= MAXROWS INTEGER */ - 223, /* (90) blocks ::= BLOCKS INTEGER */ - 224, /* (91) ctime ::= CTIME INTEGER */ - 225, /* (92) wal ::= WAL INTEGER */ - 226, /* (93) fsync ::= FSYNC INTEGER */ - 227, /* (94) comp ::= COMP INTEGER */ - 228, /* (95) prec ::= PRECISION STRING */ - 229, /* (96) update ::= UPDATE INTEGER */ - 230, /* (97) cachelast ::= CACHELAST INTEGER */ - 231, /* (98) partitions ::= PARTITIONS INTEGER */ - 202, /* (99) db_optr ::= */ - 202, /* (100) db_optr ::= db_optr cache */ - 202, /* (101) db_optr ::= db_optr replica */ - 202, /* (102) db_optr ::= db_optr quorum */ - 202, /* (103) db_optr ::= db_optr days */ - 202, /* (104) db_optr ::= db_optr minrows */ - 202, /* (105) db_optr ::= db_optr maxrows */ - 202, /* (106) db_optr ::= db_optr blocks */ - 202, /* (107) db_optr ::= db_optr ctime */ - 202, /* (108) db_optr ::= db_optr wal */ - 202, /* (109) db_optr ::= db_optr fsync */ - 202, /* (110) db_optr ::= db_optr comp */ - 202, /* (111) db_optr ::= db_optr prec */ - 202, /* (112) db_optr ::= db_optr keep */ - 202, /* (113) db_optr ::= db_optr update */ - 202, /* (114) db_optr ::= db_optr cachelast */ - 203, /* (115) topic_optr ::= db_optr */ - 203, /* (116) topic_optr ::= topic_optr partitions */ - 198, /* (117) alter_db_optr ::= */ - 198, /* (118) alter_db_optr ::= alter_db_optr replica */ - 198, /* (119) alter_db_optr ::= alter_db_optr quorum */ - 198, /* (120) alter_db_optr ::= alter_db_optr keep */ - 198, /* (121) alter_db_optr ::= alter_db_optr blocks */ - 198, /* (122) alter_db_optr ::= alter_db_optr comp */ - 198, /* (123) alter_db_optr ::= alter_db_optr wal */ - 198, /* (124) alter_db_optr ::= alter_db_optr fsync */ - 198, /* (125) alter_db_optr ::= alter_db_optr update */ - 198, /* (126) alter_db_optr ::= alter_db_optr cachelast */ - 199, /* (127) alter_topic_optr ::= alter_db_optr */ - 199, /* (128) alter_topic_optr ::= alter_topic_optr partitions */ - 204, /* (129) typename ::= ids */ - 204, /* (130) typename ::= ids LP signed RP */ - 204, /* (131) typename ::= ids UNSIGNED */ - 232, /* (132) signed ::= INTEGER */ - 232, /* (133) signed ::= PLUS INTEGER */ - 232, /* (134) signed ::= MINUS INTEGER */ - 193, /* (135) cmd ::= CREATE TABLE create_table_args */ - 193, /* (136) cmd ::= CREATE TABLE create_stable_args */ - 193, /* (137) cmd ::= CREATE STABLE create_stable_args */ - 193, /* (138) cmd ::= CREATE TABLE create_table_list */ - 235, /* (139) create_table_list ::= create_from_stable */ - 235, /* (140) create_table_list ::= create_table_list create_from_stable */ - 233, /* (141) create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ - 234, /* (142) create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ - 236, /* (143) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName TAGS LP tagitemlist RP */ - 236, /* (144) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName LP tagNamelist RP TAGS LP tagitemlist RP */ - 238, /* (145) tagNamelist ::= tagNamelist COMMA ids */ - 238, /* (146) tagNamelist ::= ids */ - 233, /* (147) create_table_args ::= ifnotexists ids cpxName AS select */ - 237, /* (148) columnlist ::= columnlist COMMA column */ - 237, /* (149) columnlist ::= column */ - 240, /* (150) column ::= ids typename */ - 216, /* (151) tagitemlist ::= tagitemlist COMMA tagitem */ - 216, /* (152) tagitemlist ::= tagitem */ - 241, /* (153) tagitem ::= INTEGER */ - 241, /* (154) tagitem ::= FLOAT */ - 241, /* (155) tagitem ::= STRING */ - 241, /* (156) tagitem ::= BOOL */ - 241, /* (157) tagitem ::= NULL */ - 241, /* (158) tagitem ::= MINUS INTEGER */ - 241, /* (159) tagitem ::= MINUS FLOAT */ - 241, /* (160) tagitem ::= PLUS INTEGER */ - 241, /* (161) tagitem ::= PLUS FLOAT */ - 239, /* (162) select ::= SELECT selcollist from where_opt interval_opt session_option fill_opt sliding_opt groupby_opt orderby_opt having_opt slimit_opt limit_opt */ - 239, /* (163) select ::= LP select RP */ - 254, /* (164) union ::= select */ - 254, /* (165) union ::= union UNION ALL select */ - 193, /* (166) cmd ::= union */ - 239, /* (167) select ::= SELECT selcollist */ - 255, /* (168) sclp ::= selcollist COMMA */ - 255, /* (169) sclp ::= */ - 242, /* (170) selcollist ::= sclp distinct expr as */ - 242, /* (171) selcollist ::= sclp STAR */ - 258, /* (172) as ::= AS ids */ - 258, /* (173) as ::= ids */ - 258, /* (174) as ::= */ - 256, /* (175) distinct ::= DISTINCT */ - 256, /* (176) distinct ::= */ - 243, /* (177) from ::= FROM tablelist */ - 243, /* (178) from ::= FROM LP union RP */ - 259, /* (179) tablelist ::= ids cpxName */ - 259, /* (180) tablelist ::= ids cpxName ids */ - 259, /* (181) tablelist ::= tablelist COMMA ids cpxName */ - 259, /* (182) tablelist ::= tablelist COMMA ids cpxName ids */ - 260, /* (183) tmvar ::= VARIABLE */ - 245, /* (184) interval_opt ::= INTERVAL LP tmvar RP */ - 245, /* (185) interval_opt ::= INTERVAL LP tmvar COMMA tmvar RP */ - 245, /* (186) interval_opt ::= */ - 246, /* (187) session_option ::= */ - 246, /* (188) session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ - 247, /* (189) fill_opt ::= */ - 247, /* (190) fill_opt ::= FILL LP ID COMMA tagitemlist RP */ - 247, /* (191) fill_opt ::= FILL LP ID RP */ - 248, /* (192) sliding_opt ::= SLIDING LP tmvar RP */ - 248, /* (193) sliding_opt ::= */ - 250, /* (194) orderby_opt ::= */ - 250, /* (195) orderby_opt ::= ORDER BY sortlist */ - 261, /* (196) sortlist ::= sortlist COMMA item sortorder */ - 261, /* (197) sortlist ::= item sortorder */ - 263, /* (198) item ::= ids cpxName */ - 264, /* (199) sortorder ::= ASC */ - 264, /* (200) sortorder ::= DESC */ - 264, /* (201) sortorder ::= */ - 249, /* (202) groupby_opt ::= */ - 249, /* (203) groupby_opt ::= GROUP BY grouplist */ - 265, /* (204) grouplist ::= grouplist COMMA item */ - 265, /* (205) grouplist ::= item */ - 251, /* (206) having_opt ::= */ - 251, /* (207) having_opt ::= HAVING expr */ - 253, /* (208) limit_opt ::= */ - 253, /* (209) limit_opt ::= LIMIT signed */ - 253, /* (210) limit_opt ::= LIMIT signed OFFSET signed */ - 253, /* (211) limit_opt ::= LIMIT signed COMMA signed */ - 252, /* (212) slimit_opt ::= */ - 252, /* (213) slimit_opt ::= SLIMIT signed */ - 252, /* (214) slimit_opt ::= SLIMIT signed SOFFSET signed */ - 252, /* (215) slimit_opt ::= SLIMIT signed COMMA signed */ - 244, /* (216) where_opt ::= */ - 244, /* (217) where_opt ::= WHERE expr */ - 257, /* (218) expr ::= LP expr RP */ - 257, /* (219) expr ::= ID */ - 257, /* (220) expr ::= ID DOT ID */ - 257, /* (221) expr ::= ID DOT STAR */ - 257, /* (222) expr ::= INTEGER */ - 257, /* (223) expr ::= MINUS INTEGER */ - 257, /* (224) expr ::= PLUS INTEGER */ - 257, /* (225) expr ::= FLOAT */ - 257, /* (226) expr ::= MINUS FLOAT */ - 257, /* (227) expr ::= PLUS FLOAT */ - 257, /* (228) expr ::= STRING */ - 257, /* (229) expr ::= NOW */ - 257, /* (230) expr ::= VARIABLE */ - 257, /* (231) expr ::= BOOL */ - 257, /* (232) expr ::= NULL */ - 257, /* (233) expr ::= ID LP exprlist RP */ - 257, /* (234) expr ::= ID LP STAR RP */ - 257, /* (235) expr ::= expr IS NULL */ - 257, /* (236) expr ::= expr IS NOT NULL */ - 257, /* (237) expr ::= expr LT expr */ - 257, /* (238) expr ::= expr GT expr */ - 257, /* (239) expr ::= expr LE expr */ - 257, /* (240) expr ::= expr GE expr */ - 257, /* (241) expr ::= expr NE expr */ - 257, /* (242) expr ::= expr EQ expr */ - 257, /* (243) expr ::= expr BETWEEN expr AND expr */ - 257, /* (244) expr ::= expr AND expr */ - 257, /* (245) expr ::= expr OR expr */ - 257, /* (246) expr ::= expr PLUS expr */ - 257, /* (247) expr ::= expr MINUS expr */ - 257, /* (248) expr ::= expr STAR expr */ - 257, /* (249) expr ::= expr SLASH expr */ - 257, /* (250) expr ::= expr REM expr */ - 257, /* (251) expr ::= expr LIKE expr */ - 257, /* (252) expr ::= expr IN LP exprlist RP */ - 266, /* (253) exprlist ::= exprlist COMMA expritem */ - 266, /* (254) exprlist ::= expritem */ - 267, /* (255) expritem ::= expr */ - 267, /* (256) expritem ::= */ - 193, /* (257) cmd ::= RESET QUERY CACHE */ - 193, /* (258) cmd ::= SYNCDB ids REPLICA */ - 193, /* (259) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ - 193, /* (260) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ - 193, /* (261) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ - 193, /* (262) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ - 193, /* (263) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ - 193, /* (264) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ - 193, /* (265) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ - 193, /* (266) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ - 193, /* (267) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ - 193, /* (268) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ - 193, /* (269) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ - 193, /* (270) cmd ::= KILL CONNECTION INTEGER */ - 193, /* (271) cmd ::= KILL STREAM INTEGER COLON INTEGER */ - 193, /* (272) 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 FUNCTIONS */ - -2, /* (4) cmd ::= SHOW MNODES */ - -2, /* (5) cmd ::= SHOW DNODES */ - -2, /* (6) cmd ::= SHOW ACCOUNTS */ - -2, /* (7) cmd ::= SHOW USERS */ - -2, /* (8) cmd ::= SHOW MODULES */ - -2, /* (9) cmd ::= SHOW QUERIES */ - -2, /* (10) cmd ::= SHOW CONNECTIONS */ - -2, /* (11) cmd ::= SHOW STREAMS */ - -2, /* (12) cmd ::= SHOW VARIABLES */ - -2, /* (13) cmd ::= SHOW SCORES */ - -2, /* (14) cmd ::= SHOW GRANTS */ - -2, /* (15) cmd ::= SHOW VNODES */ - -3, /* (16) cmd ::= SHOW VNODES IPTOKEN */ - 0, /* (17) dbPrefix ::= */ - -2, /* (18) dbPrefix ::= ids DOT */ - 0, /* (19) cpxName ::= */ - -2, /* (20) cpxName ::= DOT ids */ - -5, /* (21) cmd ::= SHOW CREATE TABLE ids cpxName */ - -4, /* (22) cmd ::= SHOW CREATE DATABASE ids */ - -3, /* (23) cmd ::= SHOW dbPrefix TABLES */ - -5, /* (24) cmd ::= SHOW dbPrefix TABLES LIKE ids */ - -3, /* (25) cmd ::= SHOW dbPrefix STABLES */ - -5, /* (26) cmd ::= SHOW dbPrefix STABLES LIKE ids */ - -3, /* (27) cmd ::= SHOW dbPrefix VGROUPS */ - -4, /* (28) cmd ::= SHOW dbPrefix VGROUPS ids */ - -5, /* (29) cmd ::= DROP TABLE ifexists ids cpxName */ - -5, /* (30) cmd ::= DROP STABLE ifexists ids cpxName */ - -4, /* (31) cmd ::= DROP DATABASE ifexists ids */ - -4, /* (32) cmd ::= DROP TOPIC ifexists ids */ - -3, /* (33) cmd ::= DROP FUNCTION ids */ - -3, /* (34) cmd ::= DROP DNODE ids */ - -3, /* (35) cmd ::= DROP USER ids */ - -3, /* (36) cmd ::= DROP ACCOUNT ids */ - -2, /* (37) cmd ::= USE ids */ - -3, /* (38) cmd ::= DESCRIBE ids cpxName */ - -5, /* (39) cmd ::= ALTER USER ids PASS ids */ - -5, /* (40) cmd ::= ALTER USER ids PRIVILEGE ids */ - -4, /* (41) cmd ::= ALTER DNODE ids ids */ - -5, /* (42) cmd ::= ALTER DNODE ids ids ids */ - -3, /* (43) cmd ::= ALTER LOCAL ids */ - -4, /* (44) cmd ::= ALTER LOCAL ids ids */ - -4, /* (45) cmd ::= ALTER DATABASE ids alter_db_optr */ - -4, /* (46) cmd ::= ALTER TOPIC ids alter_topic_optr */ - -4, /* (47) cmd ::= ALTER ACCOUNT ids acct_optr */ - -6, /* (48) cmd ::= ALTER ACCOUNT ids PASS ids acct_optr */ - -1, /* (49) ids ::= ID */ - -1, /* (50) ids ::= STRING */ - -2, /* (51) ifexists ::= IF EXISTS */ - 0, /* (52) ifexists ::= */ - -3, /* (53) ifnotexists ::= IF NOT EXISTS */ - 0, /* (54) ifnotexists ::= */ - -3, /* (55) cmd ::= CREATE DNODE ids */ - -6, /* (56) cmd ::= CREATE ACCOUNT ids PASS ids acct_optr */ - -5, /* (57) cmd ::= CREATE DATABASE ifnotexists ids db_optr */ - -5, /* (58) cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ - -8, /* (59) cmd ::= CREATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ - -9, /* (60) cmd ::= CREATE AGGREGATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ - -5, /* (61) cmd ::= CREATE USER ids PASS ids */ - 0, /* (62) bufsize ::= */ - -2, /* (63) bufsize ::= BUFSIZE INTEGER */ - 0, /* (64) pps ::= */ - -2, /* (65) pps ::= PPS INTEGER */ - 0, /* (66) tseries ::= */ - -2, /* (67) tseries ::= TSERIES INTEGER */ - 0, /* (68) dbs ::= */ - -2, /* (69) dbs ::= DBS INTEGER */ - 0, /* (70) streams ::= */ - -2, /* (71) streams ::= STREAMS INTEGER */ - 0, /* (72) storage ::= */ - -2, /* (73) storage ::= STORAGE INTEGER */ - 0, /* (74) qtime ::= */ - -2, /* (75) qtime ::= QTIME INTEGER */ - 0, /* (76) users ::= */ - -2, /* (77) users ::= USERS INTEGER */ - 0, /* (78) conns ::= */ - -2, /* (79) conns ::= CONNS INTEGER */ - 0, /* (80) state ::= */ - -2, /* (81) state ::= STATE ids */ - -9, /* (82) acct_optr ::= pps tseries storage streams qtime dbs users conns state */ - -2, /* (83) keep ::= KEEP tagitemlist */ - -2, /* (84) cache ::= CACHE INTEGER */ - -2, /* (85) replica ::= REPLICA INTEGER */ - -2, /* (86) quorum ::= QUORUM INTEGER */ - -2, /* (87) days ::= DAYS INTEGER */ - -2, /* (88) minrows ::= MINROWS INTEGER */ - -2, /* (89) maxrows ::= MAXROWS INTEGER */ - -2, /* (90) blocks ::= BLOCKS INTEGER */ - -2, /* (91) ctime ::= CTIME INTEGER */ - -2, /* (92) wal ::= WAL INTEGER */ - -2, /* (93) fsync ::= FSYNC INTEGER */ - -2, /* (94) comp ::= COMP INTEGER */ - -2, /* (95) prec ::= PRECISION STRING */ - -2, /* (96) update ::= UPDATE INTEGER */ - -2, /* (97) cachelast ::= CACHELAST INTEGER */ - -2, /* (98) partitions ::= PARTITIONS INTEGER */ - 0, /* (99) db_optr ::= */ - -2, /* (100) db_optr ::= db_optr cache */ - -2, /* (101) db_optr ::= db_optr replica */ - -2, /* (102) db_optr ::= db_optr quorum */ - -2, /* (103) db_optr ::= db_optr days */ - -2, /* (104) db_optr ::= db_optr minrows */ - -2, /* (105) db_optr ::= db_optr maxrows */ - -2, /* (106) db_optr ::= db_optr blocks */ - -2, /* (107) db_optr ::= db_optr ctime */ - -2, /* (108) db_optr ::= db_optr wal */ - -2, /* (109) db_optr ::= db_optr fsync */ - -2, /* (110) db_optr ::= db_optr comp */ - -2, /* (111) db_optr ::= db_optr prec */ - -2, /* (112) db_optr ::= db_optr keep */ - -2, /* (113) db_optr ::= db_optr update */ - -2, /* (114) db_optr ::= db_optr cachelast */ - -1, /* (115) topic_optr ::= db_optr */ - -2, /* (116) topic_optr ::= topic_optr partitions */ - 0, /* (117) alter_db_optr ::= */ - -2, /* (118) alter_db_optr ::= alter_db_optr replica */ - -2, /* (119) alter_db_optr ::= alter_db_optr quorum */ - -2, /* (120) alter_db_optr ::= alter_db_optr keep */ - -2, /* (121) alter_db_optr ::= alter_db_optr blocks */ - -2, /* (122) alter_db_optr ::= alter_db_optr comp */ - -2, /* (123) alter_db_optr ::= alter_db_optr wal */ - -2, /* (124) alter_db_optr ::= alter_db_optr fsync */ - -2, /* (125) alter_db_optr ::= alter_db_optr update */ - -2, /* (126) alter_db_optr ::= alter_db_optr cachelast */ - -1, /* (127) alter_topic_optr ::= alter_db_optr */ - -2, /* (128) alter_topic_optr ::= alter_topic_optr partitions */ - -1, /* (129) typename ::= ids */ - -4, /* (130) typename ::= ids LP signed RP */ - -2, /* (131) typename ::= ids UNSIGNED */ - -1, /* (132) signed ::= INTEGER */ - -2, /* (133) signed ::= PLUS INTEGER */ - -2, /* (134) signed ::= MINUS INTEGER */ - -3, /* (135) cmd ::= CREATE TABLE create_table_args */ - -3, /* (136) cmd ::= CREATE TABLE create_stable_args */ - -3, /* (137) cmd ::= CREATE STABLE create_stable_args */ - -3, /* (138) cmd ::= CREATE TABLE create_table_list */ - -1, /* (139) create_table_list ::= create_from_stable */ - -2, /* (140) create_table_list ::= create_table_list create_from_stable */ - -6, /* (141) create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ - -10, /* (142) create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ - -10, /* (143) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName TAGS LP tagitemlist RP */ - -13, /* (144) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName LP tagNamelist RP TAGS LP tagitemlist RP */ - -3, /* (145) tagNamelist ::= tagNamelist COMMA ids */ - -1, /* (146) tagNamelist ::= ids */ - -5, /* (147) create_table_args ::= ifnotexists ids cpxName AS select */ - -3, /* (148) columnlist ::= columnlist COMMA column */ - -1, /* (149) columnlist ::= column */ - -2, /* (150) column ::= ids typename */ - -3, /* (151) tagitemlist ::= tagitemlist COMMA tagitem */ - -1, /* (152) tagitemlist ::= tagitem */ - -1, /* (153) tagitem ::= INTEGER */ - -1, /* (154) tagitem ::= FLOAT */ - -1, /* (155) tagitem ::= STRING */ - -1, /* (156) tagitem ::= BOOL */ - -1, /* (157) tagitem ::= NULL */ - -2, /* (158) tagitem ::= MINUS INTEGER */ - -2, /* (159) tagitem ::= MINUS FLOAT */ - -2, /* (160) tagitem ::= PLUS INTEGER */ - -2, /* (161) tagitem ::= PLUS FLOAT */ - -13, /* (162) 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, /* (163) select ::= LP select RP */ - -1, /* (164) union ::= select */ - -4, /* (165) union ::= union UNION ALL select */ - -1, /* (166) cmd ::= union */ - -2, /* (167) select ::= SELECT selcollist */ - -2, /* (168) sclp ::= selcollist COMMA */ - 0, /* (169) sclp ::= */ - -4, /* (170) selcollist ::= sclp distinct expr as */ - -2, /* (171) selcollist ::= sclp STAR */ - -2, /* (172) as ::= AS ids */ - -1, /* (173) as ::= ids */ - 0, /* (174) as ::= */ - -1, /* (175) distinct ::= DISTINCT */ - 0, /* (176) distinct ::= */ - -2, /* (177) from ::= FROM tablelist */ - -4, /* (178) from ::= FROM LP union RP */ - -2, /* (179) tablelist ::= ids cpxName */ - -3, /* (180) tablelist ::= ids cpxName ids */ - -4, /* (181) tablelist ::= tablelist COMMA ids cpxName */ - -5, /* (182) tablelist ::= tablelist COMMA ids cpxName ids */ - -1, /* (183) tmvar ::= VARIABLE */ - -4, /* (184) interval_opt ::= INTERVAL LP tmvar RP */ - -6, /* (185) interval_opt ::= INTERVAL LP tmvar COMMA tmvar RP */ - 0, /* (186) interval_opt ::= */ - 0, /* (187) session_option ::= */ - -7, /* (188) session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ - 0, /* (189) fill_opt ::= */ - -6, /* (190) fill_opt ::= FILL LP ID COMMA tagitemlist RP */ - -4, /* (191) fill_opt ::= FILL LP ID RP */ - -4, /* (192) sliding_opt ::= SLIDING LP tmvar RP */ - 0, /* (193) sliding_opt ::= */ - 0, /* (194) orderby_opt ::= */ - -3, /* (195) orderby_opt ::= ORDER BY sortlist */ - -4, /* (196) sortlist ::= sortlist COMMA item sortorder */ - -2, /* (197) sortlist ::= item sortorder */ - -2, /* (198) item ::= ids cpxName */ - -1, /* (199) sortorder ::= ASC */ - -1, /* (200) sortorder ::= DESC */ - 0, /* (201) sortorder ::= */ - 0, /* (202) groupby_opt ::= */ - -3, /* (203) groupby_opt ::= GROUP BY grouplist */ - -3, /* (204) grouplist ::= grouplist COMMA item */ - -1, /* (205) grouplist ::= item */ - 0, /* (206) having_opt ::= */ - -2, /* (207) having_opt ::= HAVING expr */ - 0, /* (208) limit_opt ::= */ - -2, /* (209) limit_opt ::= LIMIT signed */ - -4, /* (210) limit_opt ::= LIMIT signed OFFSET signed */ - -4, /* (211) limit_opt ::= LIMIT signed COMMA signed */ - 0, /* (212) slimit_opt ::= */ - -2, /* (213) slimit_opt ::= SLIMIT signed */ - -4, /* (214) slimit_opt ::= SLIMIT signed SOFFSET signed */ - -4, /* (215) slimit_opt ::= SLIMIT signed COMMA signed */ - 0, /* (216) where_opt ::= */ - -2, /* (217) where_opt ::= WHERE expr */ - -3, /* (218) expr ::= LP expr RP */ - -1, /* (219) expr ::= ID */ - -3, /* (220) expr ::= ID DOT ID */ - -3, /* (221) expr ::= ID DOT STAR */ - -1, /* (222) expr ::= INTEGER */ - -2, /* (223) expr ::= MINUS INTEGER */ - -2, /* (224) expr ::= PLUS INTEGER */ - -1, /* (225) expr ::= FLOAT */ - -2, /* (226) expr ::= MINUS FLOAT */ - -2, /* (227) expr ::= PLUS FLOAT */ - -1, /* (228) expr ::= STRING */ - -1, /* (229) expr ::= NOW */ - -1, /* (230) expr ::= VARIABLE */ - -1, /* (231) expr ::= BOOL */ - -1, /* (232) expr ::= NULL */ - -4, /* (233) expr ::= ID LP exprlist RP */ - -4, /* (234) expr ::= ID LP STAR RP */ - -3, /* (235) expr ::= expr IS NULL */ - -4, /* (236) expr ::= expr IS NOT NULL */ - -3, /* (237) expr ::= expr LT expr */ - -3, /* (238) expr ::= expr GT expr */ - -3, /* (239) expr ::= expr LE expr */ - -3, /* (240) expr ::= expr GE expr */ - -3, /* (241) expr ::= expr NE expr */ - -3, /* (242) expr ::= expr EQ expr */ - -5, /* (243) expr ::= expr BETWEEN expr AND expr */ - -3, /* (244) expr ::= expr AND expr */ - -3, /* (245) expr ::= expr OR expr */ - -3, /* (246) expr ::= expr PLUS expr */ - -3, /* (247) expr ::= expr MINUS expr */ - -3, /* (248) expr ::= expr STAR expr */ - -3, /* (249) expr ::= expr SLASH expr */ - -3, /* (250) expr ::= expr REM expr */ - -3, /* (251) expr ::= expr LIKE expr */ - -5, /* (252) expr ::= expr IN LP exprlist RP */ - -3, /* (253) exprlist ::= exprlist COMMA expritem */ - -1, /* (254) exprlist ::= expritem */ - -1, /* (255) expritem ::= expr */ - 0, /* (256) expritem ::= */ - -3, /* (257) cmd ::= RESET QUERY CACHE */ - -3, /* (258) cmd ::= SYNCDB ids REPLICA */ - -7, /* (259) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ - -7, /* (260) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ - -7, /* (261) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ - -7, /* (262) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ - -8, /* (263) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ - -9, /* (264) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ - -7, /* (265) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ - -7, /* (266) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ - -7, /* (267) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ - -7, /* (268) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ - -8, /* (269) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ - -3, /* (270) cmd ::= KILL CONNECTION INTEGER */ - -5, /* (271) cmd ::= KILL STREAM INTEGER COLON INTEGER */ - -5, /* (272) cmd ::= KILL QUERY INTEGER COLON INTEGER */ +/* 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[] = { + { 193, -1 }, /* (0) program ::= cmd */ + { 194, -2 }, /* (1) cmd ::= SHOW DATABASES */ + { 194, -2 }, /* (2) cmd ::= SHOW TOPICS */ + { 194, -2 }, /* (3) cmd ::= SHOW FUNCTIONS */ + { 194, -2 }, /* (4) cmd ::= SHOW MNODES */ + { 194, -2 }, /* (5) cmd ::= SHOW DNODES */ + { 194, -2 }, /* (6) cmd ::= SHOW ACCOUNTS */ + { 194, -2 }, /* (7) cmd ::= SHOW USERS */ + { 194, -2 }, /* (8) cmd ::= SHOW MODULES */ + { 194, -2 }, /* (9) cmd ::= SHOW QUERIES */ + { 194, -2 }, /* (10) cmd ::= SHOW CONNECTIONS */ + { 194, -2 }, /* (11) cmd ::= SHOW STREAMS */ + { 194, -2 }, /* (12) cmd ::= SHOW VARIABLES */ + { 194, -2 }, /* (13) cmd ::= SHOW SCORES */ + { 194, -2 }, /* (14) cmd ::= SHOW GRANTS */ + { 194, -2 }, /* (15) cmd ::= SHOW VNODES */ + { 194, -3 }, /* (16) cmd ::= SHOW VNODES IPTOKEN */ + { 195, 0 }, /* (17) dbPrefix ::= */ + { 195, -2 }, /* (18) dbPrefix ::= ids DOT */ + { 197, 0 }, /* (19) cpxName ::= */ + { 197, -2 }, /* (20) cpxName ::= DOT ids */ + { 194, -5 }, /* (21) cmd ::= SHOW CREATE TABLE ids cpxName */ + { 194, -4 }, /* (22) cmd ::= SHOW CREATE DATABASE ids */ + { 194, -3 }, /* (23) cmd ::= SHOW dbPrefix TABLES */ + { 194, -5 }, /* (24) cmd ::= SHOW dbPrefix TABLES LIKE ids */ + { 194, -3 }, /* (25) cmd ::= SHOW dbPrefix STABLES */ + { 194, -5 }, /* (26) cmd ::= SHOW dbPrefix STABLES LIKE ids */ + { 194, -3 }, /* (27) cmd ::= SHOW dbPrefix VGROUPS */ + { 194, -4 }, /* (28) cmd ::= SHOW dbPrefix VGROUPS ids */ + { 194, -5 }, /* (29) cmd ::= DROP TABLE ifexists ids cpxName */ + { 194, -5 }, /* (30) cmd ::= DROP STABLE ifexists ids cpxName */ + { 194, -4 }, /* (31) cmd ::= DROP DATABASE ifexists ids */ + { 194, -4 }, /* (32) cmd ::= DROP TOPIC ifexists ids */ + { 194, -3 }, /* (33) cmd ::= DROP FUNCTION ids */ + { 194, -3 }, /* (34) cmd ::= DROP DNODE ids */ + { 194, -3 }, /* (35) cmd ::= DROP USER ids */ + { 194, -3 }, /* (36) cmd ::= DROP ACCOUNT ids */ + { 194, -2 }, /* (37) cmd ::= USE ids */ + { 194, -3 }, /* (38) cmd ::= DESCRIBE ids cpxName */ + { 194, -5 }, /* (39) cmd ::= ALTER USER ids PASS ids */ + { 194, -5 }, /* (40) cmd ::= ALTER USER ids PRIVILEGE ids */ + { 194, -4 }, /* (41) cmd ::= ALTER DNODE ids ids */ + { 194, -5 }, /* (42) cmd ::= ALTER DNODE ids ids ids */ + { 194, -3 }, /* (43) cmd ::= ALTER LOCAL ids */ + { 194, -4 }, /* (44) cmd ::= ALTER LOCAL ids ids */ + { 194, -4 }, /* (45) cmd ::= ALTER DATABASE ids alter_db_optr */ + { 194, -4 }, /* (46) cmd ::= ALTER TOPIC ids alter_topic_optr */ + { 194, -4 }, /* (47) cmd ::= ALTER ACCOUNT ids acct_optr */ + { 194, -6 }, /* (48) cmd ::= ALTER ACCOUNT ids PASS ids acct_optr */ + { 196, -1 }, /* (49) ids ::= ID */ + { 196, -1 }, /* (50) ids ::= STRING */ + { 198, -2 }, /* (51) ifexists ::= IF EXISTS */ + { 198, 0 }, /* (52) ifexists ::= */ + { 202, -3 }, /* (53) ifnotexists ::= IF NOT EXISTS */ + { 202, 0 }, /* (54) ifnotexists ::= */ + { 194, -3 }, /* (55) cmd ::= CREATE DNODE ids */ + { 194, -6 }, /* (56) cmd ::= CREATE ACCOUNT ids PASS ids acct_optr */ + { 194, -5 }, /* (57) cmd ::= CREATE DATABASE ifnotexists ids db_optr */ + { 194, -5 }, /* (58) cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ + { 194, -8 }, /* (59) cmd ::= CREATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ + { 194, -9 }, /* (60) cmd ::= CREATE AGGREGATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ + { 194, -5 }, /* (61) cmd ::= CREATE USER ids PASS ids */ + { 206, 0 }, /* (62) bufsize ::= */ + { 206, -2 }, /* (63) bufsize ::= BUFSIZE INTEGER */ + { 207, 0 }, /* (64) pps ::= */ + { 207, -2 }, /* (65) pps ::= PPS INTEGER */ + { 208, 0 }, /* (66) tseries ::= */ + { 208, -2 }, /* (67) tseries ::= TSERIES INTEGER */ + { 209, 0 }, /* (68) dbs ::= */ + { 209, -2 }, /* (69) dbs ::= DBS INTEGER */ + { 210, 0 }, /* (70) streams ::= */ + { 210, -2 }, /* (71) streams ::= STREAMS INTEGER */ + { 211, 0 }, /* (72) storage ::= */ + { 211, -2 }, /* (73) storage ::= STORAGE INTEGER */ + { 212, 0 }, /* (74) qtime ::= */ + { 212, -2 }, /* (75) qtime ::= QTIME INTEGER */ + { 213, 0 }, /* (76) users ::= */ + { 213, -2 }, /* (77) users ::= USERS INTEGER */ + { 214, 0 }, /* (78) conns ::= */ + { 214, -2 }, /* (79) conns ::= CONNS INTEGER */ + { 215, 0 }, /* (80) state ::= */ + { 215, -2 }, /* (81) state ::= STATE ids */ + { 201, -9 }, /* (82) acct_optr ::= pps tseries storage streams qtime dbs users conns state */ + { 216, -2 }, /* (83) keep ::= KEEP tagitemlist */ + { 218, -2 }, /* (84) cache ::= CACHE INTEGER */ + { 219, -2 }, /* (85) replica ::= REPLICA INTEGER */ + { 220, -2 }, /* (86) quorum ::= QUORUM INTEGER */ + { 221, -2 }, /* (87) days ::= DAYS INTEGER */ + { 222, -2 }, /* (88) minrows ::= MINROWS INTEGER */ + { 223, -2 }, /* (89) maxrows ::= MAXROWS INTEGER */ + { 224, -2 }, /* (90) blocks ::= BLOCKS INTEGER */ + { 225, -2 }, /* (91) ctime ::= CTIME INTEGER */ + { 226, -2 }, /* (92) wal ::= WAL INTEGER */ + { 227, -2 }, /* (93) fsync ::= FSYNC INTEGER */ + { 228, -2 }, /* (94) comp ::= COMP INTEGER */ + { 229, -2 }, /* (95) prec ::= PRECISION STRING */ + { 230, -2 }, /* (96) update ::= UPDATE INTEGER */ + { 231, -2 }, /* (97) cachelast ::= CACHELAST INTEGER */ + { 232, -2 }, /* (98) partitions ::= PARTITIONS INTEGER */ + { 203, 0 }, /* (99) db_optr ::= */ + { 203, -2 }, /* (100) db_optr ::= db_optr cache */ + { 203, -2 }, /* (101) db_optr ::= db_optr replica */ + { 203, -2 }, /* (102) db_optr ::= db_optr quorum */ + { 203, -2 }, /* (103) db_optr ::= db_optr days */ + { 203, -2 }, /* (104) db_optr ::= db_optr minrows */ + { 203, -2 }, /* (105) db_optr ::= db_optr maxrows */ + { 203, -2 }, /* (106) db_optr ::= db_optr blocks */ + { 203, -2 }, /* (107) db_optr ::= db_optr ctime */ + { 203, -2 }, /* (108) db_optr ::= db_optr wal */ + { 203, -2 }, /* (109) db_optr ::= db_optr fsync */ + { 203, -2 }, /* (110) db_optr ::= db_optr comp */ + { 203, -2 }, /* (111) db_optr ::= db_optr prec */ + { 203, -2 }, /* (112) db_optr ::= db_optr keep */ + { 203, -2 }, /* (113) db_optr ::= db_optr update */ + { 203, -2 }, /* (114) db_optr ::= db_optr cachelast */ + { 204, -1 }, /* (115) topic_optr ::= db_optr */ + { 204, -2 }, /* (116) topic_optr ::= topic_optr partitions */ + { 199, 0 }, /* (117) alter_db_optr ::= */ + { 199, -2 }, /* (118) alter_db_optr ::= alter_db_optr replica */ + { 199, -2 }, /* (119) alter_db_optr ::= alter_db_optr quorum */ + { 199, -2 }, /* (120) alter_db_optr ::= alter_db_optr keep */ + { 199, -2 }, /* (121) alter_db_optr ::= alter_db_optr blocks */ + { 199, -2 }, /* (122) alter_db_optr ::= alter_db_optr comp */ + { 199, -2 }, /* (123) alter_db_optr ::= alter_db_optr wal */ + { 199, -2 }, /* (124) alter_db_optr ::= alter_db_optr fsync */ + { 199, -2 }, /* (125) alter_db_optr ::= alter_db_optr update */ + { 199, -2 }, /* (126) alter_db_optr ::= alter_db_optr cachelast */ + { 200, -1 }, /* (127) alter_topic_optr ::= alter_db_optr */ + { 200, -2 }, /* (128) alter_topic_optr ::= alter_topic_optr partitions */ + { 205, -1 }, /* (129) typename ::= ids */ + { 205, -4 }, /* (130) typename ::= ids LP signed RP */ + { 205, -2 }, /* (131) typename ::= ids UNSIGNED */ + { 233, -1 }, /* (132) signed ::= INTEGER */ + { 233, -2 }, /* (133) signed ::= PLUS INTEGER */ + { 233, -2 }, /* (134) signed ::= MINUS INTEGER */ + { 194, -3 }, /* (135) cmd ::= CREATE TABLE create_table_args */ + { 194, -3 }, /* (136) cmd ::= CREATE TABLE create_stable_args */ + { 194, -3 }, /* (137) cmd ::= CREATE STABLE create_stable_args */ + { 194, -3 }, /* (138) cmd ::= CREATE TABLE create_table_list */ + { 236, -1 }, /* (139) create_table_list ::= create_from_stable */ + { 236, -2 }, /* (140) create_table_list ::= create_table_list create_from_stable */ + { 234, -6 }, /* (141) create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ + { 235, -10 }, /* (142) create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ + { 237, -10 }, /* (143) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName TAGS LP tagitemlist RP */ + { 237, -13 }, /* (144) create_from_stable ::= ifnotexists ids cpxName USING ids cpxName LP tagNamelist RP TAGS LP tagitemlist RP */ + { 239, -3 }, /* (145) tagNamelist ::= tagNamelist COMMA ids */ + { 239, -1 }, /* (146) tagNamelist ::= ids */ + { 234, -5 }, /* (147) create_table_args ::= ifnotexists ids cpxName AS select */ + { 238, -3 }, /* (148) columnlist ::= columnlist COMMA column */ + { 238, -1 }, /* (149) columnlist ::= column */ + { 241, -2 }, /* (150) column ::= ids typename */ + { 217, -3 }, /* (151) tagitemlist ::= tagitemlist COMMA tagitem */ + { 217, -1 }, /* (152) tagitemlist ::= tagitem */ + { 242, -1 }, /* (153) tagitem ::= INTEGER */ + { 242, -1 }, /* (154) tagitem ::= FLOAT */ + { 242, -1 }, /* (155) tagitem ::= STRING */ + { 242, -1 }, /* (156) tagitem ::= BOOL */ + { 242, -1 }, /* (157) tagitem ::= NULL */ + { 242, -2 }, /* (158) tagitem ::= MINUS INTEGER */ + { 242, -2 }, /* (159) tagitem ::= MINUS FLOAT */ + { 242, -2 }, /* (160) tagitem ::= PLUS INTEGER */ + { 242, -2 }, /* (161) tagitem ::= PLUS FLOAT */ + { 240, -13 }, /* (162) select ::= SELECT selcollist from where_opt interval_opt session_option fill_opt sliding_opt groupby_opt orderby_opt having_opt slimit_opt limit_opt */ + { 240, -3 }, /* (163) select ::= LP select RP */ + { 255, -1 }, /* (164) union ::= select */ + { 255, -4 }, /* (165) union ::= union UNION ALL select */ + { 194, -1 }, /* (166) cmd ::= union */ + { 240, -2 }, /* (167) select ::= SELECT selcollist */ + { 256, -2 }, /* (168) sclp ::= selcollist COMMA */ + { 256, 0 }, /* (169) sclp ::= */ + { 243, -4 }, /* (170) selcollist ::= sclp distinct expr as */ + { 243, -2 }, /* (171) selcollist ::= sclp STAR */ + { 259, -2 }, /* (172) as ::= AS ids */ + { 259, -1 }, /* (173) as ::= ids */ + { 259, 0 }, /* (174) as ::= */ + { 257, -1 }, /* (175) distinct ::= DISTINCT */ + { 257, 0 }, /* (176) distinct ::= */ + { 244, -2 }, /* (177) from ::= FROM tablelist */ + { 244, -4 }, /* (178) from ::= FROM LP union RP */ + { 260, -2 }, /* (179) tablelist ::= ids cpxName */ + { 260, -3 }, /* (180) tablelist ::= ids cpxName ids */ + { 260, -4 }, /* (181) tablelist ::= tablelist COMMA ids cpxName */ + { 260, -5 }, /* (182) tablelist ::= tablelist COMMA ids cpxName ids */ + { 261, -1 }, /* (183) tmvar ::= VARIABLE */ + { 246, -4 }, /* (184) interval_opt ::= INTERVAL LP tmvar RP */ + { 246, -6 }, /* (185) interval_opt ::= INTERVAL LP tmvar COMMA tmvar RP */ + { 246, 0 }, /* (186) interval_opt ::= */ + { 247, 0 }, /* (187) session_option ::= */ + { 247, -7 }, /* (188) session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ + { 248, 0 }, /* (189) fill_opt ::= */ + { 248, -6 }, /* (190) fill_opt ::= FILL LP ID COMMA tagitemlist RP */ + { 248, -4 }, /* (191) fill_opt ::= FILL LP ID RP */ + { 249, -4 }, /* (192) sliding_opt ::= SLIDING LP tmvar RP */ + { 249, 0 }, /* (193) sliding_opt ::= */ + { 251, 0 }, /* (194) orderby_opt ::= */ + { 251, -3 }, /* (195) orderby_opt ::= ORDER BY sortlist */ + { 262, -4 }, /* (196) sortlist ::= sortlist COMMA item sortorder */ + { 262, -2 }, /* (197) sortlist ::= item sortorder */ + { 264, -2 }, /* (198) item ::= ids cpxName */ + { 265, -1 }, /* (199) sortorder ::= ASC */ + { 265, -1 }, /* (200) sortorder ::= DESC */ + { 265, 0 }, /* (201) sortorder ::= */ + { 250, 0 }, /* (202) groupby_opt ::= */ + { 250, -3 }, /* (203) groupby_opt ::= GROUP BY grouplist */ + { 266, -3 }, /* (204) grouplist ::= grouplist COMMA item */ + { 266, -1 }, /* (205) grouplist ::= item */ + { 252, 0 }, /* (206) having_opt ::= */ + { 252, -2 }, /* (207) having_opt ::= HAVING expr */ + { 254, 0 }, /* (208) limit_opt ::= */ + { 254, -2 }, /* (209) limit_opt ::= LIMIT signed */ + { 254, -4 }, /* (210) limit_opt ::= LIMIT signed OFFSET signed */ + { 254, -4 }, /* (211) limit_opt ::= LIMIT signed COMMA signed */ + { 253, 0 }, /* (212) slimit_opt ::= */ + { 253, -2 }, /* (213) slimit_opt ::= SLIMIT signed */ + { 253, -4 }, /* (214) slimit_opt ::= SLIMIT signed SOFFSET signed */ + { 253, -4 }, /* (215) slimit_opt ::= SLIMIT signed COMMA signed */ + { 245, 0 }, /* (216) where_opt ::= */ + { 245, -2 }, /* (217) where_opt ::= WHERE expr */ + { 258, -3 }, /* (218) expr ::= LP expr RP */ + { 258, -1 }, /* (219) expr ::= ID */ + { 258, -3 }, /* (220) expr ::= ID DOT ID */ + { 258, -3 }, /* (221) expr ::= ID DOT STAR */ + { 258, -1 }, /* (222) expr ::= INTEGER */ + { 258, -2 }, /* (223) expr ::= MINUS INTEGER */ + { 258, -2 }, /* (224) expr ::= PLUS INTEGER */ + { 258, -1 }, /* (225) expr ::= FLOAT */ + { 258, -2 }, /* (226) expr ::= MINUS FLOAT */ + { 258, -2 }, /* (227) expr ::= PLUS FLOAT */ + { 258, -1 }, /* (228) expr ::= STRING */ + { 258, -1 }, /* (229) expr ::= NOW */ + { 258, -1 }, /* (230) expr ::= VARIABLE */ + { 258, -2 }, /* (231) expr ::= PLUS VARIABLE */ + { 258, -2 }, /* (232) expr ::= MINUS VARIABLE */ + { 258, -1 }, /* (233) expr ::= BOOL */ + { 258, -1 }, /* (234) expr ::= NULL */ + { 258, -4 }, /* (235) expr ::= ID LP exprlist RP */ + { 258, -4 }, /* (236) expr ::= ID LP STAR RP */ + { 258, -3 }, /* (237) expr ::= expr IS NULL */ + { 258, -4 }, /* (238) expr ::= expr IS NOT NULL */ + { 258, -3 }, /* (239) expr ::= expr LT expr */ + { 258, -3 }, /* (240) expr ::= expr GT expr */ + { 258, -3 }, /* (241) expr ::= expr LE expr */ + { 258, -3 }, /* (242) expr ::= expr GE expr */ + { 258, -3 }, /* (243) expr ::= expr NE expr */ + { 258, -3 }, /* (244) expr ::= expr EQ expr */ + { 258, -5 }, /* (245) expr ::= expr BETWEEN expr AND expr */ + { 258, -3 }, /* (246) expr ::= expr AND expr */ + { 258, -3 }, /* (247) expr ::= expr OR expr */ + { 258, -3 }, /* (248) expr ::= expr PLUS expr */ + { 258, -3 }, /* (249) expr ::= expr MINUS expr */ + { 258, -3 }, /* (250) expr ::= expr STAR expr */ + { 258, -3 }, /* (251) expr ::= expr SLASH expr */ + { 258, -3 }, /* (252) expr ::= expr REM expr */ + { 258, -3 }, /* (253) expr ::= expr LIKE expr */ + { 258, -5 }, /* (254) expr ::= expr IN LP exprlist RP */ + { 267, -3 }, /* (255) exprlist ::= exprlist COMMA expritem */ + { 267, -1 }, /* (256) exprlist ::= expritem */ + { 268, -1 }, /* (257) expritem ::= expr */ + { 268, 0 }, /* (258) expritem ::= */ + { 194, -3 }, /* (259) cmd ::= RESET QUERY CACHE */ + { 194, -3 }, /* (260) cmd ::= SYNCDB ids REPLICA */ + { 194, -7 }, /* (261) cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ + { 194, -7 }, /* (262) cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ + { 194, -7 }, /* (263) cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ + { 194, -7 }, /* (264) cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ + { 194, -8 }, /* (265) cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ + { 194, -9 }, /* (266) cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ + { 194, -7 }, /* (267) cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ + { 194, -7 }, /* (268) cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ + { 194, -7 }, /* (269) cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ + { 194, -7 }, /* (270) cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ + { 194, -8 }, /* (271) cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ + { 194, -3 }, /* (272) cmd ::= KILL CONNECTION INTEGER */ + { 194, -5 }, /* (273) cmd ::= KILL STREAM INTEGER COLON INTEGER */ + { 194, -5 }, /* (274) cmd ::= KILL QUERY INTEGER COLON INTEGER */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -2345,34 +2065,30 @@ 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 YYACTIONTYPE yy_reduce( +static void 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 */ - YYACTIONTYPE yyact; /* The next action */ + int 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 = yyRuleInfoNRhs[yyruleno]; + yysize = yyRuleInfo[yyruleno].nrhs; if( yysize ){ - fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", + fprintf(yyTraceFILE, "%sReduce %d [%s], go to state %d.\n", yyTracePrompt, - yyruleno, yyRuleName[yyruleno], - yyrulenoyytos - yypParser->yystack)>yypParser->yyhwm ){ yypParser->yyhwm++; @@ -2390,19 +2106,13 @@ static YYACTIONTYPE yy_reduce( #if YYSTACKDEPTH>0 if( yypParser->yytos>=yypParser->yystackEnd ){ yyStackOverflow(yypParser); - /* 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; + return; } #else if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ if( yyGrowStack(yypParser) ){ yyStackOverflow(yypParser); - /* 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; + return; } yymsp = yypParser->yytos; } @@ -2593,13 +2303,13 @@ static YYACTIONTYPE yy_reduce( break; case 45: /* cmd ::= ALTER DATABASE ids alter_db_optr */ case 46: /* cmd ::= ALTER TOPIC ids alter_topic_optr */ yytestcase(yyruleno==46); -{ SStrToken t = {0}; setCreateDbInfo(pInfo, TSDB_SQL_ALTER_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy22, &t);} +{ SStrToken t = {0}; setCreateDbInfo(pInfo, TSDB_SQL_ALTER_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy372, &t);} break; case 47: /* cmd ::= ALTER ACCOUNT ids acct_optr */ -{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-1].minor.yy0, NULL, &yymsp[0].minor.yy83);} +{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-1].minor.yy0, NULL, &yymsp[0].minor.yy77);} break; case 48: /* 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.yy83);} +{ setCreateAcctSql(pInfo, TSDB_SQL_ALTER_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy77);} break; case 49: /* ids ::= ID */ case 50: /* ids ::= STRING */ yytestcase(yyruleno==50); @@ -2621,17 +2331,17 @@ static YYACTIONTYPE yy_reduce( { setDCLSqlElems(pInfo, TSDB_SQL_CREATE_DNODE, 1, &yymsp[0].minor.yy0);} break; case 56: /* 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.yy83);} +{ setCreateAcctSql(pInfo, TSDB_SQL_CREATE_ACCT, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy77);} break; case 57: /* cmd ::= CREATE DATABASE ifnotexists ids db_optr */ case 58: /* cmd ::= CREATE TOPIC ifnotexists ids topic_optr */ yytestcase(yyruleno==58); -{ setCreateDbInfo(pInfo, TSDB_SQL_CREATE_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy22, &yymsp[-2].minor.yy0);} +{ setCreateDbInfo(pInfo, TSDB_SQL_CREATE_DB, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy372, &yymsp[-2].minor.yy0);} break; case 59: /* cmd ::= CREATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ -{ setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &yymsp[-5].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy47, &yymsp[0].minor.yy0, 1);} +{ setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &yymsp[-5].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy325, &yymsp[0].minor.yy0, 1);} break; case 60: /* cmd ::= CREATE AGGREGATE FUNCTION ids AS ids OUTPUTTYPE typename bufsize */ -{ setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &yymsp[-5].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy47, &yymsp[0].minor.yy0, 2);} +{ setCreateFuncInfo(pInfo, TSDB_SQL_CREATE_FUNCTION, &yymsp[-5].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-1].minor.yy325, &yymsp[0].minor.yy0, 2);} break; case 61: /* cmd ::= CREATE USER ids PASS ids */ { setCreateUserSql(pInfo, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);} @@ -2662,20 +2372,20 @@ static YYACTIONTYPE yy_reduce( break; case 82: /* acct_optr ::= pps tseries storage streams qtime dbs users conns state */ { - yylhsminor.yy83.maxUsers = (yymsp[-2].minor.yy0.n>0)?atoi(yymsp[-2].minor.yy0.z):-1; - yylhsminor.yy83.maxDbs = (yymsp[-3].minor.yy0.n>0)?atoi(yymsp[-3].minor.yy0.z):-1; - yylhsminor.yy83.maxTimeSeries = (yymsp[-7].minor.yy0.n>0)?atoi(yymsp[-7].minor.yy0.z):-1; - yylhsminor.yy83.maxStreams = (yymsp[-5].minor.yy0.n>0)?atoi(yymsp[-5].minor.yy0.z):-1; - yylhsminor.yy83.maxPointsPerSecond = (yymsp[-8].minor.yy0.n>0)?atoi(yymsp[-8].minor.yy0.z):-1; - yylhsminor.yy83.maxStorage = (yymsp[-6].minor.yy0.n>0)?strtoll(yymsp[-6].minor.yy0.z, NULL, 10):-1; - yylhsminor.yy83.maxQueryTime = (yymsp[-4].minor.yy0.n>0)?strtoll(yymsp[-4].minor.yy0.z, NULL, 10):-1; - yylhsminor.yy83.maxConnections = (yymsp[-1].minor.yy0.n>0)?atoi(yymsp[-1].minor.yy0.z):-1; - yylhsminor.yy83.stat = yymsp[0].minor.yy0; + yylhsminor.yy77.maxUsers = (yymsp[-2].minor.yy0.n>0)?atoi(yymsp[-2].minor.yy0.z):-1; + yylhsminor.yy77.maxDbs = (yymsp[-3].minor.yy0.n>0)?atoi(yymsp[-3].minor.yy0.z):-1; + yylhsminor.yy77.maxTimeSeries = (yymsp[-7].minor.yy0.n>0)?atoi(yymsp[-7].minor.yy0.z):-1; + yylhsminor.yy77.maxStreams = (yymsp[-5].minor.yy0.n>0)?atoi(yymsp[-5].minor.yy0.z):-1; + yylhsminor.yy77.maxPointsPerSecond = (yymsp[-8].minor.yy0.n>0)?atoi(yymsp[-8].minor.yy0.z):-1; + yylhsminor.yy77.maxStorage = (yymsp[-6].minor.yy0.n>0)?strtoll(yymsp[-6].minor.yy0.z, NULL, 10):-1; + yylhsminor.yy77.maxQueryTime = (yymsp[-4].minor.yy0.n>0)?strtoll(yymsp[-4].minor.yy0.z, NULL, 10):-1; + yylhsminor.yy77.maxConnections = (yymsp[-1].minor.yy0.n>0)?atoi(yymsp[-1].minor.yy0.z):-1; + yylhsminor.yy77.stat = yymsp[0].minor.yy0; } - yymsp[-8].minor.yy83 = yylhsminor.yy83; + yymsp[-8].minor.yy77 = yylhsminor.yy77; break; case 83: /* keep ::= KEEP tagitemlist */ -{ yymsp[-1].minor.yy325 = yymsp[0].minor.yy325; } +{ yymsp[-1].minor.yy93 = yymsp[0].minor.yy93; } break; case 84: /* cache ::= CACHE INTEGER */ case 85: /* replica ::= REPLICA INTEGER */ yytestcase(yyruleno==85); @@ -2695,234 +2405,234 @@ static YYACTIONTYPE yy_reduce( { yymsp[-1].minor.yy0 = yymsp[0].minor.yy0; } break; case 99: /* db_optr ::= */ -{setDefaultCreateDbOption(&yymsp[1].minor.yy22); yymsp[1].minor.yy22.dbType = TSDB_DB_TYPE_DEFAULT;} +{setDefaultCreateDbOption(&yymsp[1].minor.yy372); yymsp[1].minor.yy372.dbType = TSDB_DB_TYPE_DEFAULT;} break; case 100: /* db_optr ::= db_optr cache */ -{ yylhsminor.yy22 = yymsp[-1].minor.yy22; yylhsminor.yy22.cacheBlockSize = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy22 = yylhsminor.yy22; +{ yylhsminor.yy372 = yymsp[-1].minor.yy372; yylhsminor.yy372.cacheBlockSize = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy372 = yylhsminor.yy372; break; case 101: /* db_optr ::= db_optr replica */ case 118: /* alter_db_optr ::= alter_db_optr replica */ yytestcase(yyruleno==118); -{ yylhsminor.yy22 = yymsp[-1].minor.yy22; yylhsminor.yy22.replica = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy22 = yylhsminor.yy22; +{ yylhsminor.yy372 = yymsp[-1].minor.yy372; yylhsminor.yy372.replica = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy372 = yylhsminor.yy372; break; case 102: /* db_optr ::= db_optr quorum */ case 119: /* alter_db_optr ::= alter_db_optr quorum */ yytestcase(yyruleno==119); -{ yylhsminor.yy22 = yymsp[-1].minor.yy22; yylhsminor.yy22.quorum = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy22 = yylhsminor.yy22; +{ yylhsminor.yy372 = yymsp[-1].minor.yy372; yylhsminor.yy372.quorum = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy372 = yylhsminor.yy372; break; case 103: /* db_optr ::= db_optr days */ -{ yylhsminor.yy22 = yymsp[-1].minor.yy22; yylhsminor.yy22.daysPerFile = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy22 = yylhsminor.yy22; +{ yylhsminor.yy372 = yymsp[-1].minor.yy372; yylhsminor.yy372.daysPerFile = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy372 = yylhsminor.yy372; break; case 104: /* db_optr ::= db_optr minrows */ -{ yylhsminor.yy22 = yymsp[-1].minor.yy22; yylhsminor.yy22.minRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } - yymsp[-1].minor.yy22 = yylhsminor.yy22; +{ yylhsminor.yy372 = yymsp[-1].minor.yy372; yylhsminor.yy372.minRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } + yymsp[-1].minor.yy372 = yylhsminor.yy372; break; case 105: /* db_optr ::= db_optr maxrows */ -{ yylhsminor.yy22 = yymsp[-1].minor.yy22; yylhsminor.yy22.maxRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } - yymsp[-1].minor.yy22 = yylhsminor.yy22; +{ yylhsminor.yy372 = yymsp[-1].minor.yy372; yylhsminor.yy372.maxRowsPerBlock = strtod(yymsp[0].minor.yy0.z, NULL); } + yymsp[-1].minor.yy372 = yylhsminor.yy372; break; case 106: /* db_optr ::= db_optr blocks */ case 121: /* alter_db_optr ::= alter_db_optr blocks */ yytestcase(yyruleno==121); -{ yylhsminor.yy22 = yymsp[-1].minor.yy22; yylhsminor.yy22.numOfBlocks = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy22 = yylhsminor.yy22; +{ yylhsminor.yy372 = yymsp[-1].minor.yy372; yylhsminor.yy372.numOfBlocks = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy372 = yylhsminor.yy372; break; case 107: /* db_optr ::= db_optr ctime */ -{ yylhsminor.yy22 = yymsp[-1].minor.yy22; yylhsminor.yy22.commitTime = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy22 = yylhsminor.yy22; +{ yylhsminor.yy372 = yymsp[-1].minor.yy372; yylhsminor.yy372.commitTime = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy372 = yylhsminor.yy372; break; case 108: /* db_optr ::= db_optr wal */ case 123: /* alter_db_optr ::= alter_db_optr wal */ yytestcase(yyruleno==123); -{ yylhsminor.yy22 = yymsp[-1].minor.yy22; yylhsminor.yy22.walLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy22 = yylhsminor.yy22; +{ yylhsminor.yy372 = yymsp[-1].minor.yy372; yylhsminor.yy372.walLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy372 = yylhsminor.yy372; break; case 109: /* db_optr ::= db_optr fsync */ case 124: /* alter_db_optr ::= alter_db_optr fsync */ yytestcase(yyruleno==124); -{ yylhsminor.yy22 = yymsp[-1].minor.yy22; yylhsminor.yy22.fsyncPeriod = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy22 = yylhsminor.yy22; +{ yylhsminor.yy372 = yymsp[-1].minor.yy372; yylhsminor.yy372.fsyncPeriod = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy372 = yylhsminor.yy372; break; case 110: /* db_optr ::= db_optr comp */ case 122: /* alter_db_optr ::= alter_db_optr comp */ yytestcase(yyruleno==122); -{ yylhsminor.yy22 = yymsp[-1].minor.yy22; yylhsminor.yy22.compressionLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy22 = yylhsminor.yy22; +{ yylhsminor.yy372 = yymsp[-1].minor.yy372; yylhsminor.yy372.compressionLevel = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy372 = yylhsminor.yy372; break; case 111: /* db_optr ::= db_optr prec */ -{ yylhsminor.yy22 = yymsp[-1].minor.yy22; yylhsminor.yy22.precision = yymsp[0].minor.yy0; } - yymsp[-1].minor.yy22 = yylhsminor.yy22; +{ yylhsminor.yy372 = yymsp[-1].minor.yy372; yylhsminor.yy372.precision = yymsp[0].minor.yy0; } + yymsp[-1].minor.yy372 = yylhsminor.yy372; break; case 112: /* db_optr ::= db_optr keep */ case 120: /* alter_db_optr ::= alter_db_optr keep */ yytestcase(yyruleno==120); -{ yylhsminor.yy22 = yymsp[-1].minor.yy22; yylhsminor.yy22.keep = yymsp[0].minor.yy325; } - yymsp[-1].minor.yy22 = yylhsminor.yy22; +{ yylhsminor.yy372 = yymsp[-1].minor.yy372; yylhsminor.yy372.keep = yymsp[0].minor.yy93; } + yymsp[-1].minor.yy372 = yylhsminor.yy372; break; case 113: /* db_optr ::= db_optr update */ case 125: /* alter_db_optr ::= alter_db_optr update */ yytestcase(yyruleno==125); -{ yylhsminor.yy22 = yymsp[-1].minor.yy22; yylhsminor.yy22.update = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy22 = yylhsminor.yy22; +{ yylhsminor.yy372 = yymsp[-1].minor.yy372; yylhsminor.yy372.update = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy372 = yylhsminor.yy372; break; case 114: /* db_optr ::= db_optr cachelast */ case 126: /* alter_db_optr ::= alter_db_optr cachelast */ yytestcase(yyruleno==126); -{ yylhsminor.yy22 = yymsp[-1].minor.yy22; yylhsminor.yy22.cachelast = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy22 = yylhsminor.yy22; +{ yylhsminor.yy372 = yymsp[-1].minor.yy372; yylhsminor.yy372.cachelast = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy372 = yylhsminor.yy372; break; case 115: /* topic_optr ::= db_optr */ case 127: /* alter_topic_optr ::= alter_db_optr */ yytestcase(yyruleno==127); -{ yylhsminor.yy22 = yymsp[0].minor.yy22; yylhsminor.yy22.dbType = TSDB_DB_TYPE_TOPIC; } - yymsp[0].minor.yy22 = yylhsminor.yy22; +{ yylhsminor.yy372 = yymsp[0].minor.yy372; yylhsminor.yy372.dbType = TSDB_DB_TYPE_TOPIC; } + yymsp[0].minor.yy372 = yylhsminor.yy372; break; case 116: /* topic_optr ::= topic_optr partitions */ case 128: /* alter_topic_optr ::= alter_topic_optr partitions */ yytestcase(yyruleno==128); -{ yylhsminor.yy22 = yymsp[-1].minor.yy22; yylhsminor.yy22.partitions = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[-1].minor.yy22 = yylhsminor.yy22; +{ yylhsminor.yy372 = yymsp[-1].minor.yy372; yylhsminor.yy372.partitions = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[-1].minor.yy372 = yylhsminor.yy372; break; case 117: /* alter_db_optr ::= */ -{ setDefaultCreateDbOption(&yymsp[1].minor.yy22); yymsp[1].minor.yy22.dbType = TSDB_DB_TYPE_DEFAULT;} +{ setDefaultCreateDbOption(&yymsp[1].minor.yy372); yymsp[1].minor.yy372.dbType = TSDB_DB_TYPE_DEFAULT;} break; case 129: /* typename ::= ids */ { yymsp[0].minor.yy0.type = 0; - tSetColumnType (&yylhsminor.yy47, &yymsp[0].minor.yy0); + tSetColumnType (&yylhsminor.yy325, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy47 = yylhsminor.yy47; + yymsp[0].minor.yy325 = yylhsminor.yy325; break; case 130: /* typename ::= ids LP signed RP */ { - if (yymsp[-1].minor.yy373 <= 0) { + if (yymsp[-1].minor.yy279 <= 0) { yymsp[-3].minor.yy0.type = 0; - tSetColumnType(&yylhsminor.yy47, &yymsp[-3].minor.yy0); + tSetColumnType(&yylhsminor.yy325, &yymsp[-3].minor.yy0); } else { - yymsp[-3].minor.yy0.type = -yymsp[-1].minor.yy373; // negative value of name length - tSetColumnType(&yylhsminor.yy47, &yymsp[-3].minor.yy0); + yymsp[-3].minor.yy0.type = -yymsp[-1].minor.yy279; // negative value of name length + tSetColumnType(&yylhsminor.yy325, &yymsp[-3].minor.yy0); } } - yymsp[-3].minor.yy47 = yylhsminor.yy47; + yymsp[-3].minor.yy325 = yylhsminor.yy325; break; case 131: /* 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.yy47, &yymsp[-1].minor.yy0); + tSetColumnType (&yylhsminor.yy325, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy47 = yylhsminor.yy47; + yymsp[-1].minor.yy325 = yylhsminor.yy325; break; case 132: /* signed ::= INTEGER */ -{ yylhsminor.yy373 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } - yymsp[0].minor.yy373 = yylhsminor.yy373; +{ yylhsminor.yy279 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } + yymsp[0].minor.yy279 = yylhsminor.yy279; break; case 133: /* signed ::= PLUS INTEGER */ -{ yymsp[-1].minor.yy373 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } +{ yymsp[-1].minor.yy279 = strtol(yymsp[0].minor.yy0.z, NULL, 10); } break; case 134: /* signed ::= MINUS INTEGER */ -{ yymsp[-1].minor.yy373 = -strtol(yymsp[0].minor.yy0.z, NULL, 10);} +{ yymsp[-1].minor.yy279 = -strtol(yymsp[0].minor.yy0.z, NULL, 10);} break; case 138: /* cmd ::= CREATE TABLE create_table_list */ -{ pInfo->type = TSDB_SQL_CREATE_TABLE; pInfo->pCreateTableInfo = yymsp[0].minor.yy422;} +{ pInfo->type = TSDB_SQL_CREATE_TABLE; pInfo->pCreateTableInfo = yymsp[0].minor.yy532;} break; case 139: /* create_table_list ::= create_from_stable */ { SCreateTableSql* pCreateTable = calloc(1, sizeof(SCreateTableSql)); pCreateTable->childTableInfo = taosArrayInit(4, sizeof(SCreatedTableInfo)); - taosArrayPush(pCreateTable->childTableInfo, &yymsp[0].minor.yy504); + taosArrayPush(pCreateTable->childTableInfo, &yymsp[0].minor.yy528); pCreateTable->type = TSQL_CREATE_TABLE_FROM_STABLE; - yylhsminor.yy422 = pCreateTable; + yylhsminor.yy532 = pCreateTable; } - yymsp[0].minor.yy422 = yylhsminor.yy422; + yymsp[0].minor.yy532 = yylhsminor.yy532; break; case 140: /* create_table_list ::= create_table_list create_from_stable */ { - taosArrayPush(yymsp[-1].minor.yy422->childTableInfo, &yymsp[0].minor.yy504); - yylhsminor.yy422 = yymsp[-1].minor.yy422; + taosArrayPush(yymsp[-1].minor.yy532->childTableInfo, &yymsp[0].minor.yy528); + yylhsminor.yy532 = yymsp[-1].minor.yy532; } - yymsp[-1].minor.yy422 = yylhsminor.yy422; + yymsp[-1].minor.yy532 = yylhsminor.yy532; break; case 141: /* create_table_args ::= ifnotexists ids cpxName LP columnlist RP */ { - yylhsminor.yy422 = tSetCreateTableInfo(yymsp[-1].minor.yy325, NULL, NULL, TSQL_CREATE_TABLE); - setSqlInfo(pInfo, yylhsminor.yy422, NULL, TSDB_SQL_CREATE_TABLE); + yylhsminor.yy532 = tSetCreateTableInfo(yymsp[-1].minor.yy93, NULL, NULL, TSQL_CREATE_TABLE); + setSqlInfo(pInfo, yylhsminor.yy532, 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.yy422 = yylhsminor.yy422; + yymsp[-5].minor.yy532 = yylhsminor.yy532; break; case 142: /* create_stable_args ::= ifnotexists ids cpxName LP columnlist RP TAGS LP columnlist RP */ { - yylhsminor.yy422 = tSetCreateTableInfo(yymsp[-5].minor.yy325, yymsp[-1].minor.yy325, NULL, TSQL_CREATE_STABLE); - setSqlInfo(pInfo, yylhsminor.yy422, NULL, TSDB_SQL_CREATE_TABLE); + yylhsminor.yy532 = tSetCreateTableInfo(yymsp[-5].minor.yy93, yymsp[-1].minor.yy93, NULL, TSQL_CREATE_STABLE); + setSqlInfo(pInfo, yylhsminor.yy532, 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.yy422 = yylhsminor.yy422; + yymsp[-9].minor.yy532 = yylhsminor.yy532; break; case 143: /* 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.yy504 = createNewChildTableInfo(&yymsp[-5].minor.yy0, NULL, yymsp[-1].minor.yy325, &yymsp[-8].minor.yy0, &yymsp[-9].minor.yy0); + yylhsminor.yy528 = createNewChildTableInfo(&yymsp[-5].minor.yy0, NULL, yymsp[-1].minor.yy93, &yymsp[-8].minor.yy0, &yymsp[-9].minor.yy0); } - yymsp[-9].minor.yy504 = yylhsminor.yy504; + yymsp[-9].minor.yy528 = yylhsminor.yy528; break; case 144: /* 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.yy504 = createNewChildTableInfo(&yymsp[-8].minor.yy0, yymsp[-5].minor.yy325, yymsp[-1].minor.yy325, &yymsp[-11].minor.yy0, &yymsp[-12].minor.yy0); + yylhsminor.yy528 = createNewChildTableInfo(&yymsp[-8].minor.yy0, yymsp[-5].minor.yy93, yymsp[-1].minor.yy93, &yymsp[-11].minor.yy0, &yymsp[-12].minor.yy0); } - yymsp[-12].minor.yy504 = yylhsminor.yy504; + yymsp[-12].minor.yy528 = yylhsminor.yy528; break; case 145: /* tagNamelist ::= tagNamelist COMMA ids */ -{taosArrayPush(yymsp[-2].minor.yy325, &yymsp[0].minor.yy0); yylhsminor.yy325 = yymsp[-2].minor.yy325; } - yymsp[-2].minor.yy325 = yylhsminor.yy325; +{taosArrayPush(yymsp[-2].minor.yy93, &yymsp[0].minor.yy0); yylhsminor.yy93 = yymsp[-2].minor.yy93; } + yymsp[-2].minor.yy93 = yylhsminor.yy93; break; case 146: /* tagNamelist ::= ids */ -{yylhsminor.yy325 = taosArrayInit(4, sizeof(SStrToken)); taosArrayPush(yylhsminor.yy325, &yymsp[0].minor.yy0);} - yymsp[0].minor.yy325 = yylhsminor.yy325; +{yylhsminor.yy93 = taosArrayInit(4, sizeof(SStrToken)); taosArrayPush(yylhsminor.yy93, &yymsp[0].minor.yy0);} + yymsp[0].minor.yy93 = yylhsminor.yy93; break; case 147: /* create_table_args ::= ifnotexists ids cpxName AS select */ { - yylhsminor.yy422 = tSetCreateTableInfo(NULL, NULL, yymsp[0].minor.yy494, TSQL_CREATE_STREAM); - setSqlInfo(pInfo, yylhsminor.yy422, NULL, TSDB_SQL_CREATE_TABLE); + yylhsminor.yy532 = tSetCreateTableInfo(NULL, NULL, yymsp[0].minor.yy224, TSQL_CREATE_STREAM); + setSqlInfo(pInfo, yylhsminor.yy532, 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.yy422 = yylhsminor.yy422; + yymsp[-4].minor.yy532 = yylhsminor.yy532; break; case 148: /* columnlist ::= columnlist COMMA column */ -{taosArrayPush(yymsp[-2].minor.yy325, &yymsp[0].minor.yy47); yylhsminor.yy325 = yymsp[-2].minor.yy325; } - yymsp[-2].minor.yy325 = yylhsminor.yy325; +{taosArrayPush(yymsp[-2].minor.yy93, &yymsp[0].minor.yy325); yylhsminor.yy93 = yymsp[-2].minor.yy93; } + yymsp[-2].minor.yy93 = yylhsminor.yy93; break; case 149: /* columnlist ::= column */ -{yylhsminor.yy325 = taosArrayInit(4, sizeof(TAOS_FIELD)); taosArrayPush(yylhsminor.yy325, &yymsp[0].minor.yy47);} - yymsp[0].minor.yy325 = yylhsminor.yy325; +{yylhsminor.yy93 = taosArrayInit(4, sizeof(TAOS_FIELD)); taosArrayPush(yylhsminor.yy93, &yymsp[0].minor.yy325);} + yymsp[0].minor.yy93 = yylhsminor.yy93; break; case 150: /* column ::= ids typename */ { - tSetColumnInfo(&yylhsminor.yy47, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy47); + tSetColumnInfo(&yylhsminor.yy325, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy325); } - yymsp[-1].minor.yy47 = yylhsminor.yy47; + yymsp[-1].minor.yy325 = yylhsminor.yy325; break; case 151: /* tagitemlist ::= tagitemlist COMMA tagitem */ -{ yylhsminor.yy325 = tVariantListAppend(yymsp[-2].minor.yy325, &yymsp[0].minor.yy442, -1); } - yymsp[-2].minor.yy325 = yylhsminor.yy325; +{ yylhsminor.yy93 = tVariantListAppend(yymsp[-2].minor.yy93, &yymsp[0].minor.yy518, -1); } + yymsp[-2].minor.yy93 = yylhsminor.yy93; break; case 152: /* tagitemlist ::= tagitem */ -{ yylhsminor.yy325 = tVariantListAppend(NULL, &yymsp[0].minor.yy442, -1); } - yymsp[0].minor.yy325 = yylhsminor.yy325; +{ yylhsminor.yy93 = tVariantListAppend(NULL, &yymsp[0].minor.yy518, -1); } + yymsp[0].minor.yy93 = yylhsminor.yy93; break; case 153: /* tagitem ::= INTEGER */ case 154: /* tagitem ::= FLOAT */ yytestcase(yyruleno==154); case 155: /* tagitem ::= STRING */ yytestcase(yyruleno==155); case 156: /* tagitem ::= BOOL */ yytestcase(yyruleno==156); -{ toTSDBType(yymsp[0].minor.yy0.type); tVariantCreate(&yylhsminor.yy442, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy442 = yylhsminor.yy442; +{ toTSDBType(yymsp[0].minor.yy0.type); tVariantCreate(&yylhsminor.yy518, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy518 = yylhsminor.yy518; break; case 157: /* tagitem ::= NULL */ -{ yymsp[0].minor.yy0.type = 0; tVariantCreate(&yylhsminor.yy442, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy442 = yylhsminor.yy442; +{ yymsp[0].minor.yy0.type = 0; tVariantCreate(&yylhsminor.yy518, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy518 = yylhsminor.yy518; break; case 158: /* tagitem ::= MINUS INTEGER */ case 159: /* tagitem ::= MINUS FLOAT */ yytestcase(yyruleno==159); @@ -2932,56 +2642,56 @@ static YYACTIONTYPE 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.yy442, &yymsp[-1].minor.yy0); + tVariantCreate(&yylhsminor.yy518, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy442 = yylhsminor.yy442; + yymsp[-1].minor.yy518 = yylhsminor.yy518; break; case 162: /* 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.yy494 = tSetQuerySqlNode(&yymsp[-12].minor.yy0, yymsp[-11].minor.yy325, yymsp[-10].minor.yy506, yymsp[-9].minor.yy162, yymsp[-4].minor.yy325, yymsp[-3].minor.yy325, &yymsp[-8].minor.yy328, &yymsp[-7].minor.yy84, &yymsp[-5].minor.yy0, yymsp[-6].minor.yy325, &yymsp[0].minor.yy230, &yymsp[-1].minor.yy230, yymsp[-2].minor.yy162); + yylhsminor.yy224 = tSetQuerySqlNode(&yymsp[-12].minor.yy0, yymsp[-11].minor.yy93, yymsp[-10].minor.yy330, yymsp[-9].minor.yy68, yymsp[-4].minor.yy93, yymsp[-3].minor.yy93, &yymsp[-8].minor.yy42, &yymsp[-7].minor.yy15, &yymsp[-5].minor.yy0, yymsp[-6].minor.yy93, &yymsp[0].minor.yy284, &yymsp[-1].minor.yy284, yymsp[-2].minor.yy68); } - yymsp[-12].minor.yy494 = yylhsminor.yy494; + yymsp[-12].minor.yy224 = yylhsminor.yy224; break; case 163: /* select ::= LP select RP */ -{yymsp[-2].minor.yy494 = yymsp[-1].minor.yy494;} +{yymsp[-2].minor.yy224 = yymsp[-1].minor.yy224;} break; case 164: /* union ::= select */ -{ yylhsminor.yy145 = setSubclause(NULL, yymsp[0].minor.yy494); } - yymsp[0].minor.yy145 = yylhsminor.yy145; +{ yylhsminor.yy93 = setSubclause(NULL, yymsp[0].minor.yy224); } + yymsp[0].minor.yy93 = yylhsminor.yy93; break; case 165: /* union ::= union UNION ALL select */ -{ yylhsminor.yy145 = appendSelectClause(yymsp[-3].minor.yy145, yymsp[0].minor.yy494); } - yymsp[-3].minor.yy145 = yylhsminor.yy145; +{ yylhsminor.yy93 = appendSelectClause(yymsp[-3].minor.yy93, yymsp[0].minor.yy224); } + yymsp[-3].minor.yy93 = yylhsminor.yy93; break; case 166: /* cmd ::= union */ -{ setSqlInfo(pInfo, yymsp[0].minor.yy145, NULL, TSDB_SQL_SELECT); } +{ setSqlInfo(pInfo, yymsp[0].minor.yy93, NULL, TSDB_SQL_SELECT); } break; case 167: /* select ::= SELECT selcollist */ { - yylhsminor.yy494 = tSetQuerySqlNode(&yymsp[-1].minor.yy0, yymsp[0].minor.yy325, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + yylhsminor.yy224 = tSetQuerySqlNode(&yymsp[-1].minor.yy0, yymsp[0].minor.yy93, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } - yymsp[-1].minor.yy494 = yylhsminor.yy494; + yymsp[-1].minor.yy224 = yylhsminor.yy224; break; case 168: /* sclp ::= selcollist COMMA */ -{yylhsminor.yy325 = yymsp[-1].minor.yy325;} - yymsp[-1].minor.yy325 = yylhsminor.yy325; +{yylhsminor.yy93 = yymsp[-1].minor.yy93;} + yymsp[-1].minor.yy93 = yylhsminor.yy93; break; case 169: /* sclp ::= */ case 194: /* orderby_opt ::= */ yytestcase(yyruleno==194); -{yymsp[1].minor.yy325 = 0;} +{yymsp[1].minor.yy93 = 0;} break; case 170: /* selcollist ::= sclp distinct expr as */ { - yylhsminor.yy325 = tSqlExprListAppend(yymsp[-3].minor.yy325, yymsp[-1].minor.yy162, yymsp[-2].minor.yy0.n? &yymsp[-2].minor.yy0:0, yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0); + yylhsminor.yy93 = tSqlExprListAppend(yymsp[-3].minor.yy93, yymsp[-1].minor.yy68, yymsp[-2].minor.yy0.n? &yymsp[-2].minor.yy0:0, yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0); } - yymsp[-3].minor.yy325 = yylhsminor.yy325; + yymsp[-3].minor.yy93 = yylhsminor.yy93; break; case 171: /* selcollist ::= sclp STAR */ { tSqlExpr *pNode = tSqlExprCreateIdValue(NULL, TK_ALL); - yylhsminor.yy325 = tSqlExprListAppend(yymsp[-1].minor.yy325, pNode, 0, 0); + yylhsminor.yy93 = tSqlExprListAppend(yymsp[-1].minor.yy93, pNode, 0, 0); } - yymsp[-1].minor.yy325 = yylhsminor.yy325; + yymsp[-1].minor.yy93 = yylhsminor.yy93; break; case 172: /* as ::= AS ids */ { yymsp[-1].minor.yy0 = yymsp[0].minor.yy0; } @@ -2998,71 +2708,64 @@ static YYACTIONTYPE yy_reduce( yymsp[0].minor.yy0 = yylhsminor.yy0; break; case 177: /* from ::= FROM tablelist */ -{yymsp[-1].minor.yy506 = yymsp[0].minor.yy325;} +{yymsp[-1].minor.yy330 = yymsp[0].minor.yy330;} break; case 178: /* from ::= FROM LP union RP */ -{yymsp[-3].minor.yy506 = yymsp[-1].minor.yy145;} +{yymsp[-3].minor.yy330 = setSubquery(NULL, yymsp[-1].minor.yy93);} break; case 179: /* tablelist ::= ids cpxName */ { - toTSDBType(yymsp[-1].minor.yy0.type); yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; - yylhsminor.yy325 = setTableNameList(NULL, &yymsp[-1].minor.yy0, NULL); + yylhsminor.yy330 = setTableNameList(NULL, &yymsp[-1].minor.yy0, NULL); } - yymsp[-1].minor.yy325 = yylhsminor.yy325; + yymsp[-1].minor.yy330 = yylhsminor.yy330; break; case 180: /* 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.yy325 = setTableNameList(NULL, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + yylhsminor.yy330 = setTableNameList(NULL, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy325 = yylhsminor.yy325; + yymsp[-2].minor.yy330 = yylhsminor.yy330; break; case 181: /* tablelist ::= tablelist COMMA ids cpxName */ { - toTSDBType(yymsp[-1].minor.yy0.type); yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; - yylhsminor.yy325 = setTableNameList(yymsp[-3].minor.yy325, &yymsp[-1].minor.yy0, NULL); + yylhsminor.yy330 = setTableNameList(yymsp[-3].minor.yy330, &yymsp[-1].minor.yy0, NULL); } - yymsp[-3].minor.yy325 = yylhsminor.yy325; + yymsp[-3].minor.yy330 = yylhsminor.yy330; break; case 182: /* tablelist ::= tablelist COMMA 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.yy325 = setTableNameList(yymsp[-4].minor.yy325, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + yylhsminor.yy330 = setTableNameList(yymsp[-4].minor.yy330, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } - yymsp[-4].minor.yy325 = yylhsminor.yy325; + yymsp[-4].minor.yy330 = yylhsminor.yy330; break; case 183: /* tmvar ::= VARIABLE */ {yylhsminor.yy0 = yymsp[0].minor.yy0;} yymsp[0].minor.yy0 = yylhsminor.yy0; break; case 184: /* interval_opt ::= INTERVAL LP tmvar RP */ -{yymsp[-3].minor.yy328.interval = yymsp[-1].minor.yy0; yymsp[-3].minor.yy328.offset.n = 0;} +{yymsp[-3].minor.yy42.interval = yymsp[-1].minor.yy0; yymsp[-3].minor.yy42.offset.n = 0;} break; case 185: /* interval_opt ::= INTERVAL LP tmvar COMMA tmvar RP */ -{yymsp[-5].minor.yy328.interval = yymsp[-3].minor.yy0; yymsp[-5].minor.yy328.offset = yymsp[-1].minor.yy0;} +{yymsp[-5].minor.yy42.interval = yymsp[-3].minor.yy0; yymsp[-5].minor.yy42.offset = yymsp[-1].minor.yy0;} break; case 186: /* interval_opt ::= */ -{memset(&yymsp[1].minor.yy328, 0, sizeof(yymsp[1].minor.yy328));} +{memset(&yymsp[1].minor.yy42, 0, sizeof(yymsp[1].minor.yy42));} break; case 187: /* session_option ::= */ -{yymsp[1].minor.yy84.col.n = 0; yymsp[1].minor.yy84.gap.n = 0;} +{yymsp[1].minor.yy15.col.n = 0; yymsp[1].minor.yy15.gap.n = 0;} break; case 188: /* session_option ::= SESSION LP ids cpxName COMMA tmvar RP */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; - yymsp[-6].minor.yy84.col = yymsp[-4].minor.yy0; - yymsp[-6].minor.yy84.gap = yymsp[-1].minor.yy0; + yymsp[-6].minor.yy15.col = yymsp[-4].minor.yy0; + yymsp[-6].minor.yy15.gap = yymsp[-1].minor.yy0; } break; case 189: /* fill_opt ::= */ -{ yymsp[1].minor.yy325 = 0; } +{ yymsp[1].minor.yy93 = 0; } break; case 190: /* fill_opt ::= FILL LP ID COMMA tagitemlist RP */ { @@ -3070,14 +2773,14 @@ static YYACTIONTYPE yy_reduce( toTSDBType(yymsp[-3].minor.yy0.type); tVariantCreate(&A, &yymsp[-3].minor.yy0); - tVariantListInsert(yymsp[-1].minor.yy325, &A, -1, 0); - yymsp[-5].minor.yy325 = yymsp[-1].minor.yy325; + tVariantListInsert(yymsp[-1].minor.yy93, &A, -1, 0); + yymsp[-5].minor.yy93 = yymsp[-1].minor.yy93; } break; case 191: /* fill_opt ::= FILL LP ID RP */ { toTSDBType(yymsp[-1].minor.yy0.type); - yymsp[-3].minor.yy325 = tVariantListAppendToken(NULL, &yymsp[-1].minor.yy0, -1); + yymsp[-3].minor.yy93 = tVariantListAppendToken(NULL, &yymsp[-1].minor.yy0, -1); } break; case 192: /* sliding_opt ::= SLIDING LP tmvar RP */ @@ -3087,245 +2790,250 @@ static YYACTIONTYPE yy_reduce( {yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = NULL; yymsp[1].minor.yy0.type = 0; } break; case 195: /* orderby_opt ::= ORDER BY sortlist */ -{yymsp[-2].minor.yy325 = yymsp[0].minor.yy325;} +{yymsp[-2].minor.yy93 = yymsp[0].minor.yy93;} break; case 196: /* sortlist ::= sortlist COMMA item sortorder */ { - yylhsminor.yy325 = tVariantListAppend(yymsp[-3].minor.yy325, &yymsp[-1].minor.yy442, yymsp[0].minor.yy196); + yylhsminor.yy93 = tVariantListAppend(yymsp[-3].minor.yy93, &yymsp[-1].minor.yy518, yymsp[0].minor.yy150); } - yymsp[-3].minor.yy325 = yylhsminor.yy325; + yymsp[-3].minor.yy93 = yylhsminor.yy93; break; case 197: /* sortlist ::= item sortorder */ { - yylhsminor.yy325 = tVariantListAppend(NULL, &yymsp[-1].minor.yy442, yymsp[0].minor.yy196); + yylhsminor.yy93 = tVariantListAppend(NULL, &yymsp[-1].minor.yy518, yymsp[0].minor.yy150); } - yymsp[-1].minor.yy325 = yylhsminor.yy325; + yymsp[-1].minor.yy93 = yylhsminor.yy93; break; case 198: /* item ::= ids cpxName */ { toTSDBType(yymsp[-1].minor.yy0.type); yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; - tVariantCreate(&yylhsminor.yy442, &yymsp[-1].minor.yy0); + tVariantCreate(&yylhsminor.yy518, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy442 = yylhsminor.yy442; + yymsp[-1].minor.yy518 = yylhsminor.yy518; break; case 199: /* sortorder ::= ASC */ -{ yymsp[0].minor.yy196 = TSDB_ORDER_ASC; } +{ yymsp[0].minor.yy150 = TSDB_ORDER_ASC; } break; case 200: /* sortorder ::= DESC */ -{ yymsp[0].minor.yy196 = TSDB_ORDER_DESC;} +{ yymsp[0].minor.yy150 = TSDB_ORDER_DESC;} break; case 201: /* sortorder ::= */ -{ yymsp[1].minor.yy196 = TSDB_ORDER_ASC; } +{ yymsp[1].minor.yy150 = TSDB_ORDER_ASC; } break; case 202: /* groupby_opt ::= */ -{ yymsp[1].minor.yy325 = 0;} +{ yymsp[1].minor.yy93 = 0;} break; case 203: /* groupby_opt ::= GROUP BY grouplist */ -{ yymsp[-2].minor.yy325 = yymsp[0].minor.yy325;} +{ yymsp[-2].minor.yy93 = yymsp[0].minor.yy93;} break; case 204: /* grouplist ::= grouplist COMMA item */ { - yylhsminor.yy325 = tVariantListAppend(yymsp[-2].minor.yy325, &yymsp[0].minor.yy442, -1); + yylhsminor.yy93 = tVariantListAppend(yymsp[-2].minor.yy93, &yymsp[0].minor.yy518, -1); } - yymsp[-2].minor.yy325 = yylhsminor.yy325; + yymsp[-2].minor.yy93 = yylhsminor.yy93; break; case 205: /* grouplist ::= item */ { - yylhsminor.yy325 = tVariantListAppend(NULL, &yymsp[0].minor.yy442, -1); + yylhsminor.yy93 = tVariantListAppend(NULL, &yymsp[0].minor.yy518, -1); } - yymsp[0].minor.yy325 = yylhsminor.yy325; + yymsp[0].minor.yy93 = yylhsminor.yy93; break; case 206: /* having_opt ::= */ case 216: /* where_opt ::= */ yytestcase(yyruleno==216); - case 256: /* expritem ::= */ yytestcase(yyruleno==256); -{yymsp[1].minor.yy162 = 0;} + case 258: /* expritem ::= */ yytestcase(yyruleno==258); +{yymsp[1].minor.yy68 = 0;} break; case 207: /* having_opt ::= HAVING expr */ case 217: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==217); -{yymsp[-1].minor.yy162 = yymsp[0].minor.yy162;} +{yymsp[-1].minor.yy68 = yymsp[0].minor.yy68;} break; case 208: /* limit_opt ::= */ case 212: /* slimit_opt ::= */ yytestcase(yyruleno==212); -{yymsp[1].minor.yy230.limit = -1; yymsp[1].minor.yy230.offset = 0;} +{yymsp[1].minor.yy284.limit = -1; yymsp[1].minor.yy284.offset = 0;} break; case 209: /* limit_opt ::= LIMIT signed */ case 213: /* slimit_opt ::= SLIMIT signed */ yytestcase(yyruleno==213); -{yymsp[-1].minor.yy230.limit = yymsp[0].minor.yy373; yymsp[-1].minor.yy230.offset = 0;} +{yymsp[-1].minor.yy284.limit = yymsp[0].minor.yy279; yymsp[-1].minor.yy284.offset = 0;} break; case 210: /* limit_opt ::= LIMIT signed OFFSET signed */ -{ yymsp[-3].minor.yy230.limit = yymsp[-2].minor.yy373; yymsp[-3].minor.yy230.offset = yymsp[0].minor.yy373;} +{ yymsp[-3].minor.yy284.limit = yymsp[-2].minor.yy279; yymsp[-3].minor.yy284.offset = yymsp[0].minor.yy279;} break; case 211: /* limit_opt ::= LIMIT signed COMMA signed */ -{ yymsp[-3].minor.yy230.limit = yymsp[0].minor.yy373; yymsp[-3].minor.yy230.offset = yymsp[-2].minor.yy373;} +{ yymsp[-3].minor.yy284.limit = yymsp[0].minor.yy279; yymsp[-3].minor.yy284.offset = yymsp[-2].minor.yy279;} break; case 214: /* slimit_opt ::= SLIMIT signed SOFFSET signed */ -{yymsp[-3].minor.yy230.limit = yymsp[-2].minor.yy373; yymsp[-3].minor.yy230.offset = yymsp[0].minor.yy373;} +{yymsp[-3].minor.yy284.limit = yymsp[-2].minor.yy279; yymsp[-3].minor.yy284.offset = yymsp[0].minor.yy279;} break; case 215: /* slimit_opt ::= SLIMIT signed COMMA signed */ -{yymsp[-3].minor.yy230.limit = yymsp[0].minor.yy373; yymsp[-3].minor.yy230.offset = yymsp[-2].minor.yy373;} +{yymsp[-3].minor.yy284.limit = yymsp[0].minor.yy279; yymsp[-3].minor.yy284.offset = yymsp[-2].minor.yy279;} break; case 218: /* expr ::= LP expr RP */ -{yylhsminor.yy162 = yymsp[-1].minor.yy162; yylhsminor.yy162->token.z = yymsp[-2].minor.yy0.z; yylhsminor.yy162->token.n = (yymsp[0].minor.yy0.z - yymsp[-2].minor.yy0.z + 1);} - yymsp[-2].minor.yy162 = yylhsminor.yy162; +{yylhsminor.yy68 = yymsp[-1].minor.yy68; yylhsminor.yy68->token.z = yymsp[-2].minor.yy0.z; yylhsminor.yy68->token.n = (yymsp[0].minor.yy0.z - yymsp[-2].minor.yy0.z + 1);} + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; case 219: /* expr ::= ID */ -{ yylhsminor.yy162 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_ID);} - yymsp[0].minor.yy162 = yylhsminor.yy162; +{ yylhsminor.yy68 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_ID);} + yymsp[0].minor.yy68 = yylhsminor.yy68; break; case 220: /* expr ::= ID DOT ID */ -{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy162 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ID);} - yymsp[-2].minor.yy162 = yylhsminor.yy162; +{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy68 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ID);} + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; case 221: /* expr ::= ID DOT STAR */ -{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy162 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ALL);} - yymsp[-2].minor.yy162 = yylhsminor.yy162; +{ yymsp[-2].minor.yy0.n += (1+yymsp[0].minor.yy0.n); yylhsminor.yy68 = tSqlExprCreateIdValue(&yymsp[-2].minor.yy0, TK_ALL);} + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; case 222: /* expr ::= INTEGER */ -{ yylhsminor.yy162 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_INTEGER);} - yymsp[0].minor.yy162 = yylhsminor.yy162; +{ yylhsminor.yy68 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_INTEGER);} + yymsp[0].minor.yy68 = yylhsminor.yy68; break; case 223: /* expr ::= MINUS INTEGER */ case 224: /* expr ::= PLUS INTEGER */ yytestcase(yyruleno==224); -{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_INTEGER; yylhsminor.yy162 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_INTEGER);} - yymsp[-1].minor.yy162 = yylhsminor.yy162; +{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_INTEGER; yylhsminor.yy68 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_INTEGER);} + yymsp[-1].minor.yy68 = yylhsminor.yy68; break; case 225: /* expr ::= FLOAT */ -{ yylhsminor.yy162 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_FLOAT);} - yymsp[0].minor.yy162 = yylhsminor.yy162; +{ yylhsminor.yy68 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_FLOAT);} + yymsp[0].minor.yy68 = yylhsminor.yy68; break; case 226: /* expr ::= MINUS FLOAT */ case 227: /* expr ::= PLUS FLOAT */ yytestcase(yyruleno==227); -{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_FLOAT; yylhsminor.yy162 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_FLOAT);} - yymsp[-1].minor.yy162 = yylhsminor.yy162; +{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_FLOAT; yylhsminor.yy68 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_FLOAT);} + yymsp[-1].minor.yy68 = yylhsminor.yy68; break; case 228: /* expr ::= STRING */ -{ yylhsminor.yy162 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_STRING);} - yymsp[0].minor.yy162 = yylhsminor.yy162; +{ yylhsminor.yy68 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_STRING);} + yymsp[0].minor.yy68 = yylhsminor.yy68; break; case 229: /* expr ::= NOW */ -{ yylhsminor.yy162 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NOW); } - yymsp[0].minor.yy162 = yylhsminor.yy162; +{ yylhsminor.yy68 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NOW); } + yymsp[0].minor.yy68 = yylhsminor.yy68; break; case 230: /* expr ::= VARIABLE */ -{ yylhsminor.yy162 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_VARIABLE);} - yymsp[0].minor.yy162 = yylhsminor.yy162; +{ yylhsminor.yy68 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_VARIABLE);} + yymsp[0].minor.yy68 = yylhsminor.yy68; break; - case 231: /* expr ::= BOOL */ -{ yylhsminor.yy162 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_BOOL);} - yymsp[0].minor.yy162 = yylhsminor.yy162; + case 231: /* expr ::= PLUS VARIABLE */ + case 232: /* expr ::= MINUS VARIABLE */ yytestcase(yyruleno==232); +{ yymsp[-1].minor.yy0.n += yymsp[0].minor.yy0.n; yymsp[-1].minor.yy0.type = TK_VARIABLE; yylhsminor.yy68 = tSqlExprCreateIdValue(&yymsp[-1].minor.yy0, TK_VARIABLE);} + yymsp[-1].minor.yy68 = yylhsminor.yy68; break; - case 232: /* expr ::= NULL */ -{ yylhsminor.yy162 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NULL);} - yymsp[0].minor.yy162 = yylhsminor.yy162; + case 233: /* expr ::= BOOL */ +{ yylhsminor.yy68 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_BOOL);} + yymsp[0].minor.yy68 = yylhsminor.yy68; break; - case 233: /* expr ::= ID LP exprlist RP */ -{ yylhsminor.yy162 = tSqlExprCreateFunction(yymsp[-1].minor.yy325, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } - yymsp[-3].minor.yy162 = yylhsminor.yy162; + case 234: /* expr ::= NULL */ +{ yylhsminor.yy68 = tSqlExprCreateIdValue(&yymsp[0].minor.yy0, TK_NULL);} + yymsp[0].minor.yy68 = yylhsminor.yy68; break; - case 234: /* expr ::= ID LP STAR RP */ -{ yylhsminor.yy162 = tSqlExprCreateFunction(NULL, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } - yymsp[-3].minor.yy162 = yylhsminor.yy162; + case 235: /* expr ::= ID LP exprlist RP */ +{ yylhsminor.yy68 = tSqlExprCreateFunction(yymsp[-1].minor.yy93, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } + yymsp[-3].minor.yy68 = yylhsminor.yy68; break; - case 235: /* expr ::= expr IS NULL */ -{yylhsminor.yy162 = tSqlExprCreate(yymsp[-2].minor.yy162, NULL, TK_ISNULL);} - yymsp[-2].minor.yy162 = yylhsminor.yy162; + case 236: /* expr ::= ID LP STAR RP */ +{ yylhsminor.yy68 = tSqlExprCreateFunction(NULL, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0, yymsp[-3].minor.yy0.type); } + yymsp[-3].minor.yy68 = yylhsminor.yy68; break; - case 236: /* expr ::= expr IS NOT NULL */ -{yylhsminor.yy162 = tSqlExprCreate(yymsp[-3].minor.yy162, NULL, TK_NOTNULL);} - yymsp[-3].minor.yy162 = yylhsminor.yy162; + case 237: /* expr ::= expr IS NULL */ +{yylhsminor.yy68 = tSqlExprCreate(yymsp[-2].minor.yy68, NULL, TK_ISNULL);} + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 237: /* expr ::= expr LT expr */ -{yylhsminor.yy162 = tSqlExprCreate(yymsp[-2].minor.yy162, yymsp[0].minor.yy162, TK_LT);} - yymsp[-2].minor.yy162 = yylhsminor.yy162; + case 238: /* expr ::= expr IS NOT NULL */ +{yylhsminor.yy68 = tSqlExprCreate(yymsp[-3].minor.yy68, NULL, TK_NOTNULL);} + yymsp[-3].minor.yy68 = yylhsminor.yy68; break; - case 238: /* expr ::= expr GT expr */ -{yylhsminor.yy162 = tSqlExprCreate(yymsp[-2].minor.yy162, yymsp[0].minor.yy162, TK_GT);} - yymsp[-2].minor.yy162 = yylhsminor.yy162; + case 239: /* expr ::= expr LT expr */ +{yylhsminor.yy68 = tSqlExprCreate(yymsp[-2].minor.yy68, yymsp[0].minor.yy68, TK_LT);} + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 239: /* expr ::= expr LE expr */ -{yylhsminor.yy162 = tSqlExprCreate(yymsp[-2].minor.yy162, yymsp[0].minor.yy162, TK_LE);} - yymsp[-2].minor.yy162 = yylhsminor.yy162; + case 240: /* expr ::= expr GT expr */ +{yylhsminor.yy68 = tSqlExprCreate(yymsp[-2].minor.yy68, yymsp[0].minor.yy68, TK_GT);} + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 240: /* expr ::= expr GE expr */ -{yylhsminor.yy162 = tSqlExprCreate(yymsp[-2].minor.yy162, yymsp[0].minor.yy162, TK_GE);} - yymsp[-2].minor.yy162 = yylhsminor.yy162; + case 241: /* expr ::= expr LE expr */ +{yylhsminor.yy68 = tSqlExprCreate(yymsp[-2].minor.yy68, yymsp[0].minor.yy68, TK_LE);} + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 241: /* expr ::= expr NE expr */ -{yylhsminor.yy162 = tSqlExprCreate(yymsp[-2].minor.yy162, yymsp[0].minor.yy162, TK_NE);} - yymsp[-2].minor.yy162 = yylhsminor.yy162; + case 242: /* expr ::= expr GE expr */ +{yylhsminor.yy68 = tSqlExprCreate(yymsp[-2].minor.yy68, yymsp[0].minor.yy68, TK_GE);} + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 242: /* expr ::= expr EQ expr */ -{yylhsminor.yy162 = tSqlExprCreate(yymsp[-2].minor.yy162, yymsp[0].minor.yy162, TK_EQ);} - yymsp[-2].minor.yy162 = yylhsminor.yy162; + case 243: /* expr ::= expr NE expr */ +{yylhsminor.yy68 = tSqlExprCreate(yymsp[-2].minor.yy68, yymsp[0].minor.yy68, TK_NE);} + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 243: /* expr ::= expr BETWEEN expr AND expr */ -{ tSqlExpr* X2 = tSqlExprClone(yymsp[-4].minor.yy162); yylhsminor.yy162 = tSqlExprCreate(tSqlExprCreate(yymsp[-4].minor.yy162, yymsp[-2].minor.yy162, TK_GE), tSqlExprCreate(X2, yymsp[0].minor.yy162, TK_LE), TK_AND);} - yymsp[-4].minor.yy162 = yylhsminor.yy162; + case 244: /* expr ::= expr EQ expr */ +{yylhsminor.yy68 = tSqlExprCreate(yymsp[-2].minor.yy68, yymsp[0].minor.yy68, TK_EQ);} + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 244: /* expr ::= expr AND expr */ -{yylhsminor.yy162 = tSqlExprCreate(yymsp[-2].minor.yy162, yymsp[0].minor.yy162, TK_AND);} - yymsp[-2].minor.yy162 = yylhsminor.yy162; + case 245: /* expr ::= expr BETWEEN expr AND expr */ +{ tSqlExpr* X2 = tSqlExprClone(yymsp[-4].minor.yy68); yylhsminor.yy68 = tSqlExprCreate(tSqlExprCreate(yymsp[-4].minor.yy68, yymsp[-2].minor.yy68, TK_GE), tSqlExprCreate(X2, yymsp[0].minor.yy68, TK_LE), TK_AND);} + yymsp[-4].minor.yy68 = yylhsminor.yy68; break; - case 245: /* expr ::= expr OR expr */ -{yylhsminor.yy162 = tSqlExprCreate(yymsp[-2].minor.yy162, yymsp[0].minor.yy162, TK_OR); } - yymsp[-2].minor.yy162 = yylhsminor.yy162; + case 246: /* expr ::= expr AND expr */ +{yylhsminor.yy68 = tSqlExprCreate(yymsp[-2].minor.yy68, yymsp[0].minor.yy68, TK_AND);} + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 246: /* expr ::= expr PLUS expr */ -{yylhsminor.yy162 = tSqlExprCreate(yymsp[-2].minor.yy162, yymsp[0].minor.yy162, TK_PLUS); } - yymsp[-2].minor.yy162 = yylhsminor.yy162; + case 247: /* expr ::= expr OR expr */ +{yylhsminor.yy68 = tSqlExprCreate(yymsp[-2].minor.yy68, yymsp[0].minor.yy68, TK_OR); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 247: /* expr ::= expr MINUS expr */ -{yylhsminor.yy162 = tSqlExprCreate(yymsp[-2].minor.yy162, yymsp[0].minor.yy162, TK_MINUS); } - yymsp[-2].minor.yy162 = yylhsminor.yy162; + case 248: /* expr ::= expr PLUS expr */ +{yylhsminor.yy68 = tSqlExprCreate(yymsp[-2].minor.yy68, yymsp[0].minor.yy68, TK_PLUS); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 248: /* expr ::= expr STAR expr */ -{yylhsminor.yy162 = tSqlExprCreate(yymsp[-2].minor.yy162, yymsp[0].minor.yy162, TK_STAR); } - yymsp[-2].minor.yy162 = yylhsminor.yy162; + case 249: /* expr ::= expr MINUS expr */ +{yylhsminor.yy68 = tSqlExprCreate(yymsp[-2].minor.yy68, yymsp[0].minor.yy68, TK_MINUS); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 249: /* expr ::= expr SLASH expr */ -{yylhsminor.yy162 = tSqlExprCreate(yymsp[-2].minor.yy162, yymsp[0].minor.yy162, TK_DIVIDE);} - yymsp[-2].minor.yy162 = yylhsminor.yy162; + case 250: /* expr ::= expr STAR expr */ +{yylhsminor.yy68 = tSqlExprCreate(yymsp[-2].minor.yy68, yymsp[0].minor.yy68, TK_STAR); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 250: /* expr ::= expr REM expr */ -{yylhsminor.yy162 = tSqlExprCreate(yymsp[-2].minor.yy162, yymsp[0].minor.yy162, TK_REM); } - yymsp[-2].minor.yy162 = yylhsminor.yy162; + case 251: /* expr ::= expr SLASH expr */ +{yylhsminor.yy68 = tSqlExprCreate(yymsp[-2].minor.yy68, yymsp[0].minor.yy68, TK_DIVIDE);} + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 251: /* expr ::= expr LIKE expr */ -{yylhsminor.yy162 = tSqlExprCreate(yymsp[-2].minor.yy162, yymsp[0].minor.yy162, TK_LIKE); } - yymsp[-2].minor.yy162 = yylhsminor.yy162; + case 252: /* expr ::= expr REM expr */ +{yylhsminor.yy68 = tSqlExprCreate(yymsp[-2].minor.yy68, yymsp[0].minor.yy68, TK_REM); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 252: /* expr ::= expr IN LP exprlist RP */ -{yylhsminor.yy162 = tSqlExprCreate(yymsp[-4].minor.yy162, (tSqlExpr*)yymsp[-1].minor.yy325, TK_IN); } - yymsp[-4].minor.yy162 = yylhsminor.yy162; + case 253: /* expr ::= expr LIKE expr */ +{yylhsminor.yy68 = tSqlExprCreate(yymsp[-2].minor.yy68, yymsp[0].minor.yy68, TK_LIKE); } + yymsp[-2].minor.yy68 = yylhsminor.yy68; break; - case 253: /* exprlist ::= exprlist COMMA expritem */ -{yylhsminor.yy325 = tSqlExprListAppend(yymsp[-2].minor.yy325,yymsp[0].minor.yy162,0, 0);} - yymsp[-2].minor.yy325 = yylhsminor.yy325; + case 254: /* expr ::= expr IN LP exprlist RP */ +{yylhsminor.yy68 = tSqlExprCreate(yymsp[-4].minor.yy68, (tSqlExpr*)yymsp[-1].minor.yy93, TK_IN); } + yymsp[-4].minor.yy68 = yylhsminor.yy68; break; - case 254: /* exprlist ::= expritem */ -{yylhsminor.yy325 = tSqlExprListAppend(0,yymsp[0].minor.yy162,0, 0);} - yymsp[0].minor.yy325 = yylhsminor.yy325; + case 255: /* exprlist ::= exprlist COMMA expritem */ +{yylhsminor.yy93 = tSqlExprListAppend(yymsp[-2].minor.yy93,yymsp[0].minor.yy68,0, 0);} + yymsp[-2].minor.yy93 = yylhsminor.yy93; break; - case 255: /* expritem ::= expr */ -{yylhsminor.yy162 = yymsp[0].minor.yy162;} - yymsp[0].minor.yy162 = yylhsminor.yy162; + case 256: /* exprlist ::= expritem */ +{yylhsminor.yy93 = tSqlExprListAppend(0,yymsp[0].minor.yy68,0, 0);} + yymsp[0].minor.yy93 = yylhsminor.yy93; break; - case 257: /* cmd ::= RESET QUERY CACHE */ + case 257: /* expritem ::= expr */ +{yylhsminor.yy68 = yymsp[0].minor.yy68;} + yymsp[0].minor.yy68 = yylhsminor.yy68; + break; + case 259: /* cmd ::= RESET QUERY CACHE */ { setDCLSqlElems(pInfo, TSDB_SQL_RESET_CACHE, 0);} break; - case 258: /* cmd ::= SYNCDB ids REPLICA */ + case 260: /* cmd ::= SYNCDB ids REPLICA */ { setDCLSqlElems(pInfo, TSDB_SQL_SYNC_DB_REPLICA, 1, &yymsp[-1].minor.yy0);} break; - case 259: /* cmd ::= ALTER TABLE ids cpxName ADD COLUMN columnlist */ + case 261: /* 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.yy325, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, -1); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy93, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 260: /* cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ + case 262: /* cmd ::= ALTER TABLE ids cpxName DROP COLUMN ids */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; @@ -3336,14 +3044,14 @@ static YYACTIONTYPE yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 261: /* cmd ::= ALTER TABLE ids cpxName ADD TAG columnlist */ + case 263: /* 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.yy325, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, -1); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy93, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, -1); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 262: /* cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ + case 264: /* cmd ::= ALTER TABLE ids cpxName DROP TAG ids */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; @@ -3354,7 +3062,7 @@ static YYACTIONTYPE yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 263: /* cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ + case 265: /* cmd ::= ALTER TABLE ids cpxName CHANGE TAG ids ids */ { yymsp[-5].minor.yy0.n += yymsp[-4].minor.yy0.n; @@ -3368,26 +3076,26 @@ static YYACTIONTYPE yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 264: /* cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ + case 266: /* cmd ::= ALTER TABLE ids cpxName SET TAG ids EQ tagitem */ { yymsp[-6].minor.yy0.n += yymsp[-5].minor.yy0.n; toTSDBType(yymsp[-2].minor.yy0.type); SArray* A = tVariantListAppendToken(NULL, &yymsp[-2].minor.yy0, -1); - A = tVariantListAppend(A, &yymsp[0].minor.yy442, -1); + A = tVariantListAppend(A, &yymsp[0].minor.yy518, -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); } break; - case 265: /* cmd ::= ALTER STABLE ids cpxName ADD COLUMN columnlist */ + case 267: /* 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.yy325, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, TSDB_SUPER_TABLE); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy93, NULL, TSDB_ALTER_TABLE_ADD_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 266: /* cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ + case 268: /* cmd ::= ALTER STABLE ids cpxName DROP COLUMN ids */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; @@ -3398,14 +3106,14 @@ static YYACTIONTYPE yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 267: /* cmd ::= ALTER STABLE ids cpxName ADD TAG columnlist */ + case 269: /* 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.yy325, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, TSDB_SUPER_TABLE); + SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&yymsp[-4].minor.yy0, yymsp[0].minor.yy93, NULL, TSDB_ALTER_TABLE_ADD_TAG_COLUMN, TSDB_SUPER_TABLE); setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 268: /* cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ + case 270: /* cmd ::= ALTER STABLE ids cpxName DROP TAG ids */ { yymsp[-4].minor.yy0.n += yymsp[-3].minor.yy0.n; @@ -3416,7 +3124,7 @@ static YYACTIONTYPE yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 269: /* cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ + case 271: /* cmd ::= ALTER STABLE ids cpxName CHANGE TAG ids ids */ { yymsp[-5].minor.yy0.n += yymsp[-4].minor.yy0.n; @@ -3430,22 +3138,22 @@ static YYACTIONTYPE yy_reduce( setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE); } break; - case 270: /* cmd ::= KILL CONNECTION INTEGER */ + case 272: /* cmd ::= KILL CONNECTION INTEGER */ {setKillSql(pInfo, TSDB_SQL_KILL_CONNECTION, &yymsp[0].minor.yy0);} break; - case 271: /* cmd ::= KILL STREAM INTEGER COLON INTEGER */ + case 273: /* cmd ::= KILL STREAM INTEGER COLON INTEGER */ {yymsp[-2].minor.yy0.n += (yymsp[-1].minor.yy0.n + yymsp[0].minor.yy0.n); setKillSql(pInfo, TSDB_SQL_KILL_STREAM, &yymsp[-2].minor.yy0);} break; - case 272: /* cmd ::= KILL QUERY INTEGER COLON INTEGER */ + case 274: /* cmd ::= KILL QUERY INTEGER COLON INTEGER */ {yymsp[-2].minor.yy0.n += (yymsp[-1].minor.yy0.n + yymsp[0].minor.yy0.n); setKillSql(pInfo, TSDB_SQL_KILL_QUERY, &yymsp[-2].minor.yy0);} break; default: break; /********** End reduce actions ************************************************/ }; - assert( yyrulenostateno = (YYACTIONTYPE)yyact; yymsp->major = (YYCODETYPE)yygoto; yyTraceShift(yypParser, yyact, "... then shift"); - return yyact; } /* @@ -3470,8 +3177,7 @@ static YYACTIONTYPE yy_reduce( static void yy_parse_failed( yyParser *yypParser /* The parser */ ){ - ParseARG_FETCH - ParseCTX_FETCH + ParseARG_FETCH; #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); @@ -3482,8 +3188,7 @@ static void yy_parse_failed( ** parser fails */ /************ Begin %parse_failure code ***************************************/ /************ End %parse_failure code *****************************************/ - ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ - ParseCTX_STORE + ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ } #endif /* YYNOERRORRECOVERY */ @@ -3495,8 +3200,7 @@ 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 - ParseCTX_FETCH + ParseARG_FETCH; #define TOKEN yyminor /************ Begin %syntax_error code ****************************************/ @@ -3522,8 +3226,7 @@ static void yy_syntax_error( assert(len <= outputBufLen); /************ End %syntax_error code ******************************************/ - ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ - ParseCTX_STORE + ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ } /* @@ -3532,8 +3235,7 @@ static void yy_syntax_error( static void yy_accept( yyParser *yypParser /* The parser */ ){ - ParseARG_FETCH - ParseCTX_FETCH + ParseARG_FETCH; #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); @@ -3548,8 +3250,7 @@ static void yy_accept( /*********** Begin %parse_accept code *****************************************/ /*********** End %parse_accept code *******************************************/ - ParseARG_STORE /* Suppress warning about unused %extra_argument variable */ - ParseCTX_STORE + ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ } /* The main parser program. @@ -3578,47 +3279,45 @@ void Parse( ParseARG_PDECL /* Optional %extra_argument parameter */ ){ YYMINORTYPE yyminorunion; - YYACTIONTYPE yyact; /* The parser action. */ + unsigned int 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 = (yyParser*)yyp; /* The parser */ - ParseCTX_FETCH - ParseARG_STORE + yyParser *yypParser; /* The parser */ + 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 ){ - if( yyact < YY_MIN_REDUCE ){ + int stateno = yypParser->yytos->stateno; + if( stateno < YY_MIN_REDUCE ){ fprintf(yyTraceFILE,"%sInput '%s' in state %d\n", - yyTracePrompt,yyTokenName[yymajor],yyact); + yyTracePrompt,yyTokenName[yymajor],stateno); }else{ fprintf(yyTraceFILE,"%sInput '%s' with pending reduce %d\n", - yyTracePrompt,yyTokenName[yymajor],yyact-YY_MIN_REDUCE); + yyTracePrompt,yyTokenName[yymajor],stateno-YY_MIN_REDUCE); } } #endif do{ - assert( yyact==yypParser->yytos->stateno ); - yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact); + yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); if( yyact >= YY_MIN_REDUCE ){ - yyact = yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor, - yyminor ParseCTX_PARAM); + yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor,yyminor); }else if( yyact <= YY_MAX_SHIFTREDUCE ){ - yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor); + yy_shift(yypParser,yyact,yymajor,yyminor); #ifndef YYNOERRORRECOVERY yypParser->yyerrcnt--; #endif - break; + yymajor = YYNOCODE; }else if( yyact==YY_ACCEPT_ACTION ){ yypParser->yytos--; yy_accept(yypParser); @@ -3669,9 +3368,10 @@ void Parse( yymajor = YYNOCODE; }else{ while( yypParser->yytos >= yypParser->yystack + && yymx != YYERRORSYMBOL && (yyact = yy_find_reduce_action( yypParser->yytos->stateno, - YYERRORSYMBOL)) > YY_MAX_SHIFTREDUCE + YYERRORSYMBOL)) >= YY_MIN_REDUCE ){ yy_pop_parser_stack(yypParser); } @@ -3688,8 +3388,6 @@ 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 @@ -3700,7 +3398,8 @@ void Parse( */ yy_syntax_error(yypParser,yymajor, yyminor); yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); - break; + yymajor = YYNOCODE; + #else /* YYERRORSYMBOL is not defined */ /* This is what we do if the grammar does not define ERROR: ** @@ -3722,10 +3421,10 @@ void Parse( yypParser->yyerrcnt = -1; #endif } - break; + yymajor = YYNOCODE; #endif } - }while( yypParser->yytos>yypParser->yystack ); + }while( yymajor!=YYNOCODE && yypParser->yytos>yypParser->yystack ); #ifndef NDEBUG if( yyTraceFILE ){ yyStackEntry *i; @@ -3740,17 +3439,3 @@ 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/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c index cd97b2a9d6..9df25409de 100644 --- a/src/tsdb/src/tsdbRead.c +++ b/src/tsdb/src/tsdbRead.c @@ -123,7 +123,7 @@ typedef struct STsdbQueryHandle { SMemRef *pMemRef; SArray *defaultLoadColumn;// default load column SDataBlockLoadInfo dataBlockLoadInfo; /* record current block load information */ - SLoadCompBlockInfo compBlockLoadInfo; /* record current compblock information in SQuery */ + SLoadCompBlockInfo compBlockLoadInfo; /* record current compblock information in SQueryAttr */ SArray *prev; // previous row which is before than time window SArray *next; // next row which is after the query time window @@ -286,7 +286,7 @@ static SArray* createCheckInfoFromTableGroup(STsdbQueryHandle* pQueryHandle, STa } taosArrayPush(pTableCheckInfo, &info); - tsdbDebug("%p check table uid:%"PRId64", tid:%d from lastKey:%"PRId64" %"PRIu64, pQueryHandle, info.tableId.uid, + tsdbDebug("%p check table uid:%"PRId64", tid:%d from lastKey:%"PRId64" 0x%"PRIx64, pQueryHandle, info.tableId.uid, info.tableId.tid, info.lastKey, pQueryHandle->qId); } } @@ -440,7 +440,7 @@ TsdbQueryHandleT* tsdbQueryTables(STsdbRepo* tsdb, STsdbQueryCond* pCond, STable tsdbMayTakeMemSnapshot(pQueryHandle, psTable); - tsdbDebug("%p total numOfTable:%" PRIzu " in query, %"PRIu64, pQueryHandle, taosArrayGetSize(pQueryHandle->pTableCheckInfo), pQueryHandle->qId); + tsdbDebug("%p total numOfTable:%" PRIzu " in query, 0x%"PRIx64, pQueryHandle, taosArrayGetSize(pQueryHandle->pTableCheckInfo), pQueryHandle->qId); return (TsdbQueryHandleT) pQueryHandle; } @@ -651,7 +651,7 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh SDataRow row = (SDataRow)SL_GET_NODE_DATA(node); TSKEY key = dataRowKey(row); // first timestamp in buffer tsdbDebug("%p uid:%" PRId64 ", tid:%d check data in mem from skey:%" PRId64 ", order:%d, ts range in buf:%" PRId64 - "-%" PRId64 ", lastKey:%" PRId64 ", numOfRows:%"PRId64", %"PRIu64, + "-%" PRId64 ", lastKey:%" PRId64 ", numOfRows:%"PRId64", 0x%"PRIx64, pHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, key, order, pMem->keyFirst, pMem->keyLast, pCheckInfo->lastKey, pMem->numOfRows, pHandle->qId); @@ -662,7 +662,7 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh } } else { - tsdbDebug("%p uid:%"PRId64", tid:%d no data in mem, %"PRIu64, pHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, + tsdbDebug("%p uid:%"PRId64", tid:%d no data in mem, 0x%"PRIx64, pHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, pHandle->qId); } @@ -673,7 +673,7 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh SDataRow row = (SDataRow)SL_GET_NODE_DATA(node); TSKEY key = dataRowKey(row); // first timestamp in buffer tsdbDebug("%p uid:%" PRId64 ", tid:%d check data in imem from skey:%" PRId64 ", order:%d, ts range in buf:%" PRId64 - "-%" PRId64 ", lastKey:%" PRId64 ", numOfRows:%"PRId64", %"PRIu64, + "-%" PRId64 ", lastKey:%" PRId64 ", numOfRows:%"PRId64", 0x%"PRIx64, pHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, key, order, pIMem->keyFirst, pIMem->keyLast, pCheckInfo->lastKey, pIMem->numOfRows, pHandle->qId); @@ -683,7 +683,7 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh assert(pCheckInfo->lastKey >= key); } } else { - tsdbDebug("%p uid:%"PRId64", tid:%d no data in imem, %"PRIu64, pHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, + tsdbDebug("%p uid:%"PRId64", tid:%d no data in imem, 0x%"PRIx64, pHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, pHandle->qId); } @@ -811,7 +811,7 @@ static bool hasMoreDataInCache(STsdbQueryHandle* pHandle) { } pCheckInfo->lastKey = dataRowKey(row); // first timestamp in buffer - tsdbDebug("%p uid:%" PRId64", tid:%d check data in buffer from skey:%" PRId64 ", order:%d, %"PRIu64, pHandle, + tsdbDebug("%p uid:%" PRId64", tid:%d check data in buffer from skey:%" PRId64 ", order:%d, 0x%"PRIx64, pHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, pCheckInfo->lastKey, pHandle->order, pHandle->qId); // all data in mem are checked already. @@ -986,21 +986,21 @@ static int32_t doLoadFileDataBlock(STsdbQueryHandle* pQueryHandle, SBlock* pBloc STSchema *pSchema = tsdbGetTableSchema(pCheckInfo->pTableObj); int32_t code = tdInitDataCols(pQueryHandle->pDataCols, pSchema); if (code != TSDB_CODE_SUCCESS) { - tsdbError("%p failed to malloc buf for pDataCols, %"PRIu64, pQueryHandle, pQueryHandle->qId); + tsdbError("%p failed to malloc buf for pDataCols, 0x%"PRIx64, pQueryHandle, pQueryHandle->qId); terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; goto _error; } code = tdInitDataCols(pQueryHandle->rhelper.pDCols[0], pSchema); if (code != TSDB_CODE_SUCCESS) { - tsdbError("%p failed to malloc buf for rhelper.pDataCols[0], %"PRIu64, pQueryHandle, pQueryHandle->qId); + tsdbError("%p failed to malloc buf for rhelper.pDataCols[0], 0x%"PRIx64, pQueryHandle, pQueryHandle->qId); terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; goto _error; } code = tdInitDataCols(pQueryHandle->rhelper.pDCols[1], pSchema); if (code != TSDB_CODE_SUCCESS) { - tsdbError("%p failed to malloc buf for rhelper.pDataCols[1], %"PRIu64, pQueryHandle, pQueryHandle->qId); + tsdbError("%p failed to malloc buf for rhelper.pDataCols[1], 0x%"PRIx64, pQueryHandle, pQueryHandle->qId); terrno = TSDB_CODE_TDB_OUT_OF_MEMORY; goto _error; } @@ -1036,14 +1036,14 @@ static int32_t doLoadFileDataBlock(STsdbQueryHandle* pQueryHandle, SBlock* pBloc int64_t elapsedTime = (taosGetTimestampUs() - st); pQueryHandle->cost.blockLoadTime += elapsedTime; - tsdbDebug("%p load file block into buffer, index:%d, brange:%"PRId64"-%"PRId64", rows:%d, elapsed time:%"PRId64 " us, %"PRIu64, + tsdbDebug("%p load file block into buffer, index:%d, brange:%"PRId64"-%"PRId64", rows:%d, elapsed time:%"PRId64 " us, 0x%"PRIx64, pQueryHandle, slotIndex, pBlock->keyFirst, pBlock->keyLast, pBlock->numOfRows, elapsedTime, pQueryHandle->qId); return TSDB_CODE_SUCCESS; _error: pBlock->numOfRows = 0; - tsdbError("%p error occurs in loading file block, index:%d, brange:%"PRId64"-%"PRId64", rows:%d, %"PRIu64, + tsdbError("%p error occurs in loading file block, index:%d, brange:%"PRId64"-%"PRId64", rows:%d, 0x%"PRIx64, pQueryHandle, slotIndex, pBlock->keyFirst, pBlock->keyLast, pBlock->numOfRows, pQueryHandle->qId); return terrno; } @@ -1066,7 +1066,7 @@ static int32_t handleDataMergeIfNeeded(STsdbQueryHandle* pQueryHandle, SBlock* p assert(cur->pos >= 0 && cur->pos <= binfo.rows); TSKEY key = (row != NULL)? dataRowKey(row):TSKEY_INITIAL_VAL; - tsdbDebug("%p key in mem:%"PRId64", %"PRIu64, pQueryHandle, key, pQueryHandle->qId); + tsdbDebug("%p key in mem:%"PRId64", 0x%"PRIx64, pQueryHandle, key, pQueryHandle->qId); if ((ASCENDING_TRAVERSE(pQueryHandle->order) && (key != TSKEY_INITIAL_VAL && key <= binfo.window.ekey)) || (!ASCENDING_TRAVERSE(pQueryHandle->order) && (key != TSKEY_INITIAL_VAL && key >= binfo.window.skey))) { @@ -1406,7 +1406,11 @@ static void copyOneRowFromMem(STsdbQueryHandle* pQueryHandle, int32_t capacity, SET_DOUBLE_PTR(pData, value); break; case TSDB_DATA_TYPE_TIMESTAMP: - *(TSKEY *)pData = tdGetKey(*(TKEY *)value); + if (pColInfo->info.colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) { + *(TSKEY *)pData = tdGetKey(*(TKEY *)value); + } else { + *(TSKEY *)pData = *(TSKEY *)value; + } break; default: memcpy(pData, value, pColInfo->info.bytes); @@ -1547,7 +1551,7 @@ static void copyAllRemainRowsFromFileBlock(STsdbQueryHandle* pQueryHandle, STabl updateInfoAfterMerge(pQueryHandle, pCheckInfo, numOfRows, pos); doCheckGeneratedBlockRange(pQueryHandle); - tsdbDebug("%p uid:%" PRIu64",tid:%d data block created, mixblock:%d, brange:%"PRIu64"-%"PRIu64" rows:%d, %"PRIu64, + tsdbDebug("%p uid:%" PRIu64",tid:%d data block created, mixblock:%d, brange:%"PRIu64"-%"PRIu64" rows:%d, 0x%"PRIx64, pQueryHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, cur->mixBlock, cur->win.skey, cur->win.ekey, cur->rows, pQueryHandle->qId); } @@ -1601,7 +1605,7 @@ static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo* int32_t endPos = getEndPosInDataBlock(pQueryHandle, &blockInfo); tsdbDebug("%p uid:%" PRIu64",tid:%d start merge data block, file block range:%"PRIu64"-%"PRIu64" rows:%d, start:%d," - "end:%d, %"PRIu64, + "end:%d, 0x%"PRIx64, pQueryHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, blockInfo.window.skey, blockInfo.window.ekey, blockInfo.rows, cur->pos, endPos, pQueryHandle->qId); @@ -1743,7 +1747,7 @@ static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo* updateInfoAfterMerge(pQueryHandle, pCheckInfo, numOfRows, pos); doCheckGeneratedBlockRange(pQueryHandle); - tsdbDebug("%p uid:%" PRIu64",tid:%d data block created, mixblock:%d, brange:%"PRIu64"-%"PRIu64" rows:%d, %"PRIu64, + tsdbDebug("%p uid:%" PRIu64",tid:%d data block created, mixblock:%d, brange:%"PRIu64"-%"PRIu64" rows:%d, 0x%"PRIx64, pQueryHandle, pCheckInfo->tableId.uid, pCheckInfo->tableId.tid, cur->mixBlock, cur->win.skey, cur->win.ekey, cur->rows, pQueryHandle->qId); } @@ -1919,12 +1923,12 @@ static int32_t createDataBlocksInfo(STsdbQueryHandle* pQueryHandle, int32_t numO memcpy(pQueryHandle->pDataBlockInfo, sup.pDataBlockInfo[0], sizeof(STableBlockInfo) * numOfBlocks); cleanBlockOrderSupporter(&sup, numOfQualTables); - tsdbDebug("%p create data blocks info struct completed for 1 table, %d blocks not sorted %"PRIu64, pQueryHandle, cnt, + tsdbDebug("%p create data blocks info struct completed for 1 table, %d blocks not sorted 0x%"PRIx64, pQueryHandle, cnt, pQueryHandle->qId); return TSDB_CODE_SUCCESS; } - tsdbDebug("%p create data blocks info struct completed, %d blocks in %d tables %"PRIu64, pQueryHandle, cnt, + tsdbDebug("%p create data blocks info struct completed, %d blocks in %d tables 0x%"PRIx64, pQueryHandle, cnt, numOfQualTables, pQueryHandle->qId); assert(cnt <= numOfBlocks && numOfQualTables <= numOfTables); // the pTableQueryInfo[j]->numOfBlocks may be 0 @@ -1961,7 +1965,7 @@ static int32_t createDataBlocksInfo(STsdbQueryHandle* pQueryHandle, int32_t numO * } */ - tsdbDebug("%p %d data blocks sort completed, %"PRIu64, pQueryHandle, cnt, pQueryHandle->qId); + tsdbDebug("%p %d data blocks sort completed, 0x%"PRIx64, pQueryHandle, cnt, pQueryHandle->qId); cleanBlockOrderSupporter(&sup, numOfTables); free(pTree); @@ -2019,7 +2023,7 @@ static int32_t getFirstFileDataBlock(STsdbQueryHandle* pQueryHandle, bool* exist if ((ASCENDING_TRAVERSE(pQueryHandle->order) && win.skey > pQueryHandle->window.ekey) || (!ASCENDING_TRAVERSE(pQueryHandle->order) && win.ekey < pQueryHandle->window.ekey)) { tsdbUnLockFS(REPO_FS(pQueryHandle->pTsdb)); - tsdbDebug("%p remain files are not qualified for qrange:%" PRId64 "-%" PRId64 ", ignore, %"PRIu64, pQueryHandle, + tsdbDebug("%p remain files are not qualified for qrange:%" PRId64 "-%" PRId64 ", ignore, 0x%"PRIx64, pQueryHandle, pQueryHandle->window.skey, pQueryHandle->window.ekey, pQueryHandle->qId); pQueryHandle->pFileGroup = NULL; assert(pQueryHandle->numOfBlocks == 0); @@ -2043,7 +2047,7 @@ static int32_t getFirstFileDataBlock(STsdbQueryHandle* pQueryHandle, bool* exist break; } - tsdbDebug("%p %d blocks found in file for %d table(s), fid:%d, %"PRIu64, pQueryHandle, numOfBlocks, numOfTables, + tsdbDebug("%p %d blocks found in file for %d table(s), fid:%d, 0x%"PRIx64, pQueryHandle, numOfBlocks, numOfTables, pQueryHandle->pFileGroup->fid, pQueryHandle->qId); assert(numOfBlocks >= 0); @@ -2135,7 +2139,7 @@ int32_t tsdbGetFileBlocksDistInfo(TsdbQueryHandleT* queryHandle, STableBlockDist if ((ASCENDING_TRAVERSE(pQueryHandle->order) && win.skey > pQueryHandle->window.ekey) || (!ASCENDING_TRAVERSE(pQueryHandle->order) && win.ekey < pQueryHandle->window.ekey)) { tsdbUnLockFS(REPO_FS(pQueryHandle->pTsdb)); - tsdbDebug("%p remain files are not qualified for qrange:%" PRId64 "-%" PRId64 ", ignore, %"PRIu64, pQueryHandle, + tsdbDebug("%p remain files are not qualified for qrange:%" PRId64 "-%" PRId64 ", ignore, 0x%"PRIx64, pQueryHandle, pQueryHandle->window.skey, pQueryHandle->window.ekey, pQueryHandle->qId); pQueryHandle->pFileGroup = NULL; break; @@ -2159,7 +2163,7 @@ int32_t tsdbGetFileBlocksDistInfo(TsdbQueryHandleT* queryHandle, STableBlockDist break; } - tsdbDebug("%p %d blocks found in file for %d table(s), fid:%d, %"PRIu64, pQueryHandle, numOfBlocks, numOfTables, + tsdbDebug("%p %d blocks found in file for %d table(s), fid:%d, 0x%"PRIx64, pQueryHandle, numOfBlocks, numOfTables, pQueryHandle->pFileGroup->fid, pQueryHandle->qId); if (numOfBlocks == 0) { @@ -2207,7 +2211,7 @@ static int32_t getDataBlocksInFiles(STsdbQueryHandle* pQueryHandle, bool* exists if ((!cur->mixBlock) || cur->blockCompleted) { // all data blocks in current file has been checked already, try next file if exists } else { - tsdbDebug("%p continue in current data block, index:%d, pos:%d, %"PRIu64, pQueryHandle, cur->slot, cur->pos, + tsdbDebug("%p continue in current data block, index:%d, pos:%d, 0x%"PRIx64, pQueryHandle, cur->slot, cur->pos, pQueryHandle->qId); int32_t code = handleDataMergeIfNeeded(pQueryHandle, pBlockInfo->compBlock, pCheckInfo); *exists = (pQueryHandle->realNumOfRows > 0); @@ -2336,7 +2340,7 @@ static int tsdbReadRowsFromCache(STableCheckInfo* pCheckInfo, TSKEY maxKey, int } int64_t elapsedTime = taosGetTimestampUs() - st; - tsdbDebug("%p build data block from cache completed, elapsed time:%"PRId64" us, numOfRows:%d, numOfCols:%d, %"PRIu64, pQueryHandle, + tsdbDebug("%p build data block from cache completed, elapsed time:%"PRId64" us, numOfRows:%d, numOfCols:%d, 0x%"PRIx64, pQueryHandle, elapsedTime, numOfRows, numOfCols, pQueryHandle->qId); return numOfRows; @@ -3206,9 +3210,10 @@ int32_t tsdbQuerySTableByTagCond(STsdbRepo* tsdb, uint64_t uid, TSKEY skey, cons pGroupInfo->numOfTables = (uint32_t) taosArrayGetSize(res); pGroupInfo->pGroupList = createTableGroup(res, pTagSchema, pColIndex, numOfCols, skey); - tsdbDebug("%p no table name/tag condition, all tables belong to one group, numOfTables:%u", tsdb, pGroupInfo->numOfTables); - taosArrayDestroy(res); + tsdbDebug("%p no table name/tag condition, all tables qualified, numOfTables:%u, group:%zu", tsdb, + pGroupInfo->numOfTables, taosArrayGetSize(pGroupInfo->pGroupList)); + taosArrayDestroy(res); if (tsdbUnlockRepoMeta(tsdb) < 0) goto _error; return ret; } @@ -3391,7 +3396,7 @@ void tsdbCleanupQueryHandle(TsdbQueryHandleT queryHandle) { pQueryHandle->next = doFreeColumnInfoData(pQueryHandle->next); SIOCostSummary* pCost = &pQueryHandle->cost; - tsdbDebug("%p :io-cost summary: statis-info:%"PRId64" us, datablock:%" PRId64" us, check data:%"PRId64" us, %"PRIu64, + tsdbDebug("%p :io-cost summary: statis-info:%"PRId64" us, datablock:%" PRId64" us, check data:%"PRId64" us, 0x%"PRIx64, pQueryHandle, pCost->statisInfoLoadTime, pCost->blockLoadTime, pCost->checkForNextTime, pQueryHandle->qId); tfree(pQueryHandle); @@ -3408,14 +3413,16 @@ void tsdbDestroyTableGroup(STableGroupInfo *pGroupList) { size_t numOfTables = taosArrayGetSize(p); for(int32_t j = 0; j < numOfTables; ++j) { STable* pTable = taosArrayGetP(p, j); - assert(pTable != NULL); - - tsdbUnRefTable(pTable); + if (pTable != NULL) { // in case of handling retrieve data from tsdb + tsdbUnRefTable(pTable); + } + //assert(pTable != NULL); } taosArrayDestroy(p); } + taosHashCleanup(pGroupList->map); taosArrayDestroy(pGroupList->pGroupList); pGroupList->numOfTables = 0; } @@ -3426,7 +3433,7 @@ static void applyFilterToSkipListNode(SSkipList *pSkipList, tExprNode *pExpr, SA // Scan each node in the skiplist by using iterator while (tSkipListIterNext(iter)) { SSkipListNode *pNode = tSkipListIterGet(iter); - if (exprTreeApplayFilter(pExpr, pNode, param)) { + if (exprTreeApplyFilter(pExpr, pNode, param)) { taosArrayPush(pResult, &(SL_GET_NODE_DATA(pNode))); } } diff --git a/src/util/src/tcompare.c b/src/util/src/tcompare.c index 4d18ef14e2..354e7899c2 100644 --- a/src/util/src/tcompare.c +++ b/src/util/src/tcompare.c @@ -398,6 +398,10 @@ int32_t doCompare(const char* f1, const char* f2, int32_t type, size_t size) { case TSDB_DATA_TYPE_SMALLINT: DEFAULT_COMP(GET_INT16_VAL(f1), GET_INT16_VAL(f2)); case TSDB_DATA_TYPE_TINYINT: case TSDB_DATA_TYPE_BOOL: DEFAULT_COMP(GET_INT8_VAL(f1), GET_INT8_VAL(f2)); + case TSDB_DATA_TYPE_UTINYINT: DEFAULT_COMP(GET_UINT8_VAL(f1), GET_UINT8_VAL(f2)); + case TSDB_DATA_TYPE_USMALLINT: DEFAULT_COMP(GET_UINT16_VAL(f1), GET_UINT16_VAL(f2)); + case TSDB_DATA_TYPE_UINT: DEFAULT_COMP(GET_UINT32_VAL(f1), GET_UINT32_VAL(f2)); + case TSDB_DATA_TYPE_UBIGINT: DEFAULT_COMP(GET_UINT64_VAL(f1), GET_UINT64_VAL(f2)); case TSDB_DATA_TYPE_NCHAR: { tstr* t1 = (tstr*) f1; tstr* t2 = (tstr*) f2; diff --git a/src/util/src/tcrc32c.c b/src/util/src/tcrc32c.c index 502116f9c2..054b8f8171 100644 --- a/src/util/src/tcrc32c.c +++ b/src/util/src/tcrc32c.c @@ -736,7 +736,7 @@ static uint32_t table[16][256] = { 0x9c221d09, 0x6e2e10f7, 0x7dd67004, 0x8fda7dfa} }; -#ifndef _TD_ARM_ +#if !defined(_TD_ARM_) && !defined(_TD_MIPS_) static uint32_t long_shifts[4][256] = { {0x00000000, 0xe040e0ac, 0xc56db7a9, 0x252d5705, 0x8f3719a3, 0x6f77f90f, 0x4a5aae0a, 0xaa1a4ea6, 0x1b8245b7, 0xfbc2a51b, 0xdeeff21e, 0x3eaf12b2, @@ -1187,7 +1187,7 @@ uint32_t crc32c_sf(uint32_t crci, crc_stream input, size_t length) { } return (uint32_t)crc ^ 0xffffffff; } -#ifndef _TD_ARM_ +#if !defined(_TD_ARM_) && !defined(_TD_MIPS_) /* Apply the zeros operator table to crc. */ static uint32_t shift_crc(uint32_t shift_table[][256], uint32_t crc) { return shift_table[0][crc & 0xff] ^ shift_table[1][(crc >> 8) & 0xff] ^ @@ -1198,7 +1198,7 @@ static uint32_t shift_crc(uint32_t shift_table[][256], uint32_t crc) { version. Otherwise, use the software version. */ uint32_t (*crc32c)(uint32_t crci, crc_stream bytes, size_t len) = crc32c_sf; -#ifndef _TD_ARM_ +#if !defined(_TD_ARM_) && !defined(_TD_MIPS_) /* Compute CRC-32C using the Intel hardware instruction. */ uint32_t crc32c_hw(uint32_t crc, crc_stream buf, size_t len) { crc_stream next = buf; @@ -1353,7 +1353,7 @@ uint32_t crc32c_hw(uint32_t crc, crc_stream buf, size_t len) { #endif // #ifndef _TD_ARM_ void taosResolveCRC() { -#if defined _TD_ARM_ || defined WINDOWS +#if defined _TD_ARM_ || defined _TD_MIPS_ || defined WINDOWS crc32c = crc32c_sf; #else int sse42; diff --git a/src/util/src/tlog.c b/src/util/src/tlog.c index 448bb3ecd1..7f127fc396 100644 --- a/src/util/src/tlog.c +++ b/src/util/src/tlog.c @@ -416,7 +416,8 @@ void taosPrintLog(const char *flags, int32_t dflag, const char *format, ...) { } } - if (dflag & DEBUG_SCREEN) taosWrite(1, buffer, (uint32_t)len); + if (dflag & DEBUG_SCREEN) + taosWrite(1, buffer, (uint32_t)len); if (dflag == 255) nInfo(buffer, len); } diff --git a/src/util/src/tnettest.c b/src/util/src/tnettest.c index 28abad356c..131063b0de 100644 --- a/src/util/src/tnettest.c +++ b/src/util/src/tnettest.c @@ -291,16 +291,16 @@ static void taosNetCheckPort(uint32_t hostIp, int32_t startPort, int32_t endPort info.port = port; ret = taosNetCheckTcpPort(&info); if (ret != 0) { - uError("failed to test TCP port:%d", port); + printf("failed to test TCP port:%d\n", port); } else { - uInfo("successed to test TCP port:%d", port); + printf("successed to test TCP port:%d\n", port); } ret = taosNetCheckUdpPort(&info); if (ret != 0) { - uError("failed to test UDP port:%d", port); + printf("failed to test UDP port:%d\n", port); } else { - uInfo("successed to test UDP port:%d", port); + printf("successed to test UDP port:%d\n", port); } } } @@ -464,9 +464,9 @@ static void taosNetTestRpc(char *host, int32_t startPort, int32_t pkgLen) { int32_t ret = taosNetCheckRpc(host, port, sendpkgLen, spi, NULL); if (ret < 0) { - uError("failed to test TCP port:%d", port); + printf("failed to test TCP port:%d\n", port); } else { - uInfo("successed to test TCP port:%d", port); + printf("successed to test TCP port:%d\n", port); } if (pkgLen >= tsRpcMaxUdpSize) { @@ -477,9 +477,9 @@ static void taosNetTestRpc(char *host, int32_t startPort, int32_t pkgLen) { ret = taosNetCheckRpc(host, port, pkgLen, spi, NULL); if (ret < 0) { - uError("failed to test UDP port:%d", port); + printf("failed to test UDP port:%d\n", port); } else { - uInfo("successed to test UDP port:%d", port); + printf("successed to test UDP port:%d\n", port); } } @@ -539,7 +539,7 @@ static void taosNetTestServer(char *host, int32_t startPort, int32_t pkgLen) { } void taosNetTest(char *role, char *host, int32_t port, int32_t pkgLen) { - tscEmbedded = 1; +// tscEmbedded = 1; if (host == NULL) host = tsLocalFqdn; if (port == 0) port = tsServerPort; if (pkgLen <= 10) pkgLen = 1000; @@ -559,5 +559,5 @@ void taosNetTest(char *role, char *host, int32_t port, int32_t pkgLen) { taosNetTestStartup(host, port); } - tscEmbedded = 0; +// tscEmbedded = 0; } diff --git a/src/util/src/ttimer.c b/src/util/src/ttimer.c index 9833449777..865e1159c1 100644 --- a/src/util/src/ttimer.c +++ b/src/util/src/ttimer.c @@ -538,7 +538,7 @@ static void taosTmrModuleInit(void) { void* taosTmrInit(int maxNumOfTmrs, int resolution, int longest, const char* label) { const char* ret = monotonicInit(); - tmrInfo("ttimer monotonic clock source:%s", ret); + tmrDebug("ttimer monotonic clock source:%s", ret); pthread_once(&tmrModuleInit, taosTmrModuleInit); diff --git a/src/vnode/src/vnodeRead.c b/src/vnode/src/vnodeRead.c index 2448fada50..b28bdbf130 100644 --- a/src/vnode/src/vnodeRead.c +++ b/src/vnode/src/vnodeRead.c @@ -183,7 +183,7 @@ static int32_t vnodeDumpQueryResult(SRspRet *pRet, void *pVnode, uint64_t qId, v } } else { *freeHandle = true; - vTrace("QInfo:%"PRIu64"-%p exec completed, free handle:%d", qId, *handle, *freeHandle); + vTrace("QInfo:0x%"PRIx64"-%p exec completed, free handle:%d", qId, *handle, *freeHandle); } } else { SRetrieveTableRsp *pRsp = (SRetrieveTableRsp *)rpcMallocCont(sizeof(SRetrieveTableRsp)); @@ -232,7 +232,7 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SVReadMsg *pRead) { SQueryTableRsp *pRsp = (SQueryTableRsp *)rpcMallocCont(sizeof(SQueryTableRsp)); pRsp->code = code; - pRsp->qhandle = 0; + pRsp->qId = 0; pRet->len = sizeof(SQueryTableRsp); pRet->rsp = pRsp; @@ -244,18 +244,18 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SVReadMsg *pRead) { if (handle == NULL) { // failed to register qhandle pRsp->code = terrno; terrno = 0; - vError("vgId:%d, QInfo:%"PRIu64 "-%p register qhandle failed, return to app, code:%s", pVnode->vgId, qId, (void *)pQInfo, + vError("vgId:%d, QInfo:0x%"PRIx64 "-%p register qhandle failed, return to app, code:%s", pVnode->vgId, qId, (void *)pQInfo, tstrerror(pRsp->code)); qDestroyQueryInfo(pQInfo); // destroy it directly return pRsp->code; } else { assert(*handle == pQInfo); - pRsp->qhandle = htobe64(qId); + pRsp->qId = htobe64(qId); } if (handle != NULL && vnodeNotifyCurrentQhandle(pRead->rpcHandle, qId, *handle, pVnode->vgId) != TSDB_CODE_SUCCESS) { - vError("vgId:%d, QInfo:%"PRIu64 "-%p, query discarded since link is broken, %p", pVnode->vgId, qId, *handle, + vError("vgId:%d, QInfo:0x%"PRIx64 "-%p, query discarded since link is broken, %p", pVnode->vgId, qId, *handle, pRead->rpcHandle); pRsp->code = TSDB_CODE_RPC_NETWORK_UNAVAIL; qReleaseQInfo(pVnode->qMgmt, (void **)&handle, true); @@ -266,7 +266,7 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SVReadMsg *pRead) { } if (handle != NULL) { - vTrace("vgId:%d, QInfo:%"PRIu64 "-%p, dnode query msg disposed, create qhandle and returns to app", vgId, qId, *handle); + vTrace("vgId:%d, QInfo:0x%"PRIx64 "-%p, dnode query msg disposed, create qhandle and returns to app", vgId, qId, *handle); code = vnodePutItemIntoReadQueue(pVnode, handle, pRead->rpcHandle); if (code != TSDB_CODE_SUCCESS) { pRsp->code = code; @@ -324,14 +324,14 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SVReadMsg *pRead) { } static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SVReadMsg *pRead) { - void * pCont = pRead->pCont; - SRspRet *pRet = &pRead->rspRet; + void *pCont = pRead->pCont; + SRspRet *pRet = &pRead->rspRet; SRetrieveTableMsg *pRetrieve = pCont; pRetrieve->free = htons(pRetrieve->free); pRetrieve->qId = htobe64(pRetrieve->qId); - vTrace("vgId:%d, qId:%" PRIu64 ", retrieve msg is disposed, free:%d, conn:%p", pVnode->vgId, pRetrieve->qId, + vTrace("vgId:%d, qId:0x%" PRIx64 ", retrieve msg is disposed, free:%d, conn:%p", pVnode->vgId, pRetrieve->qId, pRetrieve->free, pRead->rpcHandle); memset(pRet, 0, sizeof(SRspRet)); @@ -383,7 +383,7 @@ static int32_t vnodeProcessFetchMsg(SVnodeObj *pVnode, SVReadMsg *pRead) { memset(pRet->rsp, 0, sizeof(SRetrieveTableRsp)); freeHandle = true; } else { // result is not ready, return immediately - // Only effects in the non-blocking model + // Only affects the non-blocking model if (!tsRetrieveBlockingModel) { if (!buildRes) { assert(pRead->rpcHandle != NULL); @@ -414,7 +414,7 @@ int32_t vnodeNotifyCurrentQhandle(void *handle, uint64_t qId, void *qhandle, int pMsg->header.vgId = htonl(vgId); pMsg->header.contLen = htonl(sizeof(SRetrieveTableMsg)); - vTrace("QInfo:%"PRIu64"-%p register qhandle to connect:%p", qId, qhandle, handle); + vTrace("QInfo:0x%"PRIx64"-%p register qhandle to connect:%p", qId, qhandle, handle); return rpcReportProgress(handle, (char *)pMsg, sizeof(SRetrieveTableMsg)); } diff --git a/tests/examples/C#/C#checker/C#checker.cs b/tests/examples/C#/C#checker/C#checker.cs index 24b7060b14..80fa3b8386 100644 --- a/tests/examples/C#/C#checker/C#checker.cs +++ b/tests/examples/C#/C#checker/C#checker.cs @@ -20,358 +20,367 @@ using System.Runtime.InteropServices; using System.Collections; namespace TDengineDriver -{ - class TDengineTest - { - //connect parameters - private string host; - private string configDir; - private string user; - private string password; - private short port = 0; - - //sql parameters - private string dbName; - private string tbName; - - - private bool isInsertData; - private bool isQueryData; - - private long tableCount; - private long totalRows; - private long batchRows; - private long beginTimestamp = 1551369600000L; - - private IntPtr conn = IntPtr.Zero; - private long rowsInserted = 0; - - static void Main(string[] args) - { - TDengineTest tester = new TDengineTest(); - tester.ReadArgument(args); - - - tester.InitTDengine(); - tester.ConnectTDengine(); +{ + class TDengineTest + { + //connect parameters + private string host; + private string configDir; + private string user; + private string password; + private short port = 0; + + //sql parameters + private string dbName; + private string tbName; + + + private bool isInsertData; + private bool isQueryData; + + private long tableCount; + private long totalRows; + private long batchRows; + private long beginTimestamp = 1551369600000L; + + private IntPtr conn = IntPtr.Zero; + private long rowsInserted = 0; + + static void Main(string[] args) + { + TDengineTest tester = new TDengineTest(); + tester.ReadArgument(args); + + + tester.InitTDengine(); + tester.ConnectTDengine(); tester.createDatabase(); - tester.useDatabase(); + tester.useDatabase(); tester.checkDropTable(); tester.createTable(); tester.checkInsert(); tester.checkSelect(); - tester.checkDropTable(); - - tester.CloseConnection(); - - - - } - - public long GetArgumentAsLong(String[] argv, String argName, int minVal, int maxVal, int defaultValue) - { - int argc = argv.Length; - for (int i = 0; i < argc; ++i) - { - if (argName != argv[i]) - { - continue; - } - if (i < argc - 1) - { - String tmp = argv[i + 1]; - if (tmp[0] == '-') - { - Console.WriteLine("option {0:G} requires an argument", tmp); - ExitProgram(); - } - - long tmpVal = Convert.ToInt64(tmp); - if (tmpVal < minVal || tmpVal > maxVal) - { - Console.WriteLine("option {0:G} should in range [{1:G}, {2:G}]", argName, minVal, maxVal); - ExitProgram(); - } - - return tmpVal; - } - } - - return defaultValue; - } - - public String GetArgumentAsString(String[] argv, String argName, String defaultValue) - { - int argc = argv.Length; - for (int i = 0; i < argc; ++i) - { - if (argName != argv[i]) - { - continue; - } - if (i < argc - 1) - { - String tmp = argv[i + 1]; - if (tmp[0] == '-') - { - Console.WriteLine("option {0:G} requires an argument", tmp); - ExitProgram(); - } - return tmp; - } - } - - return defaultValue; - } - - public void PrintHelp(String[] argv) - { - for (int i = 0; i < argv.Length; ++i) - { - if ("--help" == argv[i]) - { - String indent = " "; - Console.WriteLine("taosTest is simple example to operate TDengine use C# Language.\n"); - Console.WriteLine("{0:G}{1:G}", indent, "-h"); - Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "TDEngine server IP address to connect"); - Console.WriteLine("{0:G}{1:G}", indent, "-u"); - Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "The TDEngine user name to use when connecting to the server, default is root"); - Console.WriteLine("{0:G}{1:G}", indent, "-p"); - Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "The TDEngine user name to use when connecting to the server, default is taosdata"); - Console.WriteLine("{0:G}{1:G}", indent, "-d"); - Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Database used to create table or import data, default is db"); - Console.WriteLine("{0:G}{1:G}", indent, "-s"); - Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Super Tables used to create table, default is mt"); - Console.WriteLine("{0:G}{1:G}", indent, "-t"); - Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Table prefixs, default is t"); - Console.WriteLine("{0:G}{1:G}", indent, "-w"); - Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Whether to insert data"); - Console.WriteLine("{0:G}{1:G}", indent, "-r"); - Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Whether to query data"); - Console.WriteLine("{0:G}{1:G}", indent, "-n"); - Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "How many Tables to create, default is 10"); - Console.WriteLine("{0:G}{1:G}", indent, "-b"); - Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "How many rows per insert batch, default is 10"); - Console.WriteLine("{0:G}{1:G}", indent, "-i"); - Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "How many rows to insert, default is 100"); - Console.WriteLine("{0:G}{1:G}", indent, "-c"); - Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Configuration directory"); - - ExitProgram(); - } - } - } - - public void ReadArgument(String[] argv) - { - PrintHelp(argv); - host = this.GetArgumentAsString(argv, "-h", "127.0.0.1"); - user = this.GetArgumentAsString(argv, "-u", "root"); - password = this.GetArgumentAsString(argv, "-p", "taosdata"); - dbName = this.GetArgumentAsString(argv, "-db", "test"); - tbName = this.GetArgumentAsString(argv, "-s", "weather"); - - isInsertData = this.GetArgumentAsLong(argv, "-w", 0, 1, 1) != 0; - isQueryData = this.GetArgumentAsLong(argv, "-r", 0, 1, 1) != 0; - tableCount = this.GetArgumentAsLong(argv, "-n", 1, 10000, 10); - batchRows = this.GetArgumentAsLong(argv, "-b", 1, 1000, 500); - totalRows = this.GetArgumentAsLong(argv, "-i", 1, 10000000, 10000); - configDir = this.GetArgumentAsString(argv, "-c", "C:/TDengine/cfg"); - } - - public void InitTDengine() - { - TDengine.Options((int)TDengineInitOption.TDDB_OPTION_CONFIGDIR, this.configDir); - TDengine.Options((int)TDengineInitOption.TDDB_OPTION_SHELL_ACTIVITY_TIMER, "60"); - TDengine.Init(); - Console.WriteLine("get connection starting..."); - } - - public void ConnectTDengine() - { - string db = ""; - this.conn = TDengine.Connect(this.host, this.user, this.password, db, this.port); - if (this.conn == IntPtr.Zero) - { - Console.WriteLine("connection failed: " + this.host); - ExitProgram(); - } - else - { - Console.WriteLine("[ OK ] Connection established."); - } - } - public void createDatabase() - { - StringBuilder sql = new StringBuilder(); - sql.Append("create database if not exists ").Append(this.dbName); - execute(sql.ToString()); - } - public void useDatabase() - { - StringBuilder sql = new StringBuilder(); - sql.Append("use ").Append(this.dbName); - execute(sql.ToString()); - } - public void checkSelect() - { - StringBuilder sql = new StringBuilder(); - sql.Append("select * from test.weather"); - execute(sql.ToString()); - } - public void createTable() - { - StringBuilder sql = new StringBuilder(); - sql.Append("create table if not exists ").Append(this.dbName).Append(".").Append(this.tbName).Append("(ts timestamp, temperature float, humidity int)"); - execute(sql.ToString()); - } - public void checkInsert() - { - StringBuilder sql = new StringBuilder(); - sql.Append("insert into test.weather (ts, temperature, humidity) values(now, 20.5, 34)"); - execute(sql.ToString()); - } - public void checkDropTable() - { - StringBuilder sql = new StringBuilder(); - sql.Append("drop table if exists ").Append(this.dbName).Append(".").Append(this.tbName).Append(""); - execute(sql.ToString()); - } - public void execute(string sql) - { - DateTime dt1 = DateTime.Now; - IntPtr res = TDengine.Query(this.conn, sql.ToString()); - DateTime dt2 = DateTime.Now; - TimeSpan span = dt2 - dt1; - - if (res != IntPtr.Zero) - { - Console.WriteLine("[OK] time cost: " + span.ToString() + "ms, execute statement ====> " + sql.ToString()); - } - else - { - Console.WriteLine(sql.ToString() + " failure, reason: " + TDengine.Error(res)); - ExitProgram(); - } - TDengine.FreeResult(res); - } - - public void ExecuteQuery(string sql) - { - - DateTime dt1 = DateTime.Now; - long queryRows = 0; - IntPtr res = TDengine.Query(conn, sql); - if (res == IntPtr.Zero) - { - Console.WriteLine(sql + " failure, reason: " + TDengine.Error(res)); - ExitProgram(); - } - DateTime dt2 = DateTime.Now; - TimeSpan span = dt2 - dt1; - Console.WriteLine("[OK] time cost: " + span.ToString() + "ms, execute statement ====> " + sql.ToString()); - int fieldCount = TDengine.FieldCount(res); - - List metas = TDengine.FetchFields(res); - for (int j = 0; j < metas.Count; j++) - { - TDengineMeta meta = (TDengineMeta)metas[j]; - } - - IntPtr rowdata; - StringBuilder builder = new StringBuilder(); - while ((rowdata = TDengine.FetchRows(res)) != IntPtr.Zero) - { - queryRows++; - for (int fields = 0; fields < fieldCount; ++fields) - { - TDengineMeta meta = metas[fields]; - int offset = IntPtr.Size * fields; - IntPtr data = Marshal.ReadIntPtr(rowdata, offset); - - builder.Append("---"); - - if (data == IntPtr.Zero) - { - builder.Append("NULL"); - continue; - } - - switch ((TDengineDataType)meta.type) - { - case TDengineDataType.TSDB_DATA_TYPE_BOOL: - bool v1 = Marshal.ReadByte(data) == 0 ? false : true; - builder.Append(v1); - break; - case TDengineDataType.TSDB_DATA_TYPE_TINYINT: - byte v2 = Marshal.ReadByte(data); - builder.Append(v2); - break; - case TDengineDataType.TSDB_DATA_TYPE_SMALLINT: - short v3 = Marshal.ReadInt16(data); - builder.Append(v3); - break; - case TDengineDataType.TSDB_DATA_TYPE_INT: - int v4 = Marshal.ReadInt32(data); - builder.Append(v4); - break; - case TDengineDataType.TSDB_DATA_TYPE_BIGINT: - long v5 = Marshal.ReadInt64(data); - builder.Append(v5); - break; - case TDengineDataType.TSDB_DATA_TYPE_FLOAT: - float v6 = (float)Marshal.PtrToStructure(data, typeof(float)); - builder.Append(v6); - break; - case TDengineDataType.TSDB_DATA_TYPE_DOUBLE: - double v7 = (double)Marshal.PtrToStructure(data, typeof(double)); - builder.Append(v7); - break; - case TDengineDataType.TSDB_DATA_TYPE_BINARY: - string v8 = Marshal.PtrToStringAnsi(data); - builder.Append(v8); - break; - case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP: - long v9 = Marshal.ReadInt64(data); - builder.Append(v9); - break; - case TDengineDataType.TSDB_DATA_TYPE_NCHAR: - string v10 = Marshal.PtrToStringAnsi(data); - builder.Append(v10); - break; - } - } - builder.Append("---"); - - if (queryRows <= 10) - { - Console.WriteLine(builder.ToString()); - } - builder.Clear(); - } - - if (TDengine.ErrorNo(res) != 0) - { - Console.Write("Query is not complete, Error {0:G}", TDengine.ErrorNo(res), TDengine.Error(res)); - } - - TDengine.FreeResult(res); - - } - - public void CloseConnection() - { - if (this.conn != IntPtr.Zero) - { - TDengine.Close(this.conn); - Console.WriteLine("connection closed."); - } - } - - static void ExitProgram() - { - TDengine.Cleanup(); - System.Environment.Exit(0); - } + tester.checkDropTable(); + + tester.CloseConnection(); + + + + } + + public long GetArgumentAsLong(String[] argv, String argName, int minVal, int maxVal, int defaultValue) + { + int argc = argv.Length; + for (int i = 0; i < argc; ++i) + { + if (argName != argv[i]) + { + continue; + } + if (i < argc - 1) + { + String tmp = argv[i + 1]; + if (tmp[0] == '-') + { + Console.WriteLine("option {0:G} requires an argument", tmp); + ExitProgram(); + } + + long tmpVal = Convert.ToInt64(tmp); + if (tmpVal < minVal || tmpVal > maxVal) + { + Console.WriteLine("option {0:G} should in range [{1:G}, {2:G}]", argName, minVal, maxVal); + ExitProgram(); + } + + return tmpVal; + } + } + + return defaultValue; + } + + public String GetArgumentAsString(String[] argv, String argName, String defaultValue) + { + int argc = argv.Length; + for (int i = 0; i < argc; ++i) + { + if (argName != argv[i]) + { + continue; + } + if (i < argc - 1) + { + String tmp = argv[i + 1]; + if (tmp[0] == '-') + { + Console.WriteLine("option {0:G} requires an argument", tmp); + ExitProgram(); + } + return tmp; + } + } + + return defaultValue; + } + + public void PrintHelp(String[] argv) + { + for (int i = 0; i < argv.Length; ++i) + { + if ("--help" == argv[i]) + { + String indent = " "; + Console.WriteLine("taosTest is simple example to operate TDengine use C# Language.\n"); + Console.WriteLine("{0:G}{1:G}", indent, "-h"); + Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "TDEngine server IP address to connect"); + Console.WriteLine("{0:G}{1:G}", indent, "-u"); + Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "The TDEngine user name to use when connecting to the server, default is root"); + Console.WriteLine("{0:G}{1:G}", indent, "-p"); + Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "The TDEngine user name to use when connecting to the server, default is taosdata"); + Console.WriteLine("{0:G}{1:G}", indent, "-d"); + Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Database used to create table or import data, default is db"); + Console.WriteLine("{0:G}{1:G}", indent, "-s"); + Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Super Tables used to create table, default is mt"); + Console.WriteLine("{0:G}{1:G}", indent, "-t"); + Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Table prefixs, default is t"); + Console.WriteLine("{0:G}{1:G}", indent, "-w"); + Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Whether to insert data"); + Console.WriteLine("{0:G}{1:G}", indent, "-r"); + Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Whether to query data"); + Console.WriteLine("{0:G}{1:G}", indent, "-n"); + Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "How many Tables to create, default is 10"); + Console.WriteLine("{0:G}{1:G}", indent, "-b"); + Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "How many rows per insert batch, default is 10"); + Console.WriteLine("{0:G}{1:G}", indent, "-i"); + Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "How many rows to insert, default is 100"); + Console.WriteLine("{0:G}{1:G}", indent, "-c"); + Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Configuration directory"); + + ExitProgram(); + } + } + } + + public void ReadArgument(String[] argv) + { + PrintHelp(argv); + host = this.GetArgumentAsString(argv, "-h", "127.0.0.1"); + user = this.GetArgumentAsString(argv, "-u", "root"); + password = this.GetArgumentAsString(argv, "-p", "taosdata"); + dbName = this.GetArgumentAsString(argv, "-db", "test"); + tbName = this.GetArgumentAsString(argv, "-s", "weather"); + + isInsertData = this.GetArgumentAsLong(argv, "-w", 0, 1, 1) != 0; + isQueryData = this.GetArgumentAsLong(argv, "-r", 0, 1, 1) != 0; + tableCount = this.GetArgumentAsLong(argv, "-n", 1, 10000, 10); + batchRows = this.GetArgumentAsLong(argv, "-b", 1, 1000, 500); + totalRows = this.GetArgumentAsLong(argv, "-i", 1, 10000000, 10000); + configDir = this.GetArgumentAsString(argv, "-c", "C:/TDengine/cfg"); + } + + public void InitTDengine() + { + TDengine.Options((int)TDengineInitOption.TDDB_OPTION_CONFIGDIR, this.configDir); + TDengine.Options((int)TDengineInitOption.TDDB_OPTION_SHELL_ACTIVITY_TIMER, "60"); + TDengine.Init(); + Console.WriteLine("get connection starting..."); + } + + public void ConnectTDengine() + { + string db = ""; + this.conn = TDengine.Connect(this.host, this.user, this.password, db, this.port); + if (this.conn == IntPtr.Zero) + { + Console.WriteLine("connection failed: " + this.host); + ExitProgram(); + } + else + { + Console.WriteLine("[ OK ] Connection established."); + } + } + public void createDatabase() + { + StringBuilder sql = new StringBuilder(); + sql.Append("create database if not exists ").Append(this.dbName); + execute(sql.ToString()); + } + public void useDatabase() + { + StringBuilder sql = new StringBuilder(); + sql.Append("use ").Append(this.dbName); + execute(sql.ToString()); + } + public void checkSelect() + { + StringBuilder sql = new StringBuilder(); + sql.Append("select * from test.weather"); + execute(sql.ToString()); + } + public void createTable() + { + StringBuilder sql = new StringBuilder(); + sql.Append("create table if not exists ").Append(this.dbName).Append(".").Append(this.tbName).Append("(ts timestamp, temperature float, humidity int)"); + execute(sql.ToString()); + } + public void checkInsert() + { + StringBuilder sql = new StringBuilder(); + sql.Append("insert into test.weather (ts, temperature, humidity) values(now, 20.5, 34)"); + execute(sql.ToString()); + } + public void checkDropTable() + { + StringBuilder sql = new StringBuilder(); + sql.Append("drop table if exists ").Append(this.dbName).Append(".").Append(this.tbName).Append(""); + execute(sql.ToString()); + } + public void execute(string sql) + { + DateTime dt1 = DateTime.Now; + IntPtr res = TDengine.Query(this.conn, sql.ToString()); + DateTime dt2 = DateTime.Now; + TimeSpan span = dt2 - dt1; + + if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) + { + Console.Write(sql.ToString() + " failure, "); + if (res != IntPtr.Zero) { + Console.Write("reason: " + TDengine.Error(res)); + } + Console.WriteLine(""); + ExitProgram(); + } + else + { + Console.WriteLine(sql.ToString() + " success"); + } + TDengine.FreeResult(res); + } + + public void ExecuteQuery(string sql) + { + + DateTime dt1 = DateTime.Now; + long queryRows = 0; + IntPtr res = TDengine.Query(conn, sql); + if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) + { + Console.Write(sql.ToString() + " failure, "); + if (res != IntPtr.Zero) { + Console.Write("reason: " + TDengine.Error(res)); + } + Console.WriteLine(""); + ExitProgram(); + } + DateTime dt2 = DateTime.Now; + TimeSpan span = dt2 - dt1; + Console.WriteLine("[OK] time cost: " + span.ToString() + "ms, execute statement ====> " + sql.ToString()); + int fieldCount = TDengine.FieldCount(res); + + List metas = TDengine.FetchFields(res); + for (int j = 0; j < metas.Count; j++) + { + TDengineMeta meta = (TDengineMeta)metas[j]; + } + + IntPtr rowdata; + StringBuilder builder = new StringBuilder(); + while ((rowdata = TDengine.FetchRows(res)) != IntPtr.Zero) + { + queryRows++; + for (int fields = 0; fields < fieldCount; ++fields) + { + TDengineMeta meta = metas[fields]; + int offset = IntPtr.Size * fields; + IntPtr data = Marshal.ReadIntPtr(rowdata, offset); + + builder.Append("---"); + + if (data == IntPtr.Zero) + { + builder.Append("NULL"); + continue; + } + + switch ((TDengineDataType)meta.type) + { + case TDengineDataType.TSDB_DATA_TYPE_BOOL: + bool v1 = Marshal.ReadByte(data) == 0 ? false : true; + builder.Append(v1); + break; + case TDengineDataType.TSDB_DATA_TYPE_TINYINT: + byte v2 = Marshal.ReadByte(data); + builder.Append(v2); + break; + case TDengineDataType.TSDB_DATA_TYPE_SMALLINT: + short v3 = Marshal.ReadInt16(data); + builder.Append(v3); + break; + case TDengineDataType.TSDB_DATA_TYPE_INT: + int v4 = Marshal.ReadInt32(data); + builder.Append(v4); + break; + case TDengineDataType.TSDB_DATA_TYPE_BIGINT: + long v5 = Marshal.ReadInt64(data); + builder.Append(v5); + break; + case TDengineDataType.TSDB_DATA_TYPE_FLOAT: + float v6 = (float)Marshal.PtrToStructure(data, typeof(float)); + builder.Append(v6); + break; + case TDengineDataType.TSDB_DATA_TYPE_DOUBLE: + double v7 = (double)Marshal.PtrToStructure(data, typeof(double)); + builder.Append(v7); + break; + case TDengineDataType.TSDB_DATA_TYPE_BINARY: + string v8 = Marshal.PtrToStringAnsi(data); + builder.Append(v8); + break; + case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP: + long v9 = Marshal.ReadInt64(data); + builder.Append(v9); + break; + case TDengineDataType.TSDB_DATA_TYPE_NCHAR: + string v10 = Marshal.PtrToStringAnsi(data); + builder.Append(v10); + break; + } + } + builder.Append("---"); + + if (queryRows <= 10) + { + Console.WriteLine(builder.ToString()); + } + builder.Clear(); + } + + if (TDengine.ErrorNo(res) != 0) + { + Console.Write("Query is not complete, Error {0:G}", TDengine.ErrorNo(res), TDengine.Error(res)); + } + Console.WriteLine(""); + + TDengine.FreeResult(res); + + } + + public void CloseConnection() + { + if (this.conn != IntPtr.Zero) + { + TDengine.Close(this.conn); + Console.WriteLine("connection closed."); + } + } + + static void ExitProgram() + { + TDengine.Cleanup(); + System.Environment.Exit(0); + } } } diff --git a/tests/examples/C#/TDengineDriver.cs b/tests/examples/C#/TDengineDriver.cs index b6f143e181..2c150341f6 100644 --- a/tests/examples/C#/TDengineDriver.cs +++ b/tests/examples/C#/TDengineDriver.cs @@ -19,136 +19,149 @@ using System.Runtime.InteropServices; namespace TDengineDriver { - enum TDengineDataType { - TSDB_DATA_TYPE_NULL = 0, // 1 bytes - TSDB_DATA_TYPE_BOOL = 1, // 1 bytes - TSDB_DATA_TYPE_TINYINT = 2, // 1 bytes - TSDB_DATA_TYPE_SMALLINT = 3, // 2 bytes - TSDB_DATA_TYPE_INT = 4, // 4 bytes - TSDB_DATA_TYPE_BIGINT = 5, // 8 bytes - TSDB_DATA_TYPE_FLOAT = 6, // 4 bytes - TSDB_DATA_TYPE_DOUBLE = 7, // 8 bytes - TSDB_DATA_TYPE_BINARY = 8, // string - TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes - TSDB_DATA_TYPE_NCHAR = 10 // unicode string - } - - enum TDengineInitOption - { - TSDB_OPTION_LOCALE = 0, - TSDB_OPTION_CHARSET = 1, - TSDB_OPTION_TIMEZONE = 2, - TDDB_OPTION_CONFIGDIR = 3, - TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4 - } - - class TDengineMeta - { - public string name; - public short size; - public byte type; - public string TypeName() + enum TDengineDataType { - switch ((TDengineDataType)type) - { - case TDengineDataType.TSDB_DATA_TYPE_BOOL: - return "BOOLEAN"; - case TDengineDataType.TSDB_DATA_TYPE_TINYINT: - return "BYTE"; - case TDengineDataType.TSDB_DATA_TYPE_SMALLINT: - return "SHORT"; - case TDengineDataType.TSDB_DATA_TYPE_INT: - return "INT"; - case TDengineDataType.TSDB_DATA_TYPE_BIGINT: - return "LONG"; - case TDengineDataType.TSDB_DATA_TYPE_FLOAT: - return "FLOAT"; - case TDengineDataType.TSDB_DATA_TYPE_DOUBLE: - return "DOUBLE"; - case TDengineDataType.TSDB_DATA_TYPE_BINARY: - return "STRING"; - case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP: - return "TIMESTAMP"; - case TDengineDataType.TSDB_DATA_TYPE_NCHAR: - return "NCHAR"; - default: - return "undefine"; - } - } - } - - class TDengine - { - public const int TSDB_CODE_SUCCESS = 0; - - [DllImport("taos.dll", EntryPoint = "taos_init", CallingConvention = CallingConvention.Cdecl)] - static extern public void Init(); - - [DllImport("taos.dll", EntryPoint = "taos_cleanup", CallingConvention = CallingConvention.Cdecl)] - static extern public void Cleanup(); - - [DllImport("taos.dll", EntryPoint = "taos_options", CallingConvention = CallingConvention.Cdecl)] - static extern public void Options(int option, string value); - - [DllImport("taos.dll", EntryPoint = "taos_connect", CallingConvention = CallingConvention.Cdecl)] - static extern public IntPtr Connect(string ip, string user, string password, string db, short port); - - [DllImport("taos.dll", EntryPoint = "taos_errstr", CallingConvention = CallingConvention.Cdecl)] - static extern private IntPtr taos_errstr(IntPtr res); - static public string Error(IntPtr res) - { - IntPtr errPtr = taos_errstr(res); - return Marshal.PtrToStringAnsi(errPtr); + TSDB_DATA_TYPE_NULL = 0, // 1 bytes + TSDB_DATA_TYPE_BOOL = 1, // 1 bytes + TSDB_DATA_TYPE_TINYINT = 2, // 1 bytes + TSDB_DATA_TYPE_SMALLINT = 3, // 2 bytes + TSDB_DATA_TYPE_INT = 4, // 4 bytes + TSDB_DATA_TYPE_BIGINT = 5, // 8 bytes + TSDB_DATA_TYPE_FLOAT = 6, // 4 bytes + TSDB_DATA_TYPE_DOUBLE = 7, // 8 bytes + TSDB_DATA_TYPE_BINARY = 8, // string + TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes + TSDB_DATA_TYPE_NCHAR = 10, // unicode string + TSDB_DATA_TYPE_UTINYINT = 11,// 1 byte + TSDB_DATA_TYPE_USMALLINT= 12,// 2 bytes + TSDB_DATA_TYPE_UINT = 13, // 4 bytes + TSDB_DATA_TYPE_UBIGINT= 14 // 8 bytes } - [DllImport("taos.dll", EntryPoint = "taos_errno", CallingConvention = CallingConvention.Cdecl)] - static extern public int ErrorNo(IntPtr res); - - [DllImport("taos.dll", EntryPoint = "taos_query", CallingConvention = CallingConvention.Cdecl)] - static extern public IntPtr Query(IntPtr conn, string sqlstr); - - [DllImport("taos.dll", EntryPoint = "taos_affected_rows", CallingConvention = CallingConvention.Cdecl)] - static extern public int AffectRows(IntPtr res); - - [DllImport("taos.dll", EntryPoint = "taos_field_count", CallingConvention = CallingConvention.Cdecl)] - static extern public int FieldCount(IntPtr res); - - [DllImport("taos.dll", EntryPoint = "taos_fetch_fields", CallingConvention = CallingConvention.Cdecl)] - static extern private IntPtr taos_fetch_fields(IntPtr res); - static public List FetchFields(IntPtr res) + enum TDengineInitOption { - const int fieldSize = 68; - - List metas = new List(); - if (res == IntPtr.Zero) - { - return metas; - } - - int fieldCount = FieldCount(res); - IntPtr fieldsPtr = taos_fetch_fields(res); - - for (int i = 0; i < fieldCount; ++i) - { - int offset = i * fieldSize; - - TDengineMeta meta = new TDengineMeta(); - meta.name = Marshal.PtrToStringAnsi(fieldsPtr + offset); - meta.type = Marshal.ReadByte(fieldsPtr + offset + 65); - meta.size = Marshal.ReadInt16(fieldsPtr + offset + 66); - metas.Add(meta); - } - - return metas; + TSDB_OPTION_LOCALE = 0, + TSDB_OPTION_CHARSET = 1, + TSDB_OPTION_TIMEZONE = 2, + TDDB_OPTION_CONFIGDIR = 3, + TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4 } - [DllImport("taos.dll", EntryPoint = "taos_fetch_row", CallingConvention = CallingConvention.Cdecl)] - static extern public IntPtr FetchRows(IntPtr res); + class TDengineMeta + { + public string name; + public short size; + public byte type; + public string TypeName() + { + switch ((TDengineDataType)type) + { + case TDengineDataType.TSDB_DATA_TYPE_BOOL: + return "BOOL"; + case TDengineDataType.TSDB_DATA_TYPE_TINYINT: + return "TINYINT"; + case TDengineDataType.TSDB_DATA_TYPE_SMALLINT: + return "SMALLINT"; + case TDengineDataType.TSDB_DATA_TYPE_INT: + return "INT"; + case TDengineDataType.TSDB_DATA_TYPE_BIGINT: + return "BIGINT"; + case TDengineDataType.TSDB_DATA_TYPE_UTINYINT: + return "TINYINT UNSIGNED"; + case TDengineDataType.TSDB_DATA_TYPE_USMALLINT: + return "SMALLINT UNSIGNED"; + case TDengineDataType.TSDB_DATA_TYPE_UINT: + return "INT UNSIGNED"; + case TDengineDataType.TSDB_DATA_TYPE_UBIGINT: + return "BIGINT UNSIGNED"; + case TDengineDataType.TSDB_DATA_TYPE_FLOAT: + return "FLOAT"; + case TDengineDataType.TSDB_DATA_TYPE_DOUBLE: + return "DOUBLE"; + case TDengineDataType.TSDB_DATA_TYPE_BINARY: + return "STRING"; + case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP: + return "TIMESTAMP"; + case TDengineDataType.TSDB_DATA_TYPE_NCHAR: + return "NCHAR"; + default: + return "undefine"; + } + } + } - [DllImport("taos.dll", EntryPoint = "taos_free_result", CallingConvention = CallingConvention.Cdecl)] - static extern public IntPtr FreeResult(IntPtr res); + class TDengine + { + public const int TSDB_CODE_SUCCESS = 0; - [DllImport("taos.dll", EntryPoint = "taos_close", CallingConvention = CallingConvention.Cdecl)] - static extern public int Close(IntPtr taos); - } -} \ No newline at end of file + [DllImport("taos", EntryPoint = "taos_init", CallingConvention = CallingConvention.Cdecl)] + static extern public void Init(); + + [DllImport("taos", EntryPoint = "taos_cleanup", CallingConvention = CallingConvention.Cdecl)] + static extern public void Cleanup(); + + [DllImport("taos", EntryPoint = "taos_options", CallingConvention = CallingConvention.Cdecl)] + static extern public void Options(int option, string value); + + [DllImport("taos", EntryPoint = "taos_connect", CallingConvention = CallingConvention.Cdecl)] + static extern public IntPtr Connect(string ip, string user, string password, string db, short port); + + [DllImport("taos", EntryPoint = "taos_errstr", CallingConvention = CallingConvention.Cdecl)] + static extern private IntPtr taos_errstr(IntPtr res); + static public string Error(IntPtr res) + { + IntPtr errPtr = taos_errstr(res); + return Marshal.PtrToStringAnsi(errPtr); + } + + [DllImport("taos", EntryPoint = "taos_errno", CallingConvention = CallingConvention.Cdecl)] + static extern public int ErrorNo(IntPtr res); + + [DllImport("taos", EntryPoint = "taos_query", CallingConvention = CallingConvention.Cdecl)] + static extern public IntPtr Query(IntPtr conn, string sqlstr); + + [DllImport("taos", EntryPoint = "taos_affected_rows", CallingConvention = CallingConvention.Cdecl)] + static extern public int AffectRows(IntPtr res); + + [DllImport("taos", EntryPoint = "taos_field_count", CallingConvention = CallingConvention.Cdecl)] + static extern public int FieldCount(IntPtr res); + + [DllImport("taos", EntryPoint = "taos_fetch_fields", CallingConvention = CallingConvention.Cdecl)] + static extern private IntPtr taos_fetch_fields(IntPtr res); + static public List FetchFields(IntPtr res) + { + const int fieldSize = 68; + + List metas = new List(); + if (res == IntPtr.Zero) + { + return metas; + } + + int fieldCount = FieldCount(res); + IntPtr fieldsPtr = taos_fetch_fields(res); + + for (int i = 0; i < fieldCount; ++i) + { + int offset = i * fieldSize; + + TDengineMeta meta = new TDengineMeta(); + meta.name = Marshal.PtrToStringAnsi(fieldsPtr + offset); + meta.type = Marshal.ReadByte(fieldsPtr + offset + 65); + meta.size = Marshal.ReadInt16(fieldsPtr + offset + 66); + metas.Add(meta); + } + + return metas; + } + + [DllImport("taos", EntryPoint = "taos_fetch_row", CallingConvention = CallingConvention.Cdecl)] + static extern public IntPtr FetchRows(IntPtr res); + + [DllImport("taos", EntryPoint = "taos_free_result", CallingConvention = CallingConvention.Cdecl)] + static extern public IntPtr FreeResult(IntPtr res); + + [DllImport("taos", EntryPoint = "taos_close", CallingConvention = CallingConvention.Cdecl)] + static extern public int Close(IntPtr taos); + } +} diff --git a/tests/examples/C#/TDengineTest.cs b/tests/examples/C#/TDengineTest.cs index 6b3f1160ad..f4ee62527f 100644 --- a/tests/examples/C#/TDengineTest.cs +++ b/tests/examples/C#/TDengineTest.cs @@ -165,7 +165,7 @@ namespace TDengineDriver public void ReadArgument(String[] argv) { PrintHelp(argv); - host = this.GetArgumentAsString(argv, "-h", "192.168.100.128"); + host = this.GetArgumentAsString(argv, "-h", "127.0.0.1"); user = this.GetArgumentAsString(argv, "-u", "root"); password = this.GetArgumentAsString(argv, "-p", "taosdata"); dbName = this.GetArgumentAsString(argv, "-d", "db"); @@ -212,42 +212,54 @@ namespace TDengineDriver StringBuilder sql = new StringBuilder(); sql.Append("create database if not exists ").Append(this.dbName); IntPtr res = TDengine.Query(this.conn, sql.ToString()); - if (res != IntPtr.Zero) + if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) { - Console.WriteLine(sql.ToString() + " success"); + Console.Write(sql.ToString() + " failure, "); + if (res != IntPtr.Zero) { + Console.Write("reason: " + TDengine.Error(res)); + } + Console.WriteLine(""); + ExitProgram(); } else { - Console.WriteLine(sql.ToString() + " failure, reason: " + TDengine.Error(res)); - ExitProgram(); + Console.WriteLine(sql.ToString() + " success"); } TDengine.FreeResult(res); sql.Clear(); sql.Append("use ").Append(this.dbName); res = TDengine.Query(this.conn, sql.ToString()); - if (res != IntPtr.Zero) + if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) { - Console.WriteLine(sql.ToString() + " success"); + Console.Write(sql.ToString() + " failure, "); + if (res != IntPtr.Zero) { + Console.Write("reason: " + TDengine.Error(res)); + } + Console.WriteLine(""); + ExitProgram(); } else { - Console.WriteLine(sql.ToString() + " failure, reason: " + TDengine.Error(res)); - ExitProgram(); + Console.WriteLine(sql.ToString() + " success"); } TDengine.FreeResult(res); sql.Clear(); sql.Append("create table if not exists ").Append(this.stableName).Append("(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 float, v7 double, v8 binary(10), v9 nchar(10)) tags(t1 int)"); res = TDengine.Query(this.conn, sql.ToString()); - if (res != IntPtr.Zero) + if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) { - Console.WriteLine(sql.ToString() + " success"); + Console.Write(sql.ToString() + " failure, "); + if (res != IntPtr.Zero) { + Console.Write("reason: " + TDengine.Error(res)); + } + Console.WriteLine(""); + ExitProgram(); } else { - Console.WriteLine(sql.ToString() + " failure, reason: " + TDengine.Error(res)); - ExitProgram(); + Console.WriteLine(sql.ToString() + " success"); } TDengine.FreeResult(res); @@ -257,14 +269,18 @@ namespace TDengineDriver sql = sql.Append("create table if not exists ").Append(this.tablePrefix).Append(i) .Append(" using ").Append(this.stableName).Append(" tags(").Append(i).Append(")"); res = TDengine.Query(this.conn, sql.ToString()); - if (res != IntPtr.Zero) + if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) { - Console.WriteLine(sql.ToString() + " success"); + Console.Write(sql.ToString() + " failure, "); + if (res != IntPtr.Zero) { + Console.Write("reason: " + TDengine.Error(res)); + } + Console.WriteLine(""); + ExitProgram(); } else { - Console.WriteLine(sql.ToString() + " failure, reason: " + TDengine.Error(res)); - ExitProgram(); + Console.WriteLine(sql.ToString() + " success"); } TDengine.FreeResult(res); } @@ -298,9 +314,13 @@ namespace TDengineDriver .Append(", 5, 6, 7, 'abc', 'def')"); } IntPtr res = TDengine.Query(this.conn, sql.ToString()); - if (res == IntPtr.Zero) + if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) { - Console.WriteLine(sql.ToString() + " failure, reason: " + TDengine.Error(res)); + Console.Write(sql.ToString() + " failure, "); + if (res != IntPtr.Zero) { + Console.Write("reason: " + TDengine.Error(res)); + } + Console.WriteLine(""); } int affectRows = TDengine.AffectRows(res); @@ -326,16 +346,20 @@ namespace TDengineDriver System.DateTime start = new System.DateTime(); long queryRows = 0; - + for (int i = 0; i < 1/*this.tableCount*/; ++i) { String sql = "select * from " + this.dbName + "." + tablePrefix + i; Console.WriteLine(sql); IntPtr res = TDengine.Query(conn, sql); - if (res == IntPtr.Zero) + if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) { - Console.WriteLine(sql + " failure, reason: " + TDengine.Error(res)); + Console.Write(sql.ToString() + " failure, "); + if (res != IntPtr.Zero) { + Console.Write("reason: " + TDengine.Error(res)); + } + Console.WriteLine(""); ExitProgram(); } @@ -410,6 +434,22 @@ namespace TDengineDriver string v10 = Marshal.PtrToStringAnsi(data); builder.Append(v10); break; + case TDengineDataType.TSDB_DATA_TYPE_UTINYINT: + byte v11 = Marshal.ReadByte(data); + builder.Append(v11); + break; + case TDengineDataType.TSDB_DATA_TYPE_USMALLINT: + ushort v12 = (ushort)Marshal.ReadInt16(data); + builder.Append(v12); + break; + case TDengineDataType.TSDB_DATA_TYPE_UINT: + uint v13 = (uint)Marshal.ReadInt32(data); + builder.Append(v13); + break; + case TDengineDataType.TSDB_DATA_TYPE_UBIGINT: + ulong v14 = (ulong)Marshal.ReadInt64(data); + builder.Append(v14); + break; } } builder.Append("---"); @@ -423,8 +463,10 @@ namespace TDengineDriver if (TDengine.ErrorNo(res) != 0) { - Console.Write("Query is not complete, Error {0:G}", TDengine.ErrorNo(res), TDengine.Error(res)); + Console.Write("Query is not complete, Error {0:G}", + TDengine.ErrorNo(res), TDengine.Error(res)); } + Console.WriteLine(""); TDengine.FreeResult(res); } diff --git a/tests/examples/C#/taosdemo/taosdemo.cs b/tests/examples/C#/taosdemo/taosdemo.cs index 4fc7232ad2..e092c48f15 100644 --- a/tests/examples/C#/taosdemo/taosdemo.cs +++ b/tests/examples/C#/taosdemo/taosdemo.cs @@ -370,16 +370,19 @@ namespace TDengineDriver StringBuilder sql = new StringBuilder(); sql.Append("DROP DATABASE IF EXISTS ").Append(this.dbName); IntPtr res = TDengine.Query(this.conn, sql.ToString()); - if (res != IntPtr.Zero) + if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) { - VerbosePrint(sql.ToString() + " success\n"); + Console.Write(sql.ToString() + " failure, "); + if (res != IntPtr.Zero) { + Console.Write("reason: " + TDengine.Error(res)); + } + Console.WriteLine(""); + CleanAndExitProgram(1); } else { - Console.WriteLine(sql.ToString() + " failure, reason: " + TDengine.Error(res)); - CleanAndExitProgram(1); + VerbosePrint(sql.ToString() + " success\n"); } - } public void CreateDb() @@ -387,14 +390,18 @@ namespace TDengineDriver StringBuilder sql = new StringBuilder(); sql.Append("CREATE DATABASE IF NOT EXISTS ").Append(this.dbName).Append(" replica ").Append(this.replica).Append(" keep 36500"); IntPtr res = TDengine.Query(this.conn, sql.ToString()); - if (res != IntPtr.Zero) + if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) { - VerbosePrint(sql.ToString() + " success\n"); + Console.Write(sql.ToString() + " failure, "); + if (res != IntPtr.Zero) { + Console.Write("reason: " + TDengine.Error(res)); + } + Console.WriteLine(""); + CleanAndExitProgram(1); } else { - Console.WriteLine(sql.ToString() + " failure, reason: " + TDengine.Error(res)); - CleanAndExitProgram(1); + VerbosePrint(sql.ToString() + " success\n"); } TDengine.FreeResult(res); } @@ -408,14 +415,18 @@ namespace TDengineDriver Append(this.dbName).Append(".").Append(this.stablePrefix). Append("(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 float, v7 double, v8 binary(10), v9 nchar(10), v10 tinyint unsigned, v11 smallint unsigned, v12 int unsigned, v13 bigint unsigned) tags(t1 int)"); IntPtr res = TDengine.Query(this.conn, sql.ToString()); - if (res != IntPtr.Zero) + if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) { - VerbosePrint(sql.ToString() + " success\n"); + Console.Write(sql.ToString() + " failure, "); + if (res != IntPtr.Zero) { + Console.Write("reason: " + TDengine.Error(res)); + } + Console.WriteLine(""); + CleanAndExitProgram(1); } else { - Console.WriteLine(sql.ToString() + " failure, reason: " + TDengine.Error(res)); - CleanAndExitProgram(1); + VerbosePrint(sql.ToString() + " success\n"); } TDengine.FreeResult(res); } @@ -495,9 +506,13 @@ namespace TDengineDriver IntPtr res = TDengine.Query(conn, sql); DebugPrintFormat("res: {0}\n", res); - if (res == IntPtr.Zero) + if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) { - Console.WriteLine(sql + " failure, reason: " + TDengine.Error(res)); + Console.Write(sql.ToString() + " failure, "); + if (res != IntPtr.Zero) { + Console.Write("reason: " + TDengine.Error(res)); + } + Console.WriteLine(""); CleanAndExitProgram(1); } @@ -782,9 +797,13 @@ namespace TDengineDriver } VerbosePrint(sql.ToString() + "\n"); IntPtr res = TDengine.Query(this.conn, sql.ToString()); - if (res == IntPtr.Zero) + if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) { - VerbosePrint(sql.ToString() + " failure, reason: " + TDengine.Error(res) + "\n"); + Console.Write(sql.ToString() + " failure, "); + if (res != IntPtr.Zero) { + Console.Write("reason: " + TDengine.Error(res)); + } + Console.WriteLine(""); } inserted += this.batchRows; @@ -861,14 +880,18 @@ namespace TDengineDriver sql = sql.Append("(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 float, v7 double, v8 binary(10), v9 nchar(10), v10 tinyint unsigned, v11 smallint unsigned, v12 int unsigned, v13 bigint unsigned)"); } IntPtr res = TDengine.Query(this.conn, sql.ToString()); - if (res != IntPtr.Zero) + if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) { - VerbosePrint(sql.ToString() + " success\n"); + Console.Write(sql.ToString() + " failure, "); + if (res != IntPtr.Zero) { + Console.Write("reason: " + TDengine.Error(res)); + } + Console.WriteLine(""); + CleanAndExitProgram(1); } else { - VerbosePrint(sql.ToString() + " failure, reason: " + TDengine.Error(res) + "\n"); - CleanAndExitProgram(1); + VerbosePrint(sql.ToString() + " success\n"); } TDengine.FreeResult(res); } diff --git a/tests/examples/JDBC/springbootdemo/pom.xml b/tests/examples/JDBC/springbootdemo/pom.xml index bd5f7efbc0..6c83718896 100644 --- a/tests/examples/JDBC/springbootdemo/pom.xml +++ b/tests/examples/JDBC/springbootdemo/pom.xml @@ -63,9 +63,9 @@ com.taosdata.jdbc taos-jdbcdriver - 2.0.20 + 2.0.28 - + diff --git a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/SpringbootdemoApplication.java b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/SpringbootdemoApplication.java index 8f30c29946..fa10f3b092 100644 --- a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/SpringbootdemoApplication.java +++ b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/SpringbootdemoApplication.java @@ -7,6 +7,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @MapperScan(basePackages = {"com.taosdata.example.springbootdemo.dao"}) @SpringBootApplication public class SpringbootdemoApplication { + public static void main(String[] args) { SpringApplication.run(SpringbootdemoApplication.class, args); } diff --git a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/controller/WeatherController.java b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/controller/WeatherController.java index c153e27701..cf14f5d84a 100644 --- a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/controller/WeatherController.java +++ b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/controller/WeatherController.java @@ -45,7 +45,7 @@ public class WeatherController { * @return */ @PostMapping("/{temperature}/{humidity}") - public int saveWeather(@PathVariable float temperature, @PathVariable int humidity) { + public int saveWeather(@PathVariable float temperature, @PathVariable float humidity) { return weatherService.save(temperature, humidity); } diff --git a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/domain/Weather.java b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/domain/Weather.java index 255b2cdca9..c11b9a6f50 100644 --- a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/domain/Weather.java +++ b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/domain/Weather.java @@ -8,8 +8,8 @@ public class Weather { @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS", timezone = "GMT+8") private Timestamp ts; - private float temperature; - private float humidity; + private Float temperature; + private Float humidity; private String location; private int groupId; @@ -30,19 +30,19 @@ public class Weather { this.ts = ts; } - public float getTemperature() { + public Float getTemperature() { return temperature; } - public void setTemperature(float temperature) { + public void setTemperature(Float temperature) { this.temperature = temperature; } - public float getHumidity() { + public Float getHumidity() { return humidity; } - public void setHumidity(float humidity) { + public void setHumidity(Float humidity) { this.humidity = humidity; } diff --git a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/service/WeatherService.java b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/service/WeatherService.java index 0aef828e1c..26d09c7d12 100644 --- a/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/service/WeatherService.java +++ b/tests/examples/JDBC/springbootdemo/src/main/java/com/taosdata/example/springbootdemo/service/WeatherService.java @@ -39,7 +39,7 @@ public class WeatherService { return weatherMapper.select(limit, offset); } - public int save(float temperature, int humidity) { + public int save(float temperature, float humidity) { Weather weather = new Weather(); weather.setTemperature(temperature); weather.setHumidity(humidity); diff --git a/tests/examples/c/apitest.c b/tests/examples/c/apitest.c index 930a6075ca..f20c0321c4 100644 --- a/tests/examples/c/apitest.c +++ b/tests/examples/c/apitest.c @@ -435,11 +435,15 @@ void verify_async(TAOS* taos) { } void stream_callback(void *param, TAOS_RES *res, TAOS_ROW row) { + if (res == NULL || row == NULL) { + return; + } + int num_fields = taos_num_fields(res); TAOS_FIELD* fields = taos_fetch_fields(res); printf("got one row from stream_callback\n"); - char temp[256]; + char temp[256] = {0}; taos_print_row(temp, row, fields, num_fields); puts(temp); } diff --git a/tests/examples/go/taosdemo.go b/tests/examples/go/taosdemo.go index 003f5aeddc..543cfcc0f6 100644 --- a/tests/examples/go/taosdemo.go +++ b/tests/examples/go/taosdemo.go @@ -18,6 +18,7 @@ import ( "database/sql" "flag" "fmt" + "log" "math/rand" "os" "runtime" @@ -26,8 +27,6 @@ import ( "time" _ "github.com/taosdata/driver-go/taosSql" - - //"golang.org/x/sys/unix" ) const ( @@ -48,6 +47,7 @@ type config struct { dbName string supTblName string tablePrefix string + mode string numOftables int numOfRecordsPerTable int numOfRecordsPerReq int @@ -70,6 +70,7 @@ func init() { flag.StringVar(&configPara.password, "P", "taosdata", "The password to use when connecting to the server.") flag.StringVar(&configPara.dbName, "d", "test", "Destination database.") flag.StringVar(&configPara.tablePrefix, "m", "d", "Table prefix name.") + flag.StringVar(&configPara.mode, "M", "r", "mode,r:raw,s:stmt") flag.IntVar(&configPara.numOftables, "t", 2, "The number of tables.") flag.IntVar(&configPara.numOfRecordsPerTable, "n", 10, "The number of records per table.") flag.IntVar(&configPara.numOfRecordsPerReq, "r", 3, "The number of records per request.") @@ -94,6 +95,7 @@ func printAllArgs() { fmt.Printf("usr: %v\n", configPara.user) fmt.Printf("password: %v\n", configPara.password) fmt.Printf("dbName: %v\n", configPara.dbName) + fmt.Printf("mode: %v\n", configPara.mode) fmt.Printf("tablePrefix: %v\n", configPara.tablePrefix) fmt.Printf("numOftables: %v\n", configPara.numOftables) fmt.Printf("numOfRecordsPerTable: %v\n", configPara.numOfRecordsPerTable) @@ -119,6 +121,24 @@ func main() { //defer db.Close() rand.Seed(time.Now().Unix()) + if configPara.mode == "s" { + fmt.Printf("\n======== start stmt mode test ========\n") + db, err := sql.Open("taosSql", url) + if err != nil { + log.Fatalf("Open database error: %s\n", err) + } + defer db.Close() + demodbStmt := configPara.dbName + demotStmt := "demotStmt" + drop_database_stmt(db, demodbStmt) + create_database_stmt(db, demodbStmt) + use_database_stmt(db, demodbStmt) + create_table_stmt(db, demotStmt) + insert_data_stmt(db, demotStmt) + select_data_stmt(db, demotStmt) + return + } + createDatabase(configPara.dbName, configPara.supTblName) fmt.Printf("======== create database success! ========\n\n") @@ -407,6 +427,132 @@ func selectTest(dbName string, tbPrefix string, supTblName string) { checkErr(err, "rows next iteration error") } } +func drop_database_stmt(db *sql.DB, demodb string) { + st := time.Now().Nanosecond() + // drop test db + res, err := db.Exec("drop database if exists " + demodb) + checkErr(err, "drop database "+demodb) + + affectd, err := res.RowsAffected() + checkErr(err, "drop db, res.RowsAffected") + + et := time.Now().Nanosecond() + fmt.Printf("drop database result:\n %d row(s) affectd (%6.6fs)\n\n", affectd, (float32(et-st))/1e9) +} + +func create_database_stmt(db *sql.DB, demodb string) { + st := time.Now().Nanosecond() + // create database + //var stmt interface{} + stmt, err := db.Prepare("create database ?") + checkErr(err, "create db, db.Prepare") + + //var res driver.Result + res, err := stmt.Exec(demodb) + checkErr(err, "create db, stmt.Exec") + + //fmt.Printf("Query OK, %d row(s) affected()", res.RowsAffected()) + affectd, err := res.RowsAffected() + checkErr(err, "create db, res.RowsAffected") + + et := time.Now().Nanosecond() + fmt.Printf("create database result:\n %d row(s) affectd (%6.6fs)\n\n", affectd, (float32(et-st))/1e9) +} + +func use_database_stmt(db *sql.DB, demodb string) { + st := time.Now().Nanosecond() + // create database + //var stmt interface{} + stmt, err := db.Prepare("use " + demodb) + checkErr(err, "use db, db.Prepare") + + res, err := stmt.Exec() + checkErr(err, "use db, stmt.Exec") + + affectd, err := res.RowsAffected() + checkErr(err, "use db, res.RowsAffected") + + et := time.Now().Nanosecond() + fmt.Printf("use database result:\n %d row(s) affectd (%6.6fs)\n\n", affectd, (float32(et-st))/1e9) +} + +func create_table_stmt(db *sql.DB, demot string) { + st := time.Now().Nanosecond() + // create table + // (ts timestamp, id int, name binary(8), len tinyint, flag bool, notes binary(8), fv float, dv double) + stmt, err := db.Prepare("create table ? (? timestamp, ? int, ? binary(10), ? tinyint, ? bool, ? binary(8), ? float, ? double)") + checkErr(err, "create table db.Prepare") + + res, err := stmt.Exec(demot, "ts", "id", "name", "len", "flag", "notes", "fv", "dv") + checkErr(err, "create table stmt.Exec") + + affectd, err := res.RowsAffected() + checkErr(err, "create table res.RowsAffected") + + et := time.Now().Nanosecond() + fmt.Printf("create table result:\n %d row(s) affectd (%6.6fs)\n\n", affectd, (float32(et-st))/1e9) +} + +func insert_data_stmt(db *sql.DB, demot string) { + st := time.Now().Nanosecond() + // insert data into table + stmt, err := db.Prepare("insert into ? values(?, ?, ?, ?, ?, ?, ?, ?) (?, ?, ?, ?, ?, ?, ?, ?) (?, ?, ?, ?, ?, ?, ?, ?)") + checkErr(err, "insert db.Prepare") + + res, err := stmt.Exec(demot, "now", 1000, "'haidian'", 6, true, "'AI world'", 6987.654, 321.987, + "now+1s", 1001, "'changyang'", 7, false, "'DeepMode'", 12356.456, 128634.456, + "now+2s", 1002, "'chuangping'", 8, true, "'database'", 3879.456, 65433478.456) + checkErr(err, "insert data, stmt.Exec") + + affectd, err := res.RowsAffected() + checkErr(err, "res.RowsAffected") + + et := time.Now().Nanosecond() + fmt.Printf("insert data result:\n %d row(s) affectd (%6.6fs)\n\n", affectd, (float32(et-st))/1e9) +} + +func select_data_stmt(db *sql.DB, demot string) { + st := time.Now().Nanosecond() + + stmt, err := db.Prepare("select ?, ?, ?, ?, ?, ?, ?, ? from ?") // go binary mode + checkErr(err, "db.Prepare") + + rows, err := stmt.Query("ts", "id", "name", "len", "flag", "notes", "fv", "dv", demot) + checkErr(err, "stmt.Query") + + fmt.Printf("%10s%s%8s %5s %8s%s %s %10s%s %7s%s %8s%s %11s%s %14s%s\n", " ", "ts", " ", "id", " ", "name", " ", "len", " ", "flag", " ", "notes", " ", "fv", " ", " ", "dv") + var affectd int + for rows.Next() { + var ts string + var name string + var id int + var len int8 + var flag bool + var notes string + var fv float32 + var dv float64 + + err = rows.Scan(&ts, &id, &name, &len, &flag, ¬es, &fv, &dv) + //fmt.Println("start scan fields from row.rs, &fv:", &fv) + //err = rows.Scan(&fv) + checkErr(err, "rows.Scan") + + fmt.Printf("%s\t", ts) + fmt.Printf("%d\t", id) + fmt.Printf("%10s\t", name) + fmt.Printf("%d\t", len) + fmt.Printf("%t\t", flag) + fmt.Printf("%s\t", notes) + fmt.Printf("%06.3f\t", fv) + fmt.Printf("%09.6f\n", dv) + + affectd++ + + } + + et := time.Now().Nanosecond() + fmt.Printf("insert data result:\n %d row(s) affectd (%6.6fs)\n\n", affectd, (float32(et-st))/1e9) +} func checkErr(err error, prompt string) { if err != nil { fmt.Printf("%s\n", prompt) diff --git a/tests/perftest-scripts/perftest-query.sh b/tests/perftest-scripts/perftest-query.sh index 0325f552b1..9a16084683 100755 --- a/tests/perftest-scripts/perftest-query.sh +++ b/tests/perftest-scripts/perftest-query.sh @@ -64,7 +64,7 @@ function runQueryPerfTest { [ -f $PERFORMANCE_TEST_REPORT ] && rm $PERFORMANCE_TEST_REPORT nohup $WORK_DIR/TDengine/debug/build/bin/taosd -c /etc/taosperf/ > /dev/null 2>&1 & echoInfo "Wait TDengine to start" - sleep 120 + sleep 300 echoInfo "Run Performance Test" cd $WORK_DIR/TDengine/tests/pytest diff --git a/tests/pytest/alter/alterTabAddTagWithNULL.py b/tests/pytest/alter/alterTabAddTagWithNULL.py new file mode 100644 index 0000000000..52bdc0fe75 --- /dev/null +++ b/tests/pytest/alter/alterTabAddTagWithNULL.py @@ -0,0 +1,85 @@ +################################################################### +# 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(f"start to execute {__file__}") + tdSql.init(conn.cursor(), logSql) + + 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 table stbtag (ts timestamp, c1 int) TAGS(t1 int)") + tdSql.execute("create table tag1 using stbtag tags(1)") + + tdLog.printNoPrefix("==========step2:alter stb add tag create new chiltable") + tdSql.execute("alter table stbtag add tag t2 int") + tdSql.execute("alter table stbtag add tag t3 tinyint") + tdSql.execute("alter table stbtag add tag t4 smallint ") + tdSql.execute("alter table stbtag add tag t5 bigint") + tdSql.execute("alter table stbtag add tag t6 float ") + tdSql.execute("alter table stbtag add tag t7 double ") + tdSql.execute("alter table stbtag add tag t8 bool ") + tdSql.execute("alter table stbtag add tag t9 binary(10) ") + tdSql.execute("alter table stbtag add tag t10 nchar(10)") + + tdSql.execute("create table tag2 using stbtag tags(2, 22, 23, 24, 25, 26.1, 27.1, 1, 'binary9', 'nchar10')") + tdSql.query( "select tbname, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10 from stbtag" ) + tdSql.checkData(1, 0, "tag2") + tdSql.checkData(1, 1, 2) + tdSql.checkData(1, 2, 22) + tdSql.checkData(1, 3, 23) + tdSql.checkData(1, 4, 24) + tdSql.checkData(1, 5, 25) + tdSql.checkData(1, 6, 26.1) + tdSql.checkData(1, 7, 27.1) + tdSql.checkData(1, 8, 1) + tdSql.checkData(1, 9, "binary9") + tdSql.checkData(1, 10, "nchar10") + + tdLog.printNoPrefix("==========step3:alter stb drop tag create new chiltable") + tdSql.execute("alter table stbtag drop tag t2 ") + tdSql.execute("alter table stbtag drop tag t3 ") + tdSql.execute("alter table stbtag drop tag t4 ") + tdSql.execute("alter table stbtag drop tag t5 ") + tdSql.execute("alter table stbtag drop tag t6 ") + tdSql.execute("alter table stbtag drop tag t7 ") + tdSql.execute("alter table stbtag drop tag t8 ") + tdSql.execute("alter table stbtag drop tag t9 ") + tdSql.execute("alter table stbtag drop tag t10 ") + + tdSql.execute("create table tag3 using stbtag tags(3)") + tdSql.query("select * from stbtag where tbname like 'tag3' ") + tdSql.checkCols(3) + tdSql.query("select tbname, t1 from stbtag where tbname like 'tag3' ") + tdSql.checkData(0, 1, 3) + + + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) \ No newline at end of file diff --git a/tests/pytest/alter/alterTimestampColDataProcess.py b/tests/pytest/alter/alterTimestampColDataProcess.py new file mode 100644 index 0000000000..b235a8bf4c --- /dev/null +++ b/tests/pytest/alter/alterTimestampColDataProcess.py @@ -0,0 +1,73 @@ +################################################################### +# 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(f"start to execute {__file__}") + tdSql.init(conn.cursor(), logSql) + + 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") + # timestamp list: + # 0 -> "1970-01-01 08:00:00" | -28800000 -> "1970-01-01 00:00:00" | -946800000000 -> "1940-01-01 00:00:00" + # -631180800000 -> "1950-01-01 00:00:00" + ts1 = 0 + ts2 = -28800000 + ts3 = -946800000000 + ts4 = "1950-01-01 00:00:00" + tdSql.execute( + "create table stb2ts (ts timestamp, ts1 timestamp, ts2 timestamp, c1 int, ts3 timestamp) TAGS(t1 int)" + ) + tdSql.execute("create table t2ts1 using stb2ts tags(1)") + + tdSql.execute(f"insert into t2ts1 values ({ts1}, {ts1}, {ts1}, 1, {ts1})") + tdSql.execute(f"insert into t2ts1 values ({ts2}, {ts2}, {ts2}, 2, {ts2})") + tdSql.execute(f"insert into t2ts1 values ({ts3}, {ts3}, {ts3}, 4, {ts3})") + tdSql.execute(f"insert into t2ts1 values ('{ts4}', '{ts4}', '{ts4}', 3, '{ts4}')") + + tdLog.printNoPrefix("==========step2:check inserted data") + tdSql.query("select * from stb2ts where ts1=0 and ts2='1970-01-01 08:00:00' ") + tdSql.checkRows(1) + tdSql.checkData(0, 4,'1970-01-01 08:00:00') + + tdSql.query("select * from stb2ts where ts1=-28800000 and ts2='1970-01-01 00:00:00' ") + tdSql.checkRows(1) + tdSql.checkData(0, 4, '1970-01-01 00:00:00') + + tdSql.query("select * from stb2ts where ts1=-946800000000 and ts2='1940-01-01 00:00:00' ") + tdSql.checkRows(1) + tdSql.checkData(0, 4, '1940-01-01 00:00:00') + + tdSql.query("select * from stb2ts where ts1=-631180800000 and ts2='1950-01-01 00:00:00' ") + tdSql.checkRows(1) + tdSql.checkData(0, 4, '1950-01-01 00:00:00') + + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) \ No newline at end of file diff --git a/tests/pytest/fulltest.sh b/tests/pytest/fulltest.sh index e7e0586636..86fbe2860d 100755 --- a/tests/pytest/fulltest.sh +++ b/tests/pytest/fulltest.sh @@ -219,6 +219,10 @@ 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 +python3 ./test.py -f query/querySecondtscolumnTowherenow.py +python3 ./test.py -f query/queryFilterTswithDateUnit.py + + #stream python3 ./test.py -f stream/metric_1.py @@ -234,6 +238,8 @@ python3 ./test.py -f stream/table_n.py #alter table python3 ./test.py -f alter/alter_table_crash.py +python3 ./test.py -f alter/alterTabAddTagWithNULL.py +python3 ./test.py -f alter/alterTimestampColDataProcess.py # client python3 ./test.py -f client/client.py @@ -303,6 +309,11 @@ python3 ./test.py -f insert/unsignedSmallint.py python3 ./test.py -f insert/unsignedTinyint.py python3 ./test.py -f query/filterAllUnsignedIntTypes.py +python3 ./test.py -f tag_lite/unsignedInt.py +python3 ./test.py -f tag_lite/unsignedBigint.py +python3 ./test.py -f tag_lite/unsignedSmallint.py +python3 ./test.py -f tag_lite/unsignedTinyint.py + python3 ./test.py -f functions/function_percentile2.py python3 ./test.py -f insert/boundary2.py python3 ./test.py -f alter/alter_debugFlag.py diff --git a/tests/pytest/query/queryFilterTswithDateUnit.py b/tests/pytest/query/queryFilterTswithDateUnit.py new file mode 100644 index 0000000000..90e30c5156 --- /dev/null +++ b/tests/pytest/query/queryFilterTswithDateUnit.py @@ -0,0 +1,166 @@ +################################################################### +# 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(f"start to execute {__file__}") + tdSql.init(conn.cursor(), logSql) + + def insertnow(self, tsp1, tsp2, tsp3): + + tdSql.execute( + "create table stbts (ts timestamp, ts1 timestamp, c1 int, ts2 timestamp) TAGS(t1 int)" + ) + tdSql.execute("create table tts1 using stbts tags(1)") + + tdSql.execute("insert into tts1 values (now+1d, now+1d, 6, now+1d)") + tdSql.execute("insert into tts1 values (now, now, 5, now)") + tdSql.execute("insert into tts1 values (now-1d, now-1d, 4, now-1d)") + tdSql.execute(f"insert into tts1 values ({tsp1}, {tsp1}, 3, {tsp1})") + tdSql.execute(f"insert into tts1 values ({tsp2}, {tsp2}, 2, {tsp2})") + tdSql.execute(f"insert into tts1 values ({tsp3}, {tsp3}, 1, {tsp3})") + + + def querynow(self): + + tdLog.printNoPrefix("==========step query: execute query operation") + time.sleep(1) + + cols = ["ts", "ts1", "ts2"] + + for col in cols: + tdSql.error(f" select * from tts1 where {col} = 1d ") + tdSql.error(f" select * from tts1 where {col} < 1d ") + tdSql.error(f" select * from tts1 where {col} > 1d ") + tdSql.error(f" select * from tts1 where {col} >= 1d ") + tdSql.error(f" select * from tts1 where {col} <= 1d ") + tdSql.error(f" select * from tts1 where {col} <> 1d ") + + tdSql.error(f" select * from tts1 where {col} = 1m ") + tdSql.error(f" select * from tts1 where {col} < 1m ") + tdSql.error(f" select * from tts1 where {col} > 1m ") + tdSql.error(f" select * from tts1 where {col} >= 1m ") + tdSql.error(f" select * from tts1 where {col} <= 1m ") + tdSql.error(f" select * from tts1 where {col} <> 1m ") + + tdSql.error(f" select * from tts1 where {col} = 1s ") + tdSql.error(f" select * from tts1 where {col} < 1s ") + tdSql.error(f" select * from tts1 where {col} > 1s ") + tdSql.error(f" select * from tts1 where {col} >= 1s ") + tdSql.error(f" select * from tts1 where {col} <= 1s ") + tdSql.error(f" select * from tts1 where {col} <> 1s ") + + tdSql.error(f" select * from tts1 where {col} = 1a ") + tdSql.error(f" select * from tts1 where {col} < 1a ") + tdSql.error(f" select * from tts1 where {col} > 1a ") + tdSql.error(f" select * from tts1 where {col} >= 1a ") + tdSql.error(f" select * from tts1 where {col} <= 1a ") + tdSql.error(f" select * from tts1 where {col} <> 1a ") + + tdSql.error(f" select * from tts1 where {col} = 1h ") + tdSql.error(f" select * from tts1 where {col} < 1h ") + tdSql.error(f" select * from tts1 where {col} > 1h ") + tdSql.error(f" select * from tts1 where {col} >= 1h ") + tdSql.error(f" select * from tts1 where {col} <= 1h ") + tdSql.error(f" select * from tts1 where {col} <> 1h ") + + tdSql.error(f" select * from tts1 where {col} = 1w ") + tdSql.error(f" select * from tts1 where {col} < 1w ") + tdSql.error(f" select * from tts1 where {col} > 1w ") + tdSql.error(f" select * from tts1 where {col} >= 1w ") + tdSql.error(f" select * from tts1 where {col} <= 1w ") + tdSql.error(f" select * from tts1 where {col} <> 1w ") + + tdSql.error(f" select * from tts1 where {col} = 1u ") + tdSql.error(f" select * from tts1 where {col} < 1u ") + tdSql.error(f" select * from tts1 where {col} > 1u ") + tdSql.error(f" select * from tts1 where {col} >= 1u ") + tdSql.error(f" select * from tts1 where {col} <= 1u ") + tdSql.error(f" select * from tts1 where {col} <> 1u ") + + tdSql.error(f" select * from tts1 where {col} = 0d ") + tdSql.error(f" select * from tts1 where {col} < 0s ") + tdSql.error(f" select * from tts1 where {col} > 0a ") + tdSql.error(f" select * from tts1 where {col} >= 0m ") + tdSql.error(f" select * from tts1 where {col} <= 0h ") + tdSql.error(f" select * from tts1 where {col} <> 0u ") + tdSql.error(f" select * from tts1 where {col} <> 0w ") + + tdSql.error(f" select * from tts1 where {col} = 1m+1h ") + tdSql.error(f" select * from tts1 where {col} < 1w-1d ") + tdSql.error(f" select * from tts1 where {col} > 0a/1u ") + tdSql.error(f" select * from tts1 where {col} >= 1d/0s ") + tdSql.error(f" select * from tts1 where {col} <= 1s*1a ") + tdSql.error(f" select * from tts1 where {col} <> 0w/0d ") + + tdSql.error(f" select * from tts1 where {col} = 1m+1h ") + tdSql.error(f" select * from tts1 where {col} < 1w-1d ") + tdSql.error(f" select * from tts1 where {col} > 0a/1u ") + tdSql.error(f" select * from tts1 where {col} >= 1d/0s ") + tdSql.error(f" select * from tts1 where {col} <= 1s*1a ") + tdSql.error(f" select * from tts1 where {col} <> 0w/0d ") + + tdSql.error(f" select * from tts1 where {col} = 1u+1 ") + tdSql.error(f" select * from tts1 where {col} < 1a-1 ") + tdSql.error(f" select * from tts1 where {col} > 1s*1 ") + tdSql.error(f" select * from tts1 where {col} >= 1m/1 ") + tdSql.error(f" select * from tts1 where {col} <= 1h/0 ") + tdSql.error(f" select * from tts1 where {col} <> 0/1d ") + tdSql.error(f" select * from tts1 where {col} <> 1w+'2010-01-01 00:00:00' ") + + + def run(self): + tdSql.execute("drop database if exists dbms") + tdSql.execute("drop database if exists dbus") + + # timestamp list: + # 0 -> "1970-01-01 08:00:00" | -28800000 -> "1970-01-01 00:00:00" | -946800000000 -> "1940-01-01 00:00:00" + # -631180800000 -> "1950-01-01 00:00:00" + + tdLog.printNoPrefix("==========step1:create table precision ms && insert data && query") + # create databases precision is ms + tdSql.execute("create database if not exists dbms keep 36500") + tdSql.execute("use dbms") + tsp1 = 0 + tsp2 = -28800000 + tsp3 = -946800000000 + self.insertnow(tsp1,tsp2,tsp3) + self.querynow() + + tdLog.printNoPrefix("==========step2:create table precision us && insert data && query") + # create databases precision is us + tdSql.execute("create database if not exists dbus keep 36500 precision 'us' ") + tdSql.execute("use dbus") + tsp2 = -28800000 * 1000 + tsp3 = -946800000000 * 1000 + self.insertnow(tsp1,tsp2,tsp3) + self.querynow() + + + + + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) \ No newline at end of file diff --git a/tests/pytest/query/queryNormal.py b/tests/pytest/query/queryNormal.py index 4e3f9dd3bd..52e49a57c6 100644 --- a/tests/pytest/query/queryNormal.py +++ b/tests/pytest/query/queryNormal.py @@ -16,7 +16,7 @@ import taos from util.log import * from util.cases import * from util.sql import * - +from util.dnodes import * class TDTestCase: def init(self, conn, logSql): @@ -122,6 +122,32 @@ class TDTestCase: tdSql.query("SELECT server_status()") tdSql.checkRows(1) + # https://jira.taosdata.com:18080/browse/TD-3800 + tdSql.execute("create table m1(ts timestamp, k int) tags(a int)") + tdSql.execute("create table tm0 using m1 tags(1)") + tdSql.execute("create table tm1 using m1 tags(2)") + tdSql.execute("insert into tm0 values('2020-3-1 1:1:1', 112)") + tdSql.execute("insert into tm1 values('2020-1-1 1:1:1', 1)('2020-3-1 0:1:1', 421)") + + tdSql.query("select last(*) from m1 group by tbname") + tdSql.checkData(0, 0, "2020-03-01 01:01:01") + tdSql.checkData(0, 1, 112) + tdSql.checkData(0, 2, "tm0") + tdSql.checkData(1, 0, "2020-03-01 00:01:01") + tdSql.checkData(1, 1, 421) + tdSql.checkData(1, 2, "tm1") + + tdDnodes.stop(1) + tdDnodes.start(1) + + tdSql.query("select last(*) from m1 group by tbname") + tdSql.checkData(0, 0, "2020-03-01 01:01:01") + tdSql.checkData(0, 1, 112) + tdSql.checkData(0, 2, "tm0") + tdSql.checkData(1, 0, "2020-03-01 00:01:01") + tdSql.checkData(1, 1, 421) + tdSql.checkData(1, 2, "tm1") + def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) diff --git a/tests/pytest/query/querySecondtscolumnTowherenow.py b/tests/pytest/query/querySecondtscolumnTowherenow.py new file mode 100644 index 0000000000..dfc18d99a6 --- /dev/null +++ b/tests/pytest/query/querySecondtscolumnTowherenow.py @@ -0,0 +1,131 @@ +################################################################### +# 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(f"start to execute {__file__}") + tdSql.init(conn.cursor(), logSql) + + 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") + # timestamp list: + # 0->"1970-01-01 08:00:00" | -28800000->"1970-01-01 00:00:00" | -946800000000->"1940-01-01 00:00:00" + ts1 = 0 + ts2 = -28800000 + ts3 = -946800000000 + tdSql.execute( + "create table stb2ts (ts timestamp, ts1 timestamp, ts2 timestamp, c1 int, ts3 timestamp) TAGS(t1 int)" + ) + tdSql.execute("create table t2ts1 using stb2ts tags(1)") + + tdSql.execute("insert into t2ts1 values (now, now, now, 1, now)") + tdSql.execute("insert into t2ts1 values (now-1m, now-1m, now-1m, 1, now-1m)") + tdSql.execute(f"insert into t2ts1 values ({ts1}, {ts1}, {ts1}, 1, {ts1})") + # tdSql.execute(f"insert into t2ts1 values ({ts2}, {ts2}, {ts2}, 1, {ts2})") + # tdSql.execute(f"insert into t2ts1 values ({ts3}, {ts3}, {ts3}, 1, {ts3})") + + tdLog.printNoPrefix("==========step2:query") + time.sleep(1) + # query primary key timestamp column + tdSql.execute("select * from t2ts1 where ts < now") + ts_len1 = len(tdSql.cursor.fetchall()) + tdSql.execute("select * from t2ts1 where ts <= now") + ts_len2 = len(tdSql.cursor.fetchall()) + tdSql.execute("select * from t2ts1 where ts > now") + ts_len3 = len(tdSql.cursor.fetchall()) + tdSql.execute("select * from t2ts1 where ts >= now") + ts_len4 = len(tdSql.cursor.fetchall()) + tdSql.execute("select * from t2ts1 where ts = now") + ts_len5 = len(tdSql.cursor.fetchall()) + tdSql.execute("select * from t2ts1 where ts <> now") + ts_len6 = len(tdSql.cursor.fetchall()) + tdSql.execute("select * from t2ts1 where ts between 0 and now") + ts_len7 = len(tdSql.cursor.fetchall()) + tdSql.execute("select * from t2ts1 where ts between now and now+100d") + ts_len8 = len(tdSql.cursor.fetchall()) + + # query noemal timestamp column + tdSql.query("select * from t2ts1 where ts1 < now") + tdSql.checkRows(ts_len1) + tdSql.query("select * from t2ts1 where ts2 < now") + tdSql.checkRows(ts_len1) + tdSql.query("select * from t2ts1 where ts3 < now") + tdSql.checkRows(ts_len1) + + tdSql.query("select * from t2ts1 where ts1 <= now") + tdSql.checkRows(ts_len2) + tdSql.query("select * from t2ts1 where ts2 <= now") + tdSql.checkRows(ts_len2) + tdSql.query("select * from t2ts1 where ts3 <= now") + tdSql.checkRows(ts_len2) + + tdSql.query("select * from t2ts1 where ts1 > now") + tdSql.checkRows(ts_len3) + tdSql.query("select * from t2ts1 where ts2 > now") + tdSql.checkRows(ts_len3) + tdSql.query("select * from t2ts1 where ts3 > now") + tdSql.checkRows(ts_len3) + + tdSql.query("select * from t2ts1 where ts1 >= now") + tdSql.checkRows(ts_len4) + tdSql.query("select * from t2ts1 where ts2 >= now") + tdSql.checkRows(ts_len4) + tdSql.query("select * from t2ts1 where ts3 >= now") + tdSql.checkRows(ts_len4) + + tdSql.query("select * from t2ts1 where ts1 = now") + tdSql.checkRows(ts_len5) + tdSql.query("select * from t2ts1 where ts2 = now") + tdSql.checkRows(ts_len5) + tdSql.query("select * from t2ts1 where ts2 = now") + tdSql.checkRows(ts_len5) + + tdSql.query("select * from t2ts1 where ts1 <> now") + tdSql.checkRows(ts_len6) + tdSql.query("select * from t2ts1 where ts2 <> now") + tdSql.checkRows(ts_len6) + tdSql.query("select * from t2ts1 where ts3 <> now") + tdSql.checkRows(ts_len6) + + tdSql.query("select * from t2ts1 where ts1 between 0 and now") + tdSql.checkRows(ts_len7) + tdSql.query("select * from t2ts1 where ts2 between 0 and now") + tdSql.checkRows(ts_len7) + tdSql.query("select * from t2ts1 where ts3 between 0 and now") + tdSql.checkRows(ts_len7) + + tdSql.query("select * from t2ts1 where ts1 between now and now+100d") + tdSql.checkRows(ts_len8) + tdSql.query("select * from t2ts1 where ts2 between now and now+100d") + tdSql.checkRows(ts_len8) + tdSql.query("select * from t2ts1 where ts3 between now and now+100d") + tdSql.checkRows(ts_len8) + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) \ No newline at end of file diff --git a/tests/pytest/stream/new.py b/tests/pytest/stream/new.py index 70f300e937..4a0e47c01a 100644 --- a/tests/pytest/stream/new.py +++ b/tests/pytest/stream/new.py @@ -42,7 +42,7 @@ class TDTestCase: tdLog.info("=============== step3") start = time.time() - tdSql.waitedQuery("select * from st", 1, 120) + tdSql.waitedQuery("select * from st", 1, 180) delay = int(time.time() - start) + 80 v = tdSql.getData(0, 3) if v >= 51: diff --git a/tests/pytest/stream/stream2.py b/tests/pytest/stream/stream2.py index d71742048a..9b4eb8725c 100644 --- a/tests/pytest/stream/stream2.py +++ b/tests/pytest/stream/stream2.py @@ -88,6 +88,8 @@ class TDTestCase: except Exception as e: tdLog.info(repr(e)) + + time.sleep(5) tdSql.query("show streams") tdSql.checkRows(1) tdSql.checkData(0, 2, 's0') @@ -146,6 +148,7 @@ class TDTestCase: except Exception as e: tdLog.info(repr(e)) + time.sleep(5) tdSql.query("show streams") tdSql.checkRows(2) tdSql.checkData(0, 2, 's1') diff --git a/tests/pytest/stream/sys.py b/tests/pytest/stream/sys.py index a73e7043e8..c9a3fccfe6 100644 --- a/tests/pytest/stream/sys.py +++ b/tests/pytest/stream/sys.py @@ -47,7 +47,7 @@ class TDTestCase: "select * from iostrm", ] for sql in sqls: - (rows, _) = tdSql.waitedQuery(sql, 1, 120) + (rows, _) = tdSql.waitedQuery(sql, 1, 240) if rows < 1: tdLog.exit("failed: sql:%s, expect at least one row" % sql) diff --git a/tests/pytest/tools/taosdemoTestTblAlt.py b/tests/pytest/tools/taosdemoTestTblAlt.py index bb367817cf..9aa131624e 100644 --- a/tests/pytest/tools/taosdemoTestTblAlt.py +++ b/tests/pytest/tools/taosdemoTestTblAlt.py @@ -100,8 +100,8 @@ class TDTestCase: print("alter table test.meters add column col10 int") tdSql.execute("alter table test.meters add column col10 int") - 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)") + print("insert into test.t9 values (now, 1, 2, 3, 4, 0)") + tdSql.execute("insert into test.t9 values (now, 1, 2, 3, 4, 0)") def run(self): tdSql.prepare() diff --git a/tests/pytest/util/sql.py b/tests/pytest/util/sql.py index 16931cca33..ba9cb4d53d 100644 --- a/tests/pytest/util/sql.py +++ b/tests/pytest/util/sql.py @@ -87,6 +87,7 @@ class TDSql: self.queryResult = self.cursor.fetchall() self.queryRows = len(self.queryResult) self.queryCols = len(self.cursor.description) + tdLog.info("sql: %s, try to retrieve %d rows,get %d rows" % (sql, expectRows, self.queryRows)) if self.queryRows >= expectRows: return (self.queryRows, i) time.sleep(1) @@ -105,6 +106,14 @@ class TDSql: args = (caller.filename, caller.lineno, self.sql, self.queryRows, expectRows) tdLog.exit("%s(%d) failed: sql:%s, queryRows:%d != expect:%d" % args) + def checkCols(self, expectCols): + if self.queryCols == expectCols: + tdLog.info("sql:%s, queryCols:%d == expect:%d" % (self.sql, self.queryCols, expectCols)) + else: + caller = inspect.getframeinfo(inspect.stack()[1][0]) + args = (caller.filename, caller.lineno, self.sql, self.queryCols, expectCols) + tdLog.exit("%s(%d) failed: sql:%s, queryCols:%d != expect:%d" % args) + def checkRowCol(self, row, col): caller = inspect.getframeinfo(inspect.stack()[2][0]) if row < 0: diff --git a/tests/script/general/parser/alter1.sim b/tests/script/general/parser/alter1.sim index a52202fc1a..3b6b0d9465 100644 --- a/tests/script/general/parser/alter1.sim +++ b/tests/script/general/parser/alter1.sim @@ -129,8 +129,8 @@ if $rows != 3 then return -1 endi -sql drop database $db -sql show databases -if $rows != 0 then - return -1 -endi +#sql drop database $db +#sql show databases +#if $rows != 0 then +# return -1 +#endi diff --git a/tests/script/general/parser/col_arithmetic_query.sim b/tests/script/general/parser/col_arithmetic_query.sim index 2c56c6445f..191f56fcfb 100644 --- a/tests/script/general/parser/col_arithmetic_query.sim +++ b/tests/script/general/parser/col_arithmetic_query.sim @@ -414,6 +414,7 @@ if $rows != 1 then endi if $data00 != 0.204545455 then + print expect 0.204545455, actual: $data00 return -1 endi diff --git a/tests/script/general/parser/first_last_query.sim b/tests/script/general/parser/first_last_query.sim index 2d08759f3f..2dff1dd51b 100644 --- a/tests/script/general/parser/first_last_query.sim +++ b/tests/script/general/parser/first_last_query.sim @@ -269,4 +269,50 @@ if $data14 != @test2@ then return -1 endi -sql drop table stest \ No newline at end of file +sql drop table stest + +print ===================>td-3779 +sql create table m1(ts timestamp, k int) tags(a int); +sql create table tm0 using m1 tags(1); +sql create table tm1 using m1 tags(2); +sql insert into tm0 values('2020-3-1 1:1:1', 112); +sql insert into tm1 values('2020-1-1 1:1:1', 1)('2020-3-1 0:1:1', 421); +system sh/exec.sh -n dnode1 -s stop -x SIGINT +sleep 1000 + +system sh/exec.sh -n dnode1 -s start +print ================== server restart completed +sleep 1000 +sql connect +sql use first_db0; + +sql select last(*) from m1 group by tbname; +if $rows != 2 then + return -1 +endi + +if $data00 != @20-03-01 01:01:01.000@ then + return -1 +endi + +if $data01 != 112 then + return -1 +endi + +if $data02 != @tm0@ then + return -1 +endi + +if $data10 != @20-03-01 00:01:01.000@ then + return -1 +endi + +if $data11 != 421 then + return -1 +endi + +if $data12 != @tm1@ then + return -1 +endi + +sql drop table m1 \ No newline at end of file diff --git a/tests/script/general/parser/having.sim b/tests/script/general/parser/having.sim index 2e95664d31..ddafdd7329 100644 --- a/tests/script/general/parser/having.sim +++ b/tests/script/general/parser/having.sim @@ -141,9 +141,7 @@ if $data30 != 4 then 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; diff --git a/tests/script/general/parser/having_child.sim b/tests/script/general/parser/having_child.sim index 1f29a63b91..a38db3fe44 100644 --- a/tests/script/general/parser/having_child.sim +++ b/tests/script/general/parser/having_child.sim @@ -1,6 +1,6 @@ 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 walLevel -v 1 system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 2 system sh/exec.sh -n dnode1 -s start @@ -1460,8 +1460,7 @@ 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 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; diff --git a/tests/script/general/parser/join_multivnode.sim b/tests/script/general/parser/join_multivnode.sim index 2322496a94..c72b2c5b3e 100644 --- a/tests/script/general/parser/join_multivnode.sim +++ b/tests/script/general/parser/join_multivnode.sim @@ -142,7 +142,7 @@ if $rows != 300 then endi if $data00 != @70-01-01 08:01:40.990@ then - print expect 0, actual: $data00 + print expect 70-01-01 08:01:40.990, actual: $data00 return -1 endi diff --git a/tests/script/general/parser/limit2_query.sim b/tests/script/general/parser/limit2_query.sim index 9fe287960d..c35fd369ca 100644 --- a/tests/script/general/parser/limit2_query.sim +++ b/tests/script/general/parser/limit2_query.sim @@ -148,6 +148,9 @@ if $rows != 8200 then return -1 endi +sql select max(c1) from lm2_tb0 where ts >= 1537146000000 and ts <= 1543145400000 interval(5m) fill(value, -1000) limit 100000; + + sql select max(c1) from lm2_tb0 where ts >= 1537146000000 and ts <= 1543145400000 interval(5m) fill(value, -1000, -2) limit 10 offset 8190; if $rows != 10 then return -1 diff --git a/tests/script/general/parser/select_with_tags.sim b/tests/script/general/parser/select_with_tags.sim index da8e876577..7e5f31f759 100644 --- a/tests/script/general/parser/select_with_tags.sim +++ b/tests/script/general/parser/select_with_tags.sim @@ -26,7 +26,7 @@ sql drop database if exists $db -x step1 step1: sql create database if not exists $db keep 36500 sql use $db -sql create table $mt (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 int, t2 binary(12)) +sql create table $mt (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 int, t2 binary(12), t3 int) $i = 0 $j = 1 @@ -36,7 +36,7 @@ while $i < $tbNum $tg2 = ' . abc $tg2 = $tg2 . $i $tg2 = $tg2 . ' - sql create table $tb using $mt tags( $i , $tg2 ) + sql create table $tb using $mt tags( $i , $tg2 , 123 ) $x = 0 while $x < $rowNum @@ -85,6 +85,7 @@ if $data00 != @70-01-01 08:01:40.000@ then endi if $data01 != @select_tags_tb0@ then + print expect: select_tags_tb0, actual: $data01 return -1 endi @@ -160,7 +161,7 @@ if $data03 != @abc15@ then endi sql select top(c6, 3) from select_tags_mt0 interval(10a) -sql select top(c3,10) from select_tags_mt0 interval(10a) group by tbname +sql select top(c3,10) from select_tags_mt0 interval(10a) group by tbname,t1,t2 sql select top(c6, 3) from select_tags_mt0 interval(10a) group by tbname; sql select top(c6, 10) from select_tags_mt0 interval(10a); @@ -813,7 +814,46 @@ if $row != 1 then return -1 endi -print ======= selectivity + tags+ group by + tags + filter + interval + join=========== +print TODO ======= selectivity + tags+ group by + tags + filter + interval + join=========== + +print ==========================mix tag columns and group by columns====================== +sql select top(c1, 100), tbname from select_tags_mt0 where tbname in ('select_tags_tb0', 'select_tags_tb1') group by t3 +if $rows != 100 then + return -1 +endi + +if $data00 != @70-01-01 08:01:40.094@ then + print expect: 70-01-01 08:01:40.094, actual: $data00 + return -1 +endi + +if $data01 != 94 then + return -1 +endi + +if $data02 != @select_tags_tb0@ then + return -1 +endi + +if $data03 != 123 then + return -1 +endi + +if $data10 != @70-01-01 08:01:40.095@ then + return -1 +endi + +if $data11 != 95 then + return -1 +endi + +if $data12 != @select_tags_tb0@ then + return -1 +endi + +if $data13 != 123 then + return -1 +endi print ======error sql============================================= diff --git a/tests/script/general/parser/subInfrom.sim b/tests/script/general/parser/subInfrom.sim new file mode 100644 index 0000000000..e47831ee87 --- /dev/null +++ b/tests/script/general/parser/subInfrom.sim @@ -0,0 +1,147 @@ +system sh/stop_dnodes.sh + +system sh/deploy.sh -n dnode1 -i 1 +system sh/cfg.sh -n dnode1 -c walLevel -v 1 +system sh/exec.sh -n dnode1 -s start +sleep 100 +sql connect +sleep 100 + +print ========== sub_in_from.sim +$i = 0 + +$dbPrefix = subdb +$tbPrefix = sub_tb +$stbPrefix = sub_stb +$tbNum = 10 +$rowNum = 1000 +$totalNum = $tbNum * $rowNum +$loops = 200000 +$log = 10000 +$ts0 = 1537146000000 +$delta = 600000 +$i = 0 +$db = $dbPrefix . $i +$stb = $stbPrefix . $i + +sql drop database $db -x step1 +step1: +sql create database $db cache 16 maxrows 4096 keep 36500 +print ====== create tables +sql use $db +sql create table $stb (ts timestamp, c1 int, c2 bigint, c3 float, c4 double, c5 smallint, c6 tinyint, c7 bool, c8 binary(10), c9 nchar(10)) tags(t1 int) + +$i = 0 +$ts = $ts0 +$halfNum = $tbNum / 2 +while $i < $halfNum + $tbId = $i + $halfNum + $tb = $tbPrefix . $i + $tb1 = $tbPrefix . $tbId + sql create table $tb using $stb tags( $i ) + sql create table $tb1 using $stb tags( $tbId ) + + $x = 0 + while $x < $rowNum + $xs = $x * $delta + $ts = $ts0 + $xs + $c = $x / 10 + $c = $c * 10 + $c = $x - $c + $binary = 'binary . $c + $binary = $binary . ' + $nchar = 'nchar . $c + $nchar = $nchar . ' + sql insert into $tb values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar ) + sql insert into $tb1 values ( $ts , $c , NULL , $c , NULL , $c , $c , true, $binary , $nchar ) + $x = $x + 1 + endw + + $i = $i + 1 +endw +print ====== tables created + +sql_error select count(*) from (select count(*) from abc.sub_stb0) +sql_error select val + 20 from (select count(*) from sub_stb0 interval(10h)) +sql_error select abc+20 from (select count(*) from sub_stb0 interval(1s)) + +sql select count(*) from (select count(*) from sub_stb0 interval(10h)) +if $rows != 1 then + return -1 +endi + +if $data00 != 18 then + print expect 18, actual: $data00 + return -1 +endi + +sql select ts from (select count(*) from sub_stb0 interval(10h)) +if $rows != 18 then + return -1 +endi + +if $data00 != @18-09-17 04:00:00.000@ then + return -1 +endi + +if $data01 != @18-09-17 14:00:00.000@ then + return -1 +endi + +sql select val + 20, val from (select count(*) as val from sub_stb0 interval(10h)) +if $rows != 18 then + return -1 +endi + +if $data00 != 320.000000 then + return -1 +endi + +if $data01 != 300 then + return -1 +endi + +if $data10 != 620 then + return -1 +endi + +if $data11 != 600 then + return -1 +endi + +if $data20 != 620 then + return -1 +endi + +if $data21 != 600 then + return -1 +endi + +sql select max(val), min(val), max(val) - min(val) from (select count(*) val from sub_stb0 interval(10h)) +if $rows != 1 then + return -1 +endi + +if $data00 != 600 then + return -1 +endi + +if $data01 != 100 then + return -1 +endi + +if $data02 != 500.000000 then + return -1 +endi + +sql select first(ts,val),last(ts,val) from (select count(*) val from sub_stb0 interval(10h)) +sql select top(val, 5) from (select count(*) val from sub_stb0 interval(10h)) +sql select diff(val) from (select count(*) val from sub_stb0 interval(10h)) +sql select apercentile(val, 50) from (select count(*) val from sub_stb0 interval(10h)) + +# not support yet +sql select percentile(val, 50) from (select count(*) val from sub_stb0 interval(10h)) +sql select stddev(val) from (select count(*) val from sub_stb0 interval(10h)) + +print ====================>complex query + diff --git a/tests/script/general/parser/testSuite.sim b/tests/script/general/parser/testSuite.sim index 808981c0c4..6f32ed972f 100644 --- a/tests/script/general/parser/testSuite.sim +++ b/tests/script/general/parser/testSuite.sim @@ -1,59 +1,61 @@ -run general/parser/alter.sim -run general/parser/alter1.sim -run general/parser/alter_stable.sim -run general/parser/auto_create_tb.sim -run general/parser/auto_create_tb_drop_tb.sim -run general/parser/col_arithmetic_operation.sim -run general/parser/columnValue.sim -run general/parser/commit.sim -run general/parser/create_db.sim -run general/parser/create_mt.sim -run general/parser/create_tb.sim -run general/parser/dbtbnameValidate.sim -run general/parser/fill.sim -run general/parser/fill_stb.sim -#run general/parser/fill_us.sim # -run general/parser/first_last.sim -run general/parser/import_commit1.sim -run general/parser/import_commit2.sim -run general/parser/import_commit3.sim +#run general/parser/alter.sim +#run general/parser/alter1.sim +#run general/parser/alter_stable.sim +#run general/parser/auto_create_tb.sim +#run general/parser/auto_create_tb_drop_tb.sim +#run general/parser/col_arithmetic_operation.sim +#run general/parser/columnValue.sim +#run general/parser/commit.sim +#run general/parser/create_db.sim +#run general/parser/create_mt.sim +#run general/parser/create_tb.sim +#run general/parser/dbtbnameValidate.sim +#run general/parser/fill.sim +#run general/parser/fill_stb.sim +##run general/parser/fill_us.sim # +#run general/parser/first_last.sim +#run general/parser/import_commit1.sim +#run general/parser/import_commit2.sim +#run general/parser/import_commit3.sim #run general/parser/import_file.sim -run general/parser/insert_tb.sim -run general/parser/tags_dynamically_specifiy.sim -run general/parser/interp.sim -run general/parser/lastrow.sim -run general/parser/limit.sim -run general/parser/limit1.sim -run general/parser/limit1_tblocks100.sim -run general/parser/limit2.sim -run general/parser/mixed_blocks.sim -run general/parser/nchar.sim -run general/parser/null_char.sim -run general/parser/selectResNum.sim -run general/parser/select_across_vnodes.sim -run general/parser/select_from_cache_disk.sim -run general/parser/set_tag_vals.sim -run general/parser/single_row_in_tb.sim -run general/parser/slimit.sim -run general/parser/slimit1.sim -run general/parser/slimit_alter_tags.sim -run general/parser/tbnameIn.sim -run general/parser/slimit_alter_tags.sim # persistent failed -run general/parser/join.sim -run general/parser/join_multivnode.sim -run general/parser/join_manyblocks.sim -run general/parser/projection_limit_offset.sim -run general/parser/select_with_tags.sim -run general/parser/groupby.sim -run general/parser/tags_filter.sim -run general/parser/topbot.sim -run general/parser/union.sim -run general/parser/constCol.sim +#run general/parser/insert_tb.sim +#run general/parser/tags_dynamically_specifiy.sim +#run general/parser/interp.sim +#run general/parser/lastrow.sim +#run general/parser/limit.sim +#run general/parser/limit1.sim +#run general/parser/limit1_tblocks100.sim +#run general/parser/limit2.sim +#run general/parser/mixed_blocks.sim +#run general/parser/nchar.sim +#run general/parser/null_char.sim +#run general/parser/selectResNum.sim +#run general/parser/select_across_vnodes.sim +#run general/parser/select_from_cache_disk.sim +#run general/parser/set_tag_vals.sim +#run general/parser/single_row_in_tb.sim +#run general/parser/slimit.sim +#run general/parser/slimit1.sim +#run general/parser/slimit_alter_tags.sim +#run general/parser/tbnameIn.sim +#run general/parser/join.sim +#run general/parser/join_multivnode.sim +#run general/parser/join_manyblocks.sim +#run general/parser/projection_limit_offset.sim +#run general/parser/select_with_tags.sim +#run general/parser/select_distinct_tag.sim +#run general/parser/groupby.sim +#run general/parser/tags_filter.sim +#run general/parser/topbot.sim +#run general/parser/union.sim +#run general/parser/constCol.sim run general/parser/where.sim run general/parser/timestamp.sim run general/parser/sliding.sim run general/parser/function.sim run general/parser/stableOp.sim +run general/parser/having.sim +run general/parser/having_child.sim run general/parser/slimit_alter_tags.sim run general/parser/udf.sim run general/parser/udf_dll.sim diff --git a/tests/script/general/stream/stream_1970.sim b/tests/script/general/stream/stream_1970.sim new file mode 100644 index 0000000000..30a733c08f --- /dev/null +++ b/tests/script/general/stream/stream_1970.sim @@ -0,0 +1,73 @@ +system sh/stop_dnodes.sh + +system sh/deploy.sh -n dnode1 -i 1 +system sh/cfg.sh -n dnode1 -c walLevel -v 1 +system sh/exec.sh -n dnode1 -s start + +sleep 2000 +sql connect + +print ======================== dnode1 start + +$dbPrefix = s3_db +$tbPrefix = s3_tb +$mtPrefix = s3_mt +$stPrefix = s3_st +$tbNum = 10 +$rowNum = 20 +$totalNum = 200 + +print =============== step1 +$i = 0 +$db = $dbPrefix . $i +$mt = $mtPrefix . $i +$st = $stPrefix . $i + +sql drop databae $db -x step1 +step1: +sql create database $db keep 36500 +sql use $db +sql create stable $mt (ts timestamp, tbcol int, tbcol2 float) TAGS(tgcol int) + +sql create table cq1 as select count(*) from $mt interval(10s); + +sleep 1000 + +sql create table $st using $mt tags(1); + +sql insert into $st values (-50000, 1, 1.0); +sql insert into $st values (-10000, 1, 1.0); +sql insert into $st values (10000, 1, 1.0); + + +$i = 0 +while $i < 12 + sql select * from cq1; + + if $rows != 3 then + sleep 10000 + else + if $data00 != @70-01-01 07:59:10.000@ then + return -1 + endi + if $data01 != 1 then + return -1 + endi + if $data10 != @70-01-01 07:59:50.000@ then + return -1 + endi + if $data11 != 1 then + return -1 + endi + if $data20 != @70-01-01 08:00:10.000@ then + return -1 + endi + if $data21 != 1 then + return -1 + endi + $i = 12 + endi + + $i = $i + 1 +endw + diff --git a/tests/script/test.sh b/tests/script/test.sh index 1c7a7527ab..a092a38a2d 100755 --- a/tests/script/test.sh +++ b/tests/script/test.sh @@ -132,6 +132,7 @@ if [ -n "$FILE_NAME" ]; then else echo "ExcuteCmd:" $PROGRAM -c $CFG_DIR -f $FILE_NAME $PROGRAM -c $CFG_DIR -f $FILE_NAME +# valgrind --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all -v --workaround-gcc296-bugs=yes --log-file=${CODE_DIR}/../script/valgrind.log $PROGRAM -c $CFG_DIR -f $FILE_NAME fi else echo "ExcuteCmd:" $PROGRAM -c $CFG_DIR -f basicSuite.sim diff --git a/tests/tsim/src/simSystem.c b/tests/tsim/src/simSystem.c index d2494eddbb..0879e371ef 100644 --- a/tests/tsim/src/simSystem.c +++ b/tests/tsim/src/simSystem.c @@ -164,10 +164,9 @@ void *simExecuteScript(void *inputScript) { } if (script->killed || script->linePos >= script->numOfLines) { - printf("killed ---------------------->\n"); script = simProcessCallOver(script); if (script == NULL) { - printf("abort now!\n"); + simDebug("sim test abort now!"); break; } } else {