enh(query): add first/last function distributed implementation
This commit is contained in:
		
							parent
							
								
									594aa2fb44
								
							
						
					
					
						commit
						6d95262688
					
				|  | @ -138,6 +138,8 @@ typedef enum EFunctionType { | ||||||
|   FUNCTION_TYPE_TOP_MERGE, |   FUNCTION_TYPE_TOP_MERGE, | ||||||
|   FUNCTION_TYPE_BOTTOM_PARTIAL, |   FUNCTION_TYPE_BOTTOM_PARTIAL, | ||||||
|   FUNCTION_TYPE_BOTTOM_MERGE, |   FUNCTION_TYPE_BOTTOM_MERGE, | ||||||
|  |   FUNCTION_TYPE_FIRST_PARTIAL, | ||||||
|  |   FUNCTION_TYPE_FIRST_MERGE, | ||||||
| 
 | 
 | ||||||
|   // user defined funcion
 |   // user defined funcion
 | ||||||
|   FUNCTION_TYPE_UDF = 10000 |   FUNCTION_TYPE_UDF = 10000 | ||||||
|  |  | ||||||
|  | @ -97,6 +97,7 @@ int32_t lastFunction(SqlFunctionCtx *pCtx); | ||||||
| int32_t firstLastFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock); | int32_t firstLastFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock); | ||||||
| int32_t firstCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx); | int32_t firstCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx); | ||||||
| int32_t lastCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx); | int32_t lastCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx); | ||||||
|  | int32_t getFirstLastInfoSize(int32_t resBytes); | ||||||
| 
 | 
 | ||||||
| bool getTopBotFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv); | bool getTopBotFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv); | ||||||
| bool getTopBotMergeFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv); | bool getTopBotMergeFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv); | ||||||
|  |  | ||||||
|  | @ -954,6 +954,41 @@ static int32_t translateFirstLast(SFunctionNode* pFunc, char* pErrBuf, int32_t l | ||||||
|   return TSDB_CODE_SUCCESS; |   return TSDB_CODE_SUCCESS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static int32_t translateFirstLastImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t len, bool isPartial) { | ||||||
|  |   // first(col_list) will be rewritten as first(col)
 | ||||||
|  |   if (1 != LIST_LENGTH(pFunc->pParameterList)) { | ||||||
|  |     return TSDB_CODE_SUCCESS; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0); | ||||||
|  |   uint8_t paraType = ((SExprNode*)pPara)->resType.type; | ||||||
|  |   int32_t paraBytes = ((SExprNode*)pPara)->resType.bytes; | ||||||
|  |   if (isPartial) { | ||||||
|  |     if (QUERY_NODE_COLUMN != nodeType(pPara)) { | ||||||
|  |       return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, | ||||||
|  |                              "The parameters of first/last can only be columns"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pFunc->node.resType = (SDataType){.bytes = getFirstLastInfoSize(paraBytes) + VARSTR_HEADER_SIZE, | ||||||
|  |                                       .type = TSDB_DATA_TYPE_BINARY}; | ||||||
|  |   } else { | ||||||
|  |     if (TSDB_DATA_TYPE_BINARY != paraType) { | ||||||
|  |       return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pFunc->node.resType = ((SExprNode*)pPara)->resType; | ||||||
|  |   } | ||||||
|  |   return TSDB_CODE_SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int32_t translateFirstLastPartial(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { | ||||||
|  |   return translateFirstLastImpl(pFunc, pErrBuf, len, true); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int32_t translateFirstLastMerge(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { | ||||||
|  |   return translateFirstLastImpl(pFunc, pErrBuf, len, false); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static int32_t translateUnique(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { | static int32_t translateUnique(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { | ||||||
|   if (1 != LIST_LENGTH(pFunc->pParameterList)) { |   if (1 != LIST_LENGTH(pFunc->pParameterList)) { | ||||||
|     return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); |     return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); | ||||||
|  | @ -1706,6 +1741,28 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { | ||||||
|     .finalizeFunc = firstLastFinalize, |     .finalizeFunc = firstLastFinalize, | ||||||
|     .combineFunc  = firstCombine, |     .combineFunc  = firstCombine, | ||||||
|   }, |   }, | ||||||
|  |   { | ||||||
|  |     .name = "_first_partial", | ||||||
|  |     .type = FUNCTION_TYPE_FIRST_PARTIAL, | ||||||
|  |     .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC, | ||||||
|  |     .translateFunc = translateFirstLastPartial, | ||||||
|  |     .getEnvFunc   = getFirstLastFuncEnv, | ||||||
|  |     .initFunc     = functionSetup, | ||||||
|  |     .processFunc  = firstFunction, | ||||||
|  |     .finalizeFunc = firstLastFinalize, | ||||||
|  |     .combineFunc  = firstCombine, | ||||||
|  |   }, | ||||||
|  |   { | ||||||
|  |     .name = "_first_merge", | ||||||
|  |     .type = FUNCTION_TYPE_FIRST_MERGE, | ||||||
|  |     .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC, | ||||||
|  |     .translateFunc = translateFirstLastMerge, | ||||||
|  |     .getEnvFunc   = getFirstLastFuncEnv, | ||||||
|  |     .initFunc     = functionSetup, | ||||||
|  |     .processFunc  = firstFunction, | ||||||
|  |     .finalizeFunc = firstLastFinalize, | ||||||
|  |     .combineFunc  = firstCombine, | ||||||
|  |   }, | ||||||
|   { |   { | ||||||
|     .name = "last", |     .name = "last", | ||||||
|     .type = FUNCTION_TYPE_LAST, |     .type = FUNCTION_TYPE_LAST, | ||||||
|  |  | ||||||
|  | @ -2244,6 +2244,10 @@ int32_t apercentileCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) | ||||||
|   return TSDB_CODE_SUCCESS; |   return TSDB_CODE_SUCCESS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | int32_t getFirstLastInfoSize(int32_t resBytes) { | ||||||
|  |   return resBytes + sizeof(int64_t); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| bool getFirstLastFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) { | bool getFirstLastFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) { | ||||||
|   SColumnNode* pNode = nodesListGetNode(pFunc->pParameterList, 0); |   SColumnNode* pNode = nodesListGetNode(pFunc->pParameterList, 0); | ||||||
|   pEnv->calcMemSize = pNode->node.resType.bytes + sizeof(int64_t); |   pEnv->calcMemSize = pNode->node.resType.bytes + sizeof(int64_t); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue