enh: left join

This commit is contained in:
dapan1121 2023-12-08 15:27:22 +08:00
parent d7535f832a
commit 7fe919ad16
2 changed files with 164 additions and 119 deletions

View File

@ -53,25 +53,9 @@ typedef struct SMJoinColInfo {
char* bitMap; char* bitMap;
} SMJoinColInfo; } SMJoinColInfo;
typedef struct SMJoinCartGrp {
bool sameTsGrp;
bool firstArrIdx;
bool secondArrIdx;
int32_t firstRowIdx;
int32_t firstRowNum;
int32_t secondRowIdx;
int32_t secondRowNum;
} SMJoinCartGrp;
typedef struct SMJoinCartBlk {
SSDataBlock* pFirstBlk;
SSDataBlock* pSecondBlk;
SArray* pBlkGrps;
} SMJoinCartBlk;
typedef struct SMJoinCartCtx { typedef struct SMJoinCartCtx {
bool appendRes; bool appendRes;
bool firstOnly;
int32_t resThreshold; int32_t resThreshold;
SSDataBlock* pResBlk; SSDataBlock* pResBlk;
@ -80,12 +64,17 @@ typedef struct SMJoinCartCtx {
int32_t secondColNum; int32_t secondColNum;
SMJoinColMap* pSecondCols; SMJoinColMap* pSecondCols;
SArray* pCartRowIdx; SMJoinBlkInfo* pFirstBlk;
SArray* pCartBlks; SMJoinBlkInfo* pSecondBlk;
int32_t firstRowIdx;
int32_t firstRowNum;
int32_t secondRowIdx;
int32_t secondRowNum;
} SMJoinCartCtx; } SMJoinCartCtx;
typedef struct SMJoinBlkInfo { typedef struct SMJoinBlkInfo {
bool cloned; bool cloned;
bool inUse;
SSDataBlock* pBlk; SSDataBlock* pBlk;
void* pNext; void* pNext;
} SMJoinBlkInfo; } SMJoinBlkInfo;
@ -142,41 +131,44 @@ typedef struct SMJoinTsJoinCtx {
} SMJoinTsJoinCtx; } SMJoinTsJoinCtx;
typedef struct SBuildGrpResIn { typedef struct SBuildGrpResIn {
bool multiBlkGrp; bool multiBlk;
SMJoinBlkInfo* grpBeginBlk; SMJoinBlkInfo* pBeginBlk;
int32_t grpRowBeginIdx; int32_t rowBeginIdx;
int32_t grpRowNum; int32_t rowNum;
} SBuildGrpResIn; } SBuildGrpResIn;
typedef struct SBuildGrpResOut { typedef struct SBuildGrpResOut {
SSHashObj* pGrpHash; SSHashObj* pHash;
int32_t grpRowReadIdx; SMJoinBlkInfo* pCurrBlk;
int32_t grpRowGReadIdx; int32_t rowReadIdx;
int32_t rowGReadNum;
} SBuildGrpResOut; } SBuildGrpResOut;
typedef struct SProbeGrpResIn { typedef struct SProbeGrpResIn {
bool allRowsGrp; bool allRowsGrp;
SMJoinBlkInfo* grpBeginBlk; SMJoinBlkInfo* pBeginBlk;
int32_t grpRowBeginIdx; int32_t rowBeginIdx;
int32_t grpRowNum; int32_t rowNum;
int64_t grpLastTs; int64_t grpLastTs;
} SProbeGrpResIn; } SProbeGrpResIn;
typedef struct SProbeGrpResOut { typedef struct SProbeGrpResOut {
int32_t grpRowReadIdx; SMJoinBlkInfo* pCurrBlk;
int32_t rowReadIdx;
int32_t rowGReadNum;
} SProbeGrpResOut; } SProbeGrpResOut;
typedef struct SGrpPairRes { typedef struct SGrpPairRes {
bool sameTsGrp; bool sameTsGrp;
bool finishGrp; bool finishGrp;
bool hashJoin; bool hashJoin;
SProbeGrpResIn probeIn; SProbeGrpResIn prbIn;
SBuildGrpResIn buildIn; SBuildGrpResIn bldIn;
/* KEEP THIS PART AT THE END */ /* KEEP THIS PART AT THE END */
bool outBegin; bool outBegin;
SBuildGrpResOut buildOut; SBuildGrpResOut bldOut;
SProbeGrpResOut probeOut; SProbeGrpResOut prbOut;
/* KEEP THIS PART AT THE END */ /* KEEP THIS PART AT THE END */
} SGrpPairRes; } SGrpPairRes;
@ -269,10 +261,12 @@ typedef struct SMJoinOperatorInfo {
#define START_NEW_GRP(_ctx) memset(&(_ctx)->currGrpPair, 0, GRP_PAIR_INIT_SIZE) #define START_NEW_GRP(_ctx) memset(&(_ctx)->currGrpPair, 0, GRP_PAIR_INIT_SIZE)
#define REACH_HJOIN_THRESHOLD(_pair) ((_pair)->buildIn.grpRowNum * (_pair)->probeIn.grpRowNum > MJOIN_HJOIN_CART_THRESHOLD) #define REACH_HJOIN_THRESHOLD(_pair) ((_pair)->buildIn.rowNum * (_pair)->probeIn.rowNum > MJOIN_HJOIN_CART_THRESHOLD)
#define SET_SAME_TS_GRP_HJOIN(_pair, _octx) ((_pair)->hashJoin = (_octx)->hashCan && REACH_HJOIN_THRESHOLD(_pair)) #define SET_SAME_TS_GRP_HJOIN(_pair, _octx) ((_pair)->hashJoin = (_octx)->hashCan && REACH_HJOIN_THRESHOLD(_pair))
#define BUILD_TB_BROKEN_BLK(_sg, _out, _in) ((_sg) && (((_out)->pCurrBlk == (_in)->pBeginBlk && (_out)->rowReadIdx != (_in)->rowBeginIdx) || ((_out)->pCurrBlk != (_in)->pBeginBlk && (_out)->rowReadIdx != 0)))
#define FIN_SAME_TS_GRP(_ctx, _octx, _done) do { \ #define FIN_SAME_TS_GRP(_ctx, _octx, _done) do { \
if ((_ctx)->inSameTsGrp) { \ if ((_ctx)->inSameTsGrp) { \
(_ctx)->currGrpPair.sameTsGrp = true; \ (_ctx)->currGrpPair.sameTsGrp = true; \
@ -298,7 +292,8 @@ typedef struct SMJoinOperatorInfo {
} \ } \
} while (0) } while (0)
#define CURRENT_BLK_GRP_ROWS(_in) (((_in)->grpRowNum + (_in)->grpRowBeginIdx) <= (_in)->grpBeginBlk->pBlk->info.rows ? (_in)->grpRowNum : ((_in)->grpBeginBlk->pBlk->info.rows - (_in)->grpRowBeginIdx)) #define PRB_CUR_BLK_GRP_ROWS(_rn, _rb, _bn) (((_rn) + (_rb)) <= (_bn) ? (_rn) : ((_bn) - (_rb)))
#define BLD_CUR_BLK_GRP_ROWS(_sg, _rn, _rb, _bn) ((_sg) ? 1 : (((_rn) + (_rb)) <= (_bn) ? (_rn) : ((_bn) - (_rb))))
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -320,15 +320,6 @@ static int32_t mJoinInitMergeCtx(SOperatorInfo* pOperator, SMJoinOperatorInfo* p
pCtx->outputCtx.cartCtx.secondColNum = pBuildCtx->pTbInfo->finNum; pCtx->outputCtx.cartCtx.secondColNum = pBuildCtx->pTbInfo->finNum;
pCtx->outputCtx.cartCtx.pSecondCols = pBuildCtx->pTbInfo->finCols; pCtx->outputCtx.cartCtx.pSecondCols = pBuildCtx->pTbInfo->finCols;
pCtx->outputCtx.cartCtx.pCartRowIdx = taosArrayInit(MJOIN_DEFAULT_BUFF_BLK_ROWS_NUM, sizeof(int32_t));
if (NULL == pCtx->outputCtx.cartCtx.pCartRowIdx) {
return TSDB_CODE_OUT_OF_MEMORY;
}
pCtx->outputCtx.cartCtx.pCartGrps = taosArrayInit(MJOIN_DEFAULT_BUFF_BLK_ROWS_NUM, sizeof(SMJoinCartGrp));
if (NULL == pCtx->outputCtx.cartCtx.pCartGrps) {
return TSDB_CODE_OUT_OF_MEMORY;
}
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
@ -358,7 +349,10 @@ static int32_t mJoinAddBlkToList(SMJoinOperatorInfo* pJoin, SMJoinTableCtx* pCtx
if (NULL == pNew) { if (NULL == pNew) {
return TSDB_CODE_OUT_OF_MEMORY; return TSDB_CODE_OUT_OF_MEMORY;
} }
pNew->pBlk = pBlock; pNew->pBlk = pBlock;
pNew->inUse = true;
if (NULL == pCtx->pTailBlk) { if (NULL == pCtx->pTailBlk) {
pCtx->pTailBlk = pCtx->pHeadBlk = pNew; pCtx->pTailBlk = pCtx->pHeadBlk = pNew;
pCtx->pCurrBlk = pCtx->pHeadBlk; pCtx->pCurrBlk = pCtx->pHeadBlk;
@ -493,13 +487,13 @@ static void mJoinLeftJoinAddBlkToGrp(SMJoinOperatorInfo* pJoin, SMJoinTsJoinCtx*
int32_t rowNum = pProbeCtx->pCurrBlk->pBlk->info.rows - pProbeCtx->blkRowIdx; int32_t rowNum = pProbeCtx->pCurrBlk->pBlk->info.rows - pProbeCtx->blkRowIdx;
if (pCtx->nextProbeRow && pCtx->inDiffTsGrp) { if (pCtx->nextProbeRow && pCtx->inDiffTsGrp) {
pCtx->currGrpPair->probeIn.grpRowNum += rowNum; pCtx->currGrpPair->prbIn.rowNum += rowNum;
} else { } else {
pCtx->inDiffTsGrp = true; pCtx->inDiffTsGrp = true;
START_NEW_GRP(pCtx); START_NEW_GRP(pCtx);
pCtx->currGrpPair.probeIn.grpBeginBlk = pProbeCtx->pCurrBlk; pCtx->currGrpPair.prbIn.pBeginBlk = pProbeCtx->pCurrBlk;
pCtx->currGrpPair.probeIn.grpRowBeginIdx = pProbeCtx->blkRowIdx; pCtx->currGrpPair.prbIn.rowBeginIdx = pProbeCtx->blkRowIdx;
pCtx->currGrpPair->probeIn.grpRowNum = rowNum; pCtx->currGrpPair->prbIn.rowNum = rowNum;
} }
pCtx->nextProbeRow = true; pCtx->nextProbeRow = true;
@ -531,6 +525,7 @@ static bool mJoinBuildMoveToNextBlk(SMJoinOperatorInfo* pJoin, SMJoinTsJoinCtx*
contLoop = mJoinProbeMoveToNextBlk(pCtx, pProbeCtx); contLoop = mJoinProbeMoveToNextBlk(pCtx, pProbeCtx);
} else if (pCtx->probeTs[pProbeCtx->blkRowIdx] > *pCtx->buildEndTs) { } else if (pCtx->probeTs[pProbeCtx->blkRowIdx] > *pCtx->buildEndTs) {
contLoop = true; contLoop = true;
pBuildCtx->pCurrBlk->inUse = false;
break; break;
} else { } else {
contLoop = false; contLoop = false;
@ -563,8 +558,8 @@ static bool mLeftJoinSplitGrpImpl(SOperatorInfo* pOperator, SMJoinOperatorInfo*
for (; pProbeCtx->blkRowIdx < pCtx->probeRowNum; ++pProbeCtx->blkRowIdx) { for (; pProbeCtx->blkRowIdx < pCtx->probeRowNum; ++pProbeCtx->blkRowIdx) {
if (pCtx->pLastGrpPair && pCtx->pLastGrpPair->sameTsGrp if (pCtx->pLastGrpPair && pCtx->pLastGrpPair->sameTsGrp
&& pCtx->probeTs[pProbeCtx->blkRowIdx] == pCtx->pLastGrpPair->probeIn.grpLastTs) { && pCtx->probeTs[pProbeCtx->blkRowIdx] == pCtx->pLastGrpPair->prbIn.grpLastTs) {
pCtx->pLastGrpPair->probeIn.grpRowNum++; pCtx->pLastGrpPair->prbIn.rowNum++;
SET_SAME_TS_GRP_HJOIN(pCtx->pLastGrpPair, pOutCtx); SET_SAME_TS_GRP_HJOIN(pCtx->pLastGrpPair, pOutCtx);
continue; continue;
} }
@ -578,29 +573,29 @@ static bool mLeftJoinSplitGrpImpl(SOperatorInfo* pOperator, SMJoinOperatorInfo*
} else if (pCtx->probeTs[pProbeCtx->blkRowIdx] == pCtx->buildTs[pBuildCtx->blkRowIdx]) { } else if (pCtx->probeTs[pProbeCtx->blkRowIdx] == pCtx->buildTs[pBuildCtx->blkRowIdx]) {
FIN_DIFF_TS_GRP(pCtx, pOutCtx, false); FIN_DIFF_TS_GRP(pCtx, pOutCtx, false);
if (pCtx->inSameTsGrp) { if (pCtx->inSameTsGrp) {
pCtx->currGrpPair.buildIn.grpRowNum++; pCtx->currGrpPair.bldIn.rowNum++;
} else { } else {
pCtx->inSameTsGrp = true; pCtx->inSameTsGrp = true;
START_NEW_GRP(pCtx); START_NEW_GRP(pCtx);
pCtx->currGrpPair.buildIn.grpBeginBlk = pBuildCtx->pCurrBlk; pCtx->currGrpPair.bldIn.pBeginBlk = pBuildCtx->pCurrBlk;
pCtx->currGrpPair.buildIn.grpRowBeginIdx = pBuildCtx->blkRowIdx; pCtx->currGrpPair.bldIn.rowBeginIdx = pBuildCtx->blkRowIdx;
pCtx->currGrpPair.buildIn.grpRowNum = 1; pCtx->currGrpPair.bldIn.rowNum = 1;
pCtx->currGrpPair.probeIn.grpBeginBlk = pProbeCtx->pCurrBlk; pCtx->currGrpPair.prbIn.pBeginBlk = pProbeCtx->pCurrBlk;
pCtx->currGrpPair.probeIn.grpLastTs = pCtx->probeTs[pProbeCtx->blkRowIdx]; pCtx->currGrpPair.prbIn.grpLastTs = pCtx->probeTs[pProbeCtx->blkRowIdx];
pCtx->currGrpPair.probeIn.grpRowBeginIdx = pProbeCtx->blkRowIdx; pCtx->currGrpPair.prbIn.rowBeginIdx = pProbeCtx->blkRowIdx;
pCtx->currGrpPair.probeIn.grpRowNum = 1; pCtx->currGrpPair.prbIn.rowNum = 1;
} }
pCtx->nextProbeRow = false; pCtx->nextProbeRow = false;
} else { } else {
FIN_SAME_TS_GRP(pCtx, pOutCtx, true); FIN_SAME_TS_GRP(pCtx, pOutCtx, true);
if (pCtx->inDiffTsGrp) { if (pCtx->inDiffTsGrp) {
pCtx->currGrpPair.probeIn.grpRowNum++; pCtx->currGrpPair.prbIn.rowNum++;
} else { } else {
pCtx->inDiffTsGrp = true; pCtx->inDiffTsGrp = true;
START_NEW_GRP(pCtx); START_NEW_GRP(pCtx);
pCtx->currGrpPair.probeIn.grpBeginBlk = pProbeCtx->pCurrBlk; pCtx->currGrpPair.prbIn.pBeginBlk = pProbeCtx->pCurrBlk;
pCtx->currGrpPair.probeIn.grpRowBeginIdx = pProbeCtx->blkRowIdx; pCtx->currGrpPair.prbIn.rowBeginIdx = pProbeCtx->blkRowIdx;
pCtx->currGrpPair.probeIn.grpRowNum = 1; pCtx->currGrpPair.prbIn.rowNum = 1;
} }
pCtx->nextProbeRow = true; pCtx->nextProbeRow = true;
break; break;
@ -654,7 +649,8 @@ static bool mLeftJoinSplitGrp(SOperatorInfo* pOperator, SMJoinOperatorInfo* pJoi
if (0 == pJoin->ctx.mergeCtx.buildTbCtx.blkNum) { if (0 == pJoin->ctx.mergeCtx.buildTbCtx.blkNum) {
ASSERTS(pJoin->ctx.mergeCtx.buildTbCtx.dsFetchDone, "left join empty build table while fetch not done"); ASSERTS(pJoin->ctx.mergeCtx.buildTbCtx.dsFetchDone, "left join empty build table while fetch not done");
FIN_SAME_TS_GRP(pCtx, &pJoin->ctx.mergeCtx.outputCtx, true);
FIN_DIFF_TS_GRP(pCtx, &pJoin->ctx.mergeCtx.outputCtx, pJoin->ctx.mergeCtx.buildTbCtx.dsFetchDone); FIN_DIFF_TS_GRP(pCtx, &pJoin->ctx.mergeCtx.outputCtx, pJoin->ctx.mergeCtx.buildTbCtx.dsFetchDone);
} else { } else {
mLeftJoinSplitGrpImpl(pOperator, pJoin); mLeftJoinSplitGrpImpl(pOperator, pJoin);
@ -670,7 +666,7 @@ static void mLeftJoinCart(SMJoinCartCtx* pCtx) {
for (int32_t c = 0; c < pCtx->firstColNum; ++c) { for (int32_t c = 0; c < pCtx->firstColNum; ++c) {
SMJoinColMap* pFirstCol = pCtx->pFirstCols + c; SMJoinColMap* pFirstCol = pCtx->pFirstCols + c;
SColumnInfoData* pInCol = taosArrayGet(pCtx->pFirstBlk->pDataBlock, pFirstCol->srcSlot); SColumnInfoData* pInCol = taosArrayGet(pCtx->pFirstBlk->pBlk, pFirstCol->srcSlot);
SColumnInfoData* pOutCol = taosArrayGet(pCtx->pResBlk->pDataBlock, pFirstCol->dstSlot); SColumnInfoData* pOutCol = taosArrayGet(pCtx->pResBlk->pDataBlock, pFirstCol->dstSlot);
for (int32_t r = 0; r < pCtx->firstRowNum; ++r) { for (int32_t r = 0; r < pCtx->firstRowNum; ++r) {
if (colDataIsNull_s(pInCol, pCtx->firstRowIdx + r)) { if (colDataIsNull_s(pInCol, pCtx->firstRowIdx + r)) {
@ -681,33 +677,44 @@ static void mLeftJoinCart(SMJoinCartCtx* pCtx) {
} }
} }
for (int32_t c = 0; c < pCtx->secondColNum; ++c) { if (pCtx->firstOnly) {
SMJoinColMap* pSecondCol = pCtx->pSecondCols + c; ASSERT(1 == pCtx->secondRowNum);
SColumnInfoData* pInCol = taosArrayGet(pCtx->pSecondBlk->pDataBlock, pSecondCol->srcSlot); for (int32_t c = 0; c < pCtx->secondColNum; ++c) {
SColumnInfoData* pOutCol = taosArrayGet(pCtx->pResBlk->pDataBlock, pSecondCol->dstSlot); SMJoinColMap* pSecondCol = pCtx->pSecondCols + c;
for (int32_t r = 0; r < pCtx->firstRowNum; ++r) { SColumnInfoData* pOutCol = taosArrayGet(pCtx->pResBlk->pDataBlock, pSecondCol->dstSlot);
colDataAssignNRows(pOutCol, currRows + r * pCtx->secondRowNum, pInCol, pCtx->secondRowIdx, pCtx->secondRowNum); colDataSetNItemsNull(pOutCol, currRows, pCtx->firstRowNum);
}
} else {
for (int32_t c = 0; c < pCtx->secondColNum; ++c) {
SMJoinColMap* pSecondCol = pCtx->pSecondCols + c;
SColumnInfoData* pInCol = taosArrayGet(pCtx->pSecondBlk->pBlk, pSecondCol->srcSlot);
SColumnInfoData* pOutCol = taosArrayGet(pCtx->pResBlk->pDataBlock, pSecondCol->dstSlot);
for (int32_t r = 0; r < pCtx->firstRowNum; ++r) {
colDataAssignNRows(pOutCol, currRows + r * pCtx->secondRowNum, pInCol, pCtx->secondRowIdx, pCtx->secondRowNum);
}
} }
} }
pCtx->pResBlk.info.rows += pCtx->firstRowNum * pCtx->secondRowNum;
} }
static bool mLeftJoinSameTsOutput(SMJoinOperatorInfo* pJoin, SGrpPairRes* pPair) { static bool mLeftJoinSameTsOutput(SMJoinOperatorInfo* pJoin, SGrpPairRes* pPair) {
SProbeGrpResIn* pProbeIn = &pPair->probeIn; SProbeGrpResIn* pProbeIn = &pPair->prbIn;
SBuildGrpResIn* pBuildIn = &pPair->buildIn; SBuildGrpResIn* pBuildIn = &pPair->prbIn;
if (!pPair->outBegin) { if (!pPair->outBegin) {
} }
SMJoinBlkInfo* pBInfo = pProbeIn->grpBeginBlk; SMJoinBlkInfo* pBInfo = pProbeIn->pBeginBlk;
do { do {
if (pJoin->prevFilter) { if (pJoin->prevFilter) {
} else { } else {
if (pPair->buildOut.hashJoin) { if (pPair->bldOut.hashJoin) {
} else { } else {
for (; pProbeIn->grpRowBeginIdx < pBInfo->pBlk->info.rows && pProbeIn->grpRowNum > 0; pProbeIn->grpRowBeginIdx++, pProbeIn->grpRowNum--) { for (; pProbeIn->rowBeginIdx < pBInfo->pBlk->info.rows && pProbeIn->rowNum > 0; pProbeIn->rowBeginIdx++, pProbeIn->rowNum--) {
} }
} }
@ -719,64 +726,107 @@ static bool mLeftJoinCartOutput(SMJoinOperatorInfo* pJoin, SMJoinOutputCtx* pCtx
bool contLoop = false; bool contLoop = false;
SMJoinCartCtx* pCart = &pCtx->cartCtx; SMJoinCartCtx* pCart = &pCtx->cartCtx;
int32_t grpNum = taosArrayGetSize(pCtx->pGrpResList); int32_t grpNum = taosArrayGetSize(pCtx->pGrpResList);
int32_t rowsLeft = pCart->pResBlk pCart->pResBlk->info.rows; int32_t rowsLeft = pCart->pResBlk->info.capacity - pCart->pResBlk->info.rows;
int32_t probeRows = 0;
int32_t buildRows = 0;
bool grpDone = false, brokenBlk = false;
for (; pCtx->grpReadIdx < grpNum; pCtx->grpReadIdx++) { for (; pCtx->grpReadIdx < grpNum && pCart->pResBlk->info.rows <= pCart->resThreshold; pCtx->grpReadIdx++) {
SGrpPairRes* pPair = taosArrayGet(pCtx->pGrpResList, pCtx->grpReadIdx); SGrpPairRes* pair = taosArrayGet(pCtx->pGrpResList, pCtx->grpReadIdx);
if (!pPair->finishGrp) { if (!pair->finishGrp) {
ASSERTS(pCtx->grpReadIdx == grpNum - 1, "unfinished grp not the last"); ASSERTS(pCtx->grpReadIdx == grpNum - 1, "unfinished grp not the last");
taosArrayRemoveBatch(pCtx->pGrpResList, 0, pCtx->grpReadIdx - 1, NULL); taosArrayRemoveBatch(pCtx->pGrpResList, 0, pCtx->grpReadIdx - 1, NULL);
pCtx->grpReadIdx = 0; pCtx->grpReadIdx = 0;
break; break;
} }
if (pPair->hashJoin) { grpDone = false;
contLoop = mLeftJoinHashOutput(pJoin, pPair); pCart->firstOnly = !pair->sameTsGrp;
} else if (pCtx->cartCtx.appendRes) { do {
contLoop = mLeftJoinDirectOutput(pJoin, pPair); if (!pair->outBegin) {
} probeRows = PRB_CUR_BLK_GRP_ROWS(pair->prbIn.rowNum, pair->prbIn.rowBeginIdx, pair->prbIn.pBeginBlk->pBlk->info.rows);
buildRows = BLD_CUR_BLK_GRP_ROWS(pair->sameTsGrp, pair->bldIn.rowNum, pair->bldIn.rowBeginIdx, pair->bldIn.pBeginBlk->pBlk->info.rows);
pCart->pFirstBlk = pair->prbIn.pBeginBlk;
pCart->firstRowIdx = pair->prbIn.rowBeginIdx;
pair->prbOut.pCurrBlk = pair->prbIn.pBeginBlk;
if (pair->sameTsGrp) {
pCart->pSecondBlk = pair->bldIn.pBeginBlk;
pCart->secondRowIdx = pair->bldIn.rowBeginIdx;
pair->bldOut.pCurrBlk = pair->bldIn.pBeginBlk;
}
pair->outBegin = true;
brokenBlk = false;
} else if (BUILD_TB_BROKEN_BLK(pair->sameTsGrp, &pair->bldOut, &pair->bldIn)) {
probeRows = PRB_CUR_BLK_GRP_ROWS(1, pair->prbOut.rowReadIdx, pair->prbOut.pCurrBlk->pBlk.info.rows);
buildRows = BLD_CUR_BLK_GRP_ROWS(pair->bldIn.rowNum - pair->bldOut.rowGReadNum, pair->bldOut.rowReadIdx, pair->bldOut.pCurrBlk->pBlk.info.rows);
pCart->firstRowIdx = pair->prbOut.rowReadIdx;
pCart->secondRowIdx = pair->bldOut.rowReadIdx;
brokenBlk = true;
} else {
probeRows = PRB_CUR_BLK_GRP_ROWS(pair->prbIn.rowNum - pair->prbOut.rowGReadNum, pair->prbOut.rowReadIdx, pair->prbOut.pCurrBlk->pBlk.info.rows);
buildRows = BLD_CUR_BLK_GRP_ROWS(pair->bldIn.rowNum - pair->bldOut.rowGReadNum, pair->bldOut.rowReadIdx, pair->bldOut.pCurrBlk->pBlk.info.rows);
pCart->firstRowIdx = pair->prbOut.rowReadIdx;
if (pair->sameTsGrp) {
pCart->secondRowIdx = pair->bldOut.rowReadIdx;
}
brokenBlk = false;
}
if (!contLoop) { int64_t reqNum = probeRows * buildRows;
return false; if (reqNum <= rowsLeft) {
} pCart->firstRowNum = probeRows;
} pCart->secondRowNum = buildRows;
} pair->prbOut.rowGReadNum += probeRows;
if (!brokenBlk) {
pair->prbOut.rowReadIdx = 0;
static bool mLeftJoinOutput(SOperatorInfo* pOperator, SMJoinOperatorInfo* pJoin) { if (pair->sameTsGrp) {
SMJoinOutputCtx* pCtx = &pJoin->ctx.mergeCtx.outputCtx; pair->bldOut.rowGReadNum += buildRows;
bool contLoop = false; pair->bldOut.rowReadIdx = 0;
int32_t grpNum = taosArrayGetSize(pCtx->pGrpResList); }
} else {
pair->prbOut.rowReadIdx += probeRows;
}
if (pCtx->cartCtx.appendRes) { if (pair->prbOut.rowGReadNum >= pair->prbIn.rowNum) {
return mLeftJoinCartOutput(pJoin, pCtx); grpDone = true;
} }
for (; pCtx->grpReadIdx < grpNum; pCtx->grpReadIdx++) { rowsLeft -= reqNum;
SGrpPairRes* pPair = taosArrayGet(pCtx->pGrpResList, pCtx->grpReadIdx); } else if (buildRows <= rowsLeft) {
if (!pPair->finishGrp) { pCart->firstRowNum = brokenBlk ? 1 : (rowsLeft / buildRows);
ASSERTS(pCtx->grpReadIdx == grpNum - 1, "unfinished grp not the last");
taosArrayRemoveBatch(pCtx->pGrpResList, 0, pCtx->grpReadIdx - 1, NULL); pair->prbOut.rowGReadNum += pCart->firstRowNum;
pCtx->grpReadIdx = 0; pair->prbOut.rowReadIdx = pCart->firstRowIdx + pCart->firstRowNum;
pCart->secondRowNum = buildRows;
pair->bldOut.rowReadIdx = 0;
rowsLeft -= (pCart->firstRowNum * pCart->secondRowNum);
} else {
ASSERT(pair->sameTsGrp);
pCart->firstRowNum = 1;
pCart->secondRowNum = rowsLeft;
pair->bldOut.rowReadIdx = pCart->secondRowIdx + rowsLeft;
rowsLeft = 0;
}
mLeftJoinCart(pCart);
}while ((!grpDone) && pCart->pResBlk->info.rows <= pCart->resThreshold);
if (!grpDone) {
break; break;
} }
if (pPair->hashJoin) {
contLoop = mLeftJoinHashOutput(pJoin, pPair);
} else if (pCtx->cartCtx.appendRes) {
contLoop = mLeftJoinDirectOutput(pJoin, pPair);
}
if (!contLoop) {
return false;
}
} }
pJoin->ctx.mergeCtx.joinPhase = E_JOIN_PHASE_RETRIEVE;
return true;
} }
static SSDataBlock* mJoinDoLeftJoin(SOperatorInfo* pOperator, SMJoinOperatorInfo* pJoin) { static SSDataBlock* mJoinDoLeftJoin(SOperatorInfo* pOperator, SMJoinOperatorInfo* pJoin) {
bool contLoop = false; bool contLoop = false;