未验证 提交 77eb69a9 编写于 作者: G Ganlin Zhao 提交者: GitHub

Merge pull request #12033 from taosdata/feature/3.0_glzhao

feat(query): add spread function
......@@ -40,6 +40,7 @@ typedef enum EFunctionType {
FUNCTION_TYPE_STDDEV,
FUNCTION_TYPE_SUM,
FUNCTION_TYPE_TWA,
FUNCTION_TYPE_HISTOGRAM,
// nonstandard SQL function
FUNCTION_TYPE_BOTTOM = 500,
......
......@@ -68,6 +68,11 @@ bool getTopBotFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv);
int32_t topFunction(SqlFunctionCtx *pCtx);
int32_t topBotFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
bool getSpreadFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
bool spreadFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
int32_t spreadFunction(SqlFunctionCtx* pCtx);
int32_t spreadFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
#ifdef __cplusplus
}
#endif
......
此差异已折叠。
......@@ -80,6 +80,13 @@ typedef struct SDiffInfo {
} prev;
} SDiffInfo;
typedef struct SSpreadInfo {
double result;
bool hasResult;
double min;
double max;
} SSpreadInfo;
#define SET_VAL(_info, numOfElem, res) \
do { \
if ((numOfElem) <= 0) { \
......@@ -1639,3 +1646,101 @@ int32_t topBotFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
return pEntryInfo->numOfRes;
}
bool getSpreadFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) {
pEnv->calcMemSize = sizeof(SSpreadInfo);
return true;
}
bool spreadFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo) {
if (!functionSetup(pCtx, pResultInfo)) {
return false;
}
SSpreadInfo* pInfo = GET_ROWCELL_INTERBUF(pResultInfo);
SET_DOUBLE_VAL(&pInfo->min, DBL_MAX);
SET_DOUBLE_VAL(&pInfo->max, -DBL_MAX);
pInfo->hasResult = false;
return true;
}
int32_t spreadFunction(SqlFunctionCtx *pCtx) {
int32_t numOfElems = 0;
// Only the pre-computing information loaded and actual data does not loaded
SInputColumnInfoData* pInput = &pCtx->input;
SColumnDataAgg *pAgg = pInput->pColumnDataAgg[0];
int32_t type = pInput->pData[0]->info.type;
SSpreadInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
if (pInput->colDataAggIsSet) {
numOfElems = pInput->numOfRows - pAgg->numOfNull;
if (numOfElems == 0) {
goto _spread_over;
}
double tmin = 0.0, tmax = 0.0;
if (IS_SIGNED_NUMERIC_TYPE(type)) {
tmin = (double)GET_INT64_VAL(&pAgg->min);
tmax = (double)GET_INT64_VAL(&pAgg->max);
} else if (IS_FLOAT_TYPE(type)) {
tmin = GET_DOUBLE_VAL(&pAgg->min);
tmax = GET_DOUBLE_VAL(&pAgg->max);
} else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
tmin = (double)GET_UINT64_VAL(&pAgg->min);
tmax = (double)GET_UINT64_VAL(&pAgg->max);
}
if (GET_DOUBLE_VAL(&pInfo->min) > tmin) {
SET_DOUBLE_VAL(&pInfo->min, tmin);
}
if (GET_DOUBLE_VAL(&pInfo->max) < tmax) {
SET_DOUBLE_VAL(&pInfo->max, tmax);
}
} else { // computing based on the true data block
SColumnInfoData* pCol = pInput->pData[0];
int32_t start = pInput->startRowIndex;
int32_t numOfRows = pInput->numOfRows;
// check the valid data one by one
for (int32_t i = start; i < pInput->numOfRows + start; ++i) {
if (colDataIsNull_f(pCol->nullbitmap, i)) {
continue;
}
char *data = colDataGetData(pCol, i);
double v = 0;
GET_TYPED_DATA(v, double, type, data);
if (v < GET_DOUBLE_VAL(&pInfo->min)) {
SET_DOUBLE_VAL(&pInfo->min, v);
}
if (v > GET_DOUBLE_VAL(&pInfo->max)) {
SET_DOUBLE_VAL(&pInfo->max, v);
}
numOfElems += 1;
}
}
_spread_over:
// data in the check operation are all null, not output
SET_VAL(GET_RES_INFO(pCtx), numOfElems, 1);
if (numOfElems > 0) {
pInfo->hasResult = true;
}
return TSDB_CODE_SUCCESS;
}
int32_t spreadFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
SSpreadInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
if (pInfo->hasResult == true) {
SET_DOUBLE_VAL(&pInfo->result, pInfo->max - pInfo->min);
}
return functionFinalize(pCtx, pBlock);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册