diff --git a/include/libs/parser/parser.h b/include/libs/parser/parser.h index 860c77de15..2254298e5c 100644 --- a/include/libs/parser/parser.h +++ b/include/libs/parser/parser.h @@ -60,6 +60,8 @@ int32_t qParseQuerySql(SParseContext* pCxt, SQuery** pQuery); void qDestroyQuery(SQuery* pQueryNode); +int32_t qExtractResultSchema(const SNode* pRoot, int32_t* numOfCols, SSchema** pSchema); + #ifdef __cplusplus } #endif diff --git a/source/client/test/clientTests.cpp b/source/client/test/clientTests.cpp index 87a3e651fe..629dd90da3 100644 --- a/source/client/test/clientTests.cpp +++ b/source/client/test/clientTests.cpp @@ -661,7 +661,7 @@ TEST(testCase, agg_query_tables) { TAOS_RES* pRes = taos_query(pConn, "use abc1"); taos_free_result(pRes); - pRes = taos_query(pConn, "select k from tm0"); + pRes = taos_query(pConn, "select count(*) from tu"); if (taos_errno(pRes) != 0) { printf("failed to select from table, reason:%s\n", taos_errstr(pRes)); taos_free_result(pRes); diff --git a/source/common/src/ttime.c b/source/common/src/ttime.c index da1adf0c59..510a2809e7 100644 --- a/source/common/src/ttime.c +++ b/source/common/src/ttime.c @@ -562,8 +562,7 @@ int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precisio // not enough time range if (start < 0 || INT64_MAX - start > pInterval->interval - 1) { - end = start + pInterval->interval - 1; - + end = taosTimeAdd(start, pInterval->interval, pInterval->intervalUnit, precision) - 1; while (end < t && ((start + pInterval->sliding) <= INT64_MAX)) { // move forward to the correct time window start += pInterval->sliding; @@ -587,7 +586,7 @@ int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precisio start = taosTimeAdd(start, -pInterval->interval, pInterval->intervalUnit, precision); } else { // try to move current window to the left-hande-side, due to the offset effect. - int64_t end = start + pInterval->interval - 1; + int64_t end = taosTimeAdd(start, pInterval->interval, pInterval->intervalUnit, precision) - 1; ASSERT(end >= t); end = taosTimeAdd(end, -pInterval->sliding, pInterval->slidingUnit, precision); if (end >= t) { diff --git a/source/dnode/mnode/impl/CMakeLists.txt b/source/dnode/mnode/impl/CMakeLists.txt index 514bba19f4..dd2caf1f7f 100644 --- a/source/dnode/mnode/impl/CMakeLists.txt +++ b/source/dnode/mnode/impl/CMakeLists.txt @@ -6,7 +6,7 @@ target_include_directories( PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc" ) target_link_libraries( - mnode scheduler sdb wal transport cjson sync monitor + mnode scheduler sdb wal transport cjson sync monitor parser ) if(${BUILD_TEST}) diff --git a/source/dnode/mnode/impl/src/mndStream.c b/source/dnode/mnode/impl/src/mndStream.c index be03539b4d..e3d77ced0d 100644 --- a/source/dnode/mnode/impl/src/mndStream.c +++ b/source/dnode/mnode/impl/src/mndStream.c @@ -14,6 +14,7 @@ */ #include "mndStream.h" +#include "parser.h" #include "mndAuth.h" #include "mndDb.h" #include "mndDnode.h" @@ -218,28 +219,6 @@ static int32_t mndCheckCreateStreamReq(SCMCreateStreamReq *pCreate) { return 0; } -static SArray *mndExtractNamesFromAst(const SNode *pAst) { - if (pAst->type != QUERY_NODE_SELECT_STMT) return NULL; - - SArray *names = taosArrayInit(0, sizeof(void *)); - if (names == NULL) { - return NULL; - } - SSelectStmt *pSelect = (SSelectStmt *)pAst; - SNodeList *pNodes = pSelect->pProjectionList; - SListCell *pCell = pNodes->pHead; - while (pCell != NULL) { - if (pCell->pNode->type != QUERY_NODE_FUNCTION) { - continue; - } - SFunctionNode *pFunction = (SFunctionNode *)pCell->pNode; - char *name = strdup(pFunction->node.aliasName); - taosArrayPush(names, &name); - pCell = pCell->pNext; - } - return names; -} - static int32_t mndStreamGetPlanString(const char *ast, char **pStr) { if (NULL == ast) { return TSDB_CODE_SUCCESS; @@ -276,14 +255,16 @@ int32_t mndAddStreamToTrans(SMnode *pMnode, SStreamObj *pStream, const char *ast return -1; } #if 1 - SArray *names = mndExtractNamesFromAst(pAst); + SSchemaWrapper sw = {0}; + qExtractResultSchema(pAst, (int32_t*)&sw.nCols, &sw.pSchema); + printf("|"); - for (int i = 0; i < taosArrayGetSize(names); i++) { - printf(" %15s |", (char *)taosArrayGetP(names, i)); + for (int i = 0; i < sw.nCols; i++) { + printf(" %15s |", (char *)sw.pSchema[i].name); } printf("\n=======================================================\n"); - pStream->ColAlias = names; + pStream->ColAlias = NULL; #endif if (TSDB_CODE_SUCCESS != mndStreamGetPlanString(ast, &pStream->physicalPlan)) { diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index 2d7e2eedc6..c582873315 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -665,6 +665,9 @@ SOperatorInfo* createGroupOperatorInfo(SOperatorInfo* downstream, SExprInfo* pEx SArray* pGroupColList, SExecTaskInfo* pTaskInfo, const STableGroupInfo* pTableGroupInfo); SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols, SInterval* pInterval, SSDataBlock* pResBlock, int32_t fillType, char* fillVal, bool multigroupResult, SExecTaskInfo* pTaskInfo); +SOperatorInfo* createDistinctOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, + int32_t numOfOutput); +SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbReadHandle, STaskRuntimeEnv* pRuntimeEnv); SOperatorInfo* createTableSeqScanOperatorInfo(void* pTsdbReadHandle, STaskRuntimeEnv* pRuntimeEnv); SOperatorInfo* createAllTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, @@ -675,9 +678,7 @@ SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntim SOperatorInfo* createAllMultiTableTimeIntervalOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfOutput); SOperatorInfo* createTagScanOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput); -SOperatorInfo* createDistinctOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, SExprInfo* pExpr, - int32_t numOfOutput); -SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbReadHandle, STaskRuntimeEnv* pRuntimeEnv); + SOperatorInfo* createMultiwaySortOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput, int32_t numOfRows, void* merger); SOperatorInfo* createGlobalAggregateOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorInfo* downstream, diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 2db9406418..fdf216c7eb 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -674,12 +674,7 @@ static void getInitialStartTimeWindow(SInterval* pInterval, int32_t precision, T int64_t key = w->skey; while(key < ts) { // moving towards end - if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') { - key = taosTimeAdd(key, pInterval->sliding, pInterval->slidingUnit, precision); - } else { - key += pInterval->sliding; - } - + key = taosTimeAdd(key, pInterval->sliding, pInterval->slidingUnit, precision); if (key >= ts) { break; } @@ -695,12 +690,7 @@ static STimeWindow getActiveTimeWindow(SResultRowInfo * pResultRowInfo, int64_t if (pResultRowInfo->curPos == -1) { // the first window, from the previous stored value getInitialStartTimeWindow(pInterval, precision, ts, &w, win->ekey, true); - - if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') { - w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, precision) - 1; - } else { - w.ekey = w.skey + pInterval->interval - 1; - } + w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, precision) - 1; } else { w = getResultRow(pResultRowInfo, pResultRowInfo->curPos)->win; } @@ -722,7 +712,7 @@ static STimeWindow getActiveTimeWindow(SResultRowInfo * pResultRowInfo, int64_t } w.skey = st; - w.ekey = w.skey + pInterval->interval - 1; + w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, precision) - 1; } } return w; @@ -2208,7 +2198,7 @@ static SqlFunctionCtx* createSqlFunctionCtx_rv(SExprInfo* pExprInfo, int32_t num } for(int32_t i = 1; i < numOfOutput; ++i) { - (*rowCellInfoOffset)[i] = (int32_t)((*rowCellInfoOffset)[i - 1] + sizeof(SResultRowEntryInfo) + pFuncCtx[i].resDataInfo.interBufSize); + (*rowCellInfoOffset)[i] = (int32_t)((*rowCellInfoOffset)[i - 1] + sizeof(SResultRowEntryInfo) + pFuncCtx[i - 1].resDataInfo.interBufSize); } setCtxTagColumnInfo(pFuncCtx, numOfOutput); @@ -2407,7 +2397,7 @@ static bool isCachedLastQuery(STaskAttr *pQueryAttr) { ///////////////////////////////////////////////////////////////////////////////////////////// //todo refactor : return window void getAlignQueryTimeWindow(SInterval* pInterval, int32_t precision, int64_t key, int64_t keyFirst, int64_t keyLast, STimeWindow *win) { - assert(key >= keyFirst && key <= keyLast && pInterval->sliding <= pInterval->interval); + ASSERT(key >= keyFirst && key <= keyLast); win->skey = taosTimeTruncate(key, pInterval, precision); /* @@ -2417,10 +2407,8 @@ void getAlignQueryTimeWindow(SInterval* pInterval, int32_t precision, int64_t ke if (keyFirst > (INT64_MAX - pInterval->interval)) { assert(keyLast - keyFirst < pInterval->interval); win->ekey = INT64_MAX; - } else if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') { - win->ekey = taosTimeAdd(win->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1; } else { - win->ekey = win->skey + pInterval->interval - 1; + win->ekey = taosTimeAdd(win->skey, pInterval->interval, pInterval->intervalUnit, precision) - 1; } } diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index 9817020817..610e5a0bb2 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -528,11 +528,10 @@ void firstFunction(SqlFunctionCtx *pCtx) { char* buf = GET_ROWCELL_INTERBUF(pResInfo); SInputColumnInfoData* pInput = &pCtx->input; - SColumnInfoData* pInputCol = pInput->pData[0]; // All null data column, return directly. - if (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows) { + if (pInput->colDataAggIsSet && (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows)) { ASSERT(pInputCol->hasNull == true); return; } diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 8b97b88b09..8c842db161 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -1771,24 +1771,27 @@ static int32_t translateSubquery(STranslateContext* pCxt, SNode* pNode) { return code; } -static int32_t setReslutSchema(STranslateContext* pCxt, SQuery* pQuery) { - if (QUERY_NODE_SELECT_STMT == nodeType(pQuery->pRoot)) { - SSelectStmt* pSelect = (SSelectStmt*)pQuery->pRoot; - pQuery->numOfResCols = LIST_LENGTH(pSelect->pProjectionList); - pQuery->pResSchema = calloc(pQuery->numOfResCols, sizeof(SSchema)); - if (NULL == pQuery->pResSchema) { - return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_OUT_OF_MEMORY); +int32_t qExtractResultSchema(const SNode* pRoot, int32_t* numOfCols, SSchema** pSchema) { + if (QUERY_NODE_SELECT_STMT == nodeType(pRoot)) { + SSelectStmt* pSelect = (SSelectStmt*) pRoot; + *numOfCols = LIST_LENGTH(pSelect->pProjectionList); + *pSchema = calloc((*numOfCols), sizeof(SSchema)); + if (NULL == (*pSchema)) { + return TSDB_CODE_OUT_OF_MEMORY; } + SNode* pNode; int32_t index = 0; FOREACH(pNode, pSelect->pProjectionList) { SExprNode* pExpr = (SExprNode*)pNode; - pQuery->pResSchema[index].type = pExpr->resType.type; - pQuery->pResSchema[index].bytes = pExpr->resType.bytes; - strcpy(pQuery->pResSchema[index].name, pExpr->aliasName); + (*pSchema)[index].type = pExpr->resType.type; + (*pSchema)[index].bytes = pExpr->resType.bytes; + (*pSchema)[index].colId = index + 1; + strcpy((*pSchema)[index].name, pExpr->aliasName); index +=1; } } + return TSDB_CODE_SUCCESS; } @@ -2372,7 +2375,7 @@ static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery) { pQuery->haveResultSet = true; pQuery->directRpc = false; pQuery->msgType = TDMT_VND_QUERY; - code = setReslutSchema(pCxt, pQuery); + code = qExtractResultSchema(pQuery->pRoot, &pQuery->numOfResCols, &pQuery->pResSchema); break; case QUERY_NODE_VNODE_MODIF_STMT: pQuery->haveResultSet = false; diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index ee25b20285..dd44baed27 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -21,7 +21,7 @@ # ---- query ./test.sh -f tsim/query/interval.sim -#./test.sh -f tsim/query/interval-offset.sim +./test.sh -f tsim/query/interval-offset.sim # ---- show ./test.sh -f tsim/show/basic.sim diff --git a/tests/script/tsim/insert/basic0.sim b/tests/script/tsim/insert/basic0.sim index 46aa99127b..da74eb95e8 100644 --- a/tests/script/tsim/insert/basic0.sim +++ b/tests/script/tsim/insert/basic0.sim @@ -109,7 +109,26 @@ endi #print =============== select first(*)/first(column) from child table #sql select first(*) from ct1 -#sql select first(ts), first(c1), first(c2), first(c3) from ct1 +#print ====> select first(*) from ct1 +#print rows: $rows +#print $data00 $data01 $data02 $data03 + +sql select first(ts), first(c1), first(c2), first(c3) from ct1 +print ====> select first(ts), first(c1), first(c2), first(c3) from ct1 +print rows: $rows +print $data00 $data01 $data02 $data03 +if $rows != 1 then + return -1 +endi +if $data01 != 10 then + return -1 +endi +if $data02 != 2.00000 then + return -1 +endi +if $data03 != 3.000000000 then + return -1 +endi print =============== select min(column) from child table sql select min(c1), min(c2), min(c3) from ct1 @@ -216,10 +235,42 @@ endi # return -1 #endi +print =============== select count(column) from supter table +sql select ts, c1, c2, c3 from stb +print rows: $rows +print $data00 $data01 $data02 $data03 +print $data10 $data11 $data12 $data13 +print $data20 $data21 $data22 $data23 +print $data30 $data31 $data32 $data33 +print $data40 $data41 $data42 $data43 +print $data50 $data51 $data52 $data53 +print $data60 $data61 $data62 $data63 +print $data70 $data71 $data72 $data73 +print $data80 $data81 $data82 $data83 +if $rows != 9 then + return -1 +endi + +# The order of data from different sub tables in the super table is random, +# so this detection may fail randomly +if $data01 != 10 then + return -1 +endi +if $data02 != 2.00000 then + return -1 +endi +if $data03 != 3.000000000 then + return -1 +endi + #print =============== select count(column) from supter table #sql select count(ts), count(c1), count(c2), count(c3) from stb +#print rows: $rows #print $data00 $data01 $data02 $data03 -#if $data00 != 8 then +#print $data10 $data11 $data12 $data13 +#print $data20 $data21 $data22 $data23 +#print $data30 $data31 $data32 $data33 +#if $data00 != 9 then # return -1 #endi #if $data01 != 8 then @@ -232,7 +283,6 @@ endi # return -1 #endi - #=================================================================== #=================================================================== @@ -317,7 +367,26 @@ endi #print =============== select first(*)/first(column) from child table #sql select first(*) from ct1 -#sql select first(ts), first(c1), first(c2), first(c3) from ct1 +#print ====> select first(*) from ct1 +#print rows: $rows +#print $data00 $data01 $data02 $data03 + +sql select first(ts), first(c1), first(c2), first(c3) from ct1 +print ====> select first(ts), first(c1), first(c2), first(c3) from ct1 +print rows: $rows +print $data00 $data01 $data02 $data03 +if $rows != 1 then + return -1 +endi +if $data01 != 10 then + return -1 +endi +if $data02 != 2.00000 then + return -1 +endi +if $data03 != 3.000000000 then + return -1 +endi print =============== select min(column) from child table sql select min(c1), min(c2), min(c3) from ct1 @@ -424,6 +493,33 @@ endi # return -1 #endi +print =============== select count(column) from supter table +sql select ts, c1, c2, c3 from stb +print rows: $rows +print $data00 $data01 $data02 $data03 +print $data10 $data11 $data12 $data13 +print $data20 $data21 $data22 $data23 +print $data30 $data31 $data32 $data33 +print $data40 $data41 $data42 $data43 +print $data50 $data51 $data52 $data53 +print $data60 $data61 $data62 $data63 +print $data70 $data71 $data72 $data73 +print $data80 $data81 $data82 $data83 +if $rows != 9 then + return -1 +endi +# The order of data from different sub tables in the super table is random, +# so this detection may fail randomly +if $data01 != 10 then + return -1 +endi +if $data02 != 2.00000 then + return -1 +endi +if $data03 != 3.000000000 then + return -1 +endi + #print =============== select count(column) from supter table #sql select count(ts), count(c1), count(c2), count(c3) from stb #print $data00 $data01 $data02 $data03 diff --git a/tests/script/tsim/query/interval-offset.sim b/tests/script/tsim/query/interval-offset.sim index b2415be7d1..f188dff1ba 100644 --- a/tests/script/tsim/query/interval-offset.sim +++ b/tests/script/tsim/query/interval-offset.sim @@ -88,14 +88,17 @@ print ===> rows4: $data40 $data41 $data42 $data43 $data44 print ===> rows5: $data50 $data51 $data52 $data53 $data54 print ===> rows6: $data60 $data61 $data62 $data63 $data64 print ===> rows7: $data70 $data71 $data72 $data73 $data74 -if $rows != 8 then - print expect 8, actual $rows +print ===> rows8: $data80 $data81 $data82 $data83 $data84 +if $rows != 9 then return -1 endi -if $data00 != 2 then +if $data00 != 1 then return -1 endi -if $data70 != 1 then +if $data70 != 2 then + return -1 +endi +if $data80 != 1 then return -1 endi @@ -166,15 +169,15 @@ print ===> rows7: $data70 $data71 $data72 $data73 $data74 $data75 #endi print =============== insert data into child table ct3 (n) -sql insert into ct3 values ( '2021-12-21 01:01:01.000', NULL ) -sql insert into ct3 values ( '2021-12-31 01:01:01.000', 1 ) -sql insert into ct3 values ( '2022-01-01 01:01:06.000', 2 ) -sql insert into ct3 values ( '2022-01-07 01:01:10.000', 3 ) -sql insert into ct3 values ( '2022-01-31 01:01:16.000', 4 ) -sql insert into ct3 values ( '2022-02-01 01:01:20.000', 5 ) -sql insert into ct3 values ( '2022-02-28 01:01:26.000', 6 ) -sql insert into ct3 values ( '2022-03-01 01:01:30.000', 7 ) -sql insert into ct3 values ( '2022-03-08 01:01:36.000', 8 ) +sql insert into ct3 values ( '2021-12-21 01:01:01.000', NULL ); +sql insert into ct3 values ( '2021-12-31 01:01:01.000', 1 ); +sql insert into ct3 values ( '2022-01-01 01:01:06.000', 2 ); +sql insert into ct3 values ( '2022-01-07 01:01:10.000', 3 ); +sql insert into ct3 values ( '2022-01-31 01:01:16.000', 4 ); +sql insert into ct3 values ( '2022-02-01 01:01:20.000', 5 ); +sql insert into ct3 values ( '2022-02-28 01:01:26.000', 6 ); +sql insert into ct3 values ( '2022-03-01 01:01:30.000', 7 ); +sql insert into ct3 values ( '2022-03-08 01:01:36.000', 8 ); sql select count(tbcol), sum(tbcol), max(tbcol), min(tbcol), count(*) from ct3 interval(1n, 1w) print ===> select count(tbcol), sum(tbcol), max(tbcol), min(tbcol), count(*) from ct3 interval(1n, 1w) diff --git a/tools/shell/src/shellMain.c b/tools/shell/src/shellMain.c index ea91736aad..cc87c2c54b 100644 --- a/tools/shell/src/shellMain.c +++ b/tools/shell/src/shellMain.c @@ -17,6 +17,7 @@ #include "os.h" #include "shell.h" #include "tglobal.h" +#include "tconfig.h" #include "shellCommand.h" #include "tbase64.h" #include "tlog.h" @@ -619,20 +620,17 @@ int main(int argc, char *argv[]) { shellParseArgument(argc, argv, &args); -#if 0 if (args.dump_config) { - taosInitGlobalCfg(); - taosReadGlobalLogCfg(); + taosInitCfg(configDir, NULL, NULL, NULL, 1); - if (taosReadGlobalCfg() ! =0) { - printf("TDengine read global config failed"); + SConfig *pCfg = taosGetCfg(); + if (NULL == pCfg) { + printf("TDengine read global config failed!\n"); exit(EXIT_FAILURE); } - - taosDumpGlobalCfg(); + cfgDumpCfg(pCfg, 0, 1); exit(0); } -#endif if (args.netTestRole && args.netTestRole[0] != 0) { TAOS *con = NULL;