support other tsma funcs
This commit is contained in:
parent
cc9550f45e
commit
fa85d1caa7
|
@ -170,6 +170,12 @@ typedef enum EFunctionType {
|
||||||
FUNCTION_TYPE_FIRST_STATE_MERGE,
|
FUNCTION_TYPE_FIRST_STATE_MERGE,
|
||||||
FUNCTION_TYPE_LAST_STATE,
|
FUNCTION_TYPE_LAST_STATE,
|
||||||
FUNCTION_TYPE_LAST_STATE_MERGE,
|
FUNCTION_TYPE_LAST_STATE_MERGE,
|
||||||
|
FUNCTION_TYPE_SPREAD_STATE,
|
||||||
|
FUNCTION_TYPE_SPREAD_STATE_MERGE,
|
||||||
|
FUNCTION_TYPE_STDDEV_STATE,
|
||||||
|
FUNCTION_TYPE_STDDEV_STATE_MERGE,
|
||||||
|
FUNCTION_TYPE_HYPERLOGLOG_STATE,
|
||||||
|
FUNCTION_TYPE_HYPERLOGLOG_STATE_MERGE,
|
||||||
|
|
||||||
// geometry functions
|
// geometry functions
|
||||||
FUNCTION_TYPE_GEOM_FROM_TEXT = 4250,
|
FUNCTION_TYPE_GEOM_FROM_TEXT = 4250,
|
||||||
|
@ -282,6 +288,7 @@ int32_t fmCreateStateFuncs(SNodeList* pFuncs);
|
||||||
int32_t fmCreateStateMergeFuncs(SNodeList* pFuncs);
|
int32_t fmCreateStateMergeFuncs(SNodeList* pFuncs);
|
||||||
int32_t fmGetFuncId(const char* name);
|
int32_t fmGetFuncId(const char* name);
|
||||||
bool fmIsMyStateFunc(int32_t funcId, int32_t stateFuncId);
|
bool fmIsMyStateFunc(int32_t funcId, int32_t stateFuncId);
|
||||||
|
bool fmIsCountLikeFunc(int32_t funcId);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -583,6 +583,7 @@ typedef struct SAggPhysiNode {
|
||||||
SNodeList* pAggFuncs;
|
SNodeList* pAggFuncs;
|
||||||
bool mergeDataBlock;
|
bool mergeDataBlock;
|
||||||
bool groupKeyOptimized;
|
bool groupKeyOptimized;
|
||||||
|
bool hasCountLikeFunc;
|
||||||
} SAggPhysiNode;
|
} SAggPhysiNode;
|
||||||
|
|
||||||
typedef struct SDownstreamSourceNode {
|
typedef struct SDownstreamSourceNode {
|
||||||
|
|
|
@ -177,6 +177,8 @@ typedef struct SFunctionNode {
|
||||||
int32_t udfBufSize;
|
int32_t udfBufSize;
|
||||||
bool hasPk;
|
bool hasPk;
|
||||||
int32_t pkBytes;
|
int32_t pkBytes;
|
||||||
|
bool hasOriginalFunc;
|
||||||
|
int32_t originalFuncId;
|
||||||
} SFunctionNode;
|
} SFunctionNode;
|
||||||
|
|
||||||
typedef struct STableNode {
|
typedef struct STableNode {
|
||||||
|
|
|
@ -47,6 +47,7 @@ typedef struct SAggOperatorInfo {
|
||||||
bool groupKeyOptimized;
|
bool groupKeyOptimized;
|
||||||
bool hasValidBlock;
|
bool hasValidBlock;
|
||||||
SSDataBlock* pNewGroupBlock;
|
SSDataBlock* pNewGroupBlock;
|
||||||
|
bool hasCountFunc;
|
||||||
} SAggOperatorInfo;
|
} SAggOperatorInfo;
|
||||||
|
|
||||||
static void destroyAggOperatorInfo(void* param);
|
static void destroyAggOperatorInfo(void* param);
|
||||||
|
@ -111,6 +112,7 @@ SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SAggPhysiN
|
||||||
pInfo->groupId = UINT64_MAX;
|
pInfo->groupId = UINT64_MAX;
|
||||||
pInfo->binfo.inputTsOrder = pAggNode->node.inputTsOrder;
|
pInfo->binfo.inputTsOrder = pAggNode->node.inputTsOrder;
|
||||||
pInfo->binfo.outputTsOrder = pAggNode->node.outputTsOrder;
|
pInfo->binfo.outputTsOrder = pAggNode->node.outputTsOrder;
|
||||||
|
pInfo->hasCountFunc = pAggNode->hasCountLikeFunc;
|
||||||
|
|
||||||
setOperatorInfo(pOperator, "TableAggregate", QUERY_NODE_PHYSICAL_PLAN_HASH_AGG,
|
setOperatorInfo(pOperator, "TableAggregate", QUERY_NODE_PHYSICAL_PLAN_HASH_AGG,
|
||||||
!pAggNode->node.forceCreateNonBlockingOptr, OP_NOT_OPENED, pInfo, pTaskInfo);
|
!pAggNode->node.forceCreateNonBlockingOptr, OP_NOT_OPENED, pInfo, pTaskInfo);
|
||||||
|
@ -317,18 +319,8 @@ static int32_t createDataBlockForEmptyInput(SOperatorInfo* pOperator, SSDataBloc
|
||||||
}
|
}
|
||||||
|
|
||||||
SqlFunctionCtx* pCtx = pOperator->exprSupp.pCtx;
|
SqlFunctionCtx* pCtx = pOperator->exprSupp.pCtx;
|
||||||
bool hasCountFunc = false;
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < pOperator->exprSupp.numOfExprs; ++i) {
|
if (!pAggInfo->hasCountFunc) {
|
||||||
const char* pName = pCtx[i].pExpr->pExpr->_function.functionName;
|
|
||||||
if ((strcmp(pName, "count") == 0) || (strcmp(pName, "hyperloglog") == 0) ||
|
|
||||||
(strcmp(pName, "_hyperloglog_partial") == 0) || (strcmp(pName, "_hyperloglog_merge") == 0)) {
|
|
||||||
hasCountFunc = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasCountFunc) {
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@ extern "C" {
|
||||||
#define FUNC_MGT_IGNORE_NULL_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(27)
|
#define FUNC_MGT_IGNORE_NULL_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(27)
|
||||||
#define FUNC_MGT_PRIMARY_KEY_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(28)
|
#define FUNC_MGT_PRIMARY_KEY_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(28)
|
||||||
#define FUNC_MGT_TSMA_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(29)
|
#define FUNC_MGT_TSMA_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(29)
|
||||||
|
#define FUNC_MGT_COUNT_LIKE_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(30) // funcs that should also return 0 when no rows found
|
||||||
|
|
||||||
#define FUNC_MGT_TEST_MASK(val, mask) (((val) & (mask)) != 0)
|
#define FUNC_MGT_TEST_MASK(val, mask) (((val) & (mask)) != 0)
|
||||||
|
|
||||||
|
|
|
@ -1823,6 +1823,28 @@ static int32_t translateFirstLastMerge(SFunctionNode* pFunc, char* pErrBuf, int3
|
||||||
return translateFirstLastImpl(pFunc, pErrBuf, len, false);
|
return translateFirstLastImpl(pFunc, pErrBuf, len, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t translateFirstLastState(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
|
SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0);
|
||||||
|
int32_t paraBytes = getSDataTypeFromNode(pPara)->bytes;
|
||||||
|
|
||||||
|
pFunc->node.resType =
|
||||||
|
(SDataType){.bytes = getFirstLastInfoSize(paraBytes) + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY};
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t translateFirstLastStateMerge(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
|
SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0);
|
||||||
|
int32_t paraBytes = getSDataTypeFromNode(pPara)->bytes;
|
||||||
|
uint8_t paraType = getSDataTypeFromNode(pPara)->type;
|
||||||
|
if (paraType != TSDB_DATA_TYPE_BINARY) {
|
||||||
|
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
pFunc->node.resType =
|
||||||
|
(SDataType){.bytes = getFirstLastInfoSize(paraBytes) + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY};
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t translateUniqueMode(SFunctionNode* pFunc, char* pErrBuf, int32_t len, bool isUnique) {
|
static int32_t translateUniqueMode(SFunctionNode* pFunc, char* pErrBuf, int32_t len, bool isUnique) {
|
||||||
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
|
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
|
@ -2418,7 +2440,7 @@ 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 | FUNC_MGT_IGNORE_NULL_FUNC | FUNC_MGT_TSMA_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED | FUNC_MGT_IGNORE_NULL_FUNC | FUNC_MGT_TSMA_FUNC | FUNC_MGT_COUNT_LIKE_FUNC,
|
||||||
.translateFunc = translateCount,
|
.translateFunc = translateCount,
|
||||||
.dataRequiredFunc = countDataRequired,
|
.dataRequiredFunc = countDataRequired,
|
||||||
.getEnvFunc = getCountFuncEnv,
|
.getEnvFunc = getCountFuncEnv,
|
||||||
|
@ -2693,7 +2715,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "spread",
|
.name = "spread",
|
||||||
.type = FUNCTION_TYPE_SPREAD,
|
.type = FUNCTION_TYPE_SPREAD,
|
||||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED,
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED | FUNC_MGT_TSMA_FUNC,
|
||||||
.translateFunc = translateSpread,
|
.translateFunc = translateSpread,
|
||||||
.dataRequiredFunc = statisDataRequired,
|
.dataRequiredFunc = statisDataRequired,
|
||||||
.getEnvFunc = getSpreadFuncEnv,
|
.getEnvFunc = getSpreadFuncEnv,
|
||||||
|
@ -2706,6 +2728,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
#endif
|
#endif
|
||||||
.combineFunc = spreadCombine,
|
.combineFunc = spreadCombine,
|
||||||
.pPartialFunc = "_spread_partial",
|
.pPartialFunc = "_spread_partial",
|
||||||
|
.pStateFunc = "_spread_state",
|
||||||
.pMergeFunc = "_spread_merge"
|
.pMergeFunc = "_spread_merge"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -2737,6 +2760,8 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
.invertFunc = NULL,
|
.invertFunc = NULL,
|
||||||
#endif
|
#endif
|
||||||
.combineFunc = spreadCombine,
|
.combineFunc = spreadCombine,
|
||||||
|
.pPartialFunc = "_spread_state_merge",
|
||||||
|
.pMergeFunc = "_spread_merge",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "elapsed",
|
.name = "elapsed",
|
||||||
|
@ -2919,6 +2944,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
.sprocessFunc = firstLastScalarFunction,
|
.sprocessFunc = firstLastScalarFunction,
|
||||||
.finalizeFunc = firstLastFinalize,
|
.finalizeFunc = firstLastFinalize,
|
||||||
.pPartialFunc = "_first_partial",
|
.pPartialFunc = "_first_partial",
|
||||||
|
.pStateFunc = "_first_state",
|
||||||
.pMergeFunc = "_first_merge",
|
.pMergeFunc = "_first_merge",
|
||||||
.combineFunc = firstCombine,
|
.combineFunc = firstCombine,
|
||||||
},
|
},
|
||||||
|
@ -2946,12 +2972,14 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
.processFunc = firstFunctionMerge,
|
.processFunc = firstFunctionMerge,
|
||||||
.finalizeFunc = firstLastFinalize,
|
.finalizeFunc = firstLastFinalize,
|
||||||
.combineFunc = firstCombine,
|
.combineFunc = firstCombine,
|
||||||
|
.pPartialFunc = "_first_state_merge",
|
||||||
|
.pMergeFunc = "_first_merge",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "last",
|
.name = "last",
|
||||||
.type = FUNCTION_TYPE_LAST,
|
.type = FUNCTION_TYPE_LAST,
|
||||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC |
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC |
|
||||||
FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_IGNORE_NULL_FUNC | FUNC_MGT_PRIMARY_KEY_FUNC,
|
FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_IGNORE_NULL_FUNC | FUNC_MGT_PRIMARY_KEY_FUNC | FUNC_MGT_TSMA_FUNC,
|
||||||
.translateFunc = translateFirstLast,
|
.translateFunc = translateFirstLast,
|
||||||
.dynDataRequiredFunc = lastDynDataReq,
|
.dynDataRequiredFunc = lastDynDataReq,
|
||||||
.getEnvFunc = getFirstLastFuncEnv,
|
.getEnvFunc = getFirstLastFuncEnv,
|
||||||
|
@ -2960,6 +2988,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
.sprocessFunc = firstLastScalarFunction,
|
.sprocessFunc = firstLastScalarFunction,
|
||||||
.finalizeFunc = firstLastFinalize,
|
.finalizeFunc = firstLastFinalize,
|
||||||
.pPartialFunc = "_last_partial",
|
.pPartialFunc = "_last_partial",
|
||||||
|
.pStateFunc = "_last_state",
|
||||||
.pMergeFunc = "_last_merge",
|
.pMergeFunc = "_last_merge",
|
||||||
.combineFunc = lastCombine,
|
.combineFunc = lastCombine,
|
||||||
},
|
},
|
||||||
|
@ -2987,6 +3016,8 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
.processFunc = lastFunctionMerge,
|
.processFunc = lastFunctionMerge,
|
||||||
.finalizeFunc = firstLastFinalize,
|
.finalizeFunc = firstLastFinalize,
|
||||||
.combineFunc = lastCombine,
|
.combineFunc = lastCombine,
|
||||||
|
.pPartialFunc = "_last_state_merge",
|
||||||
|
.pMergeFunc = "_last_merge",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "twa",
|
.name = "twa",
|
||||||
|
@ -3049,7 +3080,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "hyperloglog",
|
.name = "hyperloglog",
|
||||||
.type = FUNCTION_TYPE_HYPERLOGLOG,
|
.type = FUNCTION_TYPE_HYPERLOGLOG,
|
||||||
.classification = FUNC_MGT_AGG_FUNC,
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_COUNT_LIKE_FUNC,
|
||||||
.translateFunc = translateHLL,
|
.translateFunc = translateHLL,
|
||||||
.getEnvFunc = getHLLFuncEnv,
|
.getEnvFunc = getHLLFuncEnv,
|
||||||
.initFunc = functionSetup,
|
.initFunc = functionSetup,
|
||||||
|
@ -3880,13 +3911,70 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
.type = FUNCTION_TYPE_FIRST_STATE,
|
.type = FUNCTION_TYPE_FIRST_STATE,
|
||||||
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC |
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC |
|
||||||
FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_TSMA_FUNC,
|
FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_TSMA_FUNC,
|
||||||
.translateFunc = translateAvgState,
|
.translateFunc = translateFirstLastState,
|
||||||
.getEnvFunc = getFirstLastFuncEnv,
|
.getEnvFunc = getFirstLastFuncEnv,
|
||||||
.initFunc = functionSetup,
|
.initFunc = functionSetup,
|
||||||
.processFunc = firstFunction,
|
.processFunc = firstFunction,
|
||||||
.finalizeFunc = firstLastPartialFinalize,
|
.finalizeFunc = firstLastPartialFinalize,
|
||||||
.pPartialFunc = "_first_partial",
|
.pPartialFunc = "_first_partial",
|
||||||
.pMergeFunc = "_avg_state_merge"
|
.pMergeFunc = "_first_state_merge"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "_first_state_merge",
|
||||||
|
.type = FUNCTION_TYPE_FIRST_STATE_MERGE,
|
||||||
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC |
|
||||||
|
FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_TSMA_FUNC,
|
||||||
|
.translateFunc = translateFirstLastStateMerge,
|
||||||
|
.getEnvFunc = getFirstLastFuncEnv,
|
||||||
|
.initFunc = functionSetup,
|
||||||
|
.processFunc = firstFunctionMerge,
|
||||||
|
.finalizeFunc = firstLastPartialFinalize,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "_last_state",
|
||||||
|
.type = FUNCTION_TYPE_LAST_STATE,
|
||||||
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC |
|
||||||
|
FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_TSMA_FUNC,
|
||||||
|
.translateFunc = translateFirstLastState,
|
||||||
|
.getEnvFunc = getFirstLastFuncEnv,
|
||||||
|
.initFunc = functionSetup,
|
||||||
|
.processFunc = lastFunction,
|
||||||
|
.finalizeFunc = firstLastPartialFinalize,
|
||||||
|
.pPartialFunc = "_last_partial",
|
||||||
|
.pMergeFunc = "_last_state_merge"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "_last_state_merge",
|
||||||
|
.type = FUNCTION_TYPE_LAST_STATE_MERGE,
|
||||||
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SELECT_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC |
|
||||||
|
FUNC_MGT_KEEP_ORDER_FUNC | FUNC_MGT_FORBID_SYSTABLE_FUNC | FUNC_MGT_TSMA_FUNC,
|
||||||
|
.translateFunc = translateFirstLastStateMerge,
|
||||||
|
.getEnvFunc = getFirstLastFuncEnv,
|
||||||
|
.initFunc = functionSetup,
|
||||||
|
.processFunc = lastFunctionMerge,
|
||||||
|
.finalizeFunc = firstLastPartialFinalize,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "_spread_state",
|
||||||
|
.type = FUNCTION_TYPE_SPREAD_STATE,
|
||||||
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED | FUNC_MGT_TSMA_FUNC,
|
||||||
|
.translateFunc = translateSpreadState,
|
||||||
|
.getEnvFunc = getSpreadFuncEnv,
|
||||||
|
.initFunc = spreadFunctionSetup,
|
||||||
|
.processFunc = spreadFunction,
|
||||||
|
.finalizeFunc = spreadPartialFinalize,
|
||||||
|
.pPartialFunc = "_spread_partial",
|
||||||
|
.pMergeFunc = "_last_state_merge"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "_spread_state_merge",
|
||||||
|
.type = FUNCTION_TYPE_SPREAD_STATE_MERGE,
|
||||||
|
.classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_SPECIAL_DATA_REQUIRED | FUNC_MGT_TSMA_FUNC,
|
||||||
|
.translateFunc = translateSpreadStateMerge,
|
||||||
|
.getEnvFunc = getSpreadFuncEnv,
|
||||||
|
.initFunc = spreadFunctionSetup,
|
||||||
|
.processFunc = spreadFunctionMerge,
|
||||||
|
.finalizeFunc = spreadPartialFinalize,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
|
@ -867,6 +867,12 @@ int32_t sumFunction(SqlFunctionCtx* pCtx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_sum_over:
|
_sum_over:
|
||||||
|
if (numOfElem == 0) {
|
||||||
|
if (pCtx->pExpr->pExpr->_function.pFunctNode->hasOriginalFunc &&
|
||||||
|
fmIsCountLikeFunc(pCtx->pExpr->pExpr->_function.pFunctNode->originalFuncId)) {
|
||||||
|
numOfElem = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
// data in the check operation are all null, not output
|
// data in the check operation are all null, not output
|
||||||
SET_VAL(GET_RES_INFO(pCtx), numOfElem, 1);
|
SET_VAL(GET_RES_INFO(pCtx), numOfElem, 1);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -2846,6 +2852,12 @@ static int32_t firstLastTransferInfo(SqlFunctionCtx* pCtx, SFirstLastRes* pInput
|
||||||
static int32_t firstLastFunctionMergeImpl(SqlFunctionCtx* pCtx, bool isFirstQuery) {
|
static int32_t firstLastFunctionMergeImpl(SqlFunctionCtx* pCtx, bool isFirstQuery) {
|
||||||
SInputColumnInfoData* pInput = &pCtx->input;
|
SInputColumnInfoData* pInput = &pCtx->input;
|
||||||
SColumnInfoData* pCol = pInput->pData[0];
|
SColumnInfoData* pCol = pInput->pData[0];
|
||||||
|
|
||||||
|
if (IS_NULL_TYPE(pCol->info.type)) {
|
||||||
|
SET_VAL(GET_RES_INFO(pCtx), 0, 1);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
if (pCol->info.type != TSDB_DATA_TYPE_BINARY) {
|
if (pCol->info.type != TSDB_DATA_TYPE_BINARY) {
|
||||||
return TSDB_CODE_FUNC_FUNTION_PARA_TYPE;
|
return TSDB_CODE_FUNC_FUNTION_PARA_TYPE;
|
||||||
}
|
}
|
||||||
|
@ -3852,6 +3864,11 @@ static void spreadTransferInfo(SSpreadInfo* pInput, SSpreadInfo* pOutput) {
|
||||||
int32_t spreadFunctionMerge(SqlFunctionCtx* pCtx) {
|
int32_t spreadFunctionMerge(SqlFunctionCtx* pCtx) {
|
||||||
SInputColumnInfoData* pInput = &pCtx->input;
|
SInputColumnInfoData* pInput = &pCtx->input;
|
||||||
SColumnInfoData* pCol = pInput->pData[0];
|
SColumnInfoData* pCol = pInput->pData[0];
|
||||||
|
|
||||||
|
if (IS_NULL_TYPE(pCol->info.type)) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
if (pCol->info.type != TSDB_DATA_TYPE_BINARY) {
|
if (pCol->info.type != TSDB_DATA_TYPE_BINARY) {
|
||||||
return TSDB_CODE_FUNC_FUNTION_PARA_TYPE;
|
return TSDB_CODE_FUNC_FUNTION_PARA_TYPE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -705,6 +705,12 @@ static void avgTransferInfo(SAvgRes* pInput, SAvgRes* pOutput) {
|
||||||
int32_t avgFunctionMerge(SqlFunctionCtx* pCtx) {
|
int32_t avgFunctionMerge(SqlFunctionCtx* pCtx) {
|
||||||
SInputColumnInfoData* pInput = &pCtx->input;
|
SInputColumnInfoData* pInput = &pCtx->input;
|
||||||
SColumnInfoData* pCol = pInput->pData[0];
|
SColumnInfoData* pCol = pInput->pData[0];
|
||||||
|
|
||||||
|
if (IS_NULL_TYPE(pCol->info.type)) {
|
||||||
|
SET_VAL(GET_RES_INFO(pCtx), 0, 1);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
if (pCol->info.type != TSDB_DATA_TYPE_BINARY) {
|
if (pCol->info.type != TSDB_DATA_TYPE_BINARY) {
|
||||||
return TSDB_CODE_FUNC_FUNTION_PARA_TYPE;
|
return TSDB_CODE_FUNC_FUNTION_PARA_TYPE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -413,6 +413,8 @@ static int32_t createPartialFunction(const SFunctionNode* pSrcFunc, SFunctionNod
|
||||||
nodesDestroyList(pParameterList);
|
nodesDestroyList(pParameterList);
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
(*pPartialFunc)->hasOriginalFunc = true;
|
||||||
|
(*pPartialFunc)->originalFuncId = pSrcFunc->hasOriginalFunc ? pSrcFunc->originalFuncId : pSrcFunc->funcId;
|
||||||
char name[TSDB_FUNC_NAME_LEN + TSDB_NAME_DELIMITER_LEN + TSDB_POINTER_PRINT_BYTES + 1] = {0};
|
char name[TSDB_FUNC_NAME_LEN + TSDB_NAME_DELIMITER_LEN + TSDB_POINTER_PRINT_BYTES + 1] = {0};
|
||||||
int32_t len = snprintf(name, sizeof(name) - 1, "%s.%p", (*pPartialFunc)->functionName, pSrcFunc);
|
int32_t len = snprintf(name, sizeof(name) - 1, "%s.%p", (*pPartialFunc)->functionName, pSrcFunc);
|
||||||
taosCreateMD5Hash(name, len);
|
taosCreateMD5Hash(name, len);
|
||||||
|
@ -475,6 +477,8 @@ static int32_t createMergeFunction(const SFunctionNode* pSrcFunc, const SFunctio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
pFunc->hasOriginalFunc = true;
|
||||||
|
pFunc->originalFuncId = pSrcFunc->hasOriginalFunc ? pSrcFunc->originalFuncId : pSrcFunc->funcId;
|
||||||
// overwrite function restype set by translate function
|
// overwrite function restype set by translate function
|
||||||
if (fmIsSameInOutType(pSrcFunc->funcId)) {
|
if (fmIsSameInOutType(pSrcFunc->funcId)) {
|
||||||
pFunc->node.resType = pSrcFunc->node.resType;
|
pFunc->node.resType = pSrcFunc->node.resType;
|
||||||
|
@ -635,3 +639,7 @@ bool fmIsMyStateFunc(int32_t funcId, int32_t stateFuncId) {
|
||||||
const SBuiltinFuncDefinition* pStateMergeFunc = &funcMgtBuiltins[stateMergeFuncId];
|
const SBuiltinFuncDefinition* pStateMergeFunc = &funcMgtBuiltins[stateMergeFuncId];
|
||||||
return strcmp(pStateFunc->name, pStateMergeFunc->pMergeFunc) == 0;
|
return strcmp(pStateFunc->name, pStateMergeFunc->pMergeFunc) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool fmIsCountLikeFunc(int32_t funcId) {
|
||||||
|
return isSpecificClassifyFunc(funcId, FUNC_MGT_COUNT_LIKE_FUNC);
|
||||||
|
}
|
||||||
|
|
|
@ -224,6 +224,8 @@ static int32_t functionNodeCopy(const SFunctionNode* pSrc, SFunctionNode* pDst)
|
||||||
COPY_SCALAR_FIELD(udfBufSize);
|
COPY_SCALAR_FIELD(udfBufSize);
|
||||||
COPY_SCALAR_FIELD(hasPk);
|
COPY_SCALAR_FIELD(hasPk);
|
||||||
COPY_SCALAR_FIELD(pkBytes);
|
COPY_SCALAR_FIELD(pkBytes);
|
||||||
|
COPY_SCALAR_FIELD(hasOriginalFunc);
|
||||||
|
COPY_SCALAR_FIELD(originalFuncId);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2468,6 +2468,7 @@ static const char* jkAggPhysiPlanGroupKeys = "GroupKeys";
|
||||||
static const char* jkAggPhysiPlanAggFuncs = "AggFuncs";
|
static const char* jkAggPhysiPlanAggFuncs = "AggFuncs";
|
||||||
static const char* jkAggPhysiPlanMergeDataBlock = "MergeDataBlock";
|
static const char* jkAggPhysiPlanMergeDataBlock = "MergeDataBlock";
|
||||||
static const char* jkAggPhysiPlanGroupKeyOptimized = "GroupKeyOptimized";
|
static const char* jkAggPhysiPlanGroupKeyOptimized = "GroupKeyOptimized";
|
||||||
|
static const char* jkAggPhysiPlanHasCountLikeFunc = "HasCountFunc";
|
||||||
|
|
||||||
static int32_t physiAggNodeToJson(const void* pObj, SJson* pJson) {
|
static int32_t physiAggNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
const SAggPhysiNode* pNode = (const SAggPhysiNode*)pObj;
|
const SAggPhysiNode* pNode = (const SAggPhysiNode*)pObj;
|
||||||
|
@ -2488,6 +2489,9 @@ static int32_t physiAggNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tjsonAddBoolToObject(pJson, jkAggPhysiPlanGroupKeyOptimized, pNode->groupKeyOptimized);
|
code = tjsonAddBoolToObject(pJson, jkAggPhysiPlanGroupKeyOptimized, pNode->groupKeyOptimized);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddBoolToObject(pJson, jkAggPhysiPlanHasCountLikeFunc, pNode->hasCountLikeFunc);
|
||||||
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -2511,6 +2515,9 @@ static int32_t jsonToPhysiAggNode(const SJson* pJson, void* pObj) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tjsonGetBoolValue(pJson, jkAggPhysiPlanGroupKeyOptimized, &pNode->groupKeyOptimized);
|
code = tjsonGetBoolValue(pJson, jkAggPhysiPlanGroupKeyOptimized, &pNode->groupKeyOptimized);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBoolValue(pJson, jkAggPhysiPlanHasCountLikeFunc, &pNode->hasCountLikeFunc);
|
||||||
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -4238,6 +4245,8 @@ static const char* jkFunctionParameter = "Parameters";
|
||||||
static const char* jkFunctionUdfBufSize = "UdfBufSize";
|
static const char* jkFunctionUdfBufSize = "UdfBufSize";
|
||||||
static const char* jkFunctionHasPk = "HasPk";
|
static const char* jkFunctionHasPk = "HasPk";
|
||||||
static const char* jkFunctionPkBytes = "PkBytes";
|
static const char* jkFunctionPkBytes = "PkBytes";
|
||||||
|
static const char* jkFunctionIsMergeFunc = "IsMergeFunc";
|
||||||
|
static const char* jkFunctionMergeFuncOf = "MergeFuncOf";
|
||||||
|
|
||||||
static int32_t functionNodeToJson(const void* pObj, SJson* pJson) {
|
static int32_t functionNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
const SFunctionNode* pNode = (const SFunctionNode*)pObj;
|
const SFunctionNode* pNode = (const SFunctionNode*)pObj;
|
||||||
|
@ -4264,6 +4273,13 @@ static int32_t functionNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tjsonAddIntegerToObject(pJson, jkFunctionPkBytes, pNode->pkBytes);
|
code = tjsonAddIntegerToObject(pJson, jkFunctionPkBytes, pNode->pkBytes);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddBoolToObject(pJson, jkFunctionIsMergeFunc, pNode->hasOriginalFunc);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonAddIntegerToObject(pJson, jkFunctionMergeFuncOf, pNode->originalFuncId);
|
||||||
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4292,6 +4308,13 @@ static int32_t jsonToFunctionNode(const SJson* pJson, void* pObj) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tjsonGetIntValue(pJson, jkFunctionPkBytes, &pNode->pkBytes);
|
code = tjsonGetIntValue(pJson, jkFunctionPkBytes, &pNode->pkBytes);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetBoolValue(pJson, jkFunctionIsMergeFunc, &pNode->hasOriginalFunc);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tjsonGetIntValue(pJson, jkFunctionMergeFuncOf, &pNode->originalFuncId);
|
||||||
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1109,7 +1109,9 @@ enum {
|
||||||
FUNCTION_CODE_PARAMETERS,
|
FUNCTION_CODE_PARAMETERS,
|
||||||
FUNCTION_CODE_UDF_BUF_SIZE,
|
FUNCTION_CODE_UDF_BUF_SIZE,
|
||||||
FUNCTION_NODE_HAS_PK,
|
FUNCTION_NODE_HAS_PK,
|
||||||
FUNCTION_NODE_PK_BYTES
|
FUNCTION_NODE_PK_BYTES,
|
||||||
|
FUNCTION_CODE_IS_MERGE_FUNC,
|
||||||
|
FUNCTION_CODE_MERGE_FUNC_OF,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int32_t functionNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
static int32_t functionNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||||
|
@ -1137,6 +1139,13 @@ static int32_t functionNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tlvEncodeI32(pEncoder, FUNCTION_NODE_PK_BYTES, pNode->pkBytes);
|
code = tlvEncodeI32(pEncoder, FUNCTION_NODE_PK_BYTES, pNode->pkBytes);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tlvEncodeBool(pEncoder, FUNCTION_CODE_IS_MERGE_FUNC, pNode->hasOriginalFunc);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tlvEncodeI32(pEncoder, FUNCTION_CODE_MERGE_FUNC_OF, pNode->originalFuncId);
|
||||||
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1171,6 +1180,12 @@ static int32_t msgToFunctionNode(STlvDecoder* pDecoder, void* pObj) {
|
||||||
case FUNCTION_NODE_PK_BYTES:
|
case FUNCTION_NODE_PK_BYTES:
|
||||||
code = tlvDecodeI32(pTlv, &pNode->pkBytes);
|
code = tlvDecodeI32(pTlv, &pNode->pkBytes);
|
||||||
break;
|
break;
|
||||||
|
case FUNCTION_CODE_IS_MERGE_FUNC:
|
||||||
|
code = tlvDecodeBool(pTlv, &pNode->hasOriginalFunc);
|
||||||
|
break;
|
||||||
|
case FUNCTION_CODE_MERGE_FUNC_OF:
|
||||||
|
code = tlvDecodeI32(pTlv, &pNode->originalFuncId);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2839,7 +2854,8 @@ enum {
|
||||||
PHY_AGG_CODE_GROUP_KEYS,
|
PHY_AGG_CODE_GROUP_KEYS,
|
||||||
PHY_AGG_CODE_AGG_FUNCS,
|
PHY_AGG_CODE_AGG_FUNCS,
|
||||||
PHY_AGG_CODE_MERGE_DATA_BLOCK,
|
PHY_AGG_CODE_MERGE_DATA_BLOCK,
|
||||||
PHY_AGG_CODE_GROUP_KEY_OPTIMIZE
|
PHY_AGG_CODE_GROUP_KEY_OPTIMIZE,
|
||||||
|
PHY_AGG_CODE_HAS_COUNT_LIKE_FUNCS,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int32_t physiAggNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
static int32_t physiAggNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||||
|
@ -2861,6 +2877,9 @@ static int32_t physiAggNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tlvEncodeBool(pEncoder, PHY_AGG_CODE_GROUP_KEY_OPTIMIZE, pNode->groupKeyOptimized);
|
code = tlvEncodeBool(pEncoder, PHY_AGG_CODE_GROUP_KEY_OPTIMIZE, pNode->groupKeyOptimized);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tlvEncodeBool(pEncoder, PHY_AGG_CODE_HAS_COUNT_LIKE_FUNCS, pNode->hasCountLikeFunc);
|
||||||
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -2890,6 +2909,9 @@ static int32_t msgToPhysiAggNode(STlvDecoder* pDecoder, void* pObj) {
|
||||||
case PHY_AGG_CODE_GROUP_KEY_OPTIMIZE:
|
case PHY_AGG_CODE_GROUP_KEY_OPTIMIZE:
|
||||||
code = tlvDecodeBool(pTlv, &pNode->groupKeyOptimized);
|
code = tlvDecodeBool(pTlv, &pNode->groupKeyOptimized);
|
||||||
break;
|
break;
|
||||||
|
case PHY_AGG_CODE_HAS_COUNT_LIKE_FUNCS:
|
||||||
|
code = tlvDecodeBool(pTlv, &pNode->hasCountLikeFunc);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10686,6 +10686,10 @@ static int32_t rewriteTSMAFuncs(STranslateContext* pCxt, SCreateTSMAStmt* pStmt,
|
||||||
nodesListErase(pFunc->pParameterList, pFunc->pParameterList->pHead);
|
nodesListErase(pFunc->pParameterList, pFunc->pParameterList->pHead);
|
||||||
nodesListPushFront(pFunc->pParameterList, (SNode*)pCol);
|
nodesListPushFront(pFunc->pParameterList, (SNode*)pCol);
|
||||||
snprintf(pFunc->node.userAlias, TSDB_COL_NAME_LEN, "%s", pSchema->name);
|
snprintf(pFunc->node.userAlias, TSDB_COL_NAME_LEN, "%s", pSchema->name);
|
||||||
|
// for first or last, the second param will be pk ts col, here we should remove it
|
||||||
|
if (fmIsImplicitTsFunc(pFunc->funcId) && LIST_LENGTH(pFunc->pParameterList) == 2) {
|
||||||
|
nodesListErase(pFunc->pParameterList, pFunc->pParameterList->pTail);
|
||||||
|
}
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
// recursive tsma, create func list from base tsma
|
// recursive tsma, create func list from base tsma
|
||||||
|
|
|
@ -5895,8 +5895,7 @@ static bool tsmaOptCheckValidFuncs(const SArray* pTsmaFuncs, const SNodeList* pQ
|
||||||
SFunctionNode* pQueryFunc = (SFunctionNode*)pNode;
|
SFunctionNode* pQueryFunc = (SFunctionNode*)pNode;
|
||||||
// TODO handle _wstart
|
// TODO handle _wstart
|
||||||
if (fmIsPseudoColumnFunc(pQueryFunc->funcId) || fmIsGroupKeyFunc(pQueryFunc->funcId)) continue;
|
if (fmIsPseudoColumnFunc(pQueryFunc->funcId) || fmIsGroupKeyFunc(pQueryFunc->funcId)) continue;
|
||||||
if (1 != pQueryFunc->pParameterList->length ||
|
if (nodeType(pQueryFunc->pParameterList->pHead->pNode) != QUERY_NODE_COLUMN) {
|
||||||
nodeType(pQueryFunc->pParameterList->pHead->pNode) != QUERY_NODE_COLUMN) {
|
|
||||||
failed = true;
|
failed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1556,6 +1556,17 @@ static int32_t rewritePrecalcExpr(SPhysiPlanContext* pCxt, SNode* pNode, SNodeLi
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static EDealRes hasCountLikeFunc(SNode* pNode, void* res) {
|
||||||
|
if (QUERY_NODE_FUNCTION == nodeType(pNode)) {
|
||||||
|
SFunctionNode* pFunc = (SFunctionNode*)pNode;
|
||||||
|
if (fmIsCountLikeFunc(pFunc->funcId) || (pFunc->hasOriginalFunc && fmIsCountLikeFunc(pFunc->originalFuncId))) {
|
||||||
|
*(bool*)res = true;
|
||||||
|
return DEAL_RES_END;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DEAL_RES_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t createAggPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren, SAggLogicNode* pAggLogicNode,
|
static int32_t createAggPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren, SAggLogicNode* pAggLogicNode,
|
||||||
SPhysiNode** pPhyNode, SSubplan* pSubPlan) {
|
SPhysiNode** pPhyNode, SSubplan* pSubPlan) {
|
||||||
SAggPhysiNode* pAgg =
|
SAggPhysiNode* pAgg =
|
||||||
|
@ -1579,6 +1590,7 @@ static int32_t createAggPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren,
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = rewritePrecalcExprs(pCxt, pAggLogicNode->pAggFuncs, &pPrecalcExprs, &pAggFuncs);
|
code = rewritePrecalcExprs(pCxt, pAggLogicNode->pAggFuncs, &pPrecalcExprs, &pAggFuncs);
|
||||||
}
|
}
|
||||||
|
nodesWalkExprs(pAggFuncs, hasCountLikeFunc, &pAgg->hasCountLikeFunc);
|
||||||
|
|
||||||
SDataBlockDescNode* pChildTupe = (((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc);
|
SDataBlockDescNode* pChildTupe = (((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc);
|
||||||
// push down expression to pOutputDataBlockDesc of child node
|
// push down expression to pOutputDataBlockDesc of child node
|
||||||
|
|
|
@ -771,7 +771,7 @@ class TDTestCase:
|
||||||
|
|
||||||
def test_recursive_tsma(self):
|
def test_recursive_tsma(self):
|
||||||
tdSql.execute('drop tsma tsma2')
|
tdSql.execute('drop tsma tsma2')
|
||||||
tsma_func_list = ['avg(c2)', 'avg(c3)', 'min(c4)', 'max(c3)', 'sum(c2)', 'count(ts)', 'count(c2)']
|
tsma_func_list = ['avg(c2)', 'avg(c3)', 'min(c4)', 'max(c3)', 'sum(c2)', 'count(ts)', 'count(c2)', 'first(c5)', 'last(c5)']
|
||||||
select_func_list: List[str] = tsma_func_list.copy()
|
select_func_list: List[str] = tsma_func_list.copy()
|
||||||
select_func_list.append('count(*)')
|
select_func_list.append('count(*)')
|
||||||
self.create_tsma('tsma3', 'test', 'meters', tsma_func_list, '5m')
|
self.create_tsma('tsma3', 'test', 'meters', tsma_func_list, '5m')
|
||||||
|
@ -781,6 +781,7 @@ class TDTestCase:
|
||||||
sql = 'select avg(c2), "recursive tsma4" from meters'
|
sql = 'select avg(c2), "recursive tsma4" from meters'
|
||||||
ctx = TSMAQCBuilder().with_sql(sql).should_query_with_tsma(
|
ctx = TSMAQCBuilder().with_sql(sql).should_query_with_tsma(
|
||||||
'tsma4', UsedTsma.TS_MIN, UsedTsma.TS_MAX).get_qc()
|
'tsma4', UsedTsma.TS_MIN, UsedTsma.TS_MAX).get_qc()
|
||||||
|
#time.sleep(999999)
|
||||||
self.tsma_tester.check_sql(sql, ctx)
|
self.tsma_tester.check_sql(sql, ctx)
|
||||||
self.check(self.test_query_tsma_all(select_func_list))
|
self.check(self.test_query_tsma_all(select_func_list))
|
||||||
self.create_recursive_tsma(
|
self.create_recursive_tsma(
|
||||||
|
@ -857,7 +858,7 @@ class TDTestCase:
|
||||||
sql = "SELECT avg(c1), avg(c2),_wstart, _wend,t3,t4,t5,t2 FROM meters WHERE ts >= '2018-09-17 8:00:00' AND ts < '2018-09-17 09:03:18.334' PARTITION BY t3,t4,t5,t2 INTERVAL(1d);"
|
sql = "SELECT avg(c1), avg(c2),_wstart, _wend,t3,t4,t5,t2 FROM meters WHERE ts >= '2018-09-17 8:00:00' AND ts < '2018-09-17 09:03:18.334' PARTITION BY t3,t4,t5,t2 INTERVAL(1d);"
|
||||||
ctxs.append(TSMAQCBuilder().with_sql(sql)
|
ctxs.append(TSMAQCBuilder().with_sql(sql)
|
||||||
.should_query_with_table('meters', '2018-09-17 8:00:00', '2018-09-17 09:03:18.333').get_qc())
|
.should_query_with_table('meters', '2018-09-17 8:00:00', '2018-09-17 09:03:18.333').get_qc())
|
||||||
ctxs.extend(self.test_query_tsma_all())
|
#ctxs.extend(self.test_query_tsma_all())
|
||||||
return ctxs
|
return ctxs
|
||||||
|
|
||||||
def test_query_with_tsma_interval_partition_by_col(self):
|
def test_query_with_tsma_interval_partition_by_col(self):
|
||||||
|
|
Loading…
Reference in New Issue