diff --git a/src/client/src/tscFunctionImpl.c b/src/client/src/tscFunctionImpl.c index edeca86c17f8d694ff5ace078ed79c1eef7a0781..d8ac0d3109fc207278882e365724879a8114897a 100644 --- a/src/client/src/tscFunctionImpl.c +++ b/src/client/src/tscFunctionImpl.c @@ -711,13 +711,16 @@ static int32_t firstDistFuncRequired(SQLFunctionCtx *pCtx, TSKEY start, TSKEY en if (pCtx->aOutputBuf == NULL) { return BLK_DATA_ALL_NEEDED; } - - SFirstLastInfo *pInfo = (SFirstLastInfo*) (pCtx->aOutputBuf + pCtx->inputBytes); - if (pInfo->hasResult != DATA_SET_FLAG) { - return BLK_DATA_ALL_NEEDED; - } else { // data in current block is not earlier than current result - return (pInfo->ts <= start) ? BLK_DATA_NO_NEEDED : BLK_DATA_ALL_NEEDED; - } + + return BLK_DATA_ALL_NEEDED; + // TODO pCtx->aOutputBuf is the previous windowRes output buffer, not current unloaded block. so the following filter + // is invalid +// SFirstLastInfo *pInfo = (SFirstLastInfo*) (pCtx->aOutputBuf + pCtx->inputBytes); +// if (pInfo->hasResult != DATA_SET_FLAG) { +// return BLK_DATA_ALL_NEEDED; +// } else { // data in current block is not earlier than current result +// return (pInfo->ts <= start) ? BLK_DATA_NO_NEEDED : BLK_DATA_ALL_NEEDED; +// } } static int32_t lastDistFuncRequired(SQLFunctionCtx *pCtx, TSKEY start, TSKEY end, int32_t colId) { @@ -730,12 +733,16 @@ static int32_t lastDistFuncRequired(SQLFunctionCtx *pCtx, TSKEY start, TSKEY end return BLK_DATA_ALL_NEEDED; } - SFirstLastInfo *pInfo = (SFirstLastInfo*) (pCtx->aOutputBuf + pCtx->inputBytes); - if (pInfo->hasResult != DATA_SET_FLAG) { - return BLK_DATA_ALL_NEEDED; - } else { - return (pInfo->ts > end) ? BLK_DATA_NO_NEEDED : BLK_DATA_ALL_NEEDED; - } + return BLK_DATA_ALL_NEEDED; + // TODO pCtx->aOutputBuf is the previous windowRes output buffer, not current unloaded block. so the following filter + // is invalid + +// SFirstLastInfo *pInfo = (SFirstLastInfo*) (pCtx->aOutputBuf + pCtx->inputBytes); +// if (pInfo->hasResult != DATA_SET_FLAG) { +// return BLK_DATA_ALL_NEEDED; +// } else { +// return (pInfo->ts > end) ? BLK_DATA_NO_NEEDED : BLK_DATA_ALL_NEEDED; +// } } ////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 4bc793e79f2a35661ead7bfe6bdf4e4efc1b5d92..cceb876a06d65dcc07af5e8157aa27548fdc8f01 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -351,7 +351,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { case TSDB_SQL_DESCRIBE_TABLE: { SStrToken* pToken = &pInfo->pDCLInfo->a[0]; const char* msg1 = "invalid table name"; - const char* msg2 = "table name is too long"; + const char* msg2 = "table name too long"; if (tscValidateName(pToken) != TSDB_CODE_SUCCESS) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); @@ -410,7 +410,6 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { const char* msg3 = "name too long"; pCmd->command = pInfo->type; - // tDCLSQL* pDCL = pInfo->pDCLInfo; SUserInfo* pUser = &pInfo->pDCLInfo->user; SStrToken* pName = &pUser->user; @@ -773,7 +772,7 @@ int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQu int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SStrToken* pzTableName, SSqlObj* pSql) { const char* msg1 = "name too long"; - const char* msg2 = "current database name is invalid"; + const char* msg2 = "current database or database name invalid"; SSqlCmd* pCmd = &pSql->cmd; int32_t code = TSDB_CODE_SUCCESS; @@ -6302,6 +6301,11 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) { } if (pQueryInfo->interval.interval > 0 && pQueryInfo->interval.intervalUnit != 'n' && pQueryInfo->interval.intervalUnit != 'y') { + bool initialWindows = TSWINDOW_IS_EQUAL(pQueryInfo->window, TSWINDOW_INITIALIZER); + if (initialWindows) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6); + } + int64_t timeRange = ABS(pQueryInfo->window.skey - pQueryInfo->window.ekey); // number of result is not greater than 10,000,000 if ((timeRange == 0) || (timeRange / pQueryInfo->interval.interval) > MAX_INTERVAL_TIME_WINDOW) { diff --git a/src/query/inc/qResultbuf.h b/src/query/inc/qResultbuf.h index 5303251d981f9e12bb92088b65cf6231d6e45f88..704df9f3f29cc0653c353ed194e02e72cb4c5fb2 100644 --- a/src/query/inc/qResultbuf.h +++ b/src/query/inc/qResultbuf.h @@ -73,12 +73,11 @@ typedef struct SDiskbasedResultBuf { bool comp; // compressed before flushed to disk int32_t nextPos; // next page flush position - const void* handle; // for debug purpose + const void* handle; // for debug purpose SResultBufStatis statis; } SDiskbasedResultBuf; -#define DEFAULT_INTERN_BUF_PAGE_SIZE (4096L) -#define DEFAULT_INMEM_BUF_PAGES 10 +#define DEFAULT_INTERN_BUF_PAGE_SIZE (256L) // in bytes #define PAGE_INFO_INITIALIZER (SPageDiskInfo){-1, -1} /** diff --git a/src/query/inc/qUtil.h b/src/query/inc/qUtil.h index 314159484d0de1d161cdf183534a0bc1820fa90e..5320e5622e70a93c06edb4a1e5a3fe568498ef21 100644 --- a/src/query/inc/qUtil.h +++ b/src/query/inc/qUtil.h @@ -39,7 +39,6 @@ static FORCE_INLINE SWindowResult *getWindowResult(SWindowResInfo *pWindowResInf } #define curTimeWindowIndex(_winres) ((_winres)->curIndex) -#define GET_TIMEWINDOW(_winresInfo, _win) (STimeWindow) {(_win)->skey, ((_win)->skey + (_winresInfo)->interval - 1)} #define GET_ROW_PARAM_FOR_MULTIOUTPUT(_q, tbq, sq) (((tbq) && (!sq))? (_q)->pSelectExpr[1].base.arg->argValue.i64:1) bool isWindowResClosed(SWindowResInfo *pWindowResInfo, int32_t slot); diff --git a/src/query/inc/tsqlfunction.h b/src/query/inc/tsqlfunction.h index a78bb7ec51de2886d5396a9a18192947221bce88..28b9a60102d41a11fa02fee1ca51cbf8e263bf3b 100644 --- a/src/query/inc/tsqlfunction.h +++ b/src/query/inc/tsqlfunction.h @@ -108,7 +108,7 @@ extern "C" { #define GET_FORWARD_DIRECTION_FACTOR(ord) (((ord) == TSDB_ORDER_ASC) ? QUERY_ASC_FORWARD_STEP : QUERY_DESC_FORWARD_STEP) -#define MAX_INTERVAL_TIME_WINDOW 10000000 +#define MAX_INTERVAL_TIME_WINDOW 1000000 // maximum allowed time windows in final results #define TOP_BOTTOM_QUERY_LIMIT 100 enum { diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index d3012e76624e641ce1e2051201761e52f0851f00..d3f44cdcc715bb236fafaa4947a54771052df307 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -187,7 +187,7 @@ static void setExecParams(SQuery *pQuery, SQLFunctionCtx *pCtx, void* inputData, SDataStatis *pStatis, void *param, int32_t colIndex); static void initCtxOutputBuf(SQueryRuntimeEnv *pRuntimeEnv); -static void destroyTableQueryInfo(STableQueryInfo *pTableQueryInfo); +static void destroyTableQueryInfoImpl(STableQueryInfo *pTableQueryInfo); static void resetCtxOutputBuf(SQueryRuntimeEnv *pRuntimeEnv); static bool hasMainOutput(SQuery *pQuery); static void buildTagQueryResult(SQInfo *pQInfo); @@ -782,6 +782,8 @@ static void doBlockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, bool closed SQuery * pQuery = pRuntimeEnv->pQuery; SQLFunctionCtx *pCtx = pRuntimeEnv->pCtx; + bool hasPrev = pCtx[0].preAggVals.isSet; + if (IS_MASTER_SCAN(pRuntimeEnv) || closed) { for (int32_t k = 0; k < pQuery->numOfOutput; ++k) { pCtx[k].nStartQueryTimestamp = pWin->skey; @@ -794,11 +796,17 @@ static void doBlockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, bool closed } // not a whole block involved in query processing, statistics data can not be used - pCtx[k].preAggVals.isSet = (forwardStep == numOfTotal); + // NOTE: the original value of isSet have been changed here + if (pCtx[k].preAggVals.isSet && forwardStep < numOfTotal) { + pCtx[k].preAggVals.isSet = false; + } if (functionNeedToExecute(pRuntimeEnv, &pCtx[k], functionId)) { aAggs[functionId].xFunction(&pCtx[k]); } + + // restore it + pCtx[k].preAggVals.isSet = hasPrev; } } } @@ -1975,8 +1983,7 @@ static void changeExecuteScanOrder(SQInfo *pQInfo, SQueryTableMsg* pQueryMsg, bo // 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:%p scan order changed for last_row query, old:%d, new:%d", GET_QINFO_ADDR(pQuery), - pQuery->order.order, TSDB_ORDER_ASC); + qDebug("QInfo:%p scan order changed for last_row query, old:%d, new:%d", pQInfo, pQuery->order.order, TSDB_ORDER_ASC); pQuery->order.order = TSDB_ORDER_ASC; if (pQuery->window.skey > pQuery->window.ekey) { @@ -2078,13 +2085,14 @@ static int32_t getInitialPageNum(SQInfo *pQInfo) { static void getIntermediateBufInfo(SQueryRuntimeEnv* pRuntimeEnv, int32_t* ps, int32_t* rowsize) { SQuery* pQuery = pRuntimeEnv->pQuery; + int32_t MIN_ROWS_PER_PAGE = 4; *rowsize = (int32_t)(pQuery->rowSize * GET_ROW_PARAM_FOR_MULTIOUTPUT(pQuery, pRuntimeEnv->topBotQuery, pRuntimeEnv->stableQuery)); int32_t overhead = sizeof(tFilePage); // one page contains at least two rows *ps = DEFAULT_INTERN_BUF_PAGE_SIZE; - while(((*rowsize) * 2) > (*ps) - overhead) { + while(((*rowsize) * MIN_ROWS_PER_PAGE) > (*ps) - overhead) { *ps = (*ps << 1u); } @@ -3707,7 +3715,7 @@ static STableQueryInfo *createTableQueryInfo(SQueryRuntimeEnv *pRuntimeEnv, void return pTableQueryInfo; } -void destroyTableQueryInfo(STableQueryInfo *pTableQueryInfo) { +void destroyTableQueryInfoImpl(STableQueryInfo *pTableQueryInfo) { if (pTableQueryInfo == NULL) { return; } @@ -4383,6 +4391,8 @@ static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv, TSKEY* start) { return true; } +static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo); + static int32_t setupQueryHandle(void* tsdb, SQInfo* pQInfo, bool isSTableQuery) { SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv; SQuery *pQuery = pQInfo->runtimeEnv.pQuery; @@ -4422,16 +4432,20 @@ static int32_t setupQueryHandle(void* tsdb, SQInfo* pQInfo, bool isSTableQuery) // update the query time window pQuery->window = cond.twindow; - size_t numOfGroups = GET_NUM_OF_TABLEGROUP(pQInfo); - for(int32_t i = 0; i < numOfGroups; ++i) { - SArray *group = GET_TABLEGROUP(pQInfo, i); + if (pQInfo->tableGroupInfo.numOfTables == 0) { + pQInfo->tableqinfoGroupInfo.numOfTables = 0; + } else { + size_t numOfGroups = GET_NUM_OF_TABLEGROUP(pQInfo); + for(int32_t i = 0; i < numOfGroups; ++i) { + SArray *group = GET_TABLEGROUP(pQInfo, i); - size_t t = taosArrayGetSize(group); - for (int32_t j = 0; j < t; ++j) { - STableQueryInfo *pCheckInfo = taosArrayGetP(group, j); + size_t t = taosArrayGetSize(group); + for (int32_t j = 0; j < t; ++j) { + STableQueryInfo *pCheckInfo = taosArrayGetP(group, j); - pCheckInfo->win = pQuery->window; - pCheckInfo->lastKey = pCheckInfo->win.skey; + pCheckInfo->win = pQuery->window; + pCheckInfo->lastKey = pCheckInfo->win.skey; + } } } } else if (isPointInterpoQuery(pQuery)) { @@ -6317,17 +6331,43 @@ _error: } static void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters) { - if (pFilter == NULL) { + if (pFilter == NULL || numOfFilters == 0) { return; } + for (int32_t i = 0; i < numOfFilters; i++) { if (pFilter[i].filterstr) { free((void*)(pFilter[i].pz)); } } + free(pFilter); } +static void doDestroyTableQueryInfo(STableGroupInfo* pTableqinfoGroupInfo) { + if (pTableqinfoGroupInfo->pGroupList != NULL) { + int32_t numOfGroups = (int32_t) taosArrayGetSize(pTableqinfoGroupInfo->pGroupList); + for (int32_t i = 0; i < numOfGroups; ++i) { + SArray *p = taosArrayGetP(pTableqinfoGroupInfo->pGroupList, i); + + size_t num = taosArrayGetSize(p); + for(int32_t j = 0; j < num; ++j) { + STableQueryInfo* item = taosArrayGetP(p, j); + destroyTableQueryInfoImpl(item); + } + + taosArrayDestroy(p); + } + } + + taosArrayDestroy(pTableqinfoGroupInfo->pGroupList); + taosHashCleanup(pTableqinfoGroupInfo->map); + + pTableqinfoGroupInfo->pGroupList = NULL; + pTableqinfoGroupInfo->map = NULL; + pTableqinfoGroupInfo->numOfTables = 0; +} + static void freeQInfo(SQInfo *pQInfo) { if (!isValidQInfo(pQInfo)) { return; @@ -6388,25 +6428,9 @@ static void freeQInfo(SQInfo *pQInfo) { taosTFree(pQuery); } - // todo refactor, extract method to destroytableDataInfo - if (pQInfo->tableqinfoGroupInfo.pGroupList != NULL) { - int32_t numOfGroups = (int32_t)(GET_NUM_OF_TABLEGROUP(pQInfo)); - for (int32_t i = 0; i < numOfGroups; ++i) { - SArray *p = GET_TABLEGROUP(pQInfo, i); - - size_t num = taosArrayGetSize(p); - for(int32_t j = 0; j < num; ++j) { - STableQueryInfo* item = taosArrayGetP(p, j); - destroyTableQueryInfo(item); - } - - taosArrayDestroy(p); - } - } + doDestroyTableQueryInfo(&pQInfo->tableqinfoGroupInfo); taosTFree(pQInfo->pBuf); - taosArrayDestroy(pQInfo->tableqinfoGroupInfo.pGroupList); - taosHashCleanup(pQInfo->tableqinfoGroupInfo.map); tsdbDestroyTableGroup(&pQInfo->tableGroupInfo); taosArrayDestroy(pQInfo->arrTableIdInfo); diff --git a/src/query/src/qFill.c b/src/query/src/qFill.c index 8660d9f4fe59b72aa88a058c922369d313e49b48..f186726c0120f2e2e34580fec0da00c2083e5da9 100644 --- a/src/query/src/qFill.c +++ b/src/query/src/qFill.c @@ -38,6 +38,9 @@ SFillInfo* taosInitFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int32_ pFillInfo->numOfTags = numOfTags; pFillInfo->numOfCols = numOfCols; pFillInfo->precision = precision; + + pFillInfo->interval.interval = slidingTime; + pFillInfo->interval.intervalUnit = slidingUnit; pFillInfo->interval.sliding = slidingTime; pFillInfo->interval.slidingUnit = slidingUnit; diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c index 3a39d5fc49565958b849e1a913b4f1e3b8130ead..b18f45fca601435ba8e9315f4df835b2af113e4b 100644 --- a/src/tsdb/src/tsdbRead.c +++ b/src/tsdb/src/tsdbRead.c @@ -2707,4 +2707,5 @@ void tsdbDestroyTableGroup(STableGroupInfo *pGroupList) { } taosArrayDestroy(pGroupList->pGroupList); + pGroupList->numOfTables = 0; } diff --git a/tests/pytest/client/twoClients.py b/tests/pytest/client/twoClients.py new file mode 100644 index 0000000000000000000000000000000000000000..1a1b36c55438f8ea4050bb804b739be71c570960 --- /dev/null +++ b/tests/pytest/client/twoClients.py @@ -0,0 +1,96 @@ +################################################################### +# 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 os +import sys +sys.path.insert(0, os.getcwd()) +from util.log import * +from util.sql import * +from util.dnodes import * +import taos + + +class TwoClients: + def initConnection(self): + self.host = "127.0.0.1" + self.user = "root" + self.password = "taosdata" + self.config = "/home/xp/git/TDengine/sim/dnode1/cfg" + + def run(self): + tdDnodes.init("") + tdDnodes.setTestCluster(False) + tdDnodes.setValgrind(False) + + tdDnodes.stopAll() + tdDnodes.deploy(1) + tdDnodes.start(1) + + # first client create a stable and insert data + conn1 = taos.connect(self.host, self.user, self.password, self.config) + cursor1 = conn1.cursor() + cursor1.execute("drop database if exists db") + cursor1.execute("create database db") + cursor1.execute("use db") + cursor1.execute("create table tb (ts timestamp, id int) tags(loc nchar(30))") + cursor1.execute("insert into t0 using tb tags('beijing') values(now, 1)") + + # second client alter the table created by cleint + conn2 = taos.connect(self.host, self.user, self.password, self.config) + cursor2 = conn2.cursor() + cursor2.execute("use db") + cursor2.execute("alter table tb add column name nchar(30)") + + # first client should not be able to use the origin metadata + tdSql.init(cursor1, True) + tdSql.error("insert into t0 values(now, 2)") + + # first client should be able to insert data with udpated medadata + tdSql.execute("insert into t0 values(now, 2, 'test')") + tdSql.query("select * from tb") + tdSql.checkRows(2) + + # second client drop the table + cursor2.execute("drop table t0") + cursor2.execute("create table t0 using tb tags('beijing')") + + tdSql.execute("insert into t0 values(now, 2, 'test')") + tdSql.query("select * from tb") + tdSql.checkRows(1) + + # error expected for two clients drop the same cloumn + cursor2.execute("alter table tb drop column name") + tdSql.error("alter table tb drop column name") + + cursor2.execute("alter table tb add column speed int") + tdSql.error("alter table tb add column speed int") + + + tdSql.execute("alter table tb add column size int") + tdSql.query("describe tb") + tdSql.checkRows(5) + tdSql.checkData(0, 0, "ts") + tdSql.checkData(1, 0, "id") + tdSql.checkData(2, 0, "speed") + tdSql.checkData(3, 0, "size") + tdSql.checkData(4, 0, "loc") + + + cursor1.close() + cursor2.close() + conn1.close() + conn2.close() + +clients = TwoClients() +clients.initConnection() +clients.run() \ No newline at end of file diff --git a/tests/pytest/fulltest.sh b/tests/pytest/fulltest.sh index bfa546f92e6850cad1c4c070d149961221e41e22..c74fb33c3b67dd49abf2bf8f915d360216aa562f 100755 --- a/tests/pytest/fulltest.sh +++ b/tests/pytest/fulltest.sh @@ -187,6 +187,7 @@ python3 ./test.py -f functions/function_top.py #python3 ./test.py -f functions/function_twa.py python3 queryCount.py python3 ./test.py -f query/queryGroupbyWithInterval.py +python3 client/twoClients.py # tools python3 test.py -f tools/taosdemo.py diff --git a/tests/script/general/parser/fill.sim b/tests/script/general/parser/fill.sim index 488f807fbc710199fa7489cf67d010d3e12bcc9a..f89c27d71fd8ba02105f502afd4df26a1870ffb5 100644 --- a/tests/script/general/parser/fill.sim +++ b/tests/script/general/parser/fill.sim @@ -850,6 +850,8 @@ if $rows != 12 then return -1 endi +print =====================>td-1442 +sql_error select count(*) from m_fl_tb0 interval(1s) fill(prev); print =============== clear sql drop database $db diff --git a/tests/script/general/parser/first_last_query.sim b/tests/script/general/parser/first_last_query.sim index d11bdccb12066fb0d9249b3117f8b0dc00a5eca5..8127c1923015e130a85a98a50cd8d4bca23fedb3 100644 --- a/tests/script/general/parser/first_last_query.sim +++ b/tests/script/general/parser/first_last_query.sim @@ -65,22 +65,23 @@ endi if $data00 != @18-09-18 01:40:00.000@ then return -1 endi -#if $data01 != NULL then + if $data01 != 999 then return -1 -endi -#if $data02 != NULL then +endi + if $data02 != 999 then return -1 -endi -#if $data03 != NULL then +endi + if $data03 != 999.00000 then return -1 endi -#if $data04 != NULL then + if $data04 != 999.000000000 then return -1 endi + #if $data05 != NULL then if $data05 != 999 then return -1 @@ -127,7 +128,7 @@ if $data01 != 0 then return -1 endi -#add check for out of range first/last query +print =============> add check for out of range first/last query sql select first(ts),last(ts) from first_tb4 where ts>'2018-9-18 1:40:01'; if $row != 0 then return -1 @@ -136,4 +137,130 @@ endi sql select first(ts),last(ts) from first_tb4 where ts<'2018-9-17 8:50:0'; if $row != 0 then return -1 +endi + +#first/last mix up query +#select first(size),last(size) from stest interval(1d) group by tbname; +print =====================>td-1477 + +sql create table stest(ts timestamp,size INT,filenum INT) tags (appname binary(500),tenant binary(500)); +sql insert into test1 using stest tags('test1','aaa') values ('2020-09-04 16:53:54.003',210,3); +sql insert into test2 using stest tags('test1','aaa') values ('2020-09-04 16:53:56.003',210,3); +sql insert into test11 using stest tags('test11','bbb') values ('2020-09-04 16:53:57.003',210,3); +sql insert into test12 using stest tags('test11','bbb') values ('2020-09-04 16:53:58.003',210,3); +sql insert into test21 using stest tags('test21','ccc') values ('2020-09-04 16:53:59.003',210,3); +sql insert into test22 using stest tags('test21','ccc') values ('2020-09-04 16:54:54.003',210,3); +sql select sum(size) from stest group by appname; +if $rows != 3 then + return -1 +endi + +if $data00 != 420 then + return -1 +endi +if $data10 != 420 then + return -1 +endi +if $data20 != 420 then + return -1 +endi + +if $data01 != @test1@ then +return -1 +endi +if $data11 != @test11@ then +return -1 +endi +if $data21 != @test21@ then +return -1 +endi + +sql select sum(size) from stest interval(1d) group by appname; +if $rows != 3 then + return -1 +endi + +#2020-09-04 00:00:00.000 | 420 | test1 | +#2020-09-04 00:00:00.000 | 420 | test11 | +#2020-09-04 00:00:00.000 | 420 | test21 | +if $data00 != @20-09-04 00:00:00.000@ then + return -1 +endi + +if $data10 != @20-09-04 00:00:00.000@ then + return -1 +endi + +if $data20 != @20-09-04 00:00:00.000@ then + return -1 +endi + +if $data01 != 420 then + print expect 420 , actual $data01 + return -1 +endi + +if $data11 != 420 then + return -1 +endi + +if $data21 != 420 then + return -1 +endi + +if $data02 != @test1@ then +return -1 +endi +if $data12 != @test11@ then +return -1 +endi +if $data22 != @test21@ then +return -1 +endi + +print ===================>td-1477, one table has only one block occurs this bug. +sql select first(size),count(*),LAST(SIZE) from stest where tbname in ('test1', 'test2') interval(1d) group by tbname; +if $rows != 2 then + return -1 +endi + +if $data00 != @20-09-04 00:00:00.000@ then + return -1 +endi + +if $data01 != 210 then + return -1 +endi + +if $data02 != 1 then + return -1 +endi + +if $data03 != 210 then + return -1 +endi + +if $data04 != @test1@ then + return -1 +endi + +if $data10 != @20-09-04 00:00:00.000@ then + return -1 +endi + +if $data11 != 210 then + return -1 +endi + +if $data12 != 1 then + return -1 +endi + +if $data13 != 210 then + return -1 +endi + +if $data14 != @test2@ then + print expect test2 , actual: $data14 + return -1 endi \ No newline at end of file diff --git a/tests/script/general/parser/lastrow_query.sim b/tests/script/general/parser/lastrow_query.sim index e9d8ce413dd6a4683019f70f3801cf2cc702c00d..f81a48d5b2d61ddf829920201dd01f5dd1ee44ba 100644 --- a/tests/script/general/parser/lastrow_query.sim +++ b/tests/script/general/parser/lastrow_query.sim @@ -218,4 +218,10 @@ endi if $data04 != 123.981000000 then print expect 123.981000000, actual: $data04 return -1 +endi + +sql create table tu(ts timestamp, k int) +sql select last_row(*) from tu +if $row != 0 then + return -1 endi \ No newline at end of file