diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 5a2e35045018a4780be8dff09c13454a039d4ab7..254c39d37e388b97fe3df38132e3a19e3fdece8c 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -2457,6 +2457,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col const char* msg10 = "derivative duration should be greater than 1 Second"; const char* msg11 = "third parameter in derivative should be 0 or 1"; const char* msg12 = "parameter is out of range [1, 100]"; + const char* msg13 = "third parameter should be 0 or 1"; switch (functionId) { case TSDB_FUNC_COUNT: { @@ -2790,8 +2791,16 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col case TSDB_FUNC_PERCT: case TSDB_FUNC_APERCT: { // 1. valid the number of parameters - if (pItem->pNode->Expr.paramList == NULL || taosArrayGetSize(pItem->pNode->Expr.paramList) != 2) { - /* no parameters or more than one parameter for function */ + bool valid = true; + if(pItem->pNode->Expr.paramList == NULL) { + valid = false; + } else if(functionId == TSDB_FUNC_APERCT) { + size_t cnt = taosArrayGetSize(pItem->pNode->Expr.paramList); + if(cnt != 2 && cnt !=3) valid = false; + } else { + if (taosArrayGetSize(pItem->pNode->Expr.paramList) != 2) valid = false; + } + if(!valid) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2); } @@ -2837,16 +2846,14 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col SExprInfo* pExpr = NULL; if (functionId == TSDB_FUNC_PERCT || functionId == TSDB_FUNC_APERCT) { + // param1 double tVariantDump(pVariant, val, TSDB_DATA_TYPE_DOUBLE, true); - double dp = GET_DOUBLE_VAL(val); if (dp < 0 || dp > TOP_BOTTOM_QUERY_LIMIT) { return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5); } - getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &resultType, &resultSize, &interResult, 0, false, pUdfInfo); - /* * sql function transformation * for dp = 0, it is actually min, @@ -2854,9 +2861,22 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col */ tscInsertPrimaryTsSourceColumn(pQueryInfo, pTableMetaInfo->pTableMeta->id.uid); colIndex += 1; // the first column is ts - pExpr = tscExprAppend(pQueryInfo, functionId, &index, resultType, resultSize, getNewResColId(pCmd), interResult, false); tscExprAddParams(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double)); + + // param2 int32 + if (taosArrayGetSize(pItem->pNode->Expr.paramList) == 3) { + if (pParamElem[2].pNode != NULL) { + pVariant = &pParamElem[2].pNode->value; + tVariantDump(pVariant, val, TSDB_DATA_TYPE_INT, true); + int32_t algo = GET_INT32_VAL(val); + if(algo < 0 || algo >1 ) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg13); + } + tscExprAddParams(&pExpr->base, val, TSDB_DATA_TYPE_INT, sizeof(int32_t)); + } + } + } else { tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true); diff --git a/src/query/inc/qAggMain.h b/src/query/inc/qAggMain.h index d4116fbfb2daec9b47c4a891c3c886728e6ca515..37fbcf67bc050336290bf3952a58cdd1cdf44232 100644 --- a/src/query/inc/qAggMain.h +++ b/src/query/inc/qAggMain.h @@ -106,6 +106,10 @@ extern "C" { #define MAX_INTERVAL_TIME_WINDOW 1000000 // maximum allowed time windows in final results #define TOP_BOTTOM_QUERY_LIMIT 100 +// apercentile(arg1,agr2,arg3) param arg3 value is below: +#define ALGO_DEFAULT 0 +#define ALGO_TDIGEST 1 + enum { MASTER_SCAN = 0x0u, REVERSE_SCAN = 0x1u, diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index 81c39d6fc7d66725508738f31382a36f8a05ee1d..8d0ad37472a68d119128ff75f479153a266d7ada 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -2451,7 +2451,7 @@ static bool tdigest_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo *pResultInfo) // new TDigest SAPercentileInfo *pAPerc = getAPerctInfo(pCtx); - int compression = 5; + int compression = 500; if(pAPerc) { if(pAPerc->pTDigest == NULL) { pAPerc->pTDigest = tdigestNew(compression); @@ -2486,7 +2486,7 @@ static void tdigest_do(SQLFunctionCtx *pCtx) { tdigestAdd(pAPerc->pTDigest, v, w); } - tdigestCompress(pAPerc->pTDigest); + //tdigestCompress(pAPerc->pTDigest); if (!pCtx->hasNull) { assert(pCtx->size == notNullElems); @@ -2519,7 +2519,7 @@ static void tdigest_finalizer(SQLFunctionCtx *pCtx) { if (pCtx->currentStage == MERGE_STAGE) { if (pResInfo->hasResult == DATA_SET_FLAG) { // check for null - double res = tdigestQuantile(pAPerc->pTDigest, q); + double res = tdigestQuantile(pAPerc->pTDigest, q/100); memcpy(pCtx->pOutput, &res, sizeof(double)); } else { setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes); @@ -2527,7 +2527,7 @@ static void tdigest_finalizer(SQLFunctionCtx *pCtx) { } } else { if (pAPerc->pTDigest->size > 0) { - double res = tdigestQuantile(pAPerc->pTDigest, q); + double res = tdigestQuantile(pAPerc->pTDigest, q/100); memcpy(pCtx->pOutput, &res, sizeof(double)); } else { // no need to free setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes); @@ -2542,10 +2542,18 @@ static void tdigest_finalizer(SQLFunctionCtx *pCtx) { } ////////////////////////////////////////////////////////////////////////////////// +int32_t getAlgo(SQLFunctionCtx * pCtx) { + if(pCtx->numOfParams != 2){ + return ALGO_DEFAULT; + } + if(pCtx->param[1].nType != TSDB_DATA_TYPE_INT) { + return ALGO_DEFAULT; + } + return (int32_t)pCtx->param[1].i64; +} -int algo = 1; static bool apercentile_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo *pResultInfo) { - if (algo == 1) { + if (getAlgo(pCtx) == ALGO_TDIGEST) { return tdigest_setup(pCtx, pResultInfo); } @@ -2561,7 +2569,7 @@ static bool apercentile_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo } static void apercentile_function(SQLFunctionCtx *pCtx) { - if (algo == 1) { + if (getAlgo(pCtx) == ALGO_TDIGEST) { tdigest_do(pCtx); return; } @@ -2598,7 +2606,7 @@ static void apercentile_function(SQLFunctionCtx *pCtx) { } static void apercentile_func_merge(SQLFunctionCtx *pCtx) { - if (algo == 1) { + if (getAlgo(pCtx) == ALGO_TDIGEST) { tdigest_merge(pCtx); return; } @@ -2632,8 +2640,9 @@ static void apercentile_func_merge(SQLFunctionCtx *pCtx) { SET_VAL(pCtx, 1, 1); } + static void apercentile_finalizer(SQLFunctionCtx *pCtx) { - if (algo == 1) { + if (getAlgo(pCtx) == ALGO_TDIGEST) { tdigest_finalizer(pCtx); return; }