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

feat(query): add spread function
This commit is contained in:
Ganlin Zhao 2022-04-29 09:55:14 +08:00 committed by GitHub
commit 77eb69a94f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 657 additions and 431 deletions

View File

@ -40,6 +40,7 @@ typedef enum EFunctionType {
FUNCTION_TYPE_STDDEV, FUNCTION_TYPE_STDDEV,
FUNCTION_TYPE_SUM, FUNCTION_TYPE_SUM,
FUNCTION_TYPE_TWA, FUNCTION_TYPE_TWA,
FUNCTION_TYPE_HISTOGRAM,
// nonstandard SQL function // nonstandard SQL function
FUNCTION_TYPE_BOTTOM = 500, FUNCTION_TYPE_BOTTOM = 500,

View File

@ -68,6 +68,11 @@ bool getTopBotFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv);
int32_t topFunction(SqlFunctionCtx *pCtx); int32_t topFunction(SqlFunctionCtx *pCtx);
int32_t topBotFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -212,7 +212,16 @@ static int32_t translateBottom(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
} }
static int32_t translateSpread(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { static int32_t translateSpread(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
// todo if (1 != LIST_LENGTH(pFunc->pParameterList)) {
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
}
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
if (!IS_NUMERIC_TYPE(paraType) && TSDB_DATA_TYPE_TIMESTAMP != paraType) {
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
}
pFunc->node.resType = (SDataType) { .bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes, .type = TSDB_DATA_TYPE_DOUBLE };
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
@ -431,7 +440,8 @@ static int32_t translateToJson(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
} }
const SBuiltinFuncDefinition funcMgtBuiltins[] = { const SBuiltinFuncDefinition funcMgtBuiltins[] = {
{.name = "count", {
.name = "count",
.type = FUNCTION_TYPE_COUNT, .type = FUNCTION_TYPE_COUNT,
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED, .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED,
.translateFunc = translateCount, .translateFunc = translateCount,
@ -439,8 +449,10 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.getEnvFunc = getCountFuncEnv, .getEnvFunc = getCountFuncEnv,
.initFunc = functionSetup, .initFunc = functionSetup,
.processFunc = countFunction, .processFunc = countFunction,
.finalizeFunc = functionFinalize}, .finalizeFunc = functionFinalize
{.name = "sum", },
{
.name = "sum",
.type = FUNCTION_TYPE_SUM, .type = FUNCTION_TYPE_SUM,
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED, .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED,
.translateFunc = translateSum, .translateFunc = translateSum,
@ -448,8 +460,10 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.getEnvFunc = getSumFuncEnv, .getEnvFunc = getSumFuncEnv,
.initFunc = functionSetup, .initFunc = functionSetup,
.processFunc = sumFunction, .processFunc = sumFunction,
.finalizeFunc = functionFinalize}, .finalizeFunc = functionFinalize
{.name = "min", },
{
.name = "min",
.type = FUNCTION_TYPE_MIN, .type = FUNCTION_TYPE_MIN,
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED, .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED,
.translateFunc = translateInOutNum, .translateFunc = translateInOutNum,
@ -457,8 +471,10 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.getEnvFunc = getMinmaxFuncEnv, .getEnvFunc = getMinmaxFuncEnv,
.initFunc = minFunctionSetup, .initFunc = minFunctionSetup,
.processFunc = minFunction, .processFunc = minFunction,
.finalizeFunc = functionFinalize}, .finalizeFunc = functionFinalize
{.name = "max", },
{
.name = "max",
.type = FUNCTION_TYPE_MAX, .type = FUNCTION_TYPE_MAX,
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED, .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED,
.translateFunc = translateInOutNum, .translateFunc = translateInOutNum,
@ -466,39 +482,48 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.getEnvFunc = getMinmaxFuncEnv, .getEnvFunc = getMinmaxFuncEnv,
.initFunc = maxFunctionSetup, .initFunc = maxFunctionSetup,
.processFunc = maxFunction, .processFunc = maxFunction,
.finalizeFunc = functionFinalize}, .finalizeFunc = functionFinalize
{.name = "stddev", },
{
.name = "stddev",
.type = FUNCTION_TYPE_STDDEV, .type = FUNCTION_TYPE_STDDEV,
.classification = FUNC_MGT_AGG_FUNC, .classification = FUNC_MGT_AGG_FUNC,
.translateFunc = translateInNumOutDou, .translateFunc = translateInNumOutDou,
.getEnvFunc = getStddevFuncEnv, .getEnvFunc = getStddevFuncEnv,
.initFunc = stddevFunctionSetup, .initFunc = stddevFunctionSetup,
.processFunc = stddevFunction, .processFunc = stddevFunction,
.finalizeFunc = stddevFinalize}, .finalizeFunc = stddevFinalize
{.name = "avg", },
{
.name = "avg",
.type = FUNCTION_TYPE_AVG, .type = FUNCTION_TYPE_AVG,
.classification = FUNC_MGT_AGG_FUNC, .classification = FUNC_MGT_AGG_FUNC,
.translateFunc = translateInNumOutDou, .translateFunc = translateInNumOutDou,
.getEnvFunc = getAvgFuncEnv, .getEnvFunc = getAvgFuncEnv,
.initFunc = avgFunctionSetup, .initFunc = avgFunctionSetup,
.processFunc = avgFunction, .processFunc = avgFunction,
.finalizeFunc = avgFinalize}, .finalizeFunc = avgFinalize
{.name = "percentile", },
{
.name = "percentile",
.type = FUNCTION_TYPE_PERCENTILE, .type = FUNCTION_TYPE_PERCENTILE,
.classification = FUNC_MGT_AGG_FUNC, .classification = FUNC_MGT_AGG_FUNC,
.translateFunc = translatePercentile, .translateFunc = translatePercentile,
.getEnvFunc = getPercentileFuncEnv, .getEnvFunc = getPercentileFuncEnv,
.initFunc = percentileFunctionSetup, .initFunc = percentileFunctionSetup,
.processFunc = percentileFunction, .processFunc = percentileFunction,
.finalizeFunc = percentileFinalize}, .finalizeFunc = percentileFinalize
{.name = "apercentile", },
{
.name = "apercentile",
.type = FUNCTION_TYPE_APERCENTILE, .type = FUNCTION_TYPE_APERCENTILE,
.classification = FUNC_MGT_AGG_FUNC, .classification = FUNC_MGT_AGG_FUNC,
.translateFunc = translateApercentile, .translateFunc = translateApercentile,
.getEnvFunc = getMinmaxFuncEnv, .getEnvFunc = getMinmaxFuncEnv,
.initFunc = maxFunctionSetup, .initFunc = maxFunctionSetup,
.processFunc = maxFunction, .processFunc = maxFunction,
.finalizeFunc = functionFinalize}, .finalizeFunc = functionFinalize
},
{ {
.name = "top", .name = "top",
.type = FUNCTION_TYPE_TOP, .type = FUNCTION_TYPE_TOP,
@ -509,357 +534,447 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.processFunc = topFunction, .processFunc = topFunction,
.finalizeFunc = topBotFinalize, .finalizeFunc = topBotFinalize,
}, },
{.name = "bottom", {
.name = "bottom",
.type = FUNCTION_TYPE_BOTTOM, .type = FUNCTION_TYPE_BOTTOM,
.classification = FUNC_MGT_AGG_FUNC, .classification = FUNC_MGT_AGG_FUNC,
.translateFunc = translateBottom, .translateFunc = translateBottom,
.getEnvFunc = getMinmaxFuncEnv, .getEnvFunc = getMinmaxFuncEnv,
.initFunc = maxFunctionSetup, .initFunc = maxFunctionSetup,
.processFunc = maxFunction, .processFunc = maxFunction,
.finalizeFunc = functionFinalize}, .finalizeFunc = functionFinalize
{.name = "spread", },
{
.name = "spread",
.type = FUNCTION_TYPE_SPREAD, .type = FUNCTION_TYPE_SPREAD,
.classification = FUNC_MGT_AGG_FUNC, .classification = FUNC_MGT_AGG_FUNC,
.translateFunc = translateSpread, .translateFunc = translateSpread,
.getEnvFunc = getMinmaxFuncEnv, .dataRequiredFunc = statisDataRequired,
.initFunc = maxFunctionSetup, .getEnvFunc = getSpreadFuncEnv,
.processFunc = maxFunction, .initFunc = spreadFunctionSetup,
.finalizeFunc = functionFinalize}, .processFunc = spreadFunction,
{.name = "last_row", .finalizeFunc = spreadFinalize
},
{
.name = "last_row",
.type = FUNCTION_TYPE_LAST_ROW, .type = FUNCTION_TYPE_LAST_ROW,
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_MULTI_RES_FUNC, .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_MULTI_RES_FUNC,
.translateFunc = translateLastRow, .translateFunc = translateLastRow,
.getEnvFunc = getMinmaxFuncEnv, .getEnvFunc = getMinmaxFuncEnv,
.initFunc = maxFunctionSetup, .initFunc = maxFunctionSetup,
.processFunc = maxFunction, .processFunc = maxFunction,
.finalizeFunc = functionFinalize}, .finalizeFunc = functionFinalize
{.name = "first", },
{
.name = "first",
.type = FUNCTION_TYPE_FIRST, .type = FUNCTION_TYPE_FIRST,
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_MULTI_RES_FUNC, .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_MULTI_RES_FUNC,
.translateFunc = translateFirstLast, .translateFunc = translateFirstLast,
.getEnvFunc = getFirstLastFuncEnv, .getEnvFunc = getFirstLastFuncEnv,
.initFunc = functionSetup, .initFunc = functionSetup,
.processFunc = firstFunction, .processFunc = firstFunction,
.finalizeFunc = functionFinalize}, .finalizeFunc = functionFinalize
{.name = "last", },
{
.name = "last",
.type = FUNCTION_TYPE_LAST, .type = FUNCTION_TYPE_LAST,
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_MULTI_RES_FUNC, .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_MULTI_RES_FUNC,
.translateFunc = translateFirstLast, .translateFunc = translateFirstLast,
.getEnvFunc = getFirstLastFuncEnv, .getEnvFunc = getFirstLastFuncEnv,
.initFunc = functionSetup, .initFunc = functionSetup,
.processFunc = lastFunction, .processFunc = lastFunction,
.finalizeFunc = functionFinalize}, .finalizeFunc = functionFinalize
{.name = "diff", },
{
.name = "diff",
.type = FUNCTION_TYPE_DIFF, .type = FUNCTION_TYPE_DIFF,
.classification = FUNC_MGT_NONSTANDARD_SQL_FUNC, .classification = FUNC_MGT_NONSTANDARD_SQL_FUNC,
.translateFunc = translateInOutNum, .translateFunc = translateInOutNum,
.getEnvFunc = getDiffFuncEnv, .getEnvFunc = getDiffFuncEnv,
.initFunc = diffFunctionSetup, .initFunc = diffFunctionSetup,
.processFunc = diffFunction, .processFunc = diffFunction,
.finalizeFunc = functionFinalize}, .finalizeFunc = functionFinalize
{.name = "abs", },
{
.name = "abs",
.type = FUNCTION_TYPE_ABS, .type = FUNCTION_TYPE_ABS,
.classification = FUNC_MGT_SCALAR_FUNC, .classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateInOutNum, .translateFunc = translateInOutNum,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = absFunction, .sprocessFunc = absFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "log", },
{
.name = "log",
.type = FUNCTION_TYPE_LOG, .type = FUNCTION_TYPE_LOG,
.classification = FUNC_MGT_SCALAR_FUNC, .classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateIn2NumOutDou, .translateFunc = translateIn2NumOutDou,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = logFunction, .sprocessFunc = logFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "pow", },
{
.name = "pow",
.type = FUNCTION_TYPE_POW, .type = FUNCTION_TYPE_POW,
.classification = FUNC_MGT_SCALAR_FUNC, .classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateIn2NumOutDou, .translateFunc = translateIn2NumOutDou,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = powFunction, .sprocessFunc = powFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "sqrt", },
{
.name = "sqrt",
.type = FUNCTION_TYPE_SQRT, .type = FUNCTION_TYPE_SQRT,
.classification = FUNC_MGT_SCALAR_FUNC, .classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateInNumOutDou, .translateFunc = translateInNumOutDou,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = sqrtFunction, .sprocessFunc = sqrtFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "ceil", },
{
.name = "ceil",
.type = FUNCTION_TYPE_CEIL, .type = FUNCTION_TYPE_CEIL,
.classification = FUNC_MGT_SCALAR_FUNC, .classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateInOutNum, .translateFunc = translateInOutNum,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = ceilFunction, .sprocessFunc = ceilFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "floor", },
{
.name = "floor",
.type = FUNCTION_TYPE_FLOOR, .type = FUNCTION_TYPE_FLOOR,
.classification = FUNC_MGT_SCALAR_FUNC, .classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateInOutNum, .translateFunc = translateInOutNum,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = floorFunction, .sprocessFunc = floorFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "round", },
{
.name = "round",
.type = FUNCTION_TYPE_ROUND, .type = FUNCTION_TYPE_ROUND,
.classification = FUNC_MGT_SCALAR_FUNC, .classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateInOutNum, .translateFunc = translateInOutNum,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = roundFunction, .sprocessFunc = roundFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "sin", },
{
.name = "sin",
.type = FUNCTION_TYPE_SIN, .type = FUNCTION_TYPE_SIN,
.classification = FUNC_MGT_SCALAR_FUNC, .classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateInNumOutDou, .translateFunc = translateInNumOutDou,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = sinFunction, .sprocessFunc = sinFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "cos", },
{
.name = "cos",
.type = FUNCTION_TYPE_COS, .type = FUNCTION_TYPE_COS,
.classification = FUNC_MGT_SCALAR_FUNC, .classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateInNumOutDou, .translateFunc = translateInNumOutDou,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = cosFunction, .sprocessFunc = cosFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "tan", },
{
.name = "tan",
.type = FUNCTION_TYPE_TAN, .type = FUNCTION_TYPE_TAN,
.classification = FUNC_MGT_SCALAR_FUNC, .classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateInNumOutDou, .translateFunc = translateInNumOutDou,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = tanFunction, .sprocessFunc = tanFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "asin", },
{
.name = "asin",
.type = FUNCTION_TYPE_ASIN, .type = FUNCTION_TYPE_ASIN,
.classification = FUNC_MGT_SCALAR_FUNC, .classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateInNumOutDou, .translateFunc = translateInNumOutDou,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = asinFunction, .sprocessFunc = asinFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "acos", },
{
.name = "acos",
.type = FUNCTION_TYPE_ACOS, .type = FUNCTION_TYPE_ACOS,
.classification = FUNC_MGT_SCALAR_FUNC, .classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateInNumOutDou, .translateFunc = translateInNumOutDou,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = acosFunction, .sprocessFunc = acosFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "atan", },
{
.name = "atan",
.type = FUNCTION_TYPE_ATAN, .type = FUNCTION_TYPE_ATAN,
.classification = FUNC_MGT_SCALAR_FUNC, .classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateInNumOutDou, .translateFunc = translateInNumOutDou,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = atanFunction, .sprocessFunc = atanFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "length", },
{
.name = "length",
.type = FUNCTION_TYPE_LENGTH, .type = FUNCTION_TYPE_LENGTH,
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC, .classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC,
.translateFunc = translateLength, .translateFunc = translateLength,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = lengthFunction, .sprocessFunc = lengthFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "char_length", },
{
.name = "char_length",
.type = FUNCTION_TYPE_CHAR_LENGTH, .type = FUNCTION_TYPE_CHAR_LENGTH,
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC, .classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC,
.translateFunc = translateLength, .translateFunc = translateLength,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = charLengthFunction, .sprocessFunc = charLengthFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "concat", },
{
.name = "concat",
.type = FUNCTION_TYPE_CONCAT, .type = FUNCTION_TYPE_CONCAT,
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC, .classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC,
.translateFunc = translateConcat, .translateFunc = translateConcat,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = concatFunction, .sprocessFunc = concatFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "concat_ws", },
{
.name = "concat_ws",
.type = FUNCTION_TYPE_CONCAT_WS, .type = FUNCTION_TYPE_CONCAT_WS,
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC, .classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC,
.translateFunc = translateConcatWs, .translateFunc = translateConcatWs,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = concatWsFunction, .sprocessFunc = concatWsFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "lower", },
{
.name = "lower",
.type = FUNCTION_TYPE_LOWER, .type = FUNCTION_TYPE_LOWER,
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC, .classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC,
.translateFunc = translateInOutStr, .translateFunc = translateInOutStr,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = lowerFunction, .sprocessFunc = lowerFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "upper", },
{
.name = "upper",
.type = FUNCTION_TYPE_UPPER, .type = FUNCTION_TYPE_UPPER,
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC, .classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC,
.translateFunc = translateInOutStr, .translateFunc = translateInOutStr,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = upperFunction, .sprocessFunc = upperFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "ltrim", },
{
.name = "ltrim",
.type = FUNCTION_TYPE_LTRIM, .type = FUNCTION_TYPE_LTRIM,
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC, .classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC,
.translateFunc = translateInOutStr, .translateFunc = translateInOutStr,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = ltrimFunction, .sprocessFunc = ltrimFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "rtrim", },
{
.name = "rtrim",
.type = FUNCTION_TYPE_RTRIM, .type = FUNCTION_TYPE_RTRIM,
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC, .classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC,
.translateFunc = translateInOutStr, .translateFunc = translateInOutStr,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = rtrimFunction, .sprocessFunc = rtrimFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "substr", },
{
.name = "substr",
.type = FUNCTION_TYPE_SUBSTR, .type = FUNCTION_TYPE_SUBSTR,
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC, .classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_STRING_FUNC,
.translateFunc = translateSubstr, .translateFunc = translateSubstr,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = substrFunction, .sprocessFunc = substrFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "cast", },
{
.name = "cast",
.type = FUNCTION_TYPE_CAST, .type = FUNCTION_TYPE_CAST,
.classification = FUNC_MGT_SCALAR_FUNC, .classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateCast, .translateFunc = translateCast,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = castFunction, .sprocessFunc = castFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "to_iso8601", },
{
.name = "to_iso8601",
.type = FUNCTION_TYPE_TO_ISO8601, .type = FUNCTION_TYPE_TO_ISO8601,
.classification = FUNC_MGT_SCALAR_FUNC, .classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateToIso8601, .translateFunc = translateToIso8601,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = toISO8601Function, .sprocessFunc = toISO8601Function,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "to_unixtimestamp", },
{
.name = "to_unixtimestamp",
.type = FUNCTION_TYPE_TO_UNIXTIMESTAMP, .type = FUNCTION_TYPE_TO_UNIXTIMESTAMP,
.classification = FUNC_MGT_SCALAR_FUNC, .classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateToUnixtimestamp, .translateFunc = translateToUnixtimestamp,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = toUnixtimestampFunction, .sprocessFunc = toUnixtimestampFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "timetruncate", },
{
.name = "timetruncate",
.type = FUNCTION_TYPE_TIMETRUNCATE, .type = FUNCTION_TYPE_TIMETRUNCATE,
.classification = FUNC_MGT_SCALAR_FUNC, .classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateTimeTruncate, .translateFunc = translateTimeTruncate,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = timeTruncateFunction, .sprocessFunc = timeTruncateFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "timediff", },
{
.name = "timediff",
.type = FUNCTION_TYPE_TIMEDIFF, .type = FUNCTION_TYPE_TIMEDIFF,
.classification = FUNC_MGT_SCALAR_FUNC, .classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateTimeDiff, .translateFunc = translateTimeDiff,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = timeDiffFunction, .sprocessFunc = timeDiffFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "now", },
{
.name = "now",
.type = FUNCTION_TYPE_NOW, .type = FUNCTION_TYPE_NOW,
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_DATETIME_FUNC, .classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_DATETIME_FUNC,
.translateFunc = translateTimePseudoColumn, .translateFunc = translateTimePseudoColumn,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = nowFunction, .sprocessFunc = nowFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "today", },
{
.name = "today",
.type = FUNCTION_TYPE_TODAY, .type = FUNCTION_TYPE_TODAY,
.classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_DATETIME_FUNC, .classification = FUNC_MGT_SCALAR_FUNC | FUNC_MGT_DATETIME_FUNC,
.translateFunc = translateTimePseudoColumn, .translateFunc = translateTimePseudoColumn,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = todayFunction, .sprocessFunc = todayFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "timezone", },
{
.name = "timezone",
.type = FUNCTION_TYPE_TIMEZONE, .type = FUNCTION_TYPE_TIMEZONE,
.classification = FUNC_MGT_SCALAR_FUNC, .classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateTimezone, .translateFunc = translateTimezone,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = timezoneFunction, .sprocessFunc = timezoneFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "_rowts", },
{
.name = "_rowts",
.type = FUNCTION_TYPE_ROWTS, .type = FUNCTION_TYPE_ROWTS,
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC, .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC,
.translateFunc = translateTimePseudoColumn, .translateFunc = translateTimePseudoColumn,
.getEnvFunc = getTimePseudoFuncEnv, .getEnvFunc = getTimePseudoFuncEnv,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = NULL, .sprocessFunc = NULL,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "tbname", },
{
.name = "tbname",
.type = FUNCTION_TYPE_TBNAME, .type = FUNCTION_TYPE_TBNAME,
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_SCAN_PC_FUNC, .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC,
.translateFunc = translateTbnameColumn, .translateFunc = translateTbnameColumn,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = NULL, .sprocessFunc = NULL,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "_qstartts", },
{
.name = "_qstartts",
.type = FUNCTION_TYPE_QSTARTTS, .type = FUNCTION_TYPE_QSTARTTS,
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_WINDOW_PC_FUNC, .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_WINDOW_PC_FUNC,
.translateFunc = translateTimePseudoColumn, .translateFunc = translateTimePseudoColumn,
.getEnvFunc = getTimePseudoFuncEnv, .getEnvFunc = getTimePseudoFuncEnv,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = qStartTsFunction, .sprocessFunc = qStartTsFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "_qendts", },
{
.name = "_qendts",
.type = FUNCTION_TYPE_QENDTS, .type = FUNCTION_TYPE_QENDTS,
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_WINDOW_PC_FUNC, .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_WINDOW_PC_FUNC,
.translateFunc = translateTimePseudoColumn, .translateFunc = translateTimePseudoColumn,
.getEnvFunc = getTimePseudoFuncEnv, .getEnvFunc = getTimePseudoFuncEnv,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = qEndTsFunction, .sprocessFunc = qEndTsFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "_wstartts", },
{
.name = "_wstartts",
.type = FUNCTION_TYPE_WSTARTTS, .type = FUNCTION_TYPE_WSTARTTS,
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_WINDOW_PC_FUNC, .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_WINDOW_PC_FUNC,
.translateFunc = translateTimePseudoColumn, .translateFunc = translateTimePseudoColumn,
.getEnvFunc = getTimePseudoFuncEnv, .getEnvFunc = getTimePseudoFuncEnv,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = winStartTsFunction, .sprocessFunc = winStartTsFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "_wendts", },
{
.name = "_wendts",
.type = FUNCTION_TYPE_WENDTS, .type = FUNCTION_TYPE_WENDTS,
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_WINDOW_PC_FUNC, .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_WINDOW_PC_FUNC,
.translateFunc = translateTimePseudoColumn, .translateFunc = translateTimePseudoColumn,
.getEnvFunc = getTimePseudoFuncEnv, .getEnvFunc = getTimePseudoFuncEnv,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = winEndTsFunction, .sprocessFunc = winEndTsFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "_wduration", },
{
.name = "_wduration",
.type = FUNCTION_TYPE_WDURATION, .type = FUNCTION_TYPE_WDURATION,
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_WINDOW_PC_FUNC, .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_WINDOW_PC_FUNC,
.translateFunc = translateWduration, .translateFunc = translateWduration,
.getEnvFunc = getTimePseudoFuncEnv, .getEnvFunc = getTimePseudoFuncEnv,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = winDurFunction, .sprocessFunc = winDurFunction,
.finalizeFunc = NULL}, .finalizeFunc = NULL
{.name = "to_json", },
{
.name = "to_json",
.type = FUNCTION_TYPE_TO_JSON, .type = FUNCTION_TYPE_TO_JSON,
.classification = FUNC_MGT_SCALAR_FUNC, .classification = FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateToJson, .translateFunc = translateToJson,
.getEnvFunc = NULL, .getEnvFunc = NULL,
.initFunc = NULL, .initFunc = NULL,
.sprocessFunc = toJsonFunction, .sprocessFunc = toJsonFunction,
.finalizeFunc = NULL}}; .finalizeFunc = NULL
}
};
const int32_t funcMgtBuiltinsNum = (sizeof(funcMgtBuiltins) / sizeof(SBuiltinFuncDefinition)); const int32_t funcMgtBuiltinsNum = (sizeof(funcMgtBuiltins) / sizeof(SBuiltinFuncDefinition));

View File

@ -80,6 +80,13 @@ typedef struct SDiffInfo {
} prev; } prev;
} SDiffInfo; } SDiffInfo;
typedef struct SSpreadInfo {
double result;
bool hasResult;
double min;
double max;
} SSpreadInfo;
#define SET_VAL(_info, numOfElem, res) \ #define SET_VAL(_info, numOfElem, res) \
do { \ do { \
if ((numOfElem) <= 0) { \ if ((numOfElem) <= 0) { \
@ -1639,3 +1646,101 @@ int32_t topBotFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
return pEntryInfo->numOfRes; 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);
}