From b005dad8e2b98dd4710d3af8a7ddf2b8a13daf44 Mon Sep 17 00:00:00 2001 From: xywang Date: Fri, 13 Aug 2021 00:14:12 +0800 Subject: [PATCH] [TD-2573]: ceil, floor and round functions are supported --- src/client/src/tscSQLParser.c | 16 +- src/query/inc/qAggMain.h | 1 + src/query/src/qAggMain.c | 519 ++++++++++++++++++++++++- src/query/src/qExecutor.c | 23 +- tests/script/general/compute/ceil.sim | 252 ++++++++++++ tests/script/general/compute/floor.sim | 252 ++++++++++++ tests/script/general/compute/round.sim | 252 ++++++++++++ 7 files changed, 1305 insertions(+), 10 deletions(-) create mode 100644 tests/script/general/compute/ceil.sim create mode 100644 tests/script/general/compute/floor.sim create mode 100644 tests/script/general/compute/round.sim diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 946d681ec7..8c812bee0a 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -2540,6 +2540,9 @@ 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_CEIL: + case TSDB_FUNC_FLOOR: + case TSDB_FUNC_ROUND: case TSDB_FUNC_STDDEV: case TSDB_FUNC_LEASTSQR: { // 1. valid the number of parameters @@ -6159,7 +6162,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_CEIL || f == TSDB_FUNC_FLOOR || f == TSDB_FUNC_ROUND) + { isProjectionFunction = true; break; } @@ -6761,6 +6766,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) { const char* msg2 = "aggregation function should not be mixed up with projection"; bool tagTsColExists = false; + int16_t numOfScalar = 0; int16_t numOfSelectivity = 0; int16_t numOfAggregation = 0; @@ -6794,6 +6800,8 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) { if ((aAggs[functionId].status & TSDB_FUNCSTATE_SELECTIVITY) != 0) { numOfSelectivity++; + } else if ((aAggs[functionId].status & TSDB_FUNCSTATE_SCALAR) != 0) { + numOfScalar++; } else { numOfAggregation++; } @@ -6809,14 +6817,14 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) { /* * if numOfSelectivity equals to 0, it is a super table projection query */ - if (numOfSelectivity == 1) { + if (numOfSelectivity == 1 || numOfScalar == 1) { doUpdateSqlFunctionForTagPrj(pQueryInfo); int32_t code = doUpdateSqlFunctionForColPrj(pQueryInfo); if (code != TSDB_CODE_SUCCESS) { return code; } - } else if (numOfSelectivity > 1) { + } else if (numOfSelectivity > 1 || numOfScalar > 1) { /* * If more than one selectivity functions exist, all the selectivity functions must be last_row. * Otherwise, return with error code. @@ -6848,7 +6856,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) { return invalidOperationMsg(msg, msg2); } - if (numOfAggregation > 0 || numOfSelectivity > 0) { + if (numOfAggregation > 0 || numOfScalar > 0 || numOfSelectivity > 0) { // clear the projection type flag pQueryInfo->type &= (~TSDB_QUERY_TYPE_PROJECTION_QUERY); int32_t code = doUpdateSqlFunctionForColPrj(pQueryInfo); diff --git a/src/query/inc/qAggMain.h b/src/query/inc/qAggMain.h index d4116fbfb2..53cfca418f 100644 --- a/src/query/inc/qAggMain.h +++ b/src/query/inc/qAggMain.h @@ -88,6 +88,7 @@ extern "C" { #define TSDB_FUNCSTATE_OF 0x10u // outer forward #define TSDB_FUNCSTATE_NEED_TS 0x20u // timestamp is required during query processing #define TSDB_FUNCSTATE_SELECTIVITY 0x40u // selectivity functions, can exists along with tag columns +#define TSDB_FUNCSTATE_SCALAR 0x80u #define TSDB_BASE_FUNC_SO TSDB_FUNCSTATE_SO | TSDB_FUNCSTATE_STREAM | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_OF #define TSDB_BASE_FUNC_MO TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STREAM | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_OF diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index dad05df22a..9b89dc4483 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -179,7 +179,9 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY || functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_DIFF || functionId == TSDB_FUNC_PRJ || functionId == TSDB_FUNC_TAGPRJ || - functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_INTERP) { + functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_INTERP || functionId == TSDB_FUNC_CEIL || + functionId == TSDB_FUNC_FLOOR || functionId == TSDB_FUNC_ROUND) + { *type = (int16_t)dataType; *bytes = (int16_t)dataBytes; @@ -405,13 +407,19 @@ 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_BLKINFO; ++i) { + for(int32_t i = 0; i <= TSDB_FUNC_ROUND; ++i) { int32_t nameLen = (int32_t) strlen(aAggs[i].name); if (len != nameLen) { continue; } - if (strncasecmp(aAggs[i].name, name, len) == 0) { + if (strncasecmp(aAggs[i].name, name, len) == 0 && + aAggs[i].init != NULL && + aAggs[i].xFunction != NULL && + aAggs[i].xFinalize != NULL && + aAggs[i].mergeFunc != NULL && + aAggs[i].dataReqFunc != NULL) + { return i; } } @@ -4168,6 +4176,425 @@ void blockinfo_func_finalizer(SQLFunctionCtx* pCtx) { doFinalizer(pCtx); } +void setTagCtxList(SQLFunctionCtx *pCtx) +{ + if (pCtx && pCtx->tagInfo.numOfTagCols > 0 && pCtx->ptsList) { + int32_t delta = 4; + void *data = GET_INPUT_DATA_LIST(pCtx); + void *pData = data; + + char **p = calloc(pCtx->tagInfo.numOfTagCols, POINTER_BYTES); + if (p == NULL) { + return; + } + + for (int32_t j = 0; j < pCtx->tagInfo.numOfTagCols; ++j) { + p[j] = pCtx->tagInfo.pTagCtxList[j]->pOutput; + } + + switch(pCtx->inputType) { + case TSDB_DATA_TYPE_INT: + delta = sizeof(int32_t); + break; + case TSDB_DATA_TYPE_TIMESTAMP: + case TSDB_DATA_TYPE_BIGINT: + delta = sizeof(int64_t); + break; + case TSDB_DATA_TYPE_DOUBLE: + delta = sizeof(double); + break; + case TSDB_DATA_TYPE_FLOAT: + delta = sizeof(float); + break; + case TSDB_DATA_TYPE_SMALLINT: + delta = sizeof(int16_t); + break; + case TSDB_DATA_TYPE_TINYINT: + delta = sizeof(int8_t); + break; + default: + free(p); + return; + } + + for (int32_t j = 0; j < pCtx->size; ++j) { + if (pCtx->hasNull && isNull((const char*) ((char *) pData + j * delta), pCtx->inputType)) { + continue; + } + + for (int32_t k = 0; k < pCtx->tagInfo.numOfTagCols; ++k) { + memcpy(p[k], &pCtx->ptsList[j], (size_t)pCtx->tagInfo.pTagCtxList[k]->outputBytes); + p[k] += pCtx->tagInfo.pTagCtxList[k]->outputBytes; + } + } + + free(p); + } +} + +static void ceil_function(SQLFunctionCtx *pCtx) { + void *data = GET_INPUT_DATA_LIST(pCtx); + + 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; + + switch (pCtx->inputType) { + case TSDB_DATA_TYPE_INT: { + int32_t *pData = (int32_t *)data; + int32_t *pOutput = (int32_t *)pCtx->pOutput; + + for (; i < pCtx->size && i >= 0; i += step) { + if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { + continue; + } + + *pOutput++ = (int32_t) ceil((double) pData[i]); + + notNullElems++; + } + setTagCtxList(pCtx); + break; + }; + case TSDB_DATA_TYPE_BIGINT: { + int64_t *pData = (int64_t *)data; + int64_t *pOutput = (int64_t *)pCtx->pOutput; + + for (; i < pCtx->size && i >= 0; i += step) { + if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { + continue; + } + + *pOutput++ = (int64_t) ceil((double) pData[i]); + + notNullElems++; + } + setTagCtxList(pCtx); + break; + } + case TSDB_DATA_TYPE_DOUBLE: { + double *pData = (double *)data; + double *pOutput = (double *)pCtx->pOutput; + + for (; i < pCtx->size && i >= 0; i += step) { + if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { + continue; + } + + SET_DOUBLE_VAL(pOutput, ceil(pData[i])); + pOutput++; + + notNullElems++; + } + setTagCtxList(pCtx); + break; + } + case TSDB_DATA_TYPE_FLOAT: { + float *pData = (float *)data; + float *pOutput = (float *)pCtx->pOutput; + + for (; i < pCtx->size && i >= 0; i += step) { + if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { + continue; + } + + *pOutput++ = (float) ceil((double) pData[i]); + + notNullElems++; + } + setTagCtxList(pCtx); + break; + } + case TSDB_DATA_TYPE_SMALLINT: { + int16_t *pData = (int16_t *)data; + int16_t *pOutput = (int16_t *)pCtx->pOutput; + + for (; i < pCtx->size && i >= 0; i += step) { + if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { + continue; + } + + *pOutput++ = (int16_t) ceil((double) pData[i]); + + notNullElems++; + } + setTagCtxList(pCtx); + break; + } + + case TSDB_DATA_TYPE_TINYINT: { + int8_t *pData = (int8_t *)data; + int8_t *pOutput = (int8_t *)pCtx->pOutput; + + for (; i < pCtx->size && i >= 0; i += step) { + if (pCtx->hasNull && isNull((char *)&pData[i], pCtx->inputType)) { + continue; + } + + *pOutput++ = (int8_t) ceil((double) pData[i]); + + notNullElems++; + } + setTagCtxList(pCtx); + break; + } + default: + qError("error input type"); + } + + if (notNullElems <= 0) { + /* + * current block may be null value + */ + assert(pCtx->hasNull); + } else { + GET_RES_INFO(pCtx)->numOfRes += notNullElems; + } +} + +static void floor_function(SQLFunctionCtx *pCtx) { + void *data = GET_INPUT_DATA_LIST(pCtx); + + 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; + + switch (pCtx->inputType) { + case TSDB_DATA_TYPE_INT: { + int32_t *pData = (int32_t *)data; + int32_t *pOutput = (int32_t *)pCtx->pOutput; + + for (; i < pCtx->size && i >= 0; i += step) { + if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { + continue; + } + + *pOutput++ = (int32_t) floor((double) pData[i]); + + notNullElems++; + } + setTagCtxList(pCtx); + break; + }; + case TSDB_DATA_TYPE_BIGINT: { + int64_t *pData = (int64_t *)data; + int64_t *pOutput = (int64_t *)pCtx->pOutput; + + for (; i < pCtx->size && i >= 0; i += step) { + if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { + continue; + } + + *pOutput++ = (int64_t) floor((double) pData[i]); + + notNullElems++; + } + setTagCtxList(pCtx); + break; + } + case TSDB_DATA_TYPE_DOUBLE: { + double *pData = (double *)data; + double *pOutput = (double *)pCtx->pOutput; + + for (; i < pCtx->size && i >= 0; i += step) { + if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { + continue; + } + + SET_DOUBLE_VAL(pOutput, floor(pData[i])); + pOutput++; + + notNullElems++; + } + setTagCtxList(pCtx); + break; + } + case TSDB_DATA_TYPE_FLOAT: { + float *pData = (float *)data; + float *pOutput = (float *)pCtx->pOutput; + + for (; i < pCtx->size && i >= 0; i += step) { + if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { + continue; + } + + *pOutput++ = (float) floor((double) pData[i]); + + notNullElems++; + } + setTagCtxList(pCtx); + break; + } + case TSDB_DATA_TYPE_SMALLINT: { + int16_t *pData = (int16_t *)data; + int16_t *pOutput = (int16_t *)pCtx->pOutput; + + for (; i < pCtx->size && i >= 0; i += step) { + if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { + continue; + } + + *pOutput++ = (int16_t) floor((double) pData[i]); + + notNullElems++; + } + setTagCtxList(pCtx); + break; + } + + case TSDB_DATA_TYPE_TINYINT: { + int8_t *pData = (int8_t *)data; + int8_t *pOutput = (int8_t *)pCtx->pOutput; + + for (; i < pCtx->size && i >= 0; i += step) { + if (pCtx->hasNull && isNull((char *)&pData[i], pCtx->inputType)) { + continue; + } + + *pOutput++ = (int8_t) floor((double) pData[i]); + + notNullElems++; + } + setTagCtxList(pCtx); + break; + } + default: + qError("error input type"); + } + + if (notNullElems <= 0) { + /* + * current block may be null value + */ + assert(pCtx->hasNull); + } else { + GET_RES_INFO(pCtx)->numOfRes += notNullElems; + } +} + +static void round_function(SQLFunctionCtx *pCtx) { + void *data = GET_INPUT_DATA_LIST(pCtx); + + 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; + + switch (pCtx->inputType) { + case TSDB_DATA_TYPE_INT: { + int32_t *pData = (int32_t *)data; + int32_t *pOutput = (int32_t *)pCtx->pOutput; + + for (; i < pCtx->size && i >= 0; i += step) { + if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { + continue; + } + + *pOutput++ = (int32_t) round((double) pData[i]); + + notNullElems++; + } + setTagCtxList(pCtx); + break; + }; + case TSDB_DATA_TYPE_BIGINT: { + int64_t *pData = (int64_t *)data; + int64_t *pOutput = (int64_t *)pCtx->pOutput; + + for (; i < pCtx->size && i >= 0; i += step) { + if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { + continue; + } + + *pOutput++ = (int64_t) round((double) pData[i]); + + notNullElems++; + } + setTagCtxList(pCtx); + break; + } + case TSDB_DATA_TYPE_DOUBLE: { + double *pData = (double *)data; + double *pOutput = (double *)pCtx->pOutput; + + for (; i < pCtx->size && i >= 0; i += step) { + if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { + continue; + } + + SET_DOUBLE_VAL(pOutput, round(pData[i])); + pOutput++; + + notNullElems++; + } + setTagCtxList(pCtx); + break; + } + case TSDB_DATA_TYPE_FLOAT: { + float *pData = (float *)data; + float *pOutput = (float *)pCtx->pOutput; + + for (; i < pCtx->size && i >= 0; i += step) { + if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { + continue; + } + + *pOutput++ = (float) round((double) pData[i]); + + notNullElems++; + } + setTagCtxList(pCtx); + break; + } + case TSDB_DATA_TYPE_SMALLINT: { + int16_t *pData = (int16_t *)data; + int16_t *pOutput = (int16_t *)pCtx->pOutput; + + for (; i < pCtx->size && i >= 0; i += step) { + if (pCtx->hasNull && isNull((const char*) &pData[i], pCtx->inputType)) { + continue; + } + + *pOutput++ = (int16_t) round((double) pData[i]); + + notNullElems++; + } + setTagCtxList(pCtx); + break; + } + + case TSDB_DATA_TYPE_TINYINT: { + int8_t *pData = (int8_t *)data; + int8_t *pOutput = (int8_t *)pCtx->pOutput; + + for (; i < pCtx->size && i >= 0; i += step) { + if (pCtx->hasNull && isNull((char *)&pData[i], pCtx->inputType)) { + continue; + } + + *pOutput++ = (int8_t) round((double) pData[i]); + + notNullElems++; + } + setTagCtxList(pCtx); + break; + } + default: + qError("error input type"); + } + + if (notNullElems <= 0) { + /* + * current block may be null value + */ + assert(pCtx->hasNull); + } else { + GET_RES_INFO(pCtx)->numOfRes += notNullElems; + } +} + ///////////////////////////////////////////////////////////////////////////////////////////// /* * function compatible list. @@ -4590,7 +5017,7 @@ SAggFunctionInfo aAggs[] = {{ dataBlockRequired, }, { - // 33 + // 33 "_block_dist", // return table id and the corresponding tags for join match and subscribe TSDB_FUNC_BLKINFO, TSDB_FUNC_BLKINFO, @@ -4600,4 +5027,88 @@ SAggFunctionInfo aAggs[] = {{ blockinfo_func_finalizer, block_func_merge, dataBlockRequired, + }, + { + // TODO 34 + "histogram", + TSDB_FUNC_HISTOGRAM, + TSDB_FUNC_HISTOGRAM, + TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS, + NULL, + NULL, + NULL, + NULL, + NULL + }, + { + // TODO 35 + "hll", + TSDB_FUNC_HLL, + TSDB_FUNC_HLL, + TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS, + NULL, + NULL, + NULL, + NULL, + NULL + }, + { + // TODO 36 + "mode", + TSDB_FUNC_MODE, + TSDB_FUNC_MODE, + TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS, + NULL, + NULL, + NULL, + NULL, + NULL + }, + { + // TODO 37 + "sample", + TSDB_FUNC_SAMPLE, + TSDB_FUNC_SAMPLE, + TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STABLE | TSDB_FUNCSTATE_NEED_TS, + NULL, + NULL, + NULL, + NULL, + NULL + }, + { + // 38 + "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 + }, + { + // 39 + "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 + }, + { + // 40 + "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 }}; diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 5323b4306f..142a22cc3f 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -399,6 +399,25 @@ static bool isSelectivityWithTagsQuery(SQLFunctionCtx *pCtx, int32_t numOfOutput return (numOfSelectivity > 0 && hasTags); } +static bool isScalarWithTagsQuery(SQLFunctionCtx *pCtx, int32_t numOfOutput) { + bool hasTags = false; + int32_t numOfScalar = 0; + + for (int32_t i = 0; i < numOfOutput; ++i) { + int32_t functId = pCtx[i].functionId; + if (functId == TSDB_FUNC_TAG_DUMMY || functId == TSDB_FUNC_TS_DUMMY) { + hasTags = true; + continue; + } + + if ((aAggs[functId].status & TSDB_FUNCSTATE_SCALAR) != 0) { + numOfScalar++; + } + } + + return (numOfScalar > 0 && hasTags); +} + static bool isProjQuery(SQueryAttr *pQueryAttr) { for (int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) { int32_t functId = pQueryAttr->pExpr1[i].base.functionId; @@ -1763,7 +1782,7 @@ void setBlockStatisInfo(SQLFunctionCtx *pCtx, SSDataBlock* pSDataBlock, SColInde // set the output buffer for the selectivity + tag query static int32_t setCtxTagColumnInfo(SQLFunctionCtx *pCtx, int32_t numOfOutput) { - if (!isSelectivityWithTagsQuery(pCtx, numOfOutput)) { + if (!isSelectivityWithTagsQuery(pCtx, numOfOutput) && !isScalarWithTagsQuery(pCtx, numOfOutput)) { return TSDB_CODE_SUCCESS; } @@ -1782,7 +1801,7 @@ static int32_t setCtxTagColumnInfo(SQLFunctionCtx *pCtx, int32_t numOfOutput) { if (functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS_DUMMY) { tagLen += pCtx[i].outputBytes; pTagCtx[num++] = &pCtx[i]; - } else if ((aAggs[functionId].status & TSDB_FUNCSTATE_SELECTIVITY) != 0) { + } else if ((aAggs[functionId].status & TSDB_FUNCSTATE_SELECTIVITY) != 0 || (aAggs[functionId].status & TSDB_FUNCSTATE_SCALAR) != 0) { p = &pCtx[i]; } else if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TAG) { // tag function may be the group by tag column diff --git a/tests/script/general/compute/ceil.sim b/tests/script/general/compute/ceil.sim new file mode 100644 index 0000000000..c5e3ff6c04 --- /dev/null +++ b/tests/script/general/compute/ceil.sim @@ -0,0 +1,252 @@ +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 2000 +sql connect + +$dbPrefix = m_di_db +$tbPrefix = m_di_tb +$mtPrefix = m_di_mt +$tbNum = 2 +$rowNum = 5000 + +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 + $y = 0 + + $v0 = 5000.0 + $v1 = -5000.1 + $v2 = 5000.2 + $v3 = -5000.3 + $v4 = 5000.4 + $v5 = -5000.5 + $v6 = 5000.6 + $v7 = -5000.7 + $v8 = 5000.8 + $v9 = -5000.9 + + while $x < $rowNum + $cc = $x * 60000 + $ms = 1601481600000 + $cc + + $val = $v0 + + if $y == 0 then + $val = $v0 + endi + + if $y == 1 then + $val = $v1 + endi + + if $y == 2 then + $val = $v2 + endi + + if $y == 3 then + $val = $v3 + endi + + if $y == 4 then + $val = $v4 + endi + + if $y == 5 then + $val = $v5 + endi + + if $y == 6 then + $val = $v6 + endi + + if $y == 7 then + $val = $v7 + endi + + if $y == 8 then + $val = $v8 + endi + + if $y == 9 then + $val = $v9 + endi + + $tinyint = $x / 128 + sql insert into $tb values ($ms , $x , $val , $x , $x , $tinyint , $x , $x , $x , $x ) + $x = $x + 1 + $y = $y + 1 + if $y == 10 then + $y = 0 + endi + endw + + $i = $i + 1 +endw + +sleep 100 + +print =============== step2 +$i = 1 +$tb = $tbPrefix . $i + +sql select ceil(c2) from $tb +print ===> $data00 +if $data00 != 5000.00000 then + return -1 +endi +sql select ceil(c2) from $tb +print ===> $data10 +if $data10 != -5000.00000 then + return -1 +endi +sql select ceil(c2) from $tb +print ===> $data20 +if $data20 != 5001.00000 then + return -1 +endi +sql select ceil(c2) from $tb +print ===> $data30 +if $data30 != -5000.00000 then + return -1 +endi +sql select ceil(c2) from $tb +print ===> $data40 +if $data40 != 5001.00000 then + return -1 +endi +sql select ceil(c2) from $tb +print ===> $data50 +if $data50 != -5000.00000 then + return -1 +endi +sql select ceil(c2) from $tb +print ===> $data60 +if $data60 != 5001.00000 then + return -1 +endi +sql select ceil(c2) from $tb +print ===> $data70 +if $data70 != -5000.00000 then + return -1 +endi +sql select ceil(c2) from $tb +print ===> $data80 +if $data80 != 5001.00000 then + return -1 +endi +sql select ceil(c2) from $tb +print ===> $data90 +if $data90 != -5000.00000 then + return -1 +endi + +sql select ceil(c5) from $tb +print ===> $data10 +if $data10 != 0 then + return -1 +endi +sql select ceil(c2), ceil(c6) from $tb +sql select ceil(c2) from $mt +sql_error select ceil(c7) from $tb +sql_error select ceil(c8) from $tb +sql_error select ceil(c9) from $tb +sql_error select ceil(ts) from $tb +sql_error select ceil(c2+2) from $tb +sql_error select ceil(c2) from $tb where ts > 0 and ts < now + 100m interval(10m) +sql_error select ceil(ceil(c2)) from $tb +sql_error select ceil(c2) from m_di_tb1 where c2 like '2%' + +print =============== step3 +sql select ceil(c2) from $tb where c2 <= 5001.00000 +print ===> $data00 +if $data00 != 5000.00000 then + return -1 +endi +sql select ceil(c2) from $tb where c2 <= 5001.00000 +print ===> $data10 +if $data10 != -5000.00000 then + return -1 +endi +sql select ceil(c2) from $tb where c2 <= 5001.00000 +print ===> $data20 +if $data20 != 5001.00000 then + return -1 +endi +sql select ceil(c2) from $tb where c2 <= 5001.00000 +print ===> $data70 +if $data70 != -5000.00000 then + return -1 +endi +sql select ceil(c2) from $tb where c2 <= 5001.00000 +print ===> $data80 +if $data80 != 5001.00000 then + return -1 +endi +sql select ceil(c2) from $tb where c2 <= 5001.00000 +print ===> $data90 +if $data90 != -5000.00000 then + return -1 +endi + +print =============== step4 +sql select ceil(c2) from $tb where c2 >= -5001.00000 +print ===> $data00 +if $data00 != 5000.00000 then + return -1 +endi +sql select ceil(c2) from $tb where c2 >= -5001.00000 +print ===> $data10 +if $data10 != -5000.00000 then + return -1 +endi +sql select ceil(c2) from $tb where c2 >= -5001.00000 +print ===> $data20 +if $data20 != 5001.00000 then + return -1 +endi +sql select ceil(c2) from $tb where c2 >= -5001.00000 +print ===> $data70 +if $data70 != -5000.00000 then + return -1 +endi +sql select ceil(c2) from $tb where c2 >= -5001.00000 +print ===> $data80 +if $data80 != 5001.00000 then + return -1 +endi +sql select ceil(c2) from $tb where c2 >= -5001.00000 +print ===> $data90 +if $data90 != -5000.00000 then + return -1 +endi + +print =============== step5 +sql select ceil(c1) as b from $tb interval(1m) -x step5 + return -1 +step5: + +print =============== step6 +sql select ceil(c1) as b from $tb where ts < now + 4m interval(1m) -x step6 + return -1 +step6: + +print =============== clear + +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/compute/floor.sim b/tests/script/general/compute/floor.sim new file mode 100644 index 0000000000..7fdd641139 --- /dev/null +++ b/tests/script/general/compute/floor.sim @@ -0,0 +1,252 @@ +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 2000 +sql connect + +$dbPrefix = m_di_db +$tbPrefix = m_di_tb +$mtPrefix = m_di_mt +$tbNum = 2 +$rowNum = 10000 + +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 + $y = 0 + + $v0 = 5000.0 + $v1 = -5000.1 + $v2 = 5000.2 + $v3 = -5000.3 + $v4 = 5000.4 + $v5 = -5000.5 + $v6 = 5000.6 + $v7 = -5000.7 + $v8 = 5000.8 + $v9 = -5000.9 + + while $x < $rowNum + $cc = $x * 60000 + $ms = 1601481600000 + $cc + + $val = $v0 + + if $y == 0 then + $val = $v0 + endi + + if $y == 1 then + $val = $v1 + endi + + if $y == 2 then + $val = $v2 + endi + + if $y == 3 then + $val = $v3 + endi + + if $y == 4 then + $val = $v4 + endi + + if $y == 5 then + $val = $v5 + endi + + if $y == 6 then + $val = $v6 + endi + + if $y == 7 then + $val = $v7 + endi + + if $y == 8 then + $val = $v8 + endi + + if $y == 9 then + $val = $v9 + endi + + $tinyint = $x / 128 + sql insert into $tb values ($ms , $x , $val , $x , $x , $tinyint , $x , $x , $x , $x ) + $x = $x + 1 + $y = $y + 1 + if $y == 10 then + $y = 0 + endi + endw + + $i = $i + 1 +endw + +sleep 100 + +print =============== step2 +$i = 1 +$tb = $tbPrefix . $i + +sql select floor(c2) from $tb +print ===> $data00 +if $data00 != 5000.00000 then + return -1 +endi +sql select floor(c2) from $tb +print ===> $data10 +if $data10 != -5001.00000 then + return -1 +endi +sql select floor(c2) from $tb +print ===> $data20 +if $data20 != 5000.00000 then + return -1 +endi +sql select floor(c2) from $tb +print ===> $data30 +if $data30 != -5001.00000 then + return -1 +endi +sql select floor(c2) from $tb +print ===> $data40 +if $data40 != 5000.00000 then + return -1 +endi +sql select floor(c2) from $tb +print ===> $data50 +if $data50 != -5001.00000 then + return -1 +endi +sql select floor(c2) from $tb +print ===> $data60 +if $data60 != 5000.00000 then + return -1 +endi +sql select floor(c2) from $tb +print ===> $data70 +if $data70 != -5001.00000 then + return -1 +endi +sql select floor(c2) from $tb +print ===> $data80 +if $data80 != 5000.00000 then + return -1 +endi +sql select floor(c2) from $tb +print ===> $data90 +if $data90 != -5001.00000 then + return -1 +endi + +sql select floor(c5) from $tb +print ===> $data10 +if $data10 != 0 then + return -1 +endi +sql select floor(c2), floor(c6) from $tb +sql select floor(c2) from $mt +sql_error select floor(c7) from $tb +sql_error select floor(c8) from $tb +sql_error select floor(c9) from $tb +sql_error select floor(ts) from $tb +sql_error select floor(c2+2) from $tb +sql_error select floor(c2) from $tb where ts > 0 and ts < now + 100m interval(10m) +sql_error select floor(floor(c2)) from $tb +sql_error select floor(c2) from m_di_tb1 where c2 like '2%' + +print =============== step3 +sql select floor(c2) from $tb where c2 <= 5001.00000 +print ===> $data00 +if $data00 != 5000.00000 then + return -1 +endi +sql select floor(c2) from $tb where c2 <= 5001.00000 +print ===> $data10 +if $data10 != -5001.00000 then + return -1 +endi +sql select floor(c2) from $tb where c2 <= 5001.00000 +print ===> $data20 +if $data20 != 5000.00000 then + return -1 +endi +sql select floor(c2) from $tb where c2 <= 5001.00000 +print ===> $data70 +if $data70 != -5001.00000 then + return -1 +endi +sql select floor(c2) from $tb where c2 <= 5001.00000 +print ===> $data80 +if $data80 != 5000.00000 then + return -1 +endi +sql select floor(c2) from $tb where c2 <= 5001.00000 +print ===> $data90 +if $data90 != -5001.00000 then + return -1 +endi + +print =============== step4 +sql select floor(c2) from $tb where c2 >= -5001.00000 +print ===> $data00 +if $data00 != 5000.00000 then + return -1 +endi +sql select floor(c2) from $tb where c2 >= -5001.00000 +print ===> $data10 +if $data10 != -5001.00000 then + return -1 +endi +sql select floor(c2) from $tb where c2 >= -5001.00000 +print ===> $data20 +if $data20 != 5000.00000 then + return -1 +endi +sql select floor(c2) from $tb where c2 >= -5001.00000 +print ===> $data70 +if $data70 != -5001.00000 then + return -1 +endi +sql select floor(c2) from $tb where c2 >= -5001.00000 +print ===> $data80 +if $data80 != 5000.00000 then + return -1 +endi +sql select floor(c2) from $tb where c2 >= -5001.00000 +print ===> $data90 +if $data90 != -5001.00000 then + return -1 +endi + +print =============== step5 +sql select floor(c1) as b from $tb interval(1m) -x step5 + return -1 +step5: + +print =============== step6 +sql select floor(c1) as b from $tb where ts < now + 4m interval(1m) -x step6 + return -1 +step6: + +print =============== clear + +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/compute/round.sim b/tests/script/general/compute/round.sim new file mode 100644 index 0000000000..d01e346bd9 --- /dev/null +++ b/tests/script/general/compute/round.sim @@ -0,0 +1,252 @@ +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 2000 +sql connect + +$dbPrefix = m_di_db +$tbPrefix = m_di_tb +$mtPrefix = m_di_mt +$tbNum = 2 +$rowNum = 10000 + +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 + $y = 0 + + $v0 = 5000.0 + $v1 = -5000.1 + $v2 = 5000.2 + $v3 = -5000.3 + $v4 = 5000.4 + $v5 = -5000.5 + $v6 = 5000.6 + $v7 = -5000.7 + $v8 = 5000.8 + $v9 = -5000.9 + + while $x < $rowNum + $cc = $x * 60000 + $ms = 1601481600000 + $cc + + $val = $v0 + + if $y == 0 then + $val = $v0 + endi + + if $y == 1 then + $val = $v1 + endi + + if $y == 2 then + $val = $v2 + endi + + if $y == 3 then + $val = $v3 + endi + + if $y == 4 then + $val = $v4 + endi + + if $y == 5 then + $val = $v5 + endi + + if $y == 6 then + $val = $v6 + endi + + if $y == 7 then + $val = $v7 + endi + + if $y == 8 then + $val = $v8 + endi + + if $y == 9 then + $val = $v9 + endi + + $tinyint = $x / 128 + sql insert into $tb values ($ms , $x , $val , $x , $x , $tinyint , $x , $x , $x , $x ) + $x = $x + 1 + $y = $y + 1 + if $y == 10 then + $y = 0 + endi + endw + + $i = $i + 1 +endw + +sleep 100 + +print =============== step2 +$i = 1 +$tb = $tbPrefix . $i + +sql select round(c2) from $tb +print ===> $data00 +if $data00 != 5000.00000 then + return -1 +endi +sql select round(c2) from $tb +print ===> $data10 +if $data10 != -5000.00000 then + return -1 +endi +sql select round(c2) from $tb +print ===> $data20 +if $data20 != 5000.00000 then + return -1 +endi +sql select round(c2) from $tb +print ===> $data30 +if $data30 != -5000.00000 then + return -1 +endi +sql select round(c2) from $tb +print ===> $data40 +if $data40 != 5000.00000 then + return -1 +endi +sql select round(c2) from $tb +print ===> $data50 +if $data50 != -5001.00000 then + return -1 +endi +sql select round(c2) from $tb +print ===> $data60 +if $data60 != 5001.00000 then + return -1 +endi +sql select round(c2) from $tb +print ===> $data70 +if $data70 != -5001.00000 then + return -1 +endi +sql select round(c2) from $tb +print ===> $data80 +if $data80 != 5001.00000 then + return -1 +endi +sql select round(c2) from $tb +print ===> $data90 +if $data90 != -5001.00000 then + return -1 +endi + +sql select round(c5) from $tb +print ===> $data10 +if $data10 != 0 then + return -1 +endi +sql select round(c2), round(c6) from $tb +sql select round(c2) from $mt +sql_error select round(c7) from $tb +sql_error select round(c8) from $tb +sql_error select round(c9) from $tb +sql_error select round(ts) from $tb +sql_error select round(c2+2) from $tb +sql_error select round(c2) from $tb where ts > 0 and ts < now + 100m interval(10m) +sql_error select round(round(c2)) from $tb +sql_error select round(c2) from m_di_tb1 where c2 like '2%' + +print =============== step3 +sql select round(c2) from $tb where c2 <= 5001.00000 +print ===> $data00 +if $data00 != 5000.00000 then + return -1 +endi +sql select round(c2) from $tb where c2 <= 5001.00000 +print ===> $data10 +if $data10 != -5000.00000 then + return -1 +endi +sql select round(c2) from $tb where c2 <= 5001.00000 +print ===> $data20 +if $data20 != 5000.00000 then + return -1 +endi +sql select round(c2) from $tb where c2 <= 5001.00000 +print ===> $data70 +if $data70 != -5001.00000 then + return -1 +endi +sql select round(c2) from $tb where c2 <= 5001.00000 +print ===> $data80 +if $data80 != 5001.00000 then + return -1 +endi +sql select round(c2) from $tb where c2 <= 5001.00000 +print ===> $data90 +if $data90 != -5001.00000 then + return -1 +endi + +print =============== step4 +sql select round(c2) from $tb where c2 >= -5001.00000 +print ===> $data00 +if $data00 != 5000.00000 then + return -1 +endi +sql select round(c2) from $tb where c2 >= -5001.00000 +print ===> $data10 +if $data10 != -5000.00000 then + return -1 +endi +sql select round(c2) from $tb where c2 >= -5001.00000 +print ===> $data20 +if $data20 != 5000.00000 then + return -1 +endi +sql select round(c2) from $tb where c2 >= -5001.00000 +print ===> $data70 +if $data70 != -5001.00000 then + return -1 +endi +sql select round(c2) from $tb where c2 >= -5001.00000 +print ===> $data80 +if $data80 != 5001.00000 then + return -1 +endi +sql select round(c2) from $tb where c2 >= -5001.00000 +print ===> $data90 +if $data90 != -5001.00000 then + return -1 +endi + +print =============== step5 +sql select round(c1) as b from $tb interval(1m) -x step5 + return -1 +step5: + +print =============== step6 +sql select round(c1) as b from $tb where ts < now + 4m interval(1m) -x step6 + return -1 +step6: + +print =============== clear + +system sh/exec.sh -n dnode1 -s stop -x SIGINT -- GitLab