feat: add dynamic query ctrl operator
This commit is contained in:
parent
02cec4979a
commit
ac35ae9839
|
@ -325,6 +325,7 @@ typedef struct SDataBlockDescNode {
|
||||||
|
|
||||||
typedef struct SPhysiNode {
|
typedef struct SPhysiNode {
|
||||||
ENodeType type;
|
ENodeType type;
|
||||||
|
bool dynamicOp;
|
||||||
EOrder inputTsOrder;
|
EOrder inputTsOrder;
|
||||||
EOrder outputTsOrder;
|
EOrder outputTsOrder;
|
||||||
SDataBlockDescNode* pOutputDataBlockDesc;
|
SDataBlockDescNode* pOutputDataBlockDesc;
|
||||||
|
@ -443,9 +444,17 @@ typedef struct SGroupCachePhysiNode {
|
||||||
SNodeList* pGroupCols;
|
SNodeList* pGroupCols;
|
||||||
} SGroupCachePhysiNode;
|
} SGroupCachePhysiNode;
|
||||||
|
|
||||||
|
typedef struct SStbJoinDynCtrlInfo {
|
||||||
|
int32_t vgSlot[2];
|
||||||
|
int32_t uidSlot[2];
|
||||||
|
} SStbJoinDynCtrlInfo;
|
||||||
|
|
||||||
typedef struct SDynQueryCtrlPhysiNode {
|
typedef struct SDynQueryCtrlPhysiNode {
|
||||||
SPhysiNode node;
|
SPhysiNode node;
|
||||||
EDynQueryType qType;
|
EDynQueryType qType;
|
||||||
|
union {
|
||||||
|
SStbJoinDynCtrlInfo stbJoin;
|
||||||
|
};
|
||||||
} SDynQueryCtrlPhysiNode;
|
} SDynQueryCtrlPhysiNode;
|
||||||
|
|
||||||
typedef struct SAggPhysiNode {
|
typedef struct SAggPhysiNode {
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can use, redistribute, and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3
|
||||||
|
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef TDENGINE_DYNQUERYCTRL_H
|
||||||
|
#define TDENGINE_DYNQUERYCTRL_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct SDynQueryCtrlOperatorInfo {
|
||||||
|
SStbJoinDynCtrlInfo ctrlInfo;
|
||||||
|
} SDynQueryCtrlOperatorInfo;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // TDENGINE_DYNQUERYCTRL_H
|
|
@ -21,17 +21,10 @@ extern "C" {
|
||||||
|
|
||||||
#define GROUP_CACHE_DEFAULT_PAGE_SIZE 10485760
|
#define GROUP_CACHE_DEFAULT_PAGE_SIZE 10485760
|
||||||
|
|
||||||
typedef struct SGcSessionCtx {
|
|
||||||
SOperatorInfo* pDownstream;
|
|
||||||
bool cacheHit;
|
|
||||||
bool needCache;
|
|
||||||
SGcBlkBufInfo* pLastBlk;
|
|
||||||
} SGcSessionCtx;
|
|
||||||
|
|
||||||
typedef struct SGcOperatorParam {
|
typedef struct SGcOperatorParam {
|
||||||
SOperatorBasicParam basic;
|
SOperatorBasicParam basic;
|
||||||
int64_t sessionId;
|
int64_t sessionId;
|
||||||
int32_t downstreamKey;
|
int32_t downstreamIdx;
|
||||||
bool needCache;
|
bool needCache;
|
||||||
void* pGroupValue;
|
void* pGroupValue;
|
||||||
int32_t groupValueSize;
|
int32_t groupValueSize;
|
||||||
|
@ -71,18 +64,18 @@ typedef struct SGroupColsInfo {
|
||||||
char* pData;
|
char* pData;
|
||||||
} SGroupColsInfo;
|
} SGroupColsInfo;
|
||||||
|
|
||||||
typedef struct SGcDownstreamInfo {
|
typedef struct SGcSessionCtx {
|
||||||
SSHashObj* pKey2Idx;
|
SOperatorInfo* pDownstream;
|
||||||
SOperatorInfo** ppDownStream;
|
bool cacheHit;
|
||||||
int32_t downStreamNum;
|
bool needCache;
|
||||||
} SGcDownstreamInfo;
|
SGcBlkBufInfo* pLastBlk;
|
||||||
|
} SGcSessionCtx;
|
||||||
|
|
||||||
typedef struct SGroupCacheOperatorInfo {
|
typedef struct SGroupCacheOperatorInfo {
|
||||||
SSHashObj* pSessionHash;
|
SSHashObj* pSessionHash;
|
||||||
SGroupColsInfo groupColsInfo;
|
SGroupColsInfo groupColsInfo;
|
||||||
SArray* pBlkBufs;
|
SArray* pBlkBufs;
|
||||||
SSHashObj* pBlkHash;
|
SSHashObj* pBlkHash;
|
||||||
SGcDownstreamInfo downstreamInfo;
|
|
||||||
int64_t pCurrentId;
|
int64_t pCurrentId;
|
||||||
SGcSessionCtx* pCurrent;
|
SGcSessionCtx* pCurrent;
|
||||||
} SGroupCacheOperatorInfo;
|
} SGroupCacheOperatorInfo;
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can use, redistribute, and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3
|
||||||
|
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "executorInt.h"
|
||||||
|
#include "filter.h"
|
||||||
|
#include "function.h"
|
||||||
|
#include "operator.h"
|
||||||
|
#include "os.h"
|
||||||
|
#include "querynodes.h"
|
||||||
|
#include "querytask.h"
|
||||||
|
#include "tcompare.h"
|
||||||
|
#include "tdatablock.h"
|
||||||
|
#include "thash.h"
|
||||||
|
#include "tmsg.h"
|
||||||
|
#include "ttypes.h"
|
||||||
|
#include "dynqueryctrl.h"
|
||||||
|
|
||||||
|
static void destroyDynQueryCtrlOperator(void* param) {
|
||||||
|
SDynQueryCtrlOperatorInfo* pDynCtrlOperator = (SDynQueryCtrlOperatorInfo*)param;
|
||||||
|
|
||||||
|
taosMemoryFreeClear(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
SSDataBlock* getBlockFromDynQueryCtrl(SOperatorInfo* pOperator) {
|
||||||
|
SDynQueryCtrlOperatorInfo* pInfo = pOperator->info;
|
||||||
|
while (true) {
|
||||||
|
SSDataBlock* pBlock = pOperator->pDownstream[0]->fpSet.getNextFn(pOperator->pDownstream[0]);
|
||||||
|
if (NULL == pBlock) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
addBlkToGroupCache(pOperator, pBlock, &pRes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SOperatorInfo* createDynQueryCtrlOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream,
|
||||||
|
SDynQueryCtrlPhysiNode* pPhyciNode, SExecTaskInfo* pTaskInfo) {
|
||||||
|
SDynQueryCtrlOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SDynQueryCtrlOperatorInfo));
|
||||||
|
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||||
|
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
if (pOperator == NULL || pInfo == NULL) {
|
||||||
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = appendDownstream(pOperator, pDownstream, numOfDownstream);
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&pInfo->ctrlInfo, &pPhyciNode->stbJoin, sizeof(pPhyciNode->stbJoin));
|
||||||
|
|
||||||
|
setOperatorInfo(pOperator, "DynQueryCtrlOperator", QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL, false, OP_NOT_OPENED, pInfo, pTaskInfo);
|
||||||
|
|
||||||
|
pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, getBlockFromDynQueryCtrl, NULL, destroyDynQueryCtrlOperator, optrDefaultBufFn, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
return pOperator;
|
||||||
|
|
||||||
|
_error:
|
||||||
|
if (pInfo != NULL) {
|
||||||
|
destroyDynQueryCtrlOperator(pInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
taosMemoryFree(pOperator);
|
||||||
|
pTaskInfo->code = code;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,14 +74,12 @@ static void destroyGroupCacheOperator(void* param) {
|
||||||
taosArrayDestroyEx(pGrpCacheOperator->pBlkBufs, freeGroupCacheBufPage);
|
taosArrayDestroyEx(pGrpCacheOperator->pBlkBufs, freeGroupCacheBufPage);
|
||||||
tSimpleHashCleanup(pGrpCacheOperator->pSessionHash);
|
tSimpleHashCleanup(pGrpCacheOperator->pSessionHash);
|
||||||
tSimpleHashCleanup(pGrpCacheOperator->pBlkHash);
|
tSimpleHashCleanup(pGrpCacheOperator->pBlkHash);
|
||||||
tSimpleHashCleanup(pGrpCacheOperator->downstreamInfo.pKey2Idx);
|
|
||||||
taosMemoryFree(pGrpCacheOperator->downstreamInfo.ppDownStream);
|
|
||||||
|
|
||||||
taosMemoryFreeClear(param);
|
taosMemoryFreeClear(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE int32_t addPageToGroupCacheBuf(SArray* pBlkBufs) {
|
static FORCE_INLINE int32_t addPageToGroupCacheBuf(SArray* pBlkBufs) {
|
||||||
SBufPageInfo page;
|
SGcBufPageInfo page;
|
||||||
page.pageSize = GROUP_CACHE_DEFAULT_PAGE_SIZE;
|
page.pageSize = GROUP_CACHE_DEFAULT_PAGE_SIZE;
|
||||||
page.offset = 0;
|
page.offset = 0;
|
||||||
page.data = taosMemoryMalloc(page.pageSize);
|
page.data = taosMemoryMalloc(page.pageSize);
|
||||||
|
@ -94,7 +92,7 @@ static FORCE_INLINE int32_t addPageToGroupCacheBuf(SArray* pBlkBufs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static FORCE_INLINE char* retrieveBlkFromBlkBufs(SArray* pBlkBufs, SGcBlkBufInfo* pBlkInfo) {
|
static FORCE_INLINE char* retrieveBlkFromBlkBufs(SArray* pBlkBufs, SGcBlkBufInfo* pBlkInfo) {
|
||||||
SBufPageInfo *pPage = taosArrayGet(pBlkBufs, pBlkInfo->pageId);
|
SGcBufPageInfo *pPage = taosArrayGet(pBlkBufs, pBlkInfo->pageId);
|
||||||
return pPage->data + pBlkInfo->offset;
|
return pPage->data + pBlkInfo->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +103,7 @@ static FORCE_INLINE char* moveRetrieveBlkFromBlkBufs(SArray* pBlkBufs, SGcBlkBuf
|
||||||
SGcBlkBufInfo* pCurr = (*ppLastBlk)->next;
|
SGcBlkBufInfo* pCurr = (*ppLastBlk)->next;
|
||||||
*ppLastBlk = pCurr;
|
*ppLastBlk = pCurr;
|
||||||
if (pCurr) {
|
if (pCurr) {
|
||||||
SBufPageInfo *pPage = taosArrayGet(pBlkBufs, pCurr->pageId);
|
SGcBufPageInfo *pPage = taosArrayGet(pBlkBufs, pCurr->pageId);
|
||||||
return pPage->data + pCurr->offset;
|
return pPage->data + pCurr->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +112,7 @@ static FORCE_INLINE char* moveRetrieveBlkFromBlkBufs(SArray* pBlkBufs, SGcBlkBuf
|
||||||
|
|
||||||
|
|
||||||
static int32_t initGroupCacheBufPages(SGroupCacheOperatorInfo* pInfo) {
|
static int32_t initGroupCacheBufPages(SGroupCacheOperatorInfo* pInfo) {
|
||||||
pInfo->pBlkBufs = taosArrayInit(32, sizeof(SBufPageInfo));
|
pInfo->pBlkBufs = taosArrayInit(32, sizeof(SGcBufPageInfo));
|
||||||
if (NULL == pInfo->pBlkBufs) {
|
if (NULL == pInfo->pBlkBufs) {
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
@ -128,47 +126,35 @@ static int32_t initGroupCacheDownstreamInfo(SGroupCachePhysiNode* pPhyciNode, SO
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
memcpy(pInfo->ppDownStream, pDownstream, numOfDownstream * POINTER_BYTES);
|
memcpy(pInfo->ppDownStream, pDownstream, numOfDownstream * POINTER_BYTES);
|
||||||
pInfo->pKey2Idx = tSimpleHashInit(numOfDownstream, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT));
|
|
||||||
if (NULL == pInfo->pKey2Idx) {
|
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < numOfDownstream; ++i) {
|
|
||||||
int32_t keyValue = taosArrayGet(pPhyciNode, i);
|
|
||||||
tSimpleHashPut(pInfo->pKey2Idx, &keyValue, sizeof(keyValue), &i, sizeof(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t initGroupCacheSession(SGroupCacheOperatorInfo* pGCache, SGcOperatorParam* pParam, SGcSessionCtx** ppSession) {
|
static int32_t initGroupCacheSession(struct SOperatorInfo* pOperator, SGcOperatorParam* pParam, SGcSessionCtx** ppSession) {
|
||||||
SGcSessionCtx ctx = {0};
|
SGcSessionCtx ctx = {0};
|
||||||
|
SGroupCacheOperatorInfo* pGCache = pOperator->info;
|
||||||
SGroupData* pGroup = tSimpleHashGet(pGCache->pBlkHash, pParam->pGroupValue, pParam->groupValueSize);
|
SGroupData* pGroup = tSimpleHashGet(pGCache->pBlkHash, pParam->pGroupValue, pParam->groupValueSize);
|
||||||
if (pGroup) {
|
if (pGroup) {
|
||||||
ctx.cacheHit = true;
|
ctx.cacheHit = true;
|
||||||
ctx.pLastBlk = pGroup->blks;
|
ctx.pLastBlk = pGroup->blks;
|
||||||
} else {
|
} else {
|
||||||
int32_t* pIdx = tSimpleHashGet(pGCache->downstreamInfo.pKey2Idx, &pParam->downstreamKey, sizeof(pParam->downstreamKey));
|
ctx.pDownstream = pOperator->pDownstream[pParam->downstreamIdx];
|
||||||
if (NULL == pIdx) {
|
|
||||||
qError("Invalid downstream key value: %d", pParam->downstreamKey);
|
|
||||||
return TSDB_CODE_INVALID_PARA;
|
|
||||||
}
|
|
||||||
ctx.pDownstream = pGCache->downstreamInfo.ppDownStream[*pIdx];
|
|
||||||
ctx.needCache = pParam->needCache;
|
ctx.needCache = pParam->needCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getFromSessionCache(SExecTaskInfo* pTaskInfo, SGroupCacheOperatorInfo* pGCache, SGcOperatorParam* pParam, SSDataBlock** ppRes, SGcSessionCtx** ppSession) {
|
static void getFromSessionCache(struct SOperatorInfo* pOperator, SGroupCacheOperatorInfo* pGCache, SGcOperatorParam* pParam, SSDataBlock** ppRes, SGcSessionCtx** ppSession) {
|
||||||
|
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||||
if (pParam->basic.newExec) {
|
if (pParam->basic.newExec) {
|
||||||
int32_t code = initGroupCacheSession(pGCache, pParam, ppSession);
|
int32_t code = initGroupCacheSession(pOperator, pParam, ppSession);
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
pTaskInfo->code = code;
|
pTaskInfo->code = code;
|
||||||
T_LONG_JMP(pTaskInfo->env, pTaskInfo->code);
|
T_LONG_JMP(pTaskInfo->env, pTaskInfo->code);
|
||||||
}
|
}
|
||||||
if ((*ppSession)->pLastBlk) {
|
if ((*ppSession)->pLastBlk) {
|
||||||
*ppRes = retrieveBlkFromBlkBufs(pGCache->pBlkBufs, (*ppSession)->pLastBlk);
|
*ppRes = (SSDataBlock*)retrieveBlkFromBlkBufs(pGCache->pBlkBufs, (*ppSession)->pLastBlk);
|
||||||
} else {
|
} else {
|
||||||
*ppRes = NULL;
|
*ppRes = NULL;
|
||||||
}
|
}
|
||||||
|
@ -184,7 +170,7 @@ static void getFromSessionCache(SExecTaskInfo* pTaskInfo, SGroupCacheOperatorInf
|
||||||
*ppSession = pCtx;
|
*ppSession = pCtx;
|
||||||
|
|
||||||
if (pCtx->cacheHit) {
|
if (pCtx->cacheHit) {
|
||||||
*ppRes = moveRetrieveBlkFromBlkBufs(pGCache->pBlkBufs, &pCtx->pLastBlk);
|
*ppRes = (SSDataBlock*)moveRetrieveBlkFromBlkBufs(pGCache->pBlkBufs, &pCtx->pLastBlk);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +209,7 @@ static SSDataBlock* getFromGroupCache(struct SOperatorInfo* pOperator, SOperator
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
getFromSessionCache(pTaskInfo, pGCache, pParam, &pRes, &pSession);
|
getFromSessionCache(pOperator, pGCache, pParam, &pRes, &pSession);
|
||||||
pGCache->pCurrent = pSession;
|
pGCache->pCurrent = pSession;
|
||||||
pGCache->pCurrentId = pParam->sessionId;
|
pGCache->pCurrentId = pParam->sessionId;
|
||||||
|
|
||||||
|
@ -283,8 +269,8 @@ SOperatorInfo* createGroupCacheOperatorInfo(SOperatorInfo** pDownstream, int32_t
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
code = initGroupCacheDownstreamInfo(pPhyciNode, pDownstream, numOfDownstream, &pInfo->downstreamInfo);
|
code = appendDownstream(pOperator, pDownstream, numOfDownstream);
|
||||||
if (code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -810,6 +810,11 @@ SOperatorInfo* createHashJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t n
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
code = appendDownstream(pOperator, pDownstream, numOfDownstream);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
goto _error;
|
||||||
|
}
|
||||||
|
|
||||||
pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doHashJoin, NULL, destroyHashJoinOperator, optrDefaultBufFn, NULL, NULL, NULL);
|
pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, doHashJoin, NULL, destroyHashJoinOperator, optrDefaultBufFn, NULL, NULL, NULL);
|
||||||
|
|
||||||
return pOperator;
|
return pOperator;
|
||||||
|
|
|
@ -1853,7 +1853,8 @@ enum {
|
||||||
PHY_NODE_CODE_LIMIT,
|
PHY_NODE_CODE_LIMIT,
|
||||||
PHY_NODE_CODE_SLIMIT,
|
PHY_NODE_CODE_SLIMIT,
|
||||||
PHY_NODE_CODE_INPUT_TS_ORDER,
|
PHY_NODE_CODE_INPUT_TS_ORDER,
|
||||||
PHY_NODE_CODE_OUTPUT_TS_ORDER
|
PHY_NODE_CODE_OUTPUT_TS_ORDER,
|
||||||
|
PHY_NODE_CODE_DYNAMIC_OP,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int32_t physiNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
static int32_t physiNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||||
|
@ -1878,6 +1879,9 @@ static int32_t physiNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tlvEncodeEnum(pEncoder, PHY_NODE_CODE_OUTPUT_TS_ORDER, pNode->outputTsOrder);
|
code = tlvEncodeEnum(pEncoder, PHY_NODE_CODE_OUTPUT_TS_ORDER, pNode->outputTsOrder);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = tlvEncodeBool(pEncoder, PHY_NODE_CODE_DYNAMIC_OP, pNode->dynamicOp);
|
||||||
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -1910,6 +1914,9 @@ static int32_t msgToPhysiNode(STlvDecoder* pDecoder, void* pObj) {
|
||||||
case PHY_NODE_CODE_OUTPUT_TS_ORDER:
|
case PHY_NODE_CODE_OUTPUT_TS_ORDER:
|
||||||
code = tlvDecodeEnum(pTlv, &pNode->outputTsOrder, sizeof(pNode->outputTsOrder));
|
code = tlvDecodeEnum(pTlv, &pNode->outputTsOrder, sizeof(pNode->outputTsOrder));
|
||||||
break;
|
break;
|
||||||
|
case PHY_NODE_CODE_DYNAMIC_OP:
|
||||||
|
code = tlvDecodeBool(pTlv, &pNode->dynamicOp);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3210,6 +3210,7 @@ static int32_t stbJoinOptCreateTableScanNodes(SLogicNode* pJoin, SNodeList** ppL
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pScan->node.dynamicOp = true;
|
pScan->node.dynamicOp = true;
|
||||||
|
pScan->scanType = SCAN_TYPE_TABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
|
|
@ -366,6 +366,7 @@ static SPhysiNode* makePhysiNode(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode
|
||||||
|
|
||||||
TSWAP(pPhysiNode->pLimit, pLogicNode->pLimit);
|
TSWAP(pPhysiNode->pLimit, pLogicNode->pLimit);
|
||||||
TSWAP(pPhysiNode->pSlimit, pLogicNode->pSlimit);
|
TSWAP(pPhysiNode->pSlimit, pLogicNode->pSlimit);
|
||||||
|
pPhysiNode->dynamicOp = pLogicNode->dynamicOp;
|
||||||
pPhysiNode->inputTsOrder = pLogicNode->inputTsOrder;
|
pPhysiNode->inputTsOrder = pLogicNode->inputTsOrder;
|
||||||
pPhysiNode->outputTsOrder = pLogicNode->outputTsOrder;
|
pPhysiNode->outputTsOrder = pLogicNode->outputTsOrder;
|
||||||
|
|
||||||
|
|
|
@ -1204,7 +1204,11 @@ static int32_t stbSplSplitJoinNodeImpl(SSplitContext* pCxt, SLogicSubplan* pSubp
|
||||||
SNode* pChild = NULL;
|
SNode* pChild = NULL;
|
||||||
FOREACH(pChild, pJoin->node.pChildren) {
|
FOREACH(pChild, pJoin->node.pChildren) {
|
||||||
if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pChild)) {
|
if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pChild)) {
|
||||||
|
if (pJoin->node.dynamicOp) {
|
||||||
|
code = TSDB_CODE_SUCCESS;
|
||||||
|
} else {
|
||||||
code = stbSplSplitMergeScanNode(pCxt, pSubplan, (SScanLogicNode*)pChild, false);
|
code = stbSplSplitMergeScanNode(pCxt, pSubplan, (SScanLogicNode*)pChild, false);
|
||||||
|
}
|
||||||
} else if (QUERY_NODE_LOGIC_PLAN_JOIN == nodeType(pChild)) {
|
} else if (QUERY_NODE_LOGIC_PLAN_JOIN == nodeType(pChild)) {
|
||||||
code = stbSplSplitJoinNodeImpl(pCxt, pSubplan, (SJoinLogicNode*)pChild);
|
code = stbSplSplitJoinNodeImpl(pCxt, pSubplan, (SJoinLogicNode*)pChild);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1220,7 +1224,9 @@ static int32_t stbSplSplitJoinNodeImpl(SSplitContext* pCxt, SLogicSubplan* pSubp
|
||||||
static int32_t stbSplSplitJoinNode(SSplitContext* pCxt, SStableSplitInfo* pInfo) {
|
static int32_t stbSplSplitJoinNode(SSplitContext* pCxt, SStableSplitInfo* pInfo) {
|
||||||
int32_t code = stbSplSplitJoinNodeImpl(pCxt, pInfo->pSubplan, (SJoinLogicNode*)pInfo->pSplitNode);
|
int32_t code = stbSplSplitJoinNodeImpl(pCxt, pInfo->pSubplan, (SJoinLogicNode*)pInfo->pSplitNode);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
if (!pInfo->pSplitNode->dynamicOp) {
|
||||||
pInfo->pSubplan->subplanType = SUBPLAN_TYPE_MERGE;
|
pInfo->pSubplan->subplanType = SUBPLAN_TYPE_MERGE;
|
||||||
|
}
|
||||||
SPLIT_FLAG_SET_MASK(pInfo->pSubplan->splitFlag, SPLIT_FLAG_STABLE_SPLIT);
|
SPLIT_FLAG_SET_MASK(pInfo->pSubplan->splitFlag, SPLIT_FLAG_STABLE_SPLIT);
|
||||||
}
|
}
|
||||||
return code;
|
return code;
|
||||||
|
|
Loading…
Reference in New Issue