diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h index d183fb4a721a57011ba7c09c304d4cf8ad7180dd..64195b86a1acfb4e7c25a9d51152d02a597347d9 100644 --- a/src/client/inc/tscUtil.h +++ b/src/client/inc/tscUtil.h @@ -149,6 +149,7 @@ int32_t tscGetDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, i bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo); bool tscIsTWAQuery(SQueryInfo* pQueryInfo); bool tscIsIrateQuery(SQueryInfo* pQueryInfo); +bool tscQueryContainsFunction(SQueryInfo* pQueryInfo, int16_t functionId); bool tscIsSessionWindowQuery(SQueryInfo* pQueryInfo); bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo); @@ -165,7 +166,7 @@ bool isSimpleAggregateRv(SQueryInfo* pQueryInfo); bool tscNonOrderedProjectionQueryOnSTable(SQueryInfo *pQueryInfo, int32_t tableIndex); bool tscOrderedProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex); -bool tscIsDiffDerivQuery(SQueryInfo* pQueryInfo); +bool tscIsDiffDerivLikeQuery(SQueryInfo* pQueryInfo); bool tscIsProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex); bool tscIsProjectionQuery(SQueryInfo* pQueryInfo); diff --git a/src/client/src/tscGlobalmerge.c b/src/client/src/tscGlobalmerge.c index 6acbfe3e8929c9a5a46ed0370f6cfb883988ef3e..14e426ee69f1b11fe09ef23d66190c75a2628e10 100644 --- a/src/client/src/tscGlobalmerge.c +++ b/src/client/src/tscGlobalmerge.c @@ -648,7 +648,8 @@ static void doExecuteFinalMerge(SOperatorInfo* pOperator, int32_t numOfExpr, SSD 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) { + if (pCtx[j].functionId == TSDB_FUNC_TOP || pCtx[j].functionId == TSDB_FUNC_BOTTOM || + pCtx[j].functionId == TSDB_FUNC_SAMPLE) { if(j > 0) pCtx[j].ptsOutputBuf = pCtx[j - 1].pOutput; } } diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 4d5bfe350aa6435ef04a9646491fe2c93a996e92..2d95760d375738079a079c7cff5da941702cbc86 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -2499,6 +2499,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col case TSDB_FUNC_MAX: case TSDB_FUNC_DIFF: case TSDB_FUNC_DERIVATIVE: + case TSDB_FUNC_CSUM: case TSDB_FUNC_CEIL: case TSDB_FUNC_FLOOR: case TSDB_FUNC_ROUND: @@ -2551,7 +2552,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } // set the first column ts for diff query - if (functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_DERIVATIVE) { + if (functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_DERIVATIVE || functionId == TSDB_FUNC_CSUM) { SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0}; SExprInfo* pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(pCmd), TSDB_KEYSIZE, false); @@ -2591,7 +2592,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col tickPerSec /= TSDB_TICK_PER_SECOND(TSDB_TIME_PRECISION_MICRO); } else if (info.precision == TSDB_TIME_PRECISION_MICRO) { tickPerSec /= TSDB_TICK_PER_SECOND(TSDB_TIME_PRECISION_MILLI); - } + } if (tickPerSec <= 0 || tickPerSec < TSDB_TICK_PER_SECOND(info.precision)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg10); @@ -2747,6 +2748,8 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col case TSDB_FUNC_TOP: case TSDB_FUNC_BOTTOM: + case TSDB_FUNC_MAVG: + case TSDB_FUNC_SAMPLE: case TSDB_FUNC_PERCT: case TSDB_FUNC_APERCT: { // 1. valid the number of parameters @@ -2778,7 +2781,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col } // 2. valid the column type - if (!IS_NUMERIC_TYPE(pSchema->type)) { + if (functionId != TSDB_FUNC_SAMPLE && !IS_NUMERIC_TYPE(pSchema->type)) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); } @@ -2817,11 +2820,38 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col pExpr = tscExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pCmd), interResult, false); tscExprAddParams(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double)); + } else if (functionId == TSDB_FUNC_MAVG || functionId == TSDB_FUNC_SAMPLE) { + tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true); + + int64_t numRowsSelected = GET_INT32_VAL(val); + if (numRowsSelected <= 0 || numRowsSelected > 1000) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg12); + } + + // todo REFACTOR + // set the first column ts for top/bottom query + int32_t tsFuncId = (functionId == TSDB_FUNC_MAVG) ? TSDB_FUNC_TS_DUMMY : TSDB_FUNC_TS; + SColumnIndex index1 = {index.tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX}; + pExpr = tscExprAppend(pQueryInfo, tsFuncId, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(pCmd), + 0, false); + tstrncpy(pExpr->base.aliasName, aAggs[tsFuncId].name, sizeof(pExpr->base.aliasName)); + + const int32_t TS_COLUMN_INDEX = PRIMARYKEY_TIMESTAMP_COL_INDEX; + SColumnList ids = createColumnList(1, index.tableIndex, TS_COLUMN_INDEX); + insertResultField(pQueryInfo, colIndex, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, + aAggs[tsFuncId].name, pExpr); + + colIndex += 1; // the first column is ts + + getResultDataInfo(pSchema->type, pSchema->bytes, functionId, (int32_t)numRowsSelected, &resultType, &resultSize, &interResult, 0, false, + pUdfInfo); + pExpr = tscExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pCmd), interResult, false); + tscExprAddParams(&pExpr->base, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t)); } else { tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true); - int64_t nTop = GET_INT32_VAL(val); - if (nTop <= 0 || nTop > 100) { // todo use macro + int64_t numRowsSelected = GET_INT32_VAL(val); + if (numRowsSelected <= 0 || numRowsSelected > 100) { // todo use macro return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg12); } @@ -3314,7 +3344,8 @@ int32_t tscTansformFuncForSTableQuery(SQueryInfo* pQueryInfo) { 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_IRATE)) { + (functionId >= TSDB_FUNC_RATE && functionId <= TSDB_FUNC_IRATE) || + (functionId == TSDB_FUNC_SAMPLE)) { 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_OPERATION; @@ -3369,8 +3400,8 @@ void tscRestoreFuncForSTableQuery(SQueryInfo* pQueryInfo) { } bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { - const char* msg1 = "TWA/Diff/Derivative/Irate are not allowed to apply to super table directly"; - const char* msg2 = "TWA/Diff/Derivative/Irate only support group by tbname for super table query"; + const char* msg1 = "TWA/Diff/Derivative/Irate/CSUM/MAVG/SAMPLE are not allowed to apply to super table directly"; + const char* msg2 = "TWA/Diff/Derivative/Irate/CSUM/MAVG/SAMPLE only support group by tbname for super table query"; const char* msg3 = "functions not support for super table query"; // filter sql function not supported by metric query yet. @@ -3387,7 +3418,8 @@ bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) } } - if (tscIsTWAQuery(pQueryInfo) || tscIsDiffDerivQuery(pQueryInfo) || tscIsIrateQuery(pQueryInfo)) { + if (tscIsTWAQuery(pQueryInfo) || tscIsDiffDerivLikeQuery(pQueryInfo) || tscIsIrateQuery(pQueryInfo) || + tscQueryContainsFunction(pQueryInfo, TSDB_FUNC_SAMPLE)) { if (pQueryInfo->groupbyExpr.numOfGroupCols == 0) { invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); return true; @@ -5446,7 +5478,7 @@ int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNo const char* msg1 = "value is expected"; const char* msg2 = "invalid fill option"; - const char* msg3 = "top/bottom not support fill"; + const char* msg3 = "top/bottom/sample not support fill"; const char* msg4 = "illegal value or data overflow"; const char* msg5 = "fill only available for interval query"; const char* msg6 = "not supported function now"; @@ -5554,7 +5586,8 @@ int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNo size_t numOfExprs = tscNumOfExprs(pQueryInfo); for(int32_t i = 0; i < numOfExprs; ++i) { SExprInfo* pExpr = tscExprGet(pQueryInfo, i); - if (pExpr->base.functionId == TSDB_FUNC_TOP || pExpr->base.functionId == TSDB_FUNC_BOTTOM) { + if (pExpr->base.functionId == TSDB_FUNC_TOP || pExpr->base.functionId == TSDB_FUNC_BOTTOM + || pExpr->base.functionId == TSDB_FUNC_SAMPLE) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); } } @@ -6284,7 +6317,9 @@ int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQu } int32_t f = pExpr->base.functionId; - if ((f == TSDB_FUNC_PRJ && pExpr->base.numOfParams == 0) || f == TSDB_FUNC_DIFF || f == TSDB_FUNC_ARITHM || f == TSDB_FUNC_DERIVATIVE || + if ((f == TSDB_FUNC_PRJ && pExpr->base.numOfParams == 0) || + f == TSDB_FUNC_DIFF || f == TSDB_FUNC_ARITHM || f == TSDB_FUNC_DERIVATIVE || + f == TSDB_FUNC_CSUM || f == TSDB_FUNC_MAVG || f == TSDB_FUNC_CEIL || f == TSDB_FUNC_FLOOR || f == TSDB_FUNC_ROUND) { isProjectionFunction = true; @@ -7025,7 +7060,7 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo if (TSDB_COL_IS_TAG(pColIndex->flag)) { int32_t f = TSDB_FUNC_TAG; - if (tscIsDiffDerivQuery(pQueryInfo)) { + if (tscIsDiffDerivLikeQuery(pQueryInfo)) { f = TSDB_FUNC_TAGPRJ; } @@ -7170,6 +7205,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, char* } if (IS_MULTIOUTPUT(aAggs[f].status) && f != TSDB_FUNC_TOP && f != TSDB_FUNC_BOTTOM && f != TSDB_FUNC_DIFF && + f != TSDB_FUNC_MAVG && f != TSDB_FUNC_CSUM && f != TSDB_FUNC_SAMPLE && f != TSDB_FUNC_DERIVATIVE && f != TSDB_FUNC_TAGPRJ && f != TSDB_FUNC_PRJ) { return invalidOperationMsg(msg, msg1); } @@ -7188,7 +7224,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, char* } // projection query on super table does not compatible with "group by" syntax - if (tscIsProjectionQuery(pQueryInfo) && !(tscIsDiffDerivQuery(pQueryInfo))) { + if (tscIsProjectionQuery(pQueryInfo) && !(tscIsDiffDerivLikeQuery(pQueryInfo))) { return invalidOperationMsg(msg, msg3); } diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index de588a953b5b38b94de7617e81eeef3bdb96037f..f332aad461b31e01488867d66ba6df6405f6debe 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -271,6 +271,8 @@ bool tscIsProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex) { functionId != TSDB_FUNC_TS_COMP && functionId != TSDB_FUNC_DIFF && functionId != TSDB_FUNC_DERIVATIVE && + functionId != TSDB_FUNC_MAVG && + functionId != TSDB_FUNC_CSUM && functionId != TSDB_FUNC_TS_DUMMY && functionId != TSDB_FUNC_TID_TAG && functionId != TSDB_FUNC_CEIL && @@ -321,7 +323,9 @@ bool tscIsProjectionQuery(SQueryInfo* pQueryInfo) { return true; } -bool tscIsDiffDerivQuery(SQueryInfo* pQueryInfo) { +// these functions diff/derivative/csum/mavg will return the result computed on current row and history row/rows +// as the result for current row +bool tscIsDiffDerivLikeQuery(SQueryInfo* pQueryInfo) { size_t size = tscNumOfExprs(pQueryInfo); for (int32_t i = 0; i < size; ++i) { @@ -330,7 +334,8 @@ bool tscIsDiffDerivQuery(SQueryInfo* pQueryInfo) { continue; } - if (f == TSDB_FUNC_DIFF || f == TSDB_FUNC_DERIVATIVE) { + if (f == TSDB_FUNC_DIFF || f == TSDB_FUNC_DERIVATIVE || + f == TSDB_FUNC_CSUM || f == TSDB_FUNC_MAVG) { return true; } } @@ -551,6 +556,22 @@ bool tscIsIrateQuery(SQueryInfo* pQueryInfo) { return false; } +bool tscQueryContainsFunction(SQueryInfo* pQueryInfo, int16_t functionId) { + size_t numOfExprs = tscNumOfExprs(pQueryInfo); + for (int32_t i = 0; i < numOfExprs; ++i) { + SExprInfo* pExpr = tscExprGet(pQueryInfo, i); + if (pExpr == NULL) { + continue; + } + + if (pExpr->base.functionId == functionId) { + return true; + } + } + + return false; +} + bool tscIsSessionWindowQuery(SQueryInfo* pQueryInfo) { return pQueryInfo->sessionWindow.gap > 0; } @@ -589,7 +610,7 @@ bool isSimpleAggregateRv(SQueryInfo* pQueryInfo) { return false; } - if (tscIsDiffDerivQuery(pQueryInfo)) { + if (tscIsDiffDerivLikeQuery(pQueryInfo)) { return false; } @@ -615,7 +636,9 @@ bool isSimpleAggregateRv(SQueryInfo* pQueryInfo) { } if ((!IS_MULTIOUTPUT(aAggs[functionId].status)) || - (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_TS_COMP)) { + (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || + functionId == TSDB_FUNC_TS_COMP || + functionId == TSDB_FUNC_SAMPLE)) { return true; } } @@ -4836,7 +4859,7 @@ int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAt pQueryAttr->hasTagResults = hasTagValOutput(pQueryInfo); pQueryAttr->stabledev = isStabledev(pQueryInfo); pQueryAttr->tsCompQuery = isTsCompQuery(pQueryInfo); - pQueryAttr->diffQuery = tscIsDiffDerivQuery(pQueryInfo); + pQueryAttr->diffQuery = tscIsDiffDerivLikeQuery(pQueryInfo); pQueryAttr->simpleAgg = isSimpleAggregateRv(pQueryInfo); pQueryAttr->needReverseScan = tscNeedReverseScan(pQueryInfo); pQueryAttr->stableQuery = QUERY_IS_STABLE_QUERY(pQueryInfo->type); diff --git a/src/query/inc/qAggMain.h b/src/query/inc/qAggMain.h index 4f7821708c3e9b3c3d0eb975125e1ad12c5f82a4..e3e5ccbce9f5c49871a7f0f5378fc56845e1b410 100644 --- a/src/query/inc/qAggMain.h +++ b/src/query/inc/qAggMain.h @@ -68,18 +68,23 @@ extern "C" { #define TSDB_FUNC_IRATE 30 #define TSDB_FUNC_TID_TAG 31 #define TSDB_FUNC_DERIVATIVE 32 -#define TSDB_FUNC_BLKINFO 33 - -#define TSDB_FUNC_CEIL 34 -#define TSDB_FUNC_FLOOR 35 -#define TSDB_FUNC_ROUND 36 - -#define TSDB_FUNC_HISTOGRAM 37 -#define TSDB_FUNC_HLL 38 -#define TSDB_FUNC_MODE 39 -#define TSDB_FUNC_SAMPLE 40 -#define TSDB_FUNC_MAVG 41 -#define TSDB_FUNC_CSUM 42 + +#define TSDB_FUNC_CEIL 33 +#define TSDB_FUNC_FLOOR 34 +#define TSDB_FUNC_ROUND 35 + +#define TSDB_FUNC_CSUM 36 +#define TSDB_FUNC_MAVG 37 +#define TSDB_FUNC_SAMPLE 38 + +#define TSDB_FUNC_BLKINFO 39 + +/////////////////////////////////////////// +// the following functions is not implemented. +// after implementation, move them before TSDB_FUNC_BLKINFO. also make TSDB_FUNC_BLKINFO the maxium function index +// #define TSDB_FUNC_HISTOGRAM 40 +// #define TSDB_FUNC_HLL 41 +// #define TSDB_FUNC_MODE 42 #define TSDB_FUNCSTATE_SO 0x1u // single output #define TSDB_FUNCSTATE_MO 0x2u // dynamic number of output, not multinumber of output e.g., TOP/BOTTOM diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index 1fd682aebd6ac7899ca0a88f6a4744cd4ebbb006..5a3aa6934a8d15a84de2d2770db0aac59f48fa63 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -169,6 +169,27 @@ typedef struct SDerivInfo { bool valueSet; // the value has been set already } SDerivInfo; +typedef struct { + double cumSum; +} SCumSumInfo; + +typedef struct { + int32_t pos; + double sum; + int32_t numPointsK; + double* points; + bool kPointsMeet; +} SMovingAvgInfo; + +typedef struct { + int32_t totalPoints; + int32_t numSampled; + int16_t colBytes; + char *values; + int64_t *timeStamps; + char *taglists; +} SSampleFuncInfo; + int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, int16_t *type, int16_t *bytes, int32_t *interBytes, int16_t extLength, bool isSuperTable, SUdfInfo* pUdfInfo) { if (!isValidDataType(dataType)) { @@ -237,6 +258,27 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI return TSDB_CODE_SUCCESS; } + if (functionId == TSDB_FUNC_CSUM) { + if (IS_SIGNED_NUMERIC_TYPE(dataType)) { + *type = TSDB_DATA_TYPE_BIGINT; + } else if (IS_UNSIGNED_NUMERIC_TYPE(dataType)) { + *type = TSDB_DATA_TYPE_UBIGINT; + } else { + *type = TSDB_DATA_TYPE_DOUBLE; + } + + *bytes = sizeof(int64_t); + *interBytes = sizeof(SCumSumInfo); + return TSDB_CODE_SUCCESS; + } + + if (functionId == TSDB_FUNC_MAVG) { + *type = TSDB_DATA_TYPE_DOUBLE; + *bytes = sizeof(double); + *interBytes = sizeof(SMovingAvgInfo) + sizeof(double) * param; + return TSDB_CODE_SUCCESS; + } + if (isSuperTable) { if (functionId < 0) { if (pUdfInfo->bufSize > 0) { @@ -280,6 +322,12 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI *bytes = (int16_t)(sizeof(STopBotInfo) + (sizeof(tValuePair) + POINTER_BYTES + extLength) * param); *interBytes = *bytes; + return TSDB_CODE_SUCCESS; + } else if (functionId == TSDB_FUNC_SAMPLE) { + *type = TSDB_DATA_TYPE_BINARY; + *bytes = (int16_t)(sizeof(SSampleFuncInfo) + dataBytes*param + sizeof(int64_t)*param + extLength*param); + *interBytes = *bytes; + return TSDB_CODE_SUCCESS; } else if (functionId == TSDB_FUNC_SPREAD) { *type = TSDB_DATA_TYPE_BINARY; @@ -389,6 +437,11 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI // the output column may be larger than sizeof(STopBotInfo) *interBytes = (int32_t)size; + } else if (functionId == TSDB_FUNC_SAMPLE) { + *type = (int16_t)dataType; + *bytes = (int16_t)dataBytes; + size_t size = sizeof(SSampleFuncInfo) + dataBytes*param + sizeof(int64_t)*param + extLength*param; + *interBytes = (int32_t)size; } else if (functionId == TSDB_FUNC_LAST_ROW) { *type = (int16_t)dataType; *bytes = (int16_t)dataBytes; @@ -407,7 +460,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI // TODO use hash table int32_t isValidFunction(const char* name, int32_t len) { - for(int32_t i = 0; i <= TSDB_FUNC_ROUND; ++i) { + for(int32_t i = 0; i <= TSDB_FUNC_BLKINFO; ++i) { int32_t nameLen = (int32_t) strlen(aAggs[i].name); if (len != nameLen) { continue; @@ -4085,6 +4138,8 @@ static void irate_function(SQLFunctionCtx *pCtx) { } } +///////////////////////////////////////////////////////////////////////////////////////////////////////////// + void blockInfo_func(SQLFunctionCtx* pCtx) { SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); STableBlockDist* pDist = (STableBlockDist*) GET_ROWCELL_INTERBUF(pResInfo); @@ -4258,6 +4313,8 @@ void blockinfo_func_finalizer(SQLFunctionCtx* pCtx) { doFinalizer(pCtx); } +///////////////////////////////////////////////////////////////////////////////////////////////////////////// + #define CFR_SET_VAL(type, data, pCtx, func, i, step, notNullElems) \ do { \ type *pData = (type *) data; \ @@ -4483,6 +4540,313 @@ static void round_function(SQLFunctionCtx *pCtx) { #undef CFR_SET_VAL #undef CFR_SET_VAL_DOUBLE +////////////////////////////////////////////////////////////////////////////////// +//cumulative_sum function + +static bool csum_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInfo) { + if (!function_setup(pCtx, pResInfo)) { + return false; + } + + SCumSumInfo* pCumSumInfo = GET_ROWCELL_INTERBUF(pResInfo); + pCumSumInfo->cumSum = 0; + return true; +} + +static void csum_function(SQLFunctionCtx *pCtx) { + SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); + SCumSumInfo* pCumSumInfo = GET_ROWCELL_INTERBUF(pResInfo); + + int32_t notNullElems = 0; + int32_t step = GET_FORWARD_DIRECTION_FACTOR(pCtx->order); + int32_t i = (pCtx->order == TSDB_ORDER_ASC) ? 0 : pCtx->size -1; + + TSKEY* pTimestamp = pCtx->ptsOutputBuf; + TSKEY* tsList = GET_TS_LIST(pCtx); + + qDebug("%p csum_function() size:%d, hasNull:%d", pCtx, pCtx->size, pCtx->hasNull); + + for (; i < pCtx->size && i >= 0; i += step) { + char* pData = GET_INPUT_DATA(pCtx, i); + if (pCtx->hasNull && isNull(pData, pCtx->inputType)) { + qDebug("%p csum_function() index of null data:%d", pCtx, i); + continue; + } + + double v = 0; + GET_TYPED_DATA(v, double, pCtx->inputType, pData); + pCumSumInfo->cumSum += v; + + *pTimestamp = (tsList != NULL) ? tsList[i] : 0; + if (IS_SIGNED_NUMERIC_TYPE(pCtx->inputType)) { + int64_t *retVal = (int64_t *)pCtx->pOutput; + *retVal = (int64_t)(pCumSumInfo->cumSum); + } else if (IS_UNSIGNED_NUMERIC_TYPE(pCtx->inputType)) { + uint64_t *retVal = (uint64_t *)pCtx->pOutput; + *retVal = (uint64_t)(pCumSumInfo->cumSum); + } else if (IS_FLOAT_TYPE(pCtx->inputType)) { + double *retVal = (double*) pCtx->pOutput; + SET_DOUBLE_VAL(retVal, pCumSumInfo->cumSum); + } + + ++notNullElems; + pCtx->pOutput += pCtx->outputBytes; + pTimestamp++; + } + + if (notNullElems == 0) { + assert(pCtx->hasNull); + } else { + GET_RES_INFO(pCtx)->numOfRes += notNullElems; + GET_RES_INFO(pCtx)->hasResult = DATA_SET_FLAG; + } +} + +////////////////////////////////////////////////////////////////////////////////// +// Simple Moving_average function + +static bool mavg_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInfo) { + if (!function_setup(pCtx, pResInfo)) { + return false; + } + + SMovingAvgInfo* mavgInfo = GET_ROWCELL_INTERBUF(pResInfo); + mavgInfo->pos = 0; + mavgInfo->kPointsMeet = false; + mavgInfo->sum = 0; + mavgInfo->numPointsK = (int32_t)pCtx->param[0].i64; + mavgInfo->points = (double*)((char*)mavgInfo + sizeof(SMovingAvgInfo)); + return true; +} + +static void mavg_function(SQLFunctionCtx *pCtx) { + SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); + SMovingAvgInfo* mavgInfo = GET_ROWCELL_INTERBUF(pResInfo); + + int32_t notNullElems = 0; + int32_t step = GET_FORWARD_DIRECTION_FACTOR(pCtx->order); + int32_t i = (pCtx->order == TSDB_ORDER_ASC) ? 0 : pCtx->size -1; + + TSKEY* pTimestamp = pCtx->ptsOutputBuf; + char* pOutput = pCtx->pOutput; + TSKEY* tsList = GET_TS_LIST(pCtx); + + for (; i < pCtx->size && i >= 0; i += step) { + char* pData = GET_INPUT_DATA(pCtx, i); + if (pCtx->hasNull && isNull(pData, pCtx->inputType)) { + qDebug("%p mavg_function() index of null data:%d", pCtx, i); + continue; + } + + double v = 0; + GET_TYPED_DATA(v, double, pCtx->inputType, pData); + + if (!mavgInfo->kPointsMeet && mavgInfo->pos < mavgInfo->numPointsK - 1) { + mavgInfo->points[mavgInfo->pos] = v; + mavgInfo->sum += v; + } else { + if (!mavgInfo->kPointsMeet && mavgInfo->pos == mavgInfo->numPointsK - 1){ + mavgInfo->sum += v; + mavgInfo->kPointsMeet = true; + } else { + mavgInfo->sum = mavgInfo->sum + v - mavgInfo->points[mavgInfo->pos]; + } + mavgInfo->points[mavgInfo->pos] = v; + + *pTimestamp = (tsList != NULL) ? tsList[i] : 0; + SET_DOUBLE_VAL(pOutput, mavgInfo->sum / mavgInfo->numPointsK) + + ++notNullElems; + pOutput += pCtx->outputBytes; + pTimestamp++; + } + + ++mavgInfo->pos; + if (mavgInfo->pos == mavgInfo->numPointsK) { + mavgInfo->pos = 0; + } + } + + if (notNullElems <= 0) { + assert(pCtx->hasNull); + } else { + GET_RES_INFO(pCtx)->numOfRes += notNullElems; + GET_RES_INFO(pCtx)->hasResult = DATA_SET_FLAG; + } +} + +////////////////////////////////////////////////////////////////////////////////// +// Sample function with reservoir sampling algorithm + +static SSampleFuncInfo* getSampleFuncOutputInfo(SQLFunctionCtx *pCtx) { + SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); + + // only the first_stage stable is directly written data into final output buffer + if (pCtx->stableQuery && pCtx->currentStage != MERGE_STAGE) { + return (SSampleFuncInfo *) pCtx->pOutput; + } else { // during normal table query and super table at the secondary_stage, result is written to intermediate buffer + return GET_ROWCELL_INTERBUF(pResInfo); + } +} + +static void assignResultSample(SQLFunctionCtx *pCtx, SSampleFuncInfo *pInfo, int32_t index, int64_t ts, void *pData, uint16_t type, int16_t bytes, char *inputTags) { + assignVal(pInfo->values + index*bytes, pData, bytes, type); + *(pInfo->timeStamps + index) = ts; + + SExtTagsInfo* pTagInfo = &pCtx->tagInfo; + int32_t posTag = 0; + char* tags = pInfo->taglists + index*pTagInfo->tagsLen; + if (pCtx->currentStage == MERGE_STAGE) { + assert(inputTags != NULL); + memcpy(tags, inputTags, (size_t)pTagInfo->tagsLen); + } else { + assert(inputTags == NULL); + for (int32_t i = 0; i < pTagInfo->numOfTagCols; ++i) { + SQLFunctionCtx* ctx = pTagInfo->pTagCtxList[i]; + if (ctx->functionId == TSDB_FUNC_TS_DUMMY) { + ctx->tag.nType = TSDB_DATA_TYPE_BIGINT; + ctx->tag.i64 = ts; + } + + tVariantDump(&ctx->tag, tags + posTag, ctx->tag.nType, true); + posTag += pTagInfo->pTagCtxList[i]->outputBytes; + } + } +} + +static void do_reservoir_sample(SQLFunctionCtx *pCtx, SSampleFuncInfo *pInfo, int32_t samplesK, int64_t ts, void *pData, uint16_t type, int16_t bytes) { + pInfo->totalPoints++; + if (pInfo->numSampled < samplesK) { + assignResultSample(pCtx, pInfo, pInfo->numSampled, ts, pData, type, bytes, NULL); + pInfo->numSampled++; + } else { + int32_t j = rand() % (pInfo->totalPoints); + if (j < samplesK) { + assignResultSample(pCtx, pInfo, j, ts, pData, type, bytes, NULL); + } + } +} + +static void copySampleFuncRes(SQLFunctionCtx *pCtx, int32_t type) { + SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); + SSampleFuncInfo *pRes = GET_ROWCELL_INTERBUF(pResInfo); + + TSKEY* pTimestamp = pCtx->ptsOutputBuf; + char* pOutput = pCtx->pOutput; + for (int32_t i = 0; i < pRes->numSampled; ++i) { + assignVal(pOutput, pRes->values + i*pRes->colBytes, pRes->colBytes, type); + *pTimestamp = *(pRes->timeStamps + i); + pOutput += pCtx->outputBytes; + pTimestamp++; + } + + char **tagOutputs = calloc(pCtx->tagInfo.numOfTagCols, POINTER_BYTES); + for (int32_t i = 0; i < pCtx->tagInfo.numOfTagCols; ++i) { + tagOutputs[i] = pCtx->tagInfo.pTagCtxList[i]->pOutput; + } + + for (int32_t i = 0; i < pRes->numSampled; ++i) { + int16_t tagOffset = 0; + for (int32_t j = 0; j < pCtx->tagInfo.numOfTagCols; ++j) { + memcpy(tagOutputs[j], pRes->taglists + i*pCtx->tagInfo.tagsLen + tagOffset, (size_t)pCtx->tagInfo.pTagCtxList[j]->outputBytes); + tagOffset += pCtx->tagInfo.pTagCtxList[j]->outputBytes; + tagOutputs[j] += pCtx->tagInfo.pTagCtxList[j]->outputBytes; + } + } + + tfree(tagOutputs); +} + +static bool sample_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInfo) { + if (!function_setup(pCtx, pResInfo)) { + return false; + } + + srand(taosSafeRand()); + + SSampleFuncInfo *pRes = getSampleFuncOutputInfo(pCtx); + pRes->totalPoints = 0; + pRes->numSampled = 0; + pRes->values = ((char*)pRes + sizeof(SSampleFuncInfo)); + pRes->colBytes = (pCtx->currentStage != MERGE_STAGE) ? pCtx->inputBytes : pCtx->outputBytes; + pRes->timeStamps = (int64_t *)((char *)pRes->values + pRes->colBytes * pCtx->param[0].i64); + pRes->taglists = (char*)pRes->timeStamps + sizeof(int64_t) * pCtx->param[0].i64; + return true; +} + +static void sample_function(SQLFunctionCtx *pCtx) { + int32_t notNullElems = 0; + + SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); + SSampleFuncInfo *pRes = getSampleFuncOutputInfo(pCtx); + + if (pRes->values != ((char*)pRes + sizeof(SSampleFuncInfo))) { + pRes->values = ((char*)pRes + sizeof(SSampleFuncInfo)); + pRes->timeStamps = (int64_t*)((char*)pRes->values + pRes->colBytes * pCtx->param[0].i64); + pRes->taglists = (char*)pRes->timeStamps + sizeof(int64_t) * pCtx->param[0].i64; + } + + for (int32_t i = 0; i < pCtx->size; ++i) { + char *data = GET_INPUT_DATA(pCtx, i); + if (pCtx->hasNull && isNull(data, pCtx->inputType)) { + continue; + } + + notNullElems++; + + TSKEY ts = (pCtx->ptsList != NULL)? GET_TS_DATA(pCtx, i):0; + do_reservoir_sample(pCtx, pRes, (int32_t)pCtx->param[0].i64, ts, data, pCtx->inputType, pRes->colBytes); + } + + if (!pCtx->hasNull) { + assert(pCtx->size == notNullElems); + } + + // treat the result as only one result + SET_VAL(pCtx, notNullElems, 1); + + if (notNullElems > 0) { + pResInfo->hasResult = DATA_SET_FLAG; + } +} + +static void sample_func_merge(SQLFunctionCtx *pCtx) { + SSampleFuncInfo* pInput = (SSampleFuncInfo*)GET_INPUT_DATA_LIST(pCtx); + pInput->values = ((char*)pInput + sizeof(SSampleFuncInfo)); + pInput->timeStamps = (int64_t*)((char*)pInput->values + pInput->colBytes * pCtx->param[0].i64); + pInput->taglists = (char*)pInput->timeStamps + sizeof(int64_t)*pCtx->param[0].i64; + + SSampleFuncInfo *pOutput = getSampleFuncOutputInfo(pCtx); + pOutput->totalPoints = pInput->totalPoints; + pOutput->numSampled = pInput->numSampled; + for (int32_t i = 0; i < pInput->numSampled; ++i) { + assignResultSample(pCtx, pOutput, i, pInput->timeStamps[i], + pInput->values + i * pInput->colBytes, pCtx->outputType, pInput->colBytes, + pInput->taglists + i*pCtx->tagInfo.tagsLen); + } + + SET_VAL(pCtx, pInput->numSampled, pOutput->numSampled); + if (pOutput->numSampled > 0) { + SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); + pResInfo->hasResult = DATA_SET_FLAG; + } +} + +static void sample_func_finalizer(SQLFunctionCtx *pCtx) { + SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); + SSampleFuncInfo *pRes = GET_ROWCELL_INTERBUF(pResInfo); + + if (pRes->numSampled == 0) { // no result + assert(pResInfo->hasResult != DATA_SET_FLAG); + } + + pResInfo->numOfRes = pRes->numSampled; + GET_TRUE_DATA_TYPE(); + copySampleFuncRes(pCtx, type); + + doFinalizer(pCtx); +} + ///////////////////////////////////////////////////////////////////////////////////////////// /* * function compatible list. @@ -4496,13 +4860,15 @@ static void round_function(SQLFunctionCtx *pCtx) { */ int32_t functionCompatList[] = { // count, sum, avg, min, max, stddev, percentile, apercentile, first, last - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - // last_row,top, bottom, spread, twa, leastsqr, ts, ts_dummy, tag_dummy, ts_comp - 4, -1, -1, 1, 1, 1, 1, 1, 1, -1, - // tag, colprj, tagprj, arithmetic, diff, first_dist, last_dist, stddev_dst, interp rate irate - 1, 1, 1, 1, -1, 1, 1, 1, 5, 1, 1, - // tid_tag, derivative, blk_info,ceil, floor, round - 6, 8, 7, 1, 1, 1 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + // last_row,top, bottom, spread, twa, leastsqr, ts, ts_dummy, tag_dummy, ts_comp + 4, -1, -1, 1, 1, 1, 1, 1, 1, -1, + // tag, colprj, tagprj, arithm, diff, first_dist, last_dist, stddev_dst, interp rate, irate + 1, 1, 1, 1, -1, 1, 1, 1, 5, 1, 1, + // tid_tag, deriv, ceil, floor, round, csum, mavg, sample, + 6, 8, 1, 1, 1, -1, -1, -1, + // block_info + 7 }; SAggFunctionInfo aAggs[] = {{ @@ -4904,51 +5270,85 @@ SAggFunctionInfo aAggs[] = {{ noop1, dataBlockRequired, }, - { - // 33 - "_block_dist", // return table id and the corresponding tags for join match and subscribe - TSDB_FUNC_BLKINFO, - TSDB_FUNC_BLKINFO, - TSDB_FUNCSTATE_SO | TSDB_FUNCSTATE_STABLE, - function_setup, - blockInfo_func, - blockinfo_func_finalizer, - block_func_merge, - dataBlockRequired, + {// 33 + "ceil", + TSDB_FUNC_CEIL, + TSDB_FUNC_CEIL, + TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS | TSDB_FUNCSTATE_SCALAR, + function_setup, + ceil_function, + doFinalizer, + noop1, + dataBlockRequired + }, + {// 34 + "floor", + TSDB_FUNC_FLOOR, + TSDB_FUNC_FLOOR, + TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS | TSDB_FUNCSTATE_SCALAR, + function_setup, + floor_function, + doFinalizer, + noop1, + dataBlockRequired + }, + {// 35 + "round", + TSDB_FUNC_ROUND, + TSDB_FUNC_ROUND, + TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS | TSDB_FUNCSTATE_SCALAR, + function_setup, + round_function, + doFinalizer, + noop1, + dataBlockRequired }, { - // 34 - "ceil", - TSDB_FUNC_CEIL, - TSDB_FUNC_CEIL, - TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS | TSDB_FUNCSTATE_SCALAR, - function_setup, - ceil_function, + // 36 + "csum", + TSDB_FUNC_CSUM, + TSDB_FUNC_INVALID_ID, + TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS | TSDB_FUNCSTATE_SELECTIVITY, + csum_function_setup, + csum_function, doFinalizer, noop1, - dataBlockRequired + dataBlockRequired, }, { - // 35 - "floor", - TSDB_FUNC_FLOOR, - TSDB_FUNC_FLOOR, - TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS | TSDB_FUNCSTATE_SCALAR, - function_setup, - floor_function, + // 37 + "mavg", + TSDB_FUNC_MAVG, + TSDB_FUNC_INVALID_ID, + TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS | TSDB_FUNCSTATE_SELECTIVITY, + mavg_function_setup, + mavg_function, doFinalizer, noop1, - dataBlockRequired + dataBlockRequired, }, { - // 36 - "round", - TSDB_FUNC_ROUND, - TSDB_FUNC_ROUND, - TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS | TSDB_FUNCSTATE_SCALAR, + // 38 + "sample", + TSDB_FUNC_SAMPLE, + TSDB_FUNC_SAMPLE, + TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS | TSDB_FUNCSTATE_SELECTIVITY, + sample_function_setup, + sample_function, + sample_func_finalizer, + sample_func_merge, + dataBlockRequired, + }, + { + // 39 + "_block_dist", + TSDB_FUNC_BLKINFO, + TSDB_FUNC_BLKINFO, + TSDB_FUNCSTATE_SO | TSDB_FUNCSTATE_STABLE, function_setup, - round_function, - doFinalizer, - noop1, - dataBlockRequired - }}; + blockInfo_func, + blockinfo_func_finalizer, + block_func_merge, + dataBlockRequired, + }, +}; diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 78d4aabdd8c4b51d9af6454ef39be82cc6d95668..bac81c98980f2d48d8436c1175baa697932aa126 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -2060,7 +2060,7 @@ static SQLFunctionCtx* createSQLFunctionCtx(SQueryRuntimeEnv* pRuntimeEnv, SExpr int32_t functionId = pCtx->functionId; if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF) { - int32_t f = pExpr[0].base.functionId; + int32_t f = pExpr[i-1].base.functionId; assert(f == TSDB_FUNC_TS || f == TSDB_FUNC_TS_DUMMY); pCtx->param[2].i64 = pQueryAttr->order.order; @@ -3653,7 +3653,8 @@ void setDefaultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *pInfo, i // set the timestamp output buffer for top/bottom/diff query int32_t fid = pCtx[i].functionId; - if (fid == TSDB_FUNC_TOP || fid == TSDB_FUNC_BOTTOM || fid == TSDB_FUNC_DIFF || fid == TSDB_FUNC_DERIVATIVE) { + if (fid == TSDB_FUNC_TOP || fid == TSDB_FUNC_BOTTOM || fid == TSDB_FUNC_DIFF || fid == TSDB_FUNC_DERIVATIVE || + fid == TSDB_FUNC_SAMPLE || fid == TSDB_FUNC_MAVG || fid == TSDB_FUNC_CSUM) { if (i > 0) pCtx[i].ptsOutputBuf = pCtx[i-1].pOutput; } } @@ -3690,7 +3691,10 @@ void updateOutputBuf(SOptrBasicInfo* pBInfo, int32_t *bufCapacity, int32_t numOf // set the correct pointer after the memory buffer reallocated. int32_t functionId = pBInfo->pCtx[i].functionId; - if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_DERIVATIVE) { + if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || + functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_DERIVATIVE || + functionId == TSDB_FUNC_CSUM || functionId == TSDB_FUNC_MAVG || + functionId == TSDB_FUNC_SAMPLE ) { if (i > 0) pBInfo->pCtx[i].ptsOutputBuf = pBInfo->pCtx[i-1].pOutput; } } @@ -3702,7 +3706,9 @@ void copyTsColoum(SSDataBlock* pRes, SQLFunctionCtx* pCtx, int32_t numOfOutput) char *src = NULL; for (int32_t i = 0; i < numOfOutput; i++) { int32_t functionId = pCtx[i].functionId; - if (functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_DERIVATIVE) { + if (functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_DERIVATIVE || + functionId == TSDB_FUNC_MAVG || functionId == TSDB_FUNC_CSUM || + functionId == TSDB_FUNC_SAMPLE) { needCopyTs = true; if (i > 0 && pCtx[i-1].functionId == TSDB_FUNC_TS_DUMMY){ SColumnInfoData* pColRes = taosArrayGet(pRes->pDataBlock, i - 1); // find ts data @@ -3918,7 +3924,8 @@ void setResultRowOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pRe continue; } - if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF) { + if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF || + functionId == TSDB_FUNC_CSUM || functionId == TSDB_FUNC_MAVG || functionId == TSDB_FUNC_SAMPLE) { if(i > 0) pCtx[i].ptsOutputBuf = pCtx[i-1].pOutput; } @@ -3979,7 +3986,9 @@ void setResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult, SQLF offset += pCtx[i].outputBytes; int32_t functionId = pCtx[i].functionId; - if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_DERIVATIVE) { + if (functionId == TSDB_FUNC_TOP || functionId == TSDB_FUNC_BOTTOM || + functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_DERIVATIVE || + functionId == TSDB_FUNC_SAMPLE || functionId == TSDB_FUNC_MAVG || functionId == TSDB_FUNC_CSUM) { if(i > 0) pCtx[i].ptsOutputBuf = pCtx[i-1].pOutput; } @@ -7922,7 +7931,7 @@ static int32_t updateOutputBufForTopBotQuery(SQueriedTableInfo* pTableInfo, SCol for (int32_t i = 0; i < numOfOutput; ++i) { int16_t functId = pExprs[i].base.functionId; - if (functId == TSDB_FUNC_TOP || functId == TSDB_FUNC_BOTTOM) { + if (functId == TSDB_FUNC_TOP || functId == TSDB_FUNC_BOTTOM || functId == TSDB_FUNC_SAMPLE) { int32_t j = getColumnIndexInSource(pTableInfo, &pExprs[i].base, pTagCols); if (j < 0 || j >= pTableInfo->numOfCols) { return TSDB_CODE_QRY_INVALID_MSG; diff --git a/src/query/src/qUtil.c b/src/query/src/qUtil.c index bc27e094db3dcb85ffa73810e922d73cd42ab3a0..8babdbf1c39c8da9139c691e24f0a87ab57fb854 100644 --- a/src/query/src/qUtil.c +++ b/src/query/src/qUtil.c @@ -33,7 +33,9 @@ typedef struct SCompSupporter { int32_t getRowNumForMultioutput(SQueryAttr* pQueryAttr, bool topBottomQuery, bool stable) { if (pQueryAttr && (!stable)) { for (int16_t i = 0; i < pQueryAttr->numOfOutput; ++i) { - if (pQueryAttr->pExpr1[i].base.functionId == TSDB_FUNC_TOP || pQueryAttr->pExpr1[i].base.functionId == TSDB_FUNC_BOTTOM) { + if (pQueryAttr->pExpr1[i].base.functionId == TSDB_FUNC_TOP || + pQueryAttr->pExpr1[i].base.functionId == TSDB_FUNC_BOTTOM || + pQueryAttr->pExpr1[i].base.functionId == TSDB_FUNC_SAMPLE) { return (int32_t)pQueryAttr->pExpr1[i].base.param[0].i64; } } diff --git a/tests/pytest/fulltest.sh b/tests/pytest/fulltest.sh index 9399064096db05a0ad528e6ff97b17b7f7f8696e..9ec44ef41dfcb3178a54ee664cbb10d2447d2298 100755 --- a/tests/pytest/fulltest.sh +++ b/tests/pytest/fulltest.sh @@ -345,6 +345,7 @@ python3 ./test.py -f functions/function_spread.py -r 1 python3 ./test.py -f functions/function_stddev.py -r 1 python3 ./test.py -f functions/function_sum.py -r 1 python3 ./test.py -f functions/function_top.py -r 1 +python3 ./test.py -f functions/function_sample.py -r 1 python3 ./test.py -f functions/function_twa.py -r 1 python3 ./test.py -f functions/function_twa_test2.py python3 ./test.py -f functions/function_stddev_td2555.py diff --git a/tests/pytest/functions/function_sample.py b/tests/pytest/functions/function_sample.py new file mode 100644 index 0000000000000000000000000000000000000000..f86805082bd9ffe52e192e823c5abebaff6c9c4e --- /dev/null +++ b/tests/pytest/functions/function_sample.py @@ -0,0 +1,69 @@ +################################################################### +# 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 +import taos +from util.log import * +from util.cases import * +from util.sql import * +import numpy as np +import collections + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor()) + + self.rowNum = 10 + self.sample_times = 10000 + self.ts = 1537146000000 + + def run(self): + tdSql.prepare() + + tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double, + col7 bool, col8 binary(20), col9 nchar(20), col11 tinyint unsigned, col12 smallint unsigned, col13 int unsigned, col14 bigint unsigned) tags(loc nchar(20))''') + tdSql.execute("create table test1 using test tags('beijing')") + for i in range(self.rowNum): + tdSql.execute("insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d', %d, %d, %d, %d)" + % (self.ts + i, i, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1, i + 1, i + 1, i + 1, i + 1)) + + + print("begin sampling. sql: select sample(col1, 2) from test1") + freqDict = collections.defaultdict(int) + for i in range(self.sample_times): + tdSql.query('select sample(col1, 2) from test1') + res1 = tdSql.getData(0, 1); + res2 = tdSql.getData(1, 1); + freqDict[res1] = freqDict[res1] + 1 + freqDict[res2] = freqDict[res2] + 1 + print("end sampling.") + + lower_bound = self.sample_times/5 - self.sample_times/50; + upper_bound = self.sample_times/5 + self.sample_times/50; + for i in range(self.rowNum): + print("{} are sampled in {} times".format(i, freqDict[i])) + + if not (freqDict[i]>=lower_bound and freqDict[i]<=upper_bound): + print("run it aggain. if it keeps appearing, sample function bug") + caller = inspect.getframeinfo(inspect.stack()[0][0]) + args = (caller.filename, caller.lineno-2) + tdLog.exit("{}({}) failed. sample function failure".format(args[0], args[1])) + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/functions/function_sample_restart.py b/tests/pytest/functions/function_sample_restart.py new file mode 100644 index 0000000000000000000000000000000000000000..f86805082bd9ffe52e192e823c5abebaff6c9c4e --- /dev/null +++ b/tests/pytest/functions/function_sample_restart.py @@ -0,0 +1,69 @@ +################################################################### +# 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 +import taos +from util.log import * +from util.cases import * +from util.sql import * +import numpy as np +import collections + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor()) + + self.rowNum = 10 + self.sample_times = 10000 + self.ts = 1537146000000 + + def run(self): + tdSql.prepare() + + tdSql.execute('''create table test(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double, + col7 bool, col8 binary(20), col9 nchar(20), col11 tinyint unsigned, col12 smallint unsigned, col13 int unsigned, col14 bigint unsigned) tags(loc nchar(20))''') + tdSql.execute("create table test1 using test tags('beijing')") + for i in range(self.rowNum): + tdSql.execute("insert into test1 values(%d, %d, %d, %d, %d, %f, %f, %d, 'taosdata%d', '涛思数据%d', %d, %d, %d, %d)" + % (self.ts + i, i, i + 1, i + 1, i + 1, i + 0.1, i + 0.1, i % 2, i + 1, i + 1, i + 1, i + 1, i + 1, i + 1)) + + + print("begin sampling. sql: select sample(col1, 2) from test1") + freqDict = collections.defaultdict(int) + for i in range(self.sample_times): + tdSql.query('select sample(col1, 2) from test1') + res1 = tdSql.getData(0, 1); + res2 = tdSql.getData(1, 1); + freqDict[res1] = freqDict[res1] + 1 + freqDict[res2] = freqDict[res2] + 1 + print("end sampling.") + + lower_bound = self.sample_times/5 - self.sample_times/50; + upper_bound = self.sample_times/5 + self.sample_times/50; + for i in range(self.rowNum): + print("{} are sampled in {} times".format(i, freqDict[i])) + + if not (freqDict[i]>=lower_bound and freqDict[i]<=upper_bound): + print("run it aggain. if it keeps appearing, sample function bug") + caller = inspect.getframeinfo(inspect.stack()[0][0]) + args = (caller.filename, caller.lineno-2) + tdLog.exit("{}({}) failed. sample function failure".format(args[0], args[1])) + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/script/fullGeneralSuite.sim b/tests/script/fullGeneralSuite.sim index 188ce1405541cbbb230ceb186c44cfd4230925fc..2f4025830d73713d7d618aa8219a1d09c0dad502 100644 --- a/tests/script/fullGeneralSuite.sim +++ b/tests/script/fullGeneralSuite.sim @@ -21,6 +21,10 @@ run general/compute/bottom.sim run general/compute/count.sim run general/compute/diff.sim run general/compute/diff2.sim +run general/compute/mavg.sim +run general/compute/mavg2.sim +run general/compute/csum.sim +run general/compute/csum2.sim run general/compute/first.sim run general/compute/interval.sim run general/compute/last.sim diff --git a/tests/script/general/compute/csum.sim b/tests/script/general/compute/csum.sim new file mode 100644 index 0000000000000000000000000000000000000000..1f291d784fa848e8da9abe502884cdbad122973d --- /dev/null +++ b/tests/script/general/compute/csum.sim @@ -0,0 +1,98 @@ +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 200 +sql connect + +$dbPrefix = m_di_db +$tbPrefix = m_di_tb +$mtPrefix = m_di_mt +$tbNum = 10 +$rowNum = 20 +$totalNum = 200 + +print =============== step1 +$i = 0 +$db = $dbPrefix . $i +$mt = $mtPrefix . $i + +sql drop database $db -x step1 +step1: +sql create database $db +sql use $db +sql create table $mt (ts timestamp, tbcol int) TAGS(tgcol int) + +$i = 0 +while $i < $tbNum + $tb = $tbPrefix . $i + sql create table $tb using $mt tags( $i ) + + $x = 0 + while $x < $rowNum + $cc = $x * 60000 + $ms = 1601481600000 + $cc + sql insert into $tb values ($ms , $x ) + $x = $x + 1 + endw + + $i = $i + 1 +endw + +sleep 100 + +print =============== step2 +$i = 1 +$tb = $tbPrefix . $i + +sql select csum(tbcol) from $tb +print ===> $data11 +if $data11 != 1 then + return -1 +endi + +print =============== step3 +$cc = 4 * 60000 +$ms = 1601481600000 + $cc +sql select csum(tbcol) from $tb where ts > $ms +print ===> $data11 +if $data11 != 11 then + return -1 +endi + +$cc = 4 * 60000 +$ms = 1601481600000 + $cc +sql select csum(tbcol) from $tb where ts <= $ms +print ===> $data11 +if $data11 != 1 then + return -1 +endi + +print =============== step4 +sql select csum(tbcol) as b from $tb +print ===> $data11 +if $data11 != 1 then + return -1 +endi + +print =============== step5 +sql select csum(tbcol) as b from $tb interval(1m) -x step5 + return -1 +step5: + +print =============== step6 +$cc = 4 * 60000 +$ms = 1601481600000 + $cc +sql select csum(tbcol) as b from $tb where ts <= $ms interval(1m) -x step6 + return -1 +step6: + +print =============== clear +sql drop database $db +sql show databases +if $rows != 0 then + return -1 +endi + +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/compute/csum2.sim b/tests/script/general/compute/csum2.sim new file mode 100644 index 0000000000000000000000000000000000000000..506070ae369ccb4c1d2bc28d149c7126079a2b54 --- /dev/null +++ b/tests/script/general/compute/csum2.sim @@ -0,0 +1,163 @@ +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 200 +sql connect + +$dbPrefix = m_di_db +$tbPrefix = m_di_tb +$mtPrefix = m_di_mt +$tbNum = 2 +$rowNum = 1000 +$totalNum = 2000 + +print =============== step1 +$i = 0 +$db = $dbPrefix . $i +$mt = $mtPrefix . $i + +sql drop database $db -x step1 +step1: +sql create database $db +sql use $db +sql create table $mt (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 nchar(5), c9 binary(10)) TAGS(tgcol int) + +$i = 0 +while $i < $tbNum + $tb = $tbPrefix . $i + sql create table $tb using $mt tags( $i ) + + $x = 0 + while $x < $rowNum + $cc = $x * 60000 + $ms = 1601481600000 + $cc + + $tinyint = $x / 128 + sql insert into $tb values ($ms , $x , $x , $x , $x , $tinyint , $x , $x , $x , $x ) + $x = $x + 1 + endw + + $i = $i + 1 +endw + +sleep 100 + +print =============== step2 +$i = 1 +$tb = $tbPrefix . $i + +sql select csum(c1) from $tb +print ===> $data11 +if $data11 != 1 then + return -1 +endi +sql select csum(c2) from $tb +print ===> $data11 +if $data11 != 1.000000000 then + return -1 +endi +sql select csum(c3) from $tb +print ===> $data11 +if $data11 != 1 then + return -1 +endi +sql select csum(c4) from $tb +print ===> $data11 +if $data11 != 1 then + return -1 +endi +sql select csum(c5) from $tb +print ===> $data11 +if $data11 != 0 then + return -1 +endi +sql select csum(c6) from $tb +print ===> $data11 +if $data11 != 1.000000000 then + return -1 +endi +sql_error select csum(c7) from $tb +sql_error select csum(c8) from $tb +sql_error select csum(c9) from $tb +sql_error select csum(ts) from $tb +sql_error select csum(c1), csum(c2) from $tb +#sql_error select 2+csum(c1) from $tb +sql_error select csum(c1+2) from $tb +sql_error select csum(c1) from $tb where ts > 0 and ts < now + 100m interval(10m) +sql_error select csum(c1) from $mt +sql_error select csum(csum(c1)) from $tb +sql_error select csum(c1) from m_di_tb1 where c2 like '2%' + + +print =============== step3 +sql select csum(c1) from $tb where c1 > 5 +print ===> $data11 +if $data11 != 13 then + return -1 +endi +sql select csum(c2) from $tb where c2 > 5 +print ===> $data11 +if $data11 != 13.000000000 then + return -1 +endi +sql select csum(c3) from $tb where c3 > 5 +print ===> $data11 +if $data11 != 13 then + return -1 +endi +sql select csum(c4) from $tb where c4 > 5 +print ===> $data11 +if $data11 != 13 then + return -1 +endi +sql select csum(c5) from $tb where c5 > 5 +print ===> $data11 +if $data11 != 12 then + return -1 +endi +sql select csum(c6) from $tb where c6 > 5 +print ===> $data11 +if $data11 != 13.000000000 then + return -1 +endi + +print =============== step4 +sql select csum(c1) from $tb where c1 > 5 and c2 < $rowNum +print ===> $data11 +if $data11 != 13 then + return -1 +endi + +sql select csum(c1) from $tb where c9 like '%9' and c1 <= 20 +print ===> $rows +if $rows != 2 then + return -1 +endi +print ===>$data01, $data11 +if $data01 != 9 then + return -1 +endi +if $data11 != 28 then + return -1 +endi + +print =============== step5 +sql select csum(c1) as b from $tb interval(1m) -x step5 + return -1 +step5: + +print =============== step6 +sql select csum(c1) as b from $tb where ts < now + 4m interval(1m) -x step6 + return -1 +step6: + +print =============== clear +#sql drop database $db +#sql show databases +#if $rows != 0 then +# return -1 +#endi + +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/compute/mavg.sim b/tests/script/general/compute/mavg.sim new file mode 100644 index 0000000000000000000000000000000000000000..d33b620842cef880d17662e82831a082f8ce1cf9 --- /dev/null +++ b/tests/script/general/compute/mavg.sim @@ -0,0 +1,98 @@ +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 200 +sql connect + +$dbPrefix = m_di_db +$tbPrefix = m_di_tb +$mtPrefix = m_di_mt +$tbNum = 10 +$rowNum = 20 +$totalNum = 200 + +print =============== step1 +$i = 0 +$db = $dbPrefix . $i +$mt = $mtPrefix . $i + +sql drop database $db -x step1 +step1: +sql create database $db +sql use $db +sql create table $mt (ts timestamp, tbcol int) TAGS(tgcol int) + +$i = 0 +while $i < $tbNum + $tb = $tbPrefix . $i + sql create table $tb using $mt tags( $i ) + + $x = 0 + while $x < $rowNum + $cc = $x * 60000 + $ms = 1601481600000 + $cc + sql insert into $tb values ($ms , $x ) + $x = $x + 1 + endw + + $i = $i + 1 +endw + +sleep 100 + +print =============== step2 +$i = 1 +$tb = $tbPrefix . $i + +sql select mavg(tbcol,2) from $tb +print ===> $data11 +if $data11 != 1.500000000 then + return -1 +endi + +print =============== step3 +$cc = 4 * 60000 +$ms = 1601481600000 + $cc +sql select mavg(tbcol,2) from $tb where ts > $ms +print ===> $data11 +if $data11 != 6.500000000 then + return -1 +endi + +$cc = 4 * 60000 +$ms = 1601481600000 + $cc +sql select mavg(tbcol,2) from $tb where ts <= $ms +print ===> $data11 +if $data11 != 1.500000000 then + return -1 +endi + +print =============== step4 +sql select mavg(tbcol,2) as b from $tb +print ===> $data11 +if $data11 != 1.500000000 then + return -1 +endi + +print =============== step5 +sql select mavg(tbcol, 2) as b from $tb interval(1m) -x step5 + return -1 +step5: + +print =============== step6 +$cc = 4 * 60000 +$ms = 1601481600000 + $cc +sql select mavg(tbcol, 2) as b from $tb where ts <= $ms interval(1m) -x step6 + return -1 +step6: + +print =============== clear +sql drop database $db +sql show databases +if $rows != 0 then + return -1 +endi + +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/compute/mavg2.sim b/tests/script/general/compute/mavg2.sim new file mode 100644 index 0000000000000000000000000000000000000000..60b170e270505b7c3e8d2ee174a4e3b8a4ad223d --- /dev/null +++ b/tests/script/general/compute/mavg2.sim @@ -0,0 +1,159 @@ +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 200 +sql connect + +$dbPrefix = m_di_db +$tbPrefix = m_di_tb +$mtPrefix = m_di_mt +$tbNum = 2 +$rowNum = 10000 +$totalNum = 20000 + +print =============== step1 +$i = 0 +$db = $dbPrefix . $i +$mt = $mtPrefix . $i + +sql drop database $db -x step1 +step1: +sql create database $db +sql use $db +sql create table $mt (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 nchar(5), c9 binary(10)) TAGS(tgcol int) + +$i = 0 +while $i < $tbNum + $tb = $tbPrefix . $i + sql create table $tb using $mt tags( $i ) + + $x = 0 + while $x < $rowNum + $cc = $x * 60000 + $ms = 1601481600000 + $cc + + $tinyint = $x / 128 + sql insert into $tb values ($ms , $x , $x , $x , $x , $tinyint , $x , $x , $x , $x ) + $x = $x + 1 + endw + + $i = $i + 1 +endw + +sleep 100 + +print =============== step2 +$i = 1 +$tb = $tbPrefix . $i + +sql select mavg(c1, 2) from $tb +print ===> $data11 +if $data11 != 1.500000000 then + return -1 +endi +sql select mavg(c2, 2) from $tb +print ===> $data11 +if $data11 != 1.500000000 then + return -1 +endi +sql select mavg(c3, 2) from $tb +print ===> $data11 +if $data11 != 1.500000000 then + return -1 +endi +sql select mavg(c4, 2) from $tb +print ===> $data11 +if $data11 != 1.500000000 then + return -1 +endi +sql select mavg(c5, 2) from $tb +print ===> $data11 +if $data11 != 0.000000000 then + return -1 +endi +sql select mavg(c6, 2) from $tb +print ===> $data11 +if $data11 != 1.500000000 then + return -1 +endi +sql_error select mavg(c7,2) from $tb +sql_error select mavg(c8,2) from $tb +sql_error select mavg(c9,2) from $tb +sql_error select mavg(ts,2) from $tb +sql_error select mavg(c1,2), mavg(c2,2) from $tb +#sql_error select 2+mavg(c1,2) from $tb +sql_error select mavg(c1+2) from $tb +sql_error select mavg(c1,2) from $tb where ts > 0 and ts < now + 100m interval(10m) +sql_error select mavg(c1,2) from $mt +sql_error select mavg(mavg(c1,2)) from $tb +sql_error select mavg(c1,2) from m_di_tb1 where c2 like '2%' + + +print =============== step3 +sql select mavg(c1,2) from $tb where c1 > 5 +print ===> $data11 +if $data11 != 7.500000000 then + return -1 +endi +sql select mavg(c2,2) from $tb where c2 > 5 +print ===> $data11 +if $data11 != 7.500000000 then + return -1 +endi +sql select mavg(c3,2) from $tb where c3 > 5 +print ===> $data11 +if $data11 != 7.500000000 then + return -1 +endi +sql select mavg(c4,2) from $tb where c4 > 5 +print ===> $data11 +if $data11 != 7.500000000 then + return -1 +endi +sql select mavg(c5,2) from $tb where c5 > 5 +print ===> $data11 +if $data11 != 6.000000000 then + return -1 +endi +sql select mavg(c6,2) from $tb where c6 > 5 +print ===> $data11 +if $data11 != 7.500000000 then + return -1 +endi + +print =============== step4 +sql select mavg(c1,2) from $tb where c1 > 5 and c2 < $rowNum +print ===> $data11 +if $data11 != 7.500000000 then + return -1 +endi + +sql select mavg(c1,2) from $tb where c9 like '%9' and c1 <= 20 +if $rows != 1 then + return -1 +endi +print ===> $data01 +if $data01 != 14.000000000 then + return -1 +endi + +print =============== step5 +sql select mavg(c1,2) as b from $tb interval(1m) -x step5 + return -1 +step5: + +print =============== step6 +sql select mavg(c1,2) as b from $tb where ts < now + 4m interval(1m) -x step6 + return -1 +step6: + +print =============== clear +#sql drop database $db +#sql show databases +#if $rows != 0 then +# return -1 +#endi + +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/compute/sample.sim b/tests/script/general/compute/sample.sim new file mode 100644 index 0000000000000000000000000000000000000000..0559d8c7253cfaa9b60e514408ed390562812538 --- /dev/null +++ b/tests/script/general/compute/sample.sim @@ -0,0 +1,165 @@ +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 200 +sql connect + +$dbPrefix = m_db +$tbPrefix = m_tb +$mtPrefix = m_mt +$tbNum = 10 +$rowNum = 20 +$totalNum = 200 + +print =============== step1 +$i = 0 +$db = $dbPrefix . $i +$mt = $mtPrefix . $i + +sql drop database $db -x step1 +step1: +sql create database $db +sql use $db +sql create table $mt (ts timestamp, tbcol int, bin binary(43), nch nchar(43)) TAGS(tgcol int) + +$i = 0 +while $i < $tbNum + $tb = $tbPrefix . $i + sql create table $tb using $mt tags( $i ) + + $x = 0 + while $x < $rowNum + $cc = $x * 60000 + $ms = 1601481600000 + $cc + + sql insert into $tb values ($ms , $x , 'binary' , 'nchar' ) + $x = $x + 1 + endw + + $i = $i + 1 +endw + +sleep 100 + +print =============== step2 +$i = 1 +$tb = $tbPrefix . $i + +sql select sample(tbcol, 1) from $tb +if $rows != 1 then + return -1 +endi +if $data01 > 19 then + return -1 +endi +sql select sample(bin, 1) from $tb +if $rows != 1 then + return -1 +endi +if $data01 != @binary@ then + return -1 +endi +sql select sample(nch, 1) from $tb +if $rows != 1 then + return -1 +endi +if $data01 != @nchar@ then + return -1 +endi + +print =============== step3 +$cc = 4 * 60000 +$ms = 1601481600000 + $cc + +sql select sample(tbcol, 1) from $tb where ts <= $ms +if $data01 > 4 then + return -1 +endi +sql select sample(bin, 1) from $tb where ts <= $ms +if $data01 != @binary@ then + return -1 +endi +sql select sample(nch, 1) from $tb where ts <= $ms +if $data01 != @nchar@ then + return -1 +endi + +print =============== step4 +sql select sample(tbcol, 1) as b from $tb +if $data01 > 19 then + return -1 +endi + +sql select sample(bin, 1) as b from $tb + +print =============== step5 +sql select sample(tbcol, 2) as b from $tb +if $rows != 2 then + return -1 +endi +if $data01 > 19 then + return -1 +endi +if $data11 > 19 then + return -1 +endi +sql_error select sample(nchar, 2) as b from $tb +sql select sample(nch, 2) as b from $tb +if $rows != 2 then + return -1 +endi +print =====> $data01 , $data11 +if $data01 != @nchar@ then + return -1 +endi +if $data11 != @nchar@ then + return -1 +endi +sql select sample(bin, 2) as b from $tb +if $rows != 2 then + return -1 +endi +if $data01 != @binary@ then + return -1 +endi +if $data11 != @binary@ then + return -1 +endi + +print =============== step6 +$cc = 4 * 60000 +$ms = 1601481600000 + $cc + +sql select sample(tbcol, 2) as b from $tb where ts <= $ms +if $rows != 2 then + return -1 +endi +if $data01 > 4 then + return -1 +endi +if $data11 > 4 then + return -1 +endi +sql select sample(bin, 2) as b from $tb where ts <= $ms +if $rows != 2 then + return -1 +endi +sql select sample(nch, 2) as b from $tb where ts <= $ms +if $rows != 2 then + return -1 +endi + +sql select sample(tbcol, 1001) as b from $tb -x step6 + return -1 +step6: + +print =============== clear +sql drop database $db +sql show databases +if $rows != 0 then + return -1 +endi + +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/compute/testSuite.sim b/tests/script/general/compute/testSuite.sim index 91bf4bf0cda54d300f4d284c9e057616d4d54abe..25c93ed29339c326628b885c34ed8766299460aa 100644 --- a/tests/script/general/compute/testSuite.sim +++ b/tests/script/general/compute/testSuite.sim @@ -3,6 +3,11 @@ run general/compute/bottom.sim run general/compute/count.sim run general/compute/diff.sim run general/compute/diff2.sim +run general/compute/csum.sim +run general/compute/csum2.sim +run general/compute/mavg.sim +run general/compute/mavg2.sim +run general/compute/sample.sim run general/compute/first.sim run general/compute/interval.sim run general/compute/last.sim diff --git a/tests/script/general/parser/col_arithmetic_operation.sim b/tests/script/general/parser/col_arithmetic_operation.sim index 8bb692e3bbe8af3ec9ed179ad29d40b4712d257b..0989f977462015e98ac6f0b625137973474c03d1 100644 --- a/tests/script/general/parser/col_arithmetic_operation.sim +++ b/tests/script/general/parser/col_arithmetic_operation.sim @@ -124,8 +124,11 @@ sql select spread(ts )/(1000*3600*24) from $stb interval(1y) sql_error select first(c1, c2) - last(c1, c2) from $stb interval(1y) sql_error select first(ts) - last(ts) from $stb interval(1y) sql_error select top(c1, 2) - last(c1) from $stb; +sql_error select sample(c1, 2) - last(c1) from $stb; sql_error select stddev(c1) - last(c1) from $stb; sql_error select diff(c1) - last(c1) from $stb; +sql_error select mavg(c1, 2) - last(c1) from $stb; +sql_error select csum(c1) - last(c1) from $stb; sql_error select first(c7) - last(c7) from $stb; sql_error select first(c8) - last(c8) from $stb; sql_error select first(c9) - last(c9) from $stb; @@ -151,4 +154,4 @@ if $data02 != 225000 then return -1 endi -system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/parser/col_arithmetic_query.sim b/tests/script/general/parser/col_arithmetic_query.sim index 17ae6cfd6b8b5636101e67e8d99f6999e50a06a5..502de9583e9727d2dbee4a5601f974d6a46173ba 100644 --- a/tests/script/general/parser/col_arithmetic_query.sim +++ b/tests/script/general/parser/col_arithmetic_query.sim @@ -174,6 +174,9 @@ endi sql_error select top(c1, 1) - bottom(c1, 1) from $tb sql_error select top(c1, 99) - bottom(c1, 99) from $tb sql_error select top(c1,1) - 88 from $tb +sql_error select sample(c1, 1) - bottom(c1, 1) from $tb +sql_error select sample(c1, 99) - bottom(c1, 99) from $tb +sql_error select sample(c1,1) - 88 from $tb # all data types [d.6] ================================================================ sql select c2-c1*1.1, c3/c2, c4*c3, c5%c4, (c6+c4)%22, c2-c2 from $tb @@ -475,11 +478,16 @@ endi sql_error select first(c1, c2) - last(c1, c2) from $stb sql_error select top(c1, 5) - bottom(c1, 5) from $stb sql_error select first(*) - 99 from $stb +sql_error select sample(c1, 5) - bottom(c1, 5) from $stb + # multi row result aggregation [d.4] sql_error select top(c1, 1) - bottom(c1, 1) from $stb sql_error select top(c1, 99) - bottom(c1, 99) from $stb +sql_error select sample(c1, 1) - top(c1, 1) from $stb +sql_error select sample(c1, 99) - top(c1, 99) from $stb + # query on super table [d.5]============================================================= # all cases in this part are query on super table diff --git a/tests/script/general/parser/function.sim b/tests/script/general/parser/function.sim index 556292b21b218f4df2aaa034d8babe35903a23b8..578234b2984a7d9440e4ea4390d8cb3a4580ab8d 100644 --- a/tests/script/general/parser/function.sim +++ b/tests/script/general/parser/function.sim @@ -1087,6 +1087,14 @@ sql select diff(val) from (select derivative(k, 1s, 0) val from t1); if $rows != 0 then return -1 endi +sql select mavg(val,2) from (select derivative(k, 1s, 0) val from t1); +if $rows != 0 then + return -1 +endi +sql select csum(val) from (select derivative(k, 1s, 0) val from t1); +if $rows != 0 then + return -1 +endi sql insert into t1 values('2020-1-1 1:1:4', 20); sql insert into t1 values('2020-1-1 1:1:6', 200); diff --git a/tests/script/general/parser/having.sim b/tests/script/general/parser/having.sim index e063333853e04faf1a7f4988b6dd1f11207aee5d..cf3452d179a57eaade2492924513a425aed5870e 100644 --- a/tests/script/general/parser/having.sim +++ b/tests/script/general/parser/having.sim @@ -121,6 +121,7 @@ if $data31 != 4 then return -1 endi +sql_error select sample(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 select last(f1) from st2 group by f1 having count(f2) > 0; @@ -140,9 +141,12 @@ if $data30 != 4 then return -1 endi -sql_error select top(f1,2) from st2 group by f1 having count(f2) > 0; -sql_error select top(f1,2) from st2 group by f1 having count(f2) > 0; -sql_error select top(f1,2) from st2 group by f1 having avg(f1) > 0; +sql_error select sample(f1,2) from st2 group by f1 having count(f2) > 0; +sql_error select sample(f1,2) from st2 group by f1 having count(f2) > 0; +sql_error select sample(f1,2) from st2 group by f1 having avg(f1) > 0; +sql_error select sample(f1,2) from st2 group by f1 having count(f2) > 0; +sql_error select sample(f1,2) from st2 group by f1 having count(f2) > 0; +sql_error select sample(f1,2) from st2 group by f1 having avg(f1) > 0; sql select avg(f1),count(f1) from st2 group by f1 having avg(f1) > 2; if $rows != 2 then @@ -1059,6 +1063,13 @@ if $data26 != 4 then endi +sql_error select avg(f1),count(st2.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1),last(f1) from st2 group by f1 having sample(f1,1); + +sql_error select avg(f1),count(st2.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1),last(f1) from st2 group by f1 having sample(f1,1) > 1; + +sql_error select avg(f1),count(st2.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1),last(f1),sample(f1,1) from st2 group by f1 having sum(f1) > 1; + +sql_error select avg(f1),count(st2.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1),last(f1),sample(f1,1),bottom(f1,1) from st2 group by f1 having bottom(f1,1) > 1; sql_error select avg(f1),count(st2.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1),last(f1) from st2 group by f1 having top(f1,1); @@ -1149,6 +1160,18 @@ sql_error select avg(f1),diff(f1) from st2 group by f1 having avg(f1) > 0; sql_error select avg(f1),diff(f1) from st2 group by f1 having spread(f2) > 0; +sql_error select avg(f1) from st2 group by f1 having mavg(f1, 2) > 0; + +sql_error select avg(f1),mavg(f1, 3) from st2 group by f1 having avg(f1) > 0; + +sql_error select avg(f1),mavg(f1, 4) from st2 group by f1 having spread(f2) > 0; + +sql_error select avg(f1) from st2 group by f1 having csum(f1) > 0; + +sql_error select avg(f1),csum(f1) from st2 group by f1 having avg(f1) > 0; + +sql_error select avg(f1),csum(f1) from st2 group by f1 having spread(f2) > 0; + sql select avg(f1) from st2 group by f1 having spread(f2) > 0; if $rows != 0 then return -1 @@ -1834,6 +1857,7 @@ if $data04 != 1 then return -1 endi +sql_error select sample(f1,2) from tb1 group by f1 having count(f1) > 0; sql_error select top(f1,2) from tb1 group by f1 having count(f1) > 0; sql_error select count(*) from tb1 group by f1 having last(*) > 0; diff --git a/tests/script/general/parser/having_child.sim b/tests/script/general/parser/having_child.sim index 0fe5448869a5720a62550a88981114e737e4965b..ff7b786638006fb862ab0e22b2c8e6c6fb65902e 100644 --- a/tests/script/general/parser/having_child.sim +++ b/tests/script/general/parser/having_child.sim @@ -120,6 +120,7 @@ if $data31 != 4 then endi sql_error select top(f1,2) from tb1 group by f1 having count(f2) > 0; +sql_error select sample(f1,2) from tb1 group by f1 having count(f2) > 0; sql select last(f1) from tb1 group by f1 having count(f2) > 0; if $rows != 4 then @@ -144,6 +145,12 @@ sql_error select top(f1,2) from tb1 group by f1 having count(f2) > 0; sql_error select top(f1,2) from tb1 group by f1 having avg(f1) > 0; +sql_error select sample(f1,2) from tb1 group by f1 having count(f2) > 0; + +sql_error select sample(f1,2) from tb1 group by f1 having count(f2) > 0; + +sql_error select sample(f1,2) from tb1 group by f1 having avg(f1) > 0; + sql select avg(f1),count(f1) from tb1 group by f1 having avg(f1) > 2; if $rows != 2 then return -1 @@ -1067,7 +1074,13 @@ if $data26 != 4 then return -1 endi +sql_error select avg(f1),count(tb1.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1),last(f1) from tb1 group by f1 having sample(f1,1); + +sql_error select avg(f1),count(tb1.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1),last(f1) from tb1 group by f1 having sample(f1,1) > 1; +sql_error select avg(f1),count(tb1.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1),last(f1),sample(f1,1),bottom(f1,1) from tb1 group by f1 having bottom(f1,1) > 1; + +sql_error select avg(f1),count(tb1.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1),last(f1),sample(f1,1),bottom(f1,1) from tb1 group by f1 having sum(f1) > 1; sql_error select avg(f1),count(tb1.*),sum(f1),stddev(f1),min(f1),max(f1),first(f1),last(f1) from tb1 group by f1 having top(f1,1); @@ -1164,6 +1177,20 @@ sql_error select avg(f1),diff(f1) from tb1 group by f1 having avg(f1) > 0; sql_error select avg(f1),diff(f1) from tb1 group by f1 having spread(f2) > 0; + +sql_error select avg(f1) from tb1 group by f1 having mavg(f1,4) > 0; + +sql_error select avg(f1),mavg(f1,5) from tb1 group by f1 having avg(f1) > 0; + +sql_error select avg(f1),mavg(f1,6) from tb1 group by f1 having spread(f2) > 0; + + +sql_error select avg(f1) from tb1 group by f1 having csum(f1) > 0; + +sql_error select avg(f1),csum(f1) from tb1 group by f1 having avg(f1) > 0; + +sql_error select avg(f1),csum(f1) from tb1 group by f1 having spread(f2) > 0; + sql select avg(f1) from tb1 group by f1 having spread(f2) > 0; if $rows != 0 then return -1 @@ -1857,4 +1884,6 @@ endi sql_error select top(f1,2) from tb1 group by f1 having count(f1) > 0; +sql_error select sample(f1,2) from tb1 group by f1 having count(f1) > 0; + system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/parser/limit.sim b/tests/script/general/parser/limit.sim index 3af2cb301854b27bc1b9c33bf8b06cbd17e87fd3..00ebc7601386e1a19cd43253794f891441e87fe3 100644 --- a/tests/script/general/parser/limit.sim +++ b/tests/script/general/parser/limit.sim @@ -80,4 +80,7 @@ sql use $db sql select * from (select ts, top(c1, 5) from $tb where ts >= $ts0 order by ts desc limit 3 offset 1) sql select * from (select ts, top(c1, 5) from $stb where ts >= $ts0 order by ts desc limit 3 offset 1) -system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file +sql select * from (select ts, sample(c1, 5) from $tb where ts >= $ts0 order by ts desc limit 3 offset 1) +sql_error select * from (select ts, sample(c1, 5) from $stb where ts >= $ts0 order by ts desc limit 3 offset 1) + +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/parser/limit1_tb.sim b/tests/script/general/parser/limit1_tb.sim index 300af7ac7b669088094c0ba72288f42d34ca374d..9c96897da89e5e2b4c3f66f30f53d5ebf674c660 100644 --- a/tests/script/general/parser/limit1_tb.sim +++ b/tests/script/general/parser/limit1_tb.sim @@ -471,6 +471,92 @@ if $data81 != -9 then return -1 endi +sql select mavg(c1,2) from $tb +$res = $rowNum - 1 +if $rows != $res then + return -1 +endi + +sql select mavg(c1,2) from $tb where c1 > 5 limit 2 offset 1 +print $rows , $data00 , $data01 , $data10 , $data11 +if $rows != 2 then + return -1 +endi +if $data00 != @18-09-17 10:20:00.000@ then + return -1 +endi +if $data01 != 7.500000000 then + return -1 +endi +if $data10 != @18-09-17 10:30:00.000@ then + return -1 +endi +if $data11 != 8.500000000 then + return -1 +endi +$limit = $rowNum / 2 +$offset = $limit - 1 +sql select mavg(c1,2) from $tb where c1 >= 0 limit $limit offset $offset +if $rows != $limit then + return -1 +endi +$limit = $rowNum / 2 +$offset = $limit + 1 +$val = $limit - 2 +sql select mavg(c1,2) from $tb where c1 >= 0 limit $limit offset $offset +print $rows , $data01 , $data81 +if $rows != $val then + return -1 +endi +if $data01 != 1.500000000 then + return -1 +endi +if $data81 != 4.500000000 then + return -1 +endi + +sql select csum(c1) from $tb +$res = $rowNum +if $rows != $res then + return -1 +endi + +sql select csum(c1) from $tb where c1 > 5 limit 2 offset 1 +if $rows != 2 then + return -1 +endi +if $data00 != @18-09-17 10:10:00.000@ then + return -1 +endi +if $data01 != 13 then + return -1 +endi +if $data10 != @18-09-17 10:20:00.000@ then + return -1 +endi +if $data11 != 21 then + return -1 +endi +$limit = $rowNum / 2 +$offset = $limit - 1 +sql select csum(c1) from $tb where c1 >= 0 limit $limit offset $offset +if $rows != $limit then + return -1 +endi +$limit = $rowNum / 2 +$offset = $limit + 1 +$val = $limit - 1 +sql select csum(c1) from $tb where c1 >= 0 limit $limit offset $offset +if $rows != $val then + return -1 +endi +if $data01 != 22501 then + return -1 +endi +if $data81 != 22545 then + return -1 +endi + ### aggregation + limit offset (with interval) sql select max(c1), max(c2), max(c3), max(c4), max(c5), max(c6) from $tb where ts >= $ts0 and ts <= $tsu interval(5m) limit 5 if $rows != 5 then diff --git a/tests/script/general/parser/limit_stb.sim b/tests/script/general/parser/limit_stb.sim index ec7c0e0f138e677c7da95c20af4bd13908aa1a0c..2e6c10cd96db8536e12acf57bf9283eb20f59d1b 100644 --- a/tests/script/general/parser/limit_stb.sim +++ b/tests/script/general/parser/limit_stb.sim @@ -828,6 +828,8 @@ if $data59 != 4 then return -1 endi +sql_error select sample(c1, 1) from $stb where ts >= $ts0 and ts <= $tsu limit 5 offset 1 + sql select top(c1, 1) from $stb where ts >= $ts0 and ts <= $tsu limit 5 offset 1 if $rows != 0 then return -1 diff --git a/tests/script/general/parser/limit_tb.sim b/tests/script/general/parser/limit_tb.sim index 4a93797d40fb65a7df9ad8d18c60292bed83dfe4..f130214ddbed895d29ed0dba08a93003cee6e32b 100644 --- a/tests/script/general/parser/limit_tb.sim +++ b/tests/script/general/parser/limit_tb.sim @@ -355,6 +355,21 @@ sql select top(c1, 1) from $tb where ts >= $ts0 and ts <= $tsu limit 5 offset 1 if $rows != 0 then return -1 endi +sql select sample(c1, 1) from $tb where ts >= $ts0 and ts <= $tsu limit 5 offset 1 +if $rows != 0 then + return -1 +endi + +sql select * from (select ts, sample(c1, 5) from $tb where ts >= $ts0 and ts <= $tsu order by ts desc limit 3 offset 1) + +sql select ts,sample(c1, 5) from $tb where ts >= $ts0 and ts <= $tsu order by ts desc limit 3 offset 1 +if $rows != 3 then + return -1 +endi +print select ts,sample(c1, 5) from $tb where ts >= $ts0 and ts <= $tsu order by ts desc limit 3 offset 1 +print $data00 $data01 $data02 +print $data10 $data11 $data12 +print $data20 $data21 $data22 print ========> TD-6017 sql select * from (select ts, top(c1, 5) from $tb where ts >= $ts0 and ts <= $tsu order by ts desc limit 3 offset 1) @@ -463,6 +478,35 @@ if $data11 != 1 then return -1 endi +sql select mavg(c1,3) from $tb where c1 > 5 limit 2 offset 1 +print $rows , $data00 , $data01 +if $rows != 1 then + return -1 +endi +if $data00 != @18-09-17 10:30:00.000@ then + return -1 +endi +if $data01 != 8.000000000 then + return -1 +endi + +sql select csum(c1) from $tb where c1 > 5 limit 2 offset 1 +if $rows != 2 then + return -1 +endi +if $data00 != @18-09-17 10:10:00.000@ then + return -1 +endi +if $data01 != 13 then + return -1 +endi +if $data10 != @18-09-17 10:20:00.000@ then + return -1 +endi +if $data11 != 21 then + return -1 +endi + ### aggregation + limit offset (with interval) sql select max(c1), max(c2), max(c3), max(c4), max(c5), max(c6) from $tb where ts >= $ts0 and ts <= $tsu interval(5m) limit 5 if $rows != 5 then diff --git a/tests/script/general/parser/nestquery.sim b/tests/script/general/parser/nestquery.sim index 3c1ba0336973b8d07c785337de2d2c66202520c4..f2c539dbf8b8bd68c6481e790198a28d860f0b92 100644 --- a/tests/script/general/parser/nestquery.sim +++ b/tests/script/general/parser/nestquery.sim @@ -186,6 +186,8 @@ sql_error select derivative(val, 1s, 0) from (select c1 val from nest_tb0); sql_error select twa(c1) from (select c1 from nest_tb0); sql_error select irate(c1) from (select c1 from nest_tb0); sql_error select diff(c1), twa(c1) from (select * from nest_tb0); +sql_error select mavg(c1,2), twa(c1) from (select * from nest_tb0); +sql_error select csum(c1), twa(c1) from (select * from nest_tb0); sql_error select irate(c1), interp(c1), twa(c1) from (select * from nest_tb0); sql select apercentile(c1, 50) from (select * from nest_tb0) interval(1d) @@ -273,6 +275,14 @@ sql select diff(c1) from (select * from nest_tb0); if $rows != 9999 then return -1 endi +sql select mavg(c1,2) from (select * from nest_tb0); +if $rows != 9999 then + return -1 +endi +sql select csum(c1) from (select * from nest_tb0); +if $rows != 10000 then + return -1 +endi sql select avg(c1),sum(c2), max(c3), min(c4), count(*), first(c7), last(c7),spread(c6) from (select * from nest_tb0) interval(1d); if $rows != 7 then @@ -330,6 +340,8 @@ if $data12 != 71680.000000000 then return -1 endi +sql select sample(x, 20) from (select c1 x from nest_tb0); + sql select top(x, 20) from (select c1 x from nest_tb0); sql select bottom(x, 20) from (select c1 x from nest_tb0) @@ -420,6 +432,35 @@ if $data01 != 1 then return -1 endi +sql select mavg(val, 2) from (select c1 val from nest_tb0); +if $rows != 9999 then + return -1 +endi + +if $data00 != @70-01-01 08:00:00.000@ then + return -1 +endi +if $data01 != 0.500000000 then + return -1 +endi + +sql select csum(val) from (select c1 val from nest_tb0); +if $rows != 10000 then + return -1 +endi + +if $data00 != @70-01-01 08:00:00.000@ then + return -1 +endi + +if $data01 != 0 then + return -1 +endi + +if $data41 != 10 then + return -1 +endi + sql_error select last_row(*) from (select * from nest_tb0) having c1 > 0 print ===========>td-4805 @@ -508,4 +549,4 @@ if $data11 != 2.000000000 then return -1 endi -system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/parser/projection_limit_offset.sim b/tests/script/general/parser/projection_limit_offset.sim index ffbcb28ffd9b4e15f707509dc5cc808ef3f8ce4a..a44d6782cecd6999eb887b574df944358f90faf7 100644 --- a/tests/script/general/parser/projection_limit_offset.sim +++ b/tests/script/general/parser/projection_limit_offset.sim @@ -296,6 +296,7 @@ sql_error select last(t1) from group_mt0; sql_error select min(t1) from group_mt0; sql_error select max(t1) from group_mt0; sql_error select top(t1, 20) from group_mt0; +sql_error select sample(t1, 20) from group_mt0; sql_error select bottom(t1, 20) from group_mt0; sql_error select avg(t1) from group_mt0; sql_error select percentile(t1, 50) from group_mt0; @@ -393,6 +394,25 @@ if $data21 != -1 then return -1 endi +sql select mavg(k,3) from tm0 +print ====> $rows , $data21 +if $row != 2 then + return -1 +endi +if $data11 != 2.333333333 then + return -1 +endi + +sql select csum(k) from tm0 +print ====> $rows , $data21 +if $row != 4 then + return -1 +endi + +if $data21 != 6 then + return -1 +endi + #error sql sql_error select * from 1; #sql_error select 1; // equals to select server_status(); diff --git a/tests/script/general/parser/select_with_tags.sim b/tests/script/general/parser/select_with_tags.sim index eb6cd75d2104f7ff61b5f5e5bccc12fdd239d3d5..195eca928fa4ddbf3795ae3e40f973ea0a5e8def 100644 --- a/tests/script/general/parser/select_with_tags.sim +++ b/tests/script/general/parser/select_with_tags.sim @@ -181,6 +181,12 @@ if $data03 != @abc15@ then return -1 endi +sql_error select sample(c6, 3) from select_tags_mt0 interval(10a) +sql select sample(c3,10) from select_tags_mt0 interval(10a) group by tbname,t1,t2 +sql select sample(c6, 3) from select_tags_mt0 interval(10a) group by tbname; +sql_error select sample(c6, 10) from select_tags_mt0 interval(10a); +sql_error select sample(c1, 80), tbname, t1, t2 from select_tags_mt0; + 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,t1,t2 sql select top(c6, 3) from select_tags_mt0 interval(10a) group by tbname; @@ -418,6 +424,11 @@ if $data11 != @70-01-01 08:01:40.001@ then return -1 endi +sql select sample(c1, 100), tbname, t1, t2 from select_tags_mt0 where tbname in ('select_tags_tb0', 'select_tags_tb1') group by tbname; +if $rows != 200 then + return -1 +endi + sql select top(c1, 100), tbname, t1, t2 from select_tags_mt0 where tbname in ('select_tags_tb0', 'select_tags_tb1') group by tbname; if $row != 200 then return -1 @@ -455,6 +466,11 @@ if $data04 != @abc0@ then return -1 endi +sql select sample(c1, 2), t2 from select_tags_mt0 where tbname in ('select_tags_tb0', 'select_tags_tb1') group by tbname,t2; +if $rows != 4 then + return -1 +endi + sql select top(c1, 2), t2 from select_tags_mt0 where tbname in ('select_tags_tb0', 'select_tags_tb1') group by tbname,t2; if $row != 4 then return -1 @@ -542,6 +558,11 @@ endi # slimit /limit +sql select sample(c1, 2), t2 from select_tags_mt0 where tbname in ('select_tags_tb0', 'select_tags_tb1') group by tbname,t2 limit 2 offset 1; +if $rows != 2 then + return -1 +endi + sql select top(c1, 2), t2 from select_tags_mt0 where tbname in ('select_tags_tb0', 'select_tags_tb1') group by tbname,t2 limit 2 offset 1; if $row != 2 then return -1 @@ -715,6 +736,11 @@ if $data25 != @select_tags_tb2@ then return -1 endi +sql select sample(c1, 5), t2 from select_tags_mt0 where c1<=2 interval(1d) group by tbname; +if $row != 15 then + return -1 +endi + sql select top(c1, 5), t2 from select_tags_mt0 where c1<=2 interval(1d) group by tbname; if $row != 15 then return -1 @@ -753,6 +779,11 @@ if $data93 != @select_tags_tb1@ then endi #if data +sql select sample(c1, 50), t2, t1, tbname from select_tags_mt0 where c1<=2 interval(1d) group by tbname; +if $row != 48 then + return -1 +endi + sql select top(c1, 50), t2, t1, tbname from select_tags_mt0 where c1<=2 interval(1d) group by tbname; if $row != 48 then return -1 @@ -838,6 +869,8 @@ endi print TODO ======= selectivity + tags+ group by + tags + filter + interval + join=========== print ==========================mix tag columns and group by columns====================== +sql_error select sample(c1, 100), tbname from select_tags_mt0 where tbname in ('select_tags_tb0', 'select_tags_tb1') group by t3 + 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 diff --git a/tests/script/general/parser/udf_dll.sim b/tests/script/general/parser/udf_dll.sim index 0f9436762adb645785ddcf9a4abaf4a5be810a34..7168e0a5ddf5502170e6bb22f30b10621795a568 100644 --- a/tests/script/general/parser/udf_dll.sim +++ b/tests/script/general/parser/udf_dll.sim @@ -489,6 +489,7 @@ sql_error select ts,sum_double(f1),f1 from tb1; sql_error select add_one(f1),count(f1) from tb1; sql_error select sum_double(f1),count(f1) from tb1; sql_error select add_one(f1),top(f1,3) from tb1; +sql_error select add_one(f1),sample(f1,3) from tb1; sql_error select add_one(f1) from tb1 interval(10a); system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/parser/udf_dll_stable.sim b/tests/script/general/parser/udf_dll_stable.sim index b8da57467e912ff27f4fbda7226c75e089f04808..15becaab22476d12829abc62db4de4f914eef271 100644 --- a/tests/script/general/parser/udf_dll_stable.sim +++ b/tests/script/general/parser/udf_dll_stable.sim @@ -508,6 +508,7 @@ sql_error select ts,sum_double(f1),f1 from tb1; sql_error select add_one(f1),count(f1) from tb1; sql_error select sum_double(f1),count(f1) from tb1; sql_error select add_one(f1),top(f1,3) from tb1; +sql_error select add_one(f1),sample(f1,3) from tb1; sql_error select add_one(f1) from tb1 interval(10a); diff --git a/tests/script/regressionSuite.sim b/tests/script/regressionSuite.sim index bada2f655202ddc34ce6e67e718336a2afc41d50..faa6672b42be666d17bafe5a6176d95cdbbc27a8 100644 --- a/tests/script/regressionSuite.sim +++ b/tests/script/regressionSuite.sim @@ -21,6 +21,11 @@ run general/compute/bottom.sim run general/compute/count.sim run general/compute/diff.sim run general/compute/diff2.sim +run general/compute/mavg.sim +run general/compute/mavg2.sim +run general/compute/sample.sim +run general/compute/csum.sim +run general/compute/csum2.sim run general/compute/first.sim run general/compute/interval.sim run general/compute/last.sim