diff --git a/src/client/inc/tscSecondaryMerge.h b/src/client/inc/tscSecondaryMerge.h index fb38326b8cbafb008619cbde1432b2f8160597a4..3b0e47f216dbe656600001da58a21ec9eee922f2 100644 --- a/src/client/inc/tscSecondaryMerge.h +++ b/src/client/inc/tscSecondaryMerge.h @@ -21,7 +21,7 @@ extern "C" { #endif #include "qextbuffer.h" -#include "qinterpolation.h" +#include "qfill.h" #include "taosmsg.h" #include "tlosertree.h" #include "tsclient.h" diff --git a/src/client/src/tscFunctionImpl.c b/src/client/src/tscFunctionImpl.c index 232bb813c623cc53f30426d20e8349cc0de09a79..f3e24e43a9e2a27a30cec01fd2d5bcce75ce63b0 100644 --- a/src/client/src/tscFunctionImpl.c +++ b/src/client/src/tscFunctionImpl.c @@ -16,8 +16,8 @@ #include "os.h" #include "qast.h" #include "qextbuffer.h" +#include "qfill.h" #include "qhistogram.h" -#include "qinterpolation.h" #include "qpercentile.h" #include "qsyntaxtreefunction.h" #include "qtsbuf.h" @@ -3418,6 +3418,7 @@ static void spread_function(SQLFunctionCtx *pCtx) { int32_t numOfElems = pCtx->size; + // todo : opt with pre-calculated result // column missing cause the hasNull to be true if (usePreVal(pCtx)) { numOfElems = pCtx->size - pCtx->preAggVals.statis.numOfNull; @@ -3446,13 +3447,13 @@ static void spread_function(SQLFunctionCtx *pCtx) { } } } else { - if (pInfo->min > pCtx->param[1].dKey) { - pInfo->min = pCtx->param[1].dKey; - } - - if (pInfo->max < pCtx->param[2].dKey) { - pInfo->max = pCtx->param[2].dKey; - } +// if (pInfo->min > pCtx->param[1].dKey) { +// pInfo->min = pCtx->param[1].dKey; +// } +// +// if (pInfo->max < pCtx->param[2].dKey) { +// pInfo->max = pCtx->param[2].dKey; +// } } void *pData = GET_INPUT_CHAR(pCtx); diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 532ba4986cd706aafe15d060e71919397c66f945..a5ea6583c10371f972e642f13cbdf851490e0aed 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -5562,7 +5562,15 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) { } ret = tVariantDump(&(pList->a[i].pVar), varDataVal(tagVal), pTagSchema[i].type); - varDataSetLen(tagVal, pList->a[i].pVar.nLen); + if (pList->a[i].pVar.nType == TSDB_DATA_TYPE_NULL) { + if (pTagSchema[i].type == TSDB_DATA_TYPE_BINARY) { + varDataSetLen(tagVal, sizeof(uint8_t)); + } else { + varDataSetLen(tagVal, sizeof(uint32_t)); + } + } else { // todo refactor + varDataSetLen(tagVal, pList->a[i].pVar.nLen); + } } else { ret = tVariantDump(&(pList->a[i].pVar), tagVal, pTagSchema[i].type); } diff --git a/src/client/src/tscSecondaryMerge.c b/src/client/src/tscSecondaryMerge.c index fc397cbd013369c904b02f15504af97f70c84d4e..575f7ee8f43a4a4bc7c7aeec8f062e0a829bac63 100644 --- a/src/client/src/tscSecondaryMerge.c +++ b/src/client/src/tscSecondaryMerge.c @@ -367,7 +367,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd int32_t startIndex = pQueryInfo->fieldsInfo.numOfOutput - pQueryInfo->groupbyExpr.numOfGroupCols; - if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) { + if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 && pReducer->pFillInfo != NULL) { pReducer->pFillInfo->pTags[0] = (char *)pReducer->pFillInfo->pTags + POINTER_BYTES * pQueryInfo->groupbyExpr.numOfGroupCols; for (int32_t i = 1; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) { SSchema *pSchema = getColumnModelSchema(pReducer->resColModel, startIndex + i - 1); diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index a4f84e5091b32627f55d1f924f93fb5ed1b59972..3a205924bf934ddb3ddf85604f349cbd9431c85c 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -1879,9 +1879,7 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) { static void transferNcharData(SSqlObj *pSql, int32_t columnIndex, TAOS_FIELD *pField) { SSqlRes *pRes = &pSql->res; - if (pRes->tsrow[columnIndex] != NULL && isNull(pRes->tsrow[columnIndex], pField->type)) { - pRes->tsrow[columnIndex] = NULL; - } else if (pField->type == TSDB_DATA_TYPE_NCHAR) { + if (pRes->tsrow[columnIndex] != NULL && pField->type == TSDB_DATA_TYPE_NCHAR) { // convert unicode to native code in a temporary buffer extra one byte for terminated symbol if (pRes->buffer[columnIndex] == NULL) { pRes->buffer[columnIndex] = malloc(pField->bytes + TSDB_NCHAR_SIZE); @@ -1893,7 +1891,7 @@ static void transferNcharData(SSqlObj *pSql, int32_t columnIndex, TAOS_FIELD *pF if (taosUcs4ToMbs(pRes->tsrow[columnIndex], pField->bytes - VARSTR_HEADER_SIZE, pRes->buffer[columnIndex])) { pRes->tsrow[columnIndex] = pRes->buffer[columnIndex]; } else { - tscError("%p charset:%s to %s. val:%ls convert failed.", pSql, DEFAULT_UNICODE_ENCODEC, tsCharset, pRes->tsrow); + tscError("%p charset:%s to %s. val:%ls convert failed.", pSql, DEFAULT_UNICODE_ENCODEC, tsCharset, pRes->tsrow[columnIndex]); pRes->tsrow[columnIndex] = NULL; } } diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 81aaab93c2d7d1c1de90b52e83f302bec4f08e32..296ffe33339eedd0574406551d4d9bf0cfa7792f 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -2126,16 +2126,26 @@ void tscGetResultColumnChr(SSqlRes* pRes, SFieldInfo* pFieldInfo, int32_t column int32_t realLen = varDataLen(pData); assert(realLen <= bytes - VARSTR_HEADER_SIZE); + if (isNull(pData, type)) { + pRes->tsrow[columnIndex] = NULL; + } else { + pRes->tsrow[columnIndex] = pData + VARSTR_HEADER_SIZE; + } + if (realLen < pInfo->pSqlExpr->resBytes - VARSTR_HEADER_SIZE) { // todo refactor *(char*) (pData + realLen + VARSTR_HEADER_SIZE) = 0; } - pRes->tsrow[columnIndex] = pData + VARSTR_HEADER_SIZE; pRes->length[columnIndex] = realLen; } else { assert(bytes == tDataTypeDesc[type].nSize); - pRes->tsrow[columnIndex] = pData; + if (isNull(pData, type)) { + pRes->tsrow[columnIndex] = NULL; + } else { + pRes->tsrow[columnIndex] = pData; + } + pRes->length[columnIndex] = bytes; } } diff --git a/src/common/src/ttypes.c b/src/common/src/ttypes.c index a972881a41a054f92ae34608bb1f038a5d52680d..0037c6c688b1375b9bb888d455dae61436f3a516 100644 --- a/src/common/src/ttypes.c +++ b/src/common/src/ttypes.c @@ -402,7 +402,7 @@ void setNullN(char *val, int32_t type, int32_t bytes, int32_t numOfElems) { *(uint64_t *)(val + i * tDataTypeDesc[type].nSize) = TSDB_DATA_DOUBLE_NULL; } break; - case TSDB_DATA_TYPE_NCHAR: + case TSDB_DATA_TYPE_NCHAR: // todo : without length? for (int32_t i = 0; i < numOfElems; ++i) { *(uint32_t *)(val + i * bytes) = TSDB_DATA_NCHAR_NULL; } diff --git a/src/query/inc/qExecutor.h b/src/query/inc/qExecutor.h index c5442d17c7e01de4a94ba7c453ef2851d0f3435d..3f4618bf1cff651af09efaf6c20f55958b8f1e74 100644 --- a/src/query/inc/qExecutor.h +++ b/src/query/inc/qExecutor.h @@ -18,15 +18,15 @@ #include "os.h" #include "hash.h" -#include "tsdb.h" -#include "qinterpolation.h" +#include "qfill.h" #include "qresultBuf.h" #include "qsqlparser.h" #include "qtsbuf.h" #include "taosdef.h" +#include "tarray.h" #include "tref.h" +#include "tsdb.h" #include "tsqlfunction.h" -#include "tarray.h" //typedef struct tFilePage { // int64_t num; @@ -154,7 +154,7 @@ typedef struct SQueryRuntimeEnv { int16_t numOfRowsPerPage; int16_t offset[TSDB_MAX_COLUMNS]; uint16_t scanFlag; // denotes reversed scan of data or not - SFillInfo* pFillInfo; + SFillInfo* pFillInfo; SWindowResInfo windowResInfo; STSBuf* pTSBuf; STSCursor cur; diff --git a/src/query/inc/qinterpolation.h b/src/query/inc/qfill.h similarity index 95% rename from src/query/inc/qinterpolation.h rename to src/query/inc/qfill.h index fccae6172986de78ec4fb95f30e380cd1f34424e..d0ba8941b215f4de141e4914b52a4cf482b4d27e 100644 --- a/src/query/inc/qinterpolation.h +++ b/src/query/inc/qfill.h @@ -13,8 +13,8 @@ * along with this program. If not, see . */ -#ifndef TDENGINE_TINTERPOLATION_H -#define TDENGINE_TINTERPOLATION_H +#ifndef TDENGINE_QFILL_H +#define TDENGINE_QFILL_H #ifdef __cplusplus extern "C" { @@ -58,7 +58,7 @@ typedef struct SPoint { void * val; } SPoint; -int64_t taosGetIntervalStartTimestamp(int64_t startTime, int64_t timeRange, char intervalTimeUnit, int16_t precision); +int64_t taosGetIntervalStartTimestamp(int64_t startTime, int64_t slidingTime, char timeUnit, int16_t precision); SFillInfo* taosInitFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int32_t capacity, int32_t numOfCols, int64_t slidingTime, int32_t fillType, SFillColInfo* pFillCol); @@ -89,4 +89,4 @@ void taosGenerateDataBlock(SFillInfo* pFillInfo, tFilePage** output, int64_t* ou } #endif -#endif // TDENGINE_TINTERPOLATION_H +#endif // TDENGINE_QFILL_H diff --git a/src/query/inc/queryLog.h b/src/query/inc/queryLog.h index 4894d67e0415d57ceb7bd3fed6499cd4fad1658c..32338a4143ef63495235b8ac0da19661654cd9a3 100644 --- a/src/query/inc/queryLog.h +++ b/src/query/inc/queryLog.h @@ -13,8 +13,8 @@ * along with this program. If not, see . */ -#ifndef TDENGINE_RPC_LOG_H -#define TDENGINE_RPC_LOG_H +#ifndef TDENGINE_QUERY_LOG_H +#define TDENGINE_QUERY_LOG_H #ifdef __cplusplus extern "C" { @@ -24,22 +24,23 @@ extern "C" { extern int32_t qDebugFlag; -#define qTrace(...) \ - if (qDebugFlag & DEBUG_TRACE) { \ - taosPrintLog("DND QRY ", qDebugFlag, __VA_ARGS__); \ +#define qTrace(...) \ + if (qDebugFlag & DEBUG_TRACE) { \ + taosPrintLog("QRY ", qDebugFlag, __VA_ARGS__); \ } -#define qError(...) \ - if (qDebugFlag & DEBUG_ERROR) { \ +#define qError(...) \ + if (qDebugFlag & DEBUG_ERROR) { \ taosPrintLog("ERROR QRY ", qDebugFlag, __VA_ARGS__); \ } -#define qWarn(...) \ - if (qDebugFlag & DEBUG_WARN) { \ - taosPrintLog("WARN QRY ", qDebugFlag, __VA_ARGS__); \ - } + +#define qWarn(...) \ + if (qDebugFlag & DEBUG_WARN) { \ + taosPrintLog("WARN QRY ", qDebugFlag, __VA_ARGS__); \ + } #ifdef __cplusplus } #endif -#endif // TDENGINE_RPC_CACHE_H +#endif // TDENGINE_QUERY_CACHE_H diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 81b179fbe636fb11f0b19f3e26d1b55888d4b0c1..11b7692e7ea65169dfb50ac66cf1b1d85e9abab9 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -12,7 +12,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -#include +#include #include "os.h" #include "hash.h" @@ -1203,11 +1203,9 @@ static void rowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pS while (1) { getNextTimeWindow(pQuery, &nextWin); - assert(pWindowResInfo->startTime <= nextWin.skey); - - if (pWindowResInfo->startTime > nextWin.skey || + if (/*pWindowResInfo->startTime > nextWin.skey ||*/ (nextWin.skey > pQuery->window.ekey && QUERY_IS_ASC_QUERY(pQuery)) || - (nextWin.skey > pQuery->window.skey && !QUERY_IS_ASC_QUERY(pQuery))) { + (nextWin.skey < pQuery->window.ekey && !QUERY_IS_ASC_QUERY(pQuery))) { break; } @@ -1337,7 +1335,6 @@ void setExecParams(SQuery *pQuery, SQLFunctionCtx *pCtx, void *inputData, TSKEY // last_dist or first_dist function // store the first&last timestamp into the intermediate buffer [1], the true // value may be null but timestamp will never be null - // pCtx->ptsList = tsCol; } else if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_TWA || functionId == TSDB_FUNC_DIFF || (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_AVG_IRATE)) { /* @@ -2374,7 +2371,7 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) { SDataBlockInfo blockInfo = tsdbRetrieveDataBlockInfo(pQueryHandle); // todo extract methods - if (isIntervalQuery(pQuery) && pRuntimeEnv->windowResInfo.prevSKey == 0) { + if (isIntervalQuery(pQuery) && pRuntimeEnv->windowResInfo.prevSKey == TSKEY_INITIAL_VAL) { TSKEY skey1, ekey1; STimeWindow w = TSWINDOW_INITIALIZER; SWindowResInfo *pWindowResInfo = &pRuntimeEnv->windowResInfo; @@ -3258,16 +3255,19 @@ bool needScanDataBlocksAgain(SQueryRuntimeEnv *pRuntimeEnv) { return toContinue; } -static SQueryStatusInfo getQueryStatusInfo(SQueryRuntimeEnv *pRuntimeEnv) { +static SQueryStatusInfo getQueryStatusInfo(SQueryRuntimeEnv *pRuntimeEnv, TSKEY start) { SQuery *pQuery = pRuntimeEnv->pQuery; STableQueryInfo* pTableQueryInfo = pQuery->current; + assert((start <= pTableQueryInfo->lastKey && QUERY_IS_ASC_QUERY(pQuery)) || + (start >= pTableQueryInfo->lastKey && !QUERY_IS_ASC_QUERY(pQuery))); + SQueryStatusInfo info = { .status = pQuery->status, .windowIndex = pRuntimeEnv->windowResInfo.curIndex, - .lastKey = pTableQueryInfo->lastKey, + .lastKey = start, .w = pQuery->window, - .curWindow = {.skey = pTableQueryInfo->lastKey, .ekey = pTableQueryInfo->win.ekey}, + .curWindow = {.skey = start, .ekey = pTableQueryInfo->win.ekey}, }; return info; @@ -3330,7 +3330,7 @@ static void clearEnvAfterReverseScan(SQueryRuntimeEnv *pRuntimeEnv, SQueryStatus pTableQueryInfo->win = pStatus->w; } -void scanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) { +void scanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv, TSKEY start) { SQInfo *pQInfo = (SQInfo *) GET_QINFO_ADDR(pRuntimeEnv); SQuery *pQuery = pRuntimeEnv->pQuery; STableQueryInfo *pTableQueryInfo = pQuery->current; @@ -3338,7 +3338,7 @@ void scanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) { setQueryStatus(pQuery, QUERY_NOT_COMPLETED); // store the start query position - SQueryStatusInfo qstatus = getQueryStatusInfo(pRuntimeEnv); + SQueryStatusInfo qstatus = getQueryStatusInfo(pRuntimeEnv, start); SET_MASTER_SCAN_FLAG(pRuntimeEnv); int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); @@ -3995,8 +3995,9 @@ void skipBlocks(SQueryRuntimeEnv *pRuntimeEnv) { } } -static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv) { +static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv, TSKEY* start) { SQuery *pQuery = pRuntimeEnv->pQuery; + *start = pQuery->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) { @@ -4019,13 +4020,14 @@ static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv) { while (tsdbNextDataBlock(pRuntimeEnv->pQueryHandle)) { SDataBlockInfo blockInfo = tsdbRetrieveDataBlockInfo(pRuntimeEnv->pQueryHandle); - if (QUERY_IS_ASC_QUERY(pQuery) && pWindowResInfo->prevSKey == 0) { - getAlignQueryTimeWindow(pQuery, blockInfo.window.skey, blockInfo.window.skey, pQuery->window.ekey, &skey1, &ekey1, - &w); - pWindowResInfo->startTime = w.skey; - pWindowResInfo->prevSKey = w.skey; + if (QUERY_IS_ASC_QUERY(pQuery)) { + if (pWindowResInfo->prevSKey == TSKEY_INITIAL_VAL) { + getAlignQueryTimeWindow(pQuery, blockInfo.window.skey, blockInfo.window.skey, pQuery->window.ekey, &skey1, + &ekey1, &w); + pWindowResInfo->startTime = w.skey; + pWindowResInfo->prevSKey = w.skey; + } } else { - // the start position of the first time window in the endpoint that spreads beyond the queried last timestamp getAlignQueryTimeWindow(pQuery, blockInfo.window.ekey, pQuery->window.ekey, blockInfo.window.ekey, &skey1, &ekey1, &w); @@ -4049,7 +4051,8 @@ static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv) { if (pQuery->limit.offset == 0) { if ((tw.skey <= blockInfo.window.ekey && QUERY_IS_ASC_QUERY(pQuery)) || (tw.ekey >= blockInfo.window.skey && !QUERY_IS_ASC_QUERY(pQuery))) { - // load the data block + // load the data block and check data remaining in current data block + // TODO optimize performance SArray * pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pQueryHandle, NULL); SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0); @@ -4060,24 +4063,38 @@ static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv) { // set the abort info pQuery->pos = startPos; - pTableQueryInfo->lastKey = ((TSKEY *)pColInfoData->pData)[startPos]; + + // reset the query start timestamp + pTableQueryInfo->win.skey = ((TSKEY *)pColInfoData->pData)[startPos]; + pQuery->window.skey = pTableQueryInfo->win.skey; + *start = pTableQueryInfo->win.skey; + pWindowResInfo->prevSKey = tw.skey; - + int32_t index = pRuntimeEnv->windowResInfo.curIndex; + int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, &blockInfo, NULL, binarySearchForKey, pDataBlock); - + pRuntimeEnv->windowResInfo.curIndex = index; // restore the window index + qTrace("QInfo:%p check data block, brange:%" PRId64 "-%" PRId64 ", rows:%d, res:%d", GET_QINFO_ADDR(pRuntimeEnv), blockInfo.window.skey, blockInfo.window.ekey, blockInfo.rows, numOfRes); return true; - } else { - // do nothing, + } else { // do nothing + *start = tw.skey; + pQuery->window.skey = tw.skey; + pWindowResInfo->prevSKey = tw.skey; return true; } } - // next time window starts from current data block + /* + * If the next time window still starts from current data block, + * load the primary timestamp column first, and then find the start position for the next queried time window. + * Note that only the primary timestamp column is required. + * TODO: Optimize for this cases. All data blocks are not needed to be loaded, only if the first actually required + * time window resides in current data block. + */ if ((tw.skey <= blockInfo.window.ekey && QUERY_IS_ASC_QUERY(pQuery)) || (tw.ekey >= blockInfo.window.skey && !QUERY_IS_ASC_QUERY(pQuery))) { - // load the data block, note that only the primary timestamp column is required SArray * pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->pQueryHandle, NULL); SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0); @@ -4092,7 +4109,7 @@ static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv) { pWindowResInfo->prevSKey = tw.skey; win = tw; } else { - break; // offset is not 0, and next time window locates in the next block. + break; // offset is not 0, and next time window begins or ends in the next block. } } } @@ -4132,7 +4149,11 @@ static void setupQueryHandle(void* tsdb, SQInfo* pQInfo, bool isSTableQuery) { cond.twindow = pItem->info->win; } - pRuntimeEnv->pQueryHandle = tsdbQueryTables(tsdb, &cond, &pQInfo->tableIdGroupInfo); + if (isFirstLastRowQuery(pQuery)) { + pRuntimeEnv->pQueryHandle = tsdbQueryLastRow(tsdb, &cond, &pQInfo->tableIdGroupInfo); + } else { + pRuntimeEnv->pQueryHandle = tsdbQueryTables(tsdb, &cond, &pQInfo->tableIdGroupInfo); + } } @@ -4405,41 +4426,6 @@ static bool multiTableMultioutputHelper(SQInfo *pQInfo, int32_t index) { return true; } -static UNUSED_FUNC int64_t doCheckTables(SQInfo *pQInfo, SArray* pTableList) { - SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv; - SQuery * pQuery = pRuntimeEnv->pQuery; - - if (!multiTableMultioutputHelper(pQInfo, 0)) { - return 0; - } - - SPointInterpoSupporter pointInterpSupporter = {0}; - pointInterpSupporterInit(pQuery, &pointInterpSupporter); - - /* - * here we set the value for before and after the specified time into the - * parameter for interpolation query - */ - pointInterpSupporterSetData(pQInfo, &pointInterpSupporter); - pointInterpSupporterDestroy(&pointInterpSupporter); - - scanAllDataBlocks(pRuntimeEnv); - - // first/last_row query, do not invoke the finalize for super table query - finalizeQueryResult(pRuntimeEnv); - - int64_t numOfRes = getNumOfResult(pRuntimeEnv); - assert(numOfRes == 1 || numOfRes == 0); - - // accumulate the point interpolation result - if (numOfRes > 0) { - pQuery->rec.rows += numOfRes; - forwardCtxOutputBuf(pRuntimeEnv, numOfRes); - } - - return numOfRes; -} - /** * super table query handler * 1. super table projection query, group-by on normal columns query, ts-comp query @@ -4490,8 +4476,8 @@ static void sequentialTableProcess(SQInfo *pQInfo) { setTagVal(pRuntimeEnv, (STableId*) taosArrayGet(tx, 0), pQInfo->tsdb); // here we simply set the first table as current table - pRuntimeEnv->pQuery->current = ((SGroupItem*) taosArrayGet(group, 0))->info; - scanAllDataBlocks(pRuntimeEnv); + pQuery->current = ((SGroupItem*) taosArrayGet(group, 0))->info; + scanAllDataBlocks(pRuntimeEnv, pQuery->current->lastKey); int64_t numOfRes = getNumOfResult(pRuntimeEnv); if (numOfRes > 0) { @@ -4551,14 +4537,13 @@ static void sequentialTableProcess(SQInfo *pQInfo) { // TODO handle the limit offset problem if (pQuery->numOfFilterCols == 0 && pQuery->limit.offset > 0) { // skipBlocks(pRuntimeEnv); - if (Q_STATUS_EQUAL(pQuery->status, QUERY_COMPLETED)) { pQInfo->tableIndex++; continue; } } - scanAllDataBlocks(pRuntimeEnv); + scanAllDataBlocks(pRuntimeEnv, pQuery->current->lastKey); pQuery->rec.rows = getNumOfResult(pRuntimeEnv); skipResults(pRuntimeEnv); @@ -4807,23 +4792,22 @@ static void tableFixedOutputProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv; SQuery *pQuery = pRuntimeEnv->pQuery; + if (!isTopBottomQuery(pQuery) && pQuery->limit.offset > 0) { // no need to execute, since the output will be ignore. + return; + } + pQuery->current = pTableInfo; // set current query table info - scanAllDataBlocks(pRuntimeEnv); + scanAllDataBlocks(pRuntimeEnv, pTableInfo->lastKey); finalizeQueryResult(pRuntimeEnv); if (isQueryKilled(pQInfo)) { return; } - // since the numOfOutputElems must be identical for all sql functions that are allowed to be executed simutanelously. + // since the numOfRows must be identical for all sql functions that are allowed to be executed simutaneously. pQuery->rec.rows = getNumOfResult(pRuntimeEnv); - // must be top/bottom query if offset > 0 - if (pQuery->limit.offset > 0) { - assert(isTopBottomQuery(pQuery)); - } - skipResults(pRuntimeEnv); limitResults(pQInfo); } @@ -4847,7 +4831,7 @@ static void tableMultiOutputProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) } while (1) { - scanAllDataBlocks(pRuntimeEnv); + scanAllDataBlocks(pRuntimeEnv, pQuery->current->lastKey); finalizeQueryResult(pRuntimeEnv); if (isQueryKilled(pQInfo)) { @@ -4890,11 +4874,11 @@ static void tableMultiOutputProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) } } -static void tableIntervalProcessImpl(SQueryRuntimeEnv *pRuntimeEnv) { +static void tableIntervalProcessImpl(SQueryRuntimeEnv *pRuntimeEnv, TSKEY start) { SQuery *pQuery = pRuntimeEnv->pQuery; while (1) { - scanAllDataBlocks(pRuntimeEnv); + scanAllDataBlocks(pRuntimeEnv, start); if (isQueryKilled(GET_QINFO_ADDR(pRuntimeEnv))) { return; @@ -4925,19 +4909,21 @@ static void tableIntervalProcessImpl(SQueryRuntimeEnv *pRuntimeEnv) { static void tableIntervalProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) { SQueryRuntimeEnv *pRuntimeEnv = &(pQInfo->runtimeEnv); - int32_t numOfInterpo = 0; SQuery *pQuery = pRuntimeEnv->pQuery; pQuery->current = pTableInfo; + int32_t numOfInterpo = 0; + TSKEY newStartKey = TSKEY_INITIAL_VAL; + // skip blocks without load the actual data block from file if no filter condition present - skipTimeInterval(pRuntimeEnv); + skipTimeInterval(pRuntimeEnv, &newStartKey); if (pQuery->limit.offset > 0 && pQuery->numOfFilterCols == 0 && pRuntimeEnv->pFillInfo == NULL) { setQueryStatus(pQuery, QUERY_COMPLETED); return; } while (1) { - tableIntervalProcessImpl(pRuntimeEnv); + tableIntervalProcessImpl(pRuntimeEnv, newStartKey); if (isIntervalQuery(pQuery)) { pQInfo->groupIndex = 0; // always start from 0 @@ -6268,10 +6254,10 @@ static void buildTagQueryResult(SQInfo* pQInfo) { memcpy(dst, data, bytes); } } - } } + pQInfo->tableIndex = pQInfo->groupInfo.numOfTables; qTrace("QInfo:%p create tag values results completed, rows:%d", pQInfo, num); } diff --git a/src/query/src/qUtil.c b/src/query/src/qUtil.c index 87ad9dbeb4601e08c92de4ba98f296c3eb30c0db..2d713e127f0acaf16349ebb19fca92719c7d8a26 100644 --- a/src/query/src/qUtil.c +++ b/src/query/src/qUtil.c @@ -20,7 +20,7 @@ #include "qextbuffer.h" #include "ttime.h" -#include "qinterpolation.h" +#include "qfill.h" #include "ttime.h" #include "qExecutor.h" @@ -37,7 +37,8 @@ int32_t initWindowResInfo(SWindowResInfo *pWindowResInfo, SQueryRuntimeEnv *pRun pWindowResInfo->hashList = taosHashInit(threshold, fn, false); pWindowResInfo->curIndex = -1; - pWindowResInfo->size = 0; + pWindowResInfo->size = 0; + pWindowResInfo->prevSKey = TSKEY_INITIAL_VAL; // use the pointer arraylist pWindowResInfo->pResult = calloc(threshold, sizeof(SWindowResult)); @@ -96,8 +97,8 @@ void resetTimeWindowInfo(SQueryRuntimeEnv *pRuntimeEnv, SWindowResInfo *pWindowR _hash_fn_t fn = taosGetDefaultHashFunction(pWindowResInfo->type); pWindowResInfo->hashList = taosHashInit(pWindowResInfo->capacity, fn, false); - pWindowResInfo->startTime = 0; - pWindowResInfo->prevSKey = 0; + pWindowResInfo->startTime = TSKEY_INITIAL_VAL; + pWindowResInfo->prevSKey = TSKEY_INITIAL_VAL; } void clearFirstNTimeWindow(SQueryRuntimeEnv *pRuntimeEnv, int32_t num) { diff --git a/src/query/src/qinterpolation.c b/src/query/src/qfill.c similarity index 97% rename from src/query/src/qinterpolation.c rename to src/query/src/qfill.c index 6573f38682062bef41e9d25ecc89b4874a6f16a8..4f69c449401bef1ab6f30a42aaa09c2f3aa14a85 100644 --- a/src/query/src/qinterpolation.c +++ b/src/query/src/qfill.c @@ -13,7 +13,7 @@ * along with this program. If not, see . */ -#include "qinterpolation.h" +#include "qfill.h" #include "os.h" #include "qextbuffer.h" #include "taosdef.h" @@ -22,13 +22,13 @@ #define FILL_IS_ASC_FILL(_f) ((_f)->order == TSDB_ORDER_ASC) -int64_t taosGetIntervalStartTimestamp(int64_t startTime, int64_t timeRange, char intervalTimeUnit, int16_t precision) { - if (timeRange == 0) { +int64_t taosGetIntervalStartTimestamp(int64_t startTime, int64_t slidingTime, char timeUnit, int16_t precision) { + if (slidingTime == 0) { return startTime; } - if (intervalTimeUnit == 'a' || intervalTimeUnit == 'm' || intervalTimeUnit == 's' || intervalTimeUnit == 'h') { - return (startTime / timeRange) * timeRange; + if (timeUnit == 'a' || timeUnit == 'm' || timeUnit == 's' || timeUnit == 'h') { + return (startTime / slidingTime) * slidingTime; } else { /* * here we revised the start time of day according to the local time zone, @@ -47,10 +47,10 @@ int64_t taosGetIntervalStartTimestamp(int64_t startTime, int64_t timeRange, char int64_t t = (precision == TSDB_TIME_PRECISION_MILLI) ? MILLISECOND_PER_SECOND : MILLISECOND_PER_SECOND * 1000L; - int64_t revStartime = (startTime / timeRange) * timeRange + timezone * t; - int64_t revEndtime = revStartime + timeRange - 1; + int64_t revStartime = (startTime / slidingTime) * slidingTime + timezone * t; + int64_t revEndtime = revStartime + slidingTime - 1; if (revEndtime < startTime) { - revStartime += timeRange; + revStartime += slidingTime; } return revStartime; diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c index 742d7c9f5847eaa301a469a248d7f6e8c03d9c9b..71d0454893a2b13ecaf24bed2f7a53dc708b8f78 100644 --- a/src/tsdb/src/tsdbRead.c +++ b/src/tsdb/src/tsdbRead.c @@ -318,12 +318,12 @@ static bool hasMoreDataInCache(STsdbQueryHandle* pHandle) { if (pCheckInfo->iter == NULL) { return false; } - } - if (!tSkipListIterNext(pCheckInfo->iter)) { // buffer is empty - return false; + if (!tSkipListIterNext(pCheckInfo->iter)) { // buffer is empty + return false; + } } - + SSkipListNode* node = tSkipListIterGet(pCheckInfo->iter); if (node == NULL) { return false; @@ -576,12 +576,12 @@ static bool loadFileDataBlock(STsdbQueryHandle* pQueryHandle, SCompBlock* pBlock } } + cur->pos = 0; if ((k1 != TSKEY_INITIAL_VAL && k1 < binfo.window.ekey) || (k2 != TSKEY_INITIAL_VAL && k2 < binfo.window.ekey)) { doLoadFileDataBlock(pQueryHandle, pBlock, pCheckInfo); mergeDataInDataBlock(pQueryHandle, pCheckInfo, pBlock, sa); } else { pQueryHandle->realNumOfRows = binfo.rows; - cur->pos = 0; } } } else { //desc order @@ -638,9 +638,11 @@ static bool loadFileDataBlock(STsdbQueryHandle* pQueryHandle, SCompBlock* pBlock } cur->pos = binfo.rows - 1; - if ((k1 != TSKEY_INITIAL_VAL && k1 < binfo.window.ekey) || (k2 != TSKEY_INITIAL_VAL && k2 < binfo.window.ekey)) { + if ((k1 != TSKEY_INITIAL_VAL && k1 > binfo.window.ekey) || (k2 != TSKEY_INITIAL_VAL && k2 > binfo.window.ekey)) { doLoadFileDataBlock(pQueryHandle, pBlock, pCheckInfo); mergeDataInDataBlock(pQueryHandle, pCheckInfo, pBlock, sa); + } else { + pQueryHandle->realNumOfRows = binfo.rows; } } // pQueryHandle->realNumOfRows = pBlock->numOfPoints; @@ -713,8 +715,7 @@ static int vnodeBinarySearchKey(char* pValue, int num, TSKEY key, int order) { return midPos; } -static int32_t copyDataFromFileBlock(STsdbQueryHandle* pQueryHandle, SDataBlockInfo* pBlockInfo, int32_t capacity, - int32_t numOfRows, int32_t start, int32_t end) { +static int32_t copyDataFromFileBlock(STsdbQueryHandle* pQueryHandle, int32_t capacity, int32_t numOfRows, int32_t start, int32_t end) { char* pData = NULL; int32_t step = ASCENDING_ORDER_TRAVERSE(pQueryHandle->order)? 1 : -1; @@ -844,7 +845,7 @@ static void mergeDataInDataBlock(STsdbQueryHandle* pQueryHandle, STableCheckInfo cur->win.ekey = tsArray[end]; // todo opt in case of no data in buffer - numOfRows = copyDataFromFileBlock(pQueryHandle, &blockInfo, pQueryHandle->outputCapacity, numOfRows, start, end); + numOfRows = copyDataFromFileBlock(pQueryHandle, pQueryHandle->outputCapacity, numOfRows, start, end); // if the buffer is not full in case of descending order query, move the data in the front of the buffer if (!ASCENDING_ORDER_TRAVERSE(pQueryHandle->order) && numOfRows < pQueryHandle->outputCapacity) { @@ -857,6 +858,9 @@ static void mergeDataInDataBlock(STsdbQueryHandle* pQueryHandle, STableCheckInfo } } + cur->blockCompleted = (((pos >= endPos || cur->lastKey > pQueryHandle->window.ekey) && ASCENDING_ORDER_TRAVERSE(pQueryHandle->order)) || + ((pos <= endPos || cur->lastKey < pQueryHandle->window.ekey) && !ASCENDING_ORDER_TRAVERSE(pQueryHandle->order))); + pCheckInfo->lastKey = cur->lastKey; pQueryHandle->realNumOfRows = numOfRows; cur->rows = numOfRows; @@ -927,8 +931,7 @@ static void mergeDataInDataBlock(STsdbQueryHandle* pQueryHandle, STableCheckInfo end = pos; } - numOfRows = - copyDataFromFileBlock(pQueryHandle, &blockInfo, pQueryHandle->outputCapacity, numOfRows, start, end); + numOfRows = copyDataFromFileBlock(pQueryHandle, pQueryHandle->outputCapacity, numOfRows, start, end); pos += (end - start + 1) * step; } } while (numOfRows < pQueryHandle->outputCapacity); @@ -964,8 +967,7 @@ static void mergeDataInDataBlock(STsdbQueryHandle* pQueryHandle, STableCheckInfo end = pos; } - numOfRows = - copyDataFromFileBlock(pQueryHandle, &blockInfo, pQueryHandle->outputCapacity, numOfRows, start, end); + numOfRows = copyDataFromFileBlock(pQueryHandle, pQueryHandle->outputCapacity, numOfRows, start, end); pos += (end - start + 1) * step; } else { @@ -993,8 +995,8 @@ static void mergeDataInDataBlock(STsdbQueryHandle* pQueryHandle, STableCheckInfo } } - cur->blockCompleted = ((pos >= endPos && ASCENDING_ORDER_TRAVERSE(pQueryHandle->order)) || - (pos <= endPos && !ASCENDING_ORDER_TRAVERSE(pQueryHandle->order))); + cur->blockCompleted = (((pos >= endPos || cur->lastKey > pQueryHandle->window.ekey) && ASCENDING_ORDER_TRAVERSE(pQueryHandle->order)) || + ((pos <= endPos || cur->lastKey < pQueryHandle->window.ekey) && !ASCENDING_ORDER_TRAVERSE(pQueryHandle->order))); if (!ASCENDING_ORDER_TRAVERSE(pQueryHandle->order)) { SWAP(cur->win.skey, cur->win.ekey, TSKEY); @@ -1342,35 +1344,9 @@ bool tsdbNextDataBlock(TsdbQueryHandleT* pqHandle) { pQueryHandle->checkFiles = false; } -// if (ASCENDING_ORDER_TRAVERSE(pQueryHandle->order)) { - return doHasDataInBuffer(pQueryHandle); -// } else { -// assert(0); -// return false; -// } - -// if (ASCENDING_ORDER_TRAVERSE(pQueryHandle->order)) { -// if (pQueryHandle->checkFiles) { -// if (getDataBlocksInFiles(pQueryHandle)) { -// return true; -// } -// -// pQueryHandle->activeIndex = 0; -// pQueryHandle->checkFiles = false; -// } -// -// return doHasDataInBuffer(pQueryHandle); -// } else { // starts from the buffer in case of descending timestamp order check data blocks -// if (!pQueryHandle->checkFiles) { -// if (doHasDataInBuffer(pQueryHandle)) { -// return true; -// } -// -// pQueryHandle->checkFiles = true; -// } -// -// return getDataBlocksInFiles(pQueryHandle); -// } + // TODO: opt by using lastKeyOnFile + // TODO: opt by consider the scan order + return doHasDataInBuffer(pQueryHandle); } void changeQueryHandleForLastrowQuery(TsdbQueryHandleT pqHandle) { @@ -1420,6 +1396,8 @@ void changeQueryHandleForLastrowQuery(TsdbQueryHandleT pqHandle) { taosArrayDestroy(pQueryHandle->pTableCheckInfo); pQueryHandle->pTableCheckInfo = taosArrayInit(1, sizeof(STableCheckInfo)); + + info.lastKey = key; taosArrayPush(pQueryHandle->pTableCheckInfo, &info); // update the query time window according to the chosen last timestamp @@ -1539,27 +1517,6 @@ SDataBlockInfo tsdbRetrieveDataBlockInfo(TsdbQueryHandleT* pQueryHandle) { SDataBlockInfo binfo = getTrueDataBlockInfo(pCheckInfo, pBlockInfo->pBlock.compBlock); return binfo; } -// else { - /* - * no data in mem or imem, or data in mem/imem with greater timestamp, no need to load data in buffer - * return the file block info directly - */ -// if (!pHandle->cur.mixBlock || pHandle->cur.rows == pBlockInfo->pBlock.compBlock->numOfPoints) { -// pBlockInfo->pTableCheckInfo->lastKey = pBlockInfo->pBlock.compBlock->keyLast + step; -// assert(pHandle->outputCapacity >= pBlockInfo->pBlock.compBlock->numOfPoints); -// -// return binfo; -// } else { -// SDataBlockInfo blockInfo = { -// .uid = pTable->tableId.uid, -// .tid = pTable->tableId.tid, -// .rows = pHandle->cur.rows, -// .window = pHandle->cur.win, -// }; -// -// return blockInfo; -// } -// } } else { STableCheckInfo* pCheckInfo = taosArrayGet(pHandle->pTableCheckInfo, pHandle->activeIndex); pTable = pCheckInfo->pTableObj; @@ -1576,6 +1533,10 @@ SDataBlockInfo tsdbRetrieveDataBlockInfo(TsdbQueryHandleT* pQueryHandle) { pCheckInfo->lastKey = win->ekey + step; } + if (!ASCENDING_ORDER_TRAVERSE(pHandle->order)) { + SWAP(pHandle->cur.win.skey, pHandle->cur.win.ekey, TSKEY); + } + SDataBlockInfo blockInfo = { .uid = pTable->tableId.uid, .tid = pTable->tableId.tid, @@ -1618,14 +1579,24 @@ SArray* tsdbRetrieveDataBlock(TsdbQueryHandleT* pQueryHandle, SArray* pIdList) { if (pBlockLoadInfo->slot == pHandle->cur.slot && pBlockLoadInfo->fileGroup->fileId == pHandle->cur.fid && pBlockLoadInfo->tid == pCheckInfo->pTableObj->tableId.tid) { return pHandle->pColumns; - } else { + } else { // only load the file block SCompBlock* pBlock = pBlockInfoEx->pBlock.compBlock; doLoadFileDataBlock(pHandle, pBlock, pCheckInfo); - - SArray* sa = getDefaultLoadColumns(pHandle, true); - mergeDataInDataBlock(pHandle, pCheckInfo, pBlock, sa); - taosArrayDestroy(sa); - + + // todo refactor + int32_t numOfRows = copyDataFromFileBlock(pHandle, pHandle->outputCapacity, 0, 0, pBlock->numOfPoints - 1); + + // if the buffer is not full in case of descending order query, move the data in the front of the buffer + if (!ASCENDING_ORDER_TRAVERSE(pHandle->order) && numOfRows < pHandle->outputCapacity) { + int32_t emptySize = pHandle->outputCapacity - numOfRows; + int32_t reqNumOfCols = taosArrayGetSize(pHandle->pColumns); + + for(int32_t i = 0; i < reqNumOfCols; ++i) { + SColumnInfoData* pColInfo = taosArrayGet(pHandle->pColumns, i); + memmove(pColInfo->pData, pColInfo->pData + emptySize * pColInfo->info.bytes, numOfRows * pColInfo->info.bytes); + } + } + return pHandle->pColumns; } } diff --git a/src/util/src/tskiplist.c b/src/util/src/tskiplist.c index b72db6a8d81a9379ad2fb3b4721ecf96c992580e..f1f34818655bd0ca70d62f1dfe81a5fb14238a68 100644 --- a/src/util/src/tskiplist.c +++ b/src/util/src/tskiplist.c @@ -573,6 +573,7 @@ bool tSkipListIterNext(SSkipListIterator *iter) { pthread_rwlock_unlock(pSkipList->lock); } + iter->step += 1; return (iter->order == TSDB_ORDER_ASC)? (iter->cur != pSkipList->pTail) : (iter->cur != pSkipList->pHead); } diff --git a/tests/script/general/parser/limit_tb.sim b/tests/script/general/parser/limit_tb.sim index 00d49b556fa013383881fd2f25c0b171e1096618..9e62d652e2527c55a02895984877b29904b8ca2a 100644 --- a/tests/script/general/parser/limit_tb.sim +++ b/tests/script/general/parser/limit_tb.sim @@ -111,18 +111,7 @@ endi if $data09 != nchar0 then return -1 endi -if $data11 != NULL then - return -1 -endi -if $data12 != NULL then - return -1 -endi -if $data13 != NULL then - return -1 -endi -if $data14 != NULL then - return -1 -endi + ## TBASE-329 sql select * from $tb where c1 < 9 order by ts desc limit 1 offset 1 @@ -537,7 +526,8 @@ endi if $data14 != 8.000000000 then return -1 endi -if $data21 != NULL then +if $data21 != null then + print expect null, actual: $data21 return -1 endi @@ -554,7 +544,7 @@ endi if $data21 != 9 then return -1 endi -if $data31 != NULL then +if $data31 != null then return -1 endi @@ -574,7 +564,7 @@ endi if $data31 != 9 then return -1 endi -if $data41 != NULL then +if $data41 != null then return -1 endi sql select sum(c1), sum(c2), sum(c3), sum(c4), sum(c5), sum(c6) from $tb where ts >= $ts0 and ts <= $tsu interval(30m) limit 5 offset 1 @@ -590,7 +580,7 @@ endi if $data21 != 9 then return -1 endi -if $data31 != NULL then +if $data31 != null then return -1 endi @@ -607,7 +597,7 @@ endi if $data21 != 7.000000000 then return -1 endi -if $data31 != NULL then +if $data31 != null then return -1 endi sql select avg(c1), avg(c2), avg(c3), avg(c4), avg(c5), avg(c6) from $tb where ts >= $ts0 and ts <= $tsu interval(30m) limit 3 offset 1 @@ -623,7 +613,7 @@ endi if $data21 != 9.000000000 then return -1 endi -if $data31 != NULL then +if $data31 != null then return -1 endi diff --git a/tests/script/general/parser/null_char.sim b/tests/script/general/parser/null_char.sim index d395b4c8baa8f29a5d292cdbc27600fd64522244..7a6c40c1a3fb9d6cabbc0109259d6e976c94556e 100644 --- a/tests/script/general/parser/null_char.sim +++ b/tests/script/general/parser/null_char.sim @@ -84,43 +84,43 @@ endi #### case 1: tag NULL, or 'NULL' sql create table mt2 (ts timestamp, col1 int, col3 float, col5 binary(8), col6 bool, col9 nchar(8)) tags (tag1 binary(8), tag2 nchar(8), tag3 int, tag5 bool) sql create table st2 using mt2 tags (NULL, 'NULL', 102, 'true') -sql describe st2 -if $rows != 10 then +sql select tag1, tag2, tag3, tag5 from st2 +if $rows != 1 then return -1 endi -if $data63 != NULL then - print ==1== expect: NULL, actually: $data63 +if $data00 != NULL then + print ==1== expect: NULL, actually: $data00 return -1 endi -if $data73 != NULL then - print ==2== expect: NULL, actually: $data73 +if $data01 != NULL then + print ==2== expect: NULL, actually: $data01 return -1 endi -if $data83 != 102 then - print ==3== expect: NULL, actually: $data83 +if $data02 != 102 then + print ==3== expect: NULL, actually: $data02 return -1 endi -if $data93 != true then - print ==4== expect: NULL, actually: $data93 +if $data03 != 1 then + print ==4== expect: 1, actually: $data03 return -1 endi sql create table st3 using mt2 tags (NULL, 'ABC', 103, 'FALSE') -sql describe st3 -if $rows != 10 then +sql select tag1, tag2, tag3, tag5 from st3 +if $rows != 1 then return -1 endi -if $data63 != NULL then - print ==5== expect: NULL, actually: $data63 +if $data00 != NULL then + print ==5== expect: NULL, actually: $data00 return -1 endi -if $data73 != ABC then +if $data01 != ABC then return -1 endi -if $data83 != 103 then +if $data02 != 103 then return -1 endi -if $data93 != false then +if $data03 != 0 then return -1 endi @@ -128,39 +128,39 @@ endi sql_error create table stx using mt2 tags ('NULL', '123aBc', 104, '123') sql_error create table sty using mt2 tags ('NULL', '123aBc', 104, 'xtz') sql create table st4 using mt2 tags ('NULL', '123aBc', 104, 'NULL') -sql describe st4 -if $rows != 10 then +sql select tag1,tag2,tag3,tag5 from st4 +if $rows != 1 then return -1 endi -if $data63 != NULL then +if $data00 != NULL then return -1 endi -if $data73 != 123aBc then +if $data01 != 123aBc then return -1 endi -if $data83 != 104 then +if $data02 != 104 then return -1 endi -if $data93 != NULL then - print ==6== expect: NULL, actually: $data93 +if $data03 != NULL then + print ==6== expect: NULL, actually: $data03 return -1 endi sql create table st5 using mt2 tags ('NULL', '123aBc', 105, NULL) -sql describe st5 -if $rows != 10 then +sql select tag1,tag2,tag3,tag5 from st5 +if $rows != 1 then return -1 endi -if $data63 != NULL then +if $data00 != NULL then return -1 endi -if $data73 != 123aBc then +if $data01 != 123aBc then return -1 endi -if $data83 != 105 then +if $data02 != 105 then return -1 endi -if $data93 != NULL then +if $data03 != NULL then return -1 endi @@ -177,28 +177,29 @@ sql_error insert into st34 using mt3 tags ('NULL', '123aBc', 105, NULL) values #### case 3: set tag value sql create table mt4 (ts timestamp, c1 int) tags (tag_binary binary(16), tag_nchar nchar(16), tag_int int, tag_bool bool, tag_float float, tag_double double) sql create table st41 using mt4 tags ("beijing", 'nchar_tag', 100, false, 9.12345, 7.123456789) -sql describe st41 -if $rows != 8 then +sql select tag_binary, tag_nchar, tag_int, tag_bool, tag_float, tag_double st41 +if $rows != 1 then return -1 endi -if $data23 != beijing then +if $data00 != beijing then return -1 endi -if $data33 != nchar_tag then +if $data01 != nchar_tag then return -1 endi -if $data43 != 100 then +if $data02 != 100 then return -1 endi -if $data53 != false then +if $data03 != false then return -1 endi -if $data63 != 9.123450 then +if $dat04 != 9.123450 then return -1 endi -if $data73 != 7.123457 then +if $data05 != 7.123457 then return -1 endi + ################# binary sql alter table st41 set tag tag_binary = "shanghai" sql describe st41 diff --git a/tests/script/general/parser/selectResNum.sim b/tests/script/general/parser/selectResNum.sim index a0adc46d5f10792b62c57eb5a1c32b5b86a14f8a..ef9116cb3f8b3d25f2921dc3e70724ab3afa2e23 100644 --- a/tests/script/general/parser/selectResNum.sim +++ b/tests/script/general/parser/selectResNum.sim @@ -23,7 +23,7 @@ $stb = $stbPrefix . $i sql drop database $db -x step1 step1: -sql create database $db cache 2048 tables 200 +sql create database $db cache 16 maxtables 200 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) diff --git a/tests/script/general/parser/single_row_in_tb.sim b/tests/script/general/parser/single_row_in_tb.sim index 52bdad20658d33faea3d9b59b629ff48d79aef21..200047140e8ea85b972ba46a5e7f113561b77f01 100644 --- a/tests/script/general/parser/single_row_in_tb.sim +++ b/tests/script/general/parser/single_row_in_tb.sim @@ -15,7 +15,7 @@ $db = $dbPrefix $stb = $stbPrefix sql drop database if exists $db -sql create database $db rows 200 maxTables 4 +sql create database $db maxrows 200 maxTables 4 print ====== create tables sql use $db sql create table $stb (ts timestamp, c1 int, c2 bigint, c3 float, c4 double, c5 bool, c6 binary(10), c7 nchar(10)) tags(t1 int) diff --git a/tests/script/general/parser/single_row_in_tb_query.sim b/tests/script/general/parser/single_row_in_tb_query.sim index 7bab49f2249bdc0cd863ad0bc804352a4b32400a..a1ae70ec814d0babf00dbf5051da45c5cd7daf94 100644 --- a/tests/script/general/parser/single_row_in_tb_query.sim +++ b/tests/script/general/parser/single_row_in_tb_query.sim @@ -130,6 +130,7 @@ if $data03 != 1 then return -1 endi if $data04 != 0.000000000 then + print expect: 0.00000000 , actual: $data04 return -1 endi if $data05 != 1 then