diff --git a/include/libs/scalar/scalar.h b/include/libs/scalar/scalar.h index d5e9a2e625380bf58cfbdd54db41d5c826dd168b..e0beaff2622d96c3081df787c326f3020d682c46 100644 --- a/include/libs/scalar/scalar.h +++ b/include/libs/scalar/scalar.h @@ -104,6 +104,9 @@ int32_t maxScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam * int32_t avgScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t stddevScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t leastSQRScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); +int32_t percentileScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); +int32_t apercentileScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); +int32_t spreadScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); #ifdef __cplusplus } diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index 3abf3ffe8e7387d552a54592ba4ab8e508f66bda..c458e2caec5c547f3c59367942e052e972af991e 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -2034,6 +2034,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .getEnvFunc = getPercentileFuncEnv, .initFunc = percentileFunctionSetup, .processFunc = percentileFunction, + .sprocessFunc = percentileScalarFunction, .finalizeFunc = percentileFinalize, .invertFunc = NULL, .combineFunc = NULL, @@ -2046,6 +2047,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .getEnvFunc = getApercentileFuncEnv, .initFunc = apercentileFunctionSetup, .processFunc = apercentileFunction, + .sprocessFunc = apercentileScalarFunction, .finalizeFunc = apercentileFinalize, .invertFunc = NULL, .combineFunc = apercentileCombine, @@ -2113,6 +2115,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .getEnvFunc = getSpreadFuncEnv, .initFunc = spreadFunctionSetup, .processFunc = spreadFunction, + .sprocessFunc = spreadScalarFunction, .finalizeFunc = spreadFinalize, .invertFunc = NULL, .combineFunc = spreadCombine, diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 316462346591522b9cb4ae15a1ecc5cf0b4d25bd..896038092555d5f1f0563580f4298b9eee9e919e 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -1167,7 +1167,11 @@ static int32_t translateRepeatScanFunc(STranslateContext* pCxt, SFunctionNode* p if (!fmIsRepeatScanFunc(pFunc->funcId)) { return TSDB_CODE_SUCCESS; } - if (isSelectStmt(pCxt->pCurrStmt) && NULL != ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable) { + if (isSelectStmt(pCxt->pCurrStmt)) { + //select percentile() without from clause is also valid + if (NULL == ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable) { + return TSDB_CODE_SUCCESS; + } SNode* pTable = ((SSelectStmt*)pCxt->pCurrStmt)->pFromTable; if (QUERY_NODE_REAL_TABLE == nodeType(pTable) && (TSDB_CHILD_TABLE == ((SRealTableNode*)pTable)->pMeta->tableType || diff --git a/source/libs/scalar/src/scalar.c b/source/libs/scalar/src/scalar.c index bbb7e07bad90fea33175e338278328b5f9a8046f..484d95cb5a5532369d9380de1324bce15a5e0fb3 100644 --- a/source/libs/scalar/src/scalar.c +++ b/source/libs/scalar/src/scalar.c @@ -700,7 +700,7 @@ EDealRes sclRewriteNonConstOperator(SNode** pNode, SScalarCtx *ctx) { EDealRes sclRewriteFunction(SNode** pNode, SScalarCtx *ctx) { SFunctionNode *node = (SFunctionNode *)*pNode; SNode* tnode = NULL; - if (!fmIsScalarFunc(node->funcId)) { + if (!fmIsScalarFunc(node->funcId) && (!ctx->dual)) { return DEAL_RES_CONTINUE; } diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c index ba35356a9c8e6cf115ad1df1684caace1741c8dd..9a8f570a52129033f3faa7f0ba09ad86fd8c1db2 100644 --- a/source/libs/scalar/src/sclfunc.c +++ b/source/libs/scalar/src/sclfunc.c @@ -2307,3 +2307,76 @@ int32_t leastSQRScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarPa pOutput->numOfRows = 1; return TSDB_CODE_SUCCESS; } + +int32_t percentileScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + SColumnInfoData *pInputData = pInput->columnData; + SColumnInfoData *pOutputData = pOutput->columnData; + + int32_t type = GET_PARAM_TYPE(pInput); + + double val; + bool hasNull = false; + for (int32_t i = 0; i < pInput->numOfRows; ++i) { + if (colDataIsNull_s(pInputData, i)) { + hasNull = true; + break; + } + char *in = pInputData->pData; + GET_TYPED_DATA(val, double, type, in); + } + + if (hasNull) { + colDataAppendNULL(pOutputData, 0); + } else { + colDataAppend(pOutputData, 0, (char *)&val, false); + } + + pOutput->numOfRows = 1; + return TSDB_CODE_SUCCESS; +} + +int32_t apercentileScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + return percentileScalarFunction(pInput, inputNum, pOutput); +} + +int32_t spreadScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + SColumnInfoData *pInputData = pInput->columnData; + SColumnInfoData *pOutputData = pOutput->columnData; + + int32_t type = GET_PARAM_TYPE(pInput); + + double min, max; + SET_DOUBLE_VAL(&min, DBL_MAX); + SET_DOUBLE_VAL(&max, -DBL_MAX); + + bool hasNull = false; + for (int32_t i = 0; i < pInput->numOfRows; ++i) { + if (colDataIsNull_s(pInputData, i)) { + hasNull = true; + break; + } + + char *in = pInputData->pData; + + double val = 0; + GET_TYPED_DATA(val, double, type, in); + + if (val < GET_DOUBLE_VAL(&min)) { + SET_DOUBLE_VAL(&min, val); + } + + if (val > GET_DOUBLE_VAL(&max)) { + SET_DOUBLE_VAL(&max, val); + } + } + + if (hasNull) { + colDataAppendNULL(pOutputData, 0); + } else { + double result = max - min; + colDataAppend(pOutputData, 0, (char *)&result, false); + } + + pOutput->numOfRows = 1; + return TSDB_CODE_SUCCESS; +}