fix: add left join case
This commit is contained in:
parent
6d24c08651
commit
e55b7c52d8
|
@ -191,26 +191,29 @@ static int32_t doCopyNItems(struct SColumnInfoData* pColumnInfoData, int32_t cur
|
|||
}
|
||||
|
||||
size_t start = 1;
|
||||
|
||||
// the first item
|
||||
memcpy(pColumnInfoData->pData, pData, itemLen);
|
||||
|
||||
int32_t t = 0;
|
||||
int32_t count = log(numOfRows) / log(2);
|
||||
uint32_t startOffset = (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) ? pColumnInfoData->varmeta.length : (currentRow * itemLen);
|
||||
|
||||
// the first item
|
||||
memcpy(pColumnInfoData->pData + startOffset, pData, itemLen);
|
||||
|
||||
while (t < count) {
|
||||
int32_t xlen = 1 << t;
|
||||
memcpy(pColumnInfoData->pData + start * itemLen + pColumnInfoData->varmeta.length, pColumnInfoData->pData,
|
||||
memcpy(pColumnInfoData->pData + start * itemLen + startOffset,
|
||||
pColumnInfoData->pData + startOffset,
|
||||
xlen * itemLen);
|
||||
t += 1;
|
||||
start += xlen;
|
||||
}
|
||||
|
||||
|
||||
// the tail part
|
||||
if (numOfRows > start) {
|
||||
memcpy(pColumnInfoData->pData + start * itemLen + currentRow * itemLen, pColumnInfoData->pData,
|
||||
memcpy(pColumnInfoData->pData + start * itemLen + startOffset,
|
||||
pColumnInfoData->pData + startOffset,
|
||||
(numOfRows - start) * itemLen);
|
||||
}
|
||||
|
||||
|
||||
if (IS_VAR_DATA_TYPE(pColumnInfoData->info.type)) {
|
||||
for (int32_t i = 0; i < numOfRows; ++i) {
|
||||
pColumnInfoData->varmeta.offset[i + currentRow] = pColumnInfoData->varmeta.length + i * itemLen;
|
||||
|
|
|
@ -191,15 +191,18 @@ typedef struct SMJoinOperatorInfo {
|
|||
#define GRP_REMAIN_ROWS(_grp) ((_grp)->endIdx - (_grp)->readIdx + 1)
|
||||
#define GRP_DONE(_grp) ((_grp)->readIdx > (_grp)->endIdx)
|
||||
|
||||
#define MJOIN_TB_ROWS_DONE(_tb) ((_tb)->blkRowIdx >= (_tb)->blk->info.rows)
|
||||
#define MJOIN_PROBE_TB_ROWS_DONE(_tb) ((_tb)->blkRowIdx >= (_tb)->blk->info.rows)
|
||||
#define MJOIN_BUILD_TB_ROWS_DONE(_tb) ((NULL == (_tb)->blk) || ((_tb)->blkRowIdx >= (_tb)->blk->info.rows))
|
||||
|
||||
#define BLK_IS_FULL(_blk) ((_blk)->info.rows == (_blk)->info.capacity)
|
||||
|
||||
|
||||
#define MJOIN_GET_TB_COL_TS(_col, _ts, _tb) \
|
||||
do { \
|
||||
(_col) = taosArrayGet((_tb)->blk->pDataBlock, (_tb)->primCol->srcSlot); \
|
||||
(_ts) = *((int64_t*)(_col)->pData + (_tb)->blkRowIdx); \
|
||||
#define MJOIN_GET_TB_COL_TS(_col, _ts, _tb) \
|
||||
do { \
|
||||
if (NULL != (_tb)->blk) { \
|
||||
(_col) = taosArrayGet((_tb)->blk->pDataBlock, (_tb)->primCol->srcSlot); \
|
||||
(_ts) = *((int64_t*)(_col)->pData + (_tb)->blkRowIdx); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define MJOIN_GET_TB_CUR_TS(_col, _ts, _tb) \
|
||||
|
|
|
@ -61,28 +61,37 @@ static int32_t mJoinInitPrimKeyInfo(SMJoinTableCtx* pTable, int32_t slotId) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mJoinInitKeyColsInfo(SMJoinTableCtx* pTable, SNodeList* pList) {
|
||||
pTable->keyNum = LIST_LENGTH(pList);
|
||||
static int32_t mJoinInitColsInfo(int32_t* colNum, int64_t* rowSize, SMJoinColInfo** pCols, SNodeList* pList) {
|
||||
*colNum = LIST_LENGTH(pList);
|
||||
|
||||
pTable->keyCols = taosMemoryMalloc(pTable->keyNum * sizeof(SMJoinColInfo));
|
||||
if (NULL == pTable->keyCols) {
|
||||
*pCols = taosMemoryMalloc((*colNum) * sizeof(SMJoinColInfo));
|
||||
if (NULL == *pCols) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
int64_t bufSize = 0;
|
||||
*rowSize = 0;
|
||||
|
||||
int32_t i = 0;
|
||||
SNode* pNode = NULL;
|
||||
FOREACH(pNode, pList) {
|
||||
SColumnNode* pColNode = (SColumnNode*)pNode;
|
||||
pTable->keyCols[i].srcSlot = pColNode->slotId;
|
||||
pTable->keyCols[i].vardata = IS_VAR_DATA_TYPE(pColNode->node.resType.type);
|
||||
pTable->keyCols[i].bytes = pColNode->node.resType.bytes;
|
||||
bufSize += pColNode->node.resType.bytes;
|
||||
(*pCols)[i].srcSlot = pColNode->slotId;
|
||||
(*pCols)[i].vardata = IS_VAR_DATA_TYPE(pColNode->node.resType.type);
|
||||
(*pCols)[i].bytes = pColNode->node.resType.bytes;
|
||||
*rowSize += pColNode->node.resType.bytes;
|
||||
++i;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int32_t mJoinInitKeyColsInfo(SMJoinTableCtx* pTable, SNodeList* pList) {
|
||||
int64_t rowSize = 0;
|
||||
MJ_ERR_RET(mJoinInitColsInfo(&pTable->keyNum, &rowSize, &pTable->keyCols, pList));
|
||||
|
||||
if (pTable->keyNum > 1) {
|
||||
pTable->keyBuf = taosMemoryMalloc(bufSize);
|
||||
pTable->keyBuf = taosMemoryMalloc(rowSize);
|
||||
if (NULL == pTable->keyBuf) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -91,27 +100,44 @@ static int32_t mJoinInitKeyColsInfo(SMJoinTableCtx* pTable, SNodeList* pList) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int32_t mJoinInitColsMap(int32_t* colNum, SMJoinColMap** pCols, int32_t blkId, SNodeList* pList) {
|
||||
*pCols = taosMemoryMalloc(LIST_LENGTH(pList) * sizeof(SMJoinColMap));
|
||||
if (NULL == *pCols) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
int32_t i = 0;
|
||||
SNode* pNode = NULL;
|
||||
FOREACH(pNode, pList) {
|
||||
STargetNode* pTarget = (STargetNode*)pNode;
|
||||
SColumnNode* pColumn = (SColumnNode*)pTarget->pExpr;
|
||||
if (pColumn->dataBlockId == blkId) {
|
||||
(*pCols)[i].srcSlot = pColumn->slotId;
|
||||
(*pCols)[i].dstSlot = pTarget->slotId;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
*colNum = i;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mJoinInitTableInfo(SMJoinOperatorInfo* pJoin, SSortMergeJoinPhysiNode* pJoinNode, SOperatorInfo** pDownstream, int32_t idx, SQueryStat* pStat) {
|
||||
SMJoinTableCtx* pTable = &pJoin->tbs[idx];
|
||||
pTable->downStream = pDownstream[idx];
|
||||
pTable->blkId = pDownstream[idx]->resultDataBlockId;
|
||||
int32_t code = mJoinInitPrimKeyInfo(pTable, (0 == idx) ? pJoinNode->leftPrimSlotId : pJoinNode->rightPrimSlotId);
|
||||
if (code) {
|
||||
return code;
|
||||
}
|
||||
code = mJoinInitKeyColsInfo(pTable, (0 == idx) ? pJoinNode->pEqLeft : pJoinNode->pEqRight);
|
||||
if (code) {
|
||||
return code;
|
||||
}
|
||||
/*
|
||||
code = mJoinInitValColsInfo(pTable, pJoinNode->pTargets);
|
||||
if (code) {
|
||||
return code;
|
||||
}
|
||||
*/
|
||||
MJ_ERR_RET(mJoinInitPrimKeyInfo(pTable, (0 == idx) ? pJoinNode->leftPrimSlotId : pJoinNode->rightPrimSlotId));
|
||||
|
||||
MJ_ERR_RET(mJoinInitKeyColsInfo(pTable, (0 == idx) ? pJoinNode->pEqLeft : pJoinNode->pEqRight));
|
||||
MJ_ERR_RET(mJoinInitColsMap(&pTable->finNum, &pTable->finCols, pTable->blkId, pJoinNode->pTargets));
|
||||
|
||||
memcpy(&pTable->inputStat, pStat, sizeof(*pStat));
|
||||
|
||||
pTable->eqGrps = taosArrayInit(8, sizeof(SMJoinGrpRows));
|
||||
taosArrayReserve(pTable->eqGrps, 1);
|
||||
|
||||
if (E_JOIN_TB_BUILD == pTable->type) {
|
||||
pTable->createdBlks = taosArrayInit(8, POINTER_BYTES);
|
||||
pTable->pGrpArrays = taosArrayInit(32, POINTER_BYTES);
|
||||
|
@ -167,6 +193,7 @@ static void mJoinSetBuildAndProbeTable(SMJoinOperatorInfo* pInfo, SSortMergeJoin
|
|||
static int32_t mJoinInitMergeCtx(SMJoinOperatorInfo* pJoin, SSortMergeJoinPhysiNode* pJoinNode) {
|
||||
SMJoinMergeCtx* pCtx = &pJoin->ctx.mergeCtx;
|
||||
|
||||
pCtx->pJoin = pJoin;
|
||||
pCtx->lastEqTs = INT64_MIN;
|
||||
pCtx->hashCan = pJoin->probe->keyNum > 0;
|
||||
|
||||
|
@ -984,14 +1011,14 @@ static SSDataBlock* mLeftJoinDo(struct SOperatorInfo* pOperator) {
|
|||
return pCtx->finBlk;
|
||||
}
|
||||
|
||||
if (MJOIN_TB_ROWS_DONE(pJoin->probe)) {
|
||||
if (MJOIN_PROBE_TB_ROWS_DONE(pJoin->probe)) {
|
||||
continue;
|
||||
} else {
|
||||
MJOIN_GET_TB_CUR_TS(pProbeCol, probeTs, pJoin->probe);
|
||||
}
|
||||
}
|
||||
|
||||
while (!MJOIN_TB_ROWS_DONE(pJoin->probe) && !MJOIN_TB_ROWS_DONE(pJoin->build)) {
|
||||
while (!MJOIN_PROBE_TB_ROWS_DONE(pJoin->probe) && !MJOIN_BUILD_TB_ROWS_DONE(pJoin->build)) {
|
||||
if (probeTs == buildTs) {
|
||||
pCtx->lastEqTs = probeTs;
|
||||
MJ_ERR_JRET(mLeftJoinProcessEqualGrp(pCtx, probeTs, false));
|
||||
|
@ -999,9 +1026,10 @@ static SSDataBlock* mLeftJoinDo(struct SOperatorInfo* pOperator) {
|
|||
return pCtx->finBlk;
|
||||
}
|
||||
|
||||
MJOIN_GET_TB_CUR_TS(pBuildCol, buildTs, pJoin->build);
|
||||
MJOIN_GET_TB_CUR_TS(pProbeCol, probeTs, pJoin->probe);
|
||||
MJOIN_GET_TB_COL_TS(pBuildCol, buildTs, pJoin->build);
|
||||
MJOIN_GET_TB_COL_TS(pProbeCol, probeTs, pJoin->probe);
|
||||
} else if (LEFT_JOIN_NO_EQUAL(asc, probeTs, buildTs)) {
|
||||
pCtx->probeNEqGrp.blk = pJoin->probe->blk;
|
||||
pCtx->probeNEqGrp.beginIdx = pJoin->probe->blkRowIdx;
|
||||
pCtx->probeNEqGrp.readIdx = pCtx->probeNEqGrp.beginIdx;
|
||||
pCtx->probeNEqGrp.endIdx = pCtx->probeNEqGrp.beginIdx;
|
||||
|
@ -1031,6 +1059,20 @@ static SSDataBlock* mLeftJoinDo(struct SOperatorInfo* pOperator) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!MJOIN_PROBE_TB_ROWS_DONE(pJoin->probe)) {
|
||||
pCtx->probeNEqGrp.blk = pJoin->probe->blk;
|
||||
pCtx->probeNEqGrp.beginIdx = pJoin->probe->blkRowIdx;
|
||||
pCtx->probeNEqGrp.readIdx = pCtx->probeNEqGrp.beginIdx;
|
||||
pCtx->probeNEqGrp.endIdx = pJoin->probe->blk->info.rows - 1;
|
||||
|
||||
pJoin->probe->blkRowIdx = pJoin->probe->blk->info.rows;
|
||||
|
||||
MJ_ERR_JRET(mLeftJoinNonEqCart(pCtx));
|
||||
if (pCtx->finBlk->info.rows >= pCtx->blkThreshold) {
|
||||
return pCtx->finBlk;
|
||||
}
|
||||
}
|
||||
} while (true);
|
||||
|
||||
_return:
|
||||
|
@ -1147,9 +1189,7 @@ SOperatorInfo* createMergeJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t
|
|||
|
||||
mJoinInitTableInfo(pInfo, pJoinNode, pDownstream, 0, &pJoinNode->inputStat[0]);
|
||||
mJoinInitTableInfo(pInfo, pJoinNode, pDownstream, 1, &pJoinNode->inputStat[1]);
|
||||
|
||||
MJ_ERR_JRET(mJoinInitCtx(pInfo, pJoinNode));
|
||||
|
||||
|
||||
if (pJoinNode->pFullOnCond != NULL) {
|
||||
MJ_ERR_JRET(filterInitFromNode(pJoinNode->pFullOnCond, &pInfo->pFPreFilter, 0));
|
||||
}
|
||||
|
@ -1162,6 +1202,8 @@ SOperatorInfo* createMergeJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t
|
|||
MJ_ERR_JRET(filterInitFromNode(pJoinNode->node.pConditions, &pInfo->pFinFilter, 0));
|
||||
}
|
||||
|
||||
MJ_ERR_JRET(mJoinInitCtx(pInfo, pJoinNode));
|
||||
|
||||
if (pJoinNode->node.inputTsOrder == ORDER_ASC) {
|
||||
pInfo->inputTsOrder = TSDB_ORDER_ASC;
|
||||
} else if (pJoinNode->node.inputTsOrder == ORDER_DESC) {
|
||||
|
|
|
@ -555,7 +555,7 @@ static EDealRes pdcJoinIsCrossTableCond(SNode* pNode, void* pContext) {
|
|||
}
|
||||
|
||||
static ECondAction pdcJoinGetCondAction(SJoinLogicNode* pJoin, SSHashObj* pLeftTbls, SSHashObj* pRightTbls,
|
||||
SNode* pNode) {
|
||||
SNode* pNode, bool whereCond) {
|
||||
EJoinType t = pJoin->joinType;
|
||||
EJoinSubType s = pJoin->subType;
|
||||
SCpdIsMultiTableCondCxt cxt = {
|
||||
|
@ -564,19 +564,19 @@ static ECondAction pdcJoinGetCondAction(SJoinLogicNode* pJoin, SSHashObj* pLeftT
|
|||
|
||||
if (cxt.havaLeftCol) {
|
||||
if (cxt.haveRightCol) {
|
||||
if (gJoinOpt[t][s].pushDownFlag & PUSH_DOWN_ON_COND) {
|
||||
if ((!whereCond) || (gJoinOpt[t][s].pushDownFlag & PUSH_DOWN_ON_COND)) {
|
||||
return COND_ACTION_PUSH_JOIN;
|
||||
}
|
||||
return COND_ACTION_STAY;
|
||||
}
|
||||
if (gJoinOpt[t][s].pushDownFlag & PUSH_DOWN_LEFT_FLT) {
|
||||
if ((!whereCond) || (gJoinOpt[t][s].pushDownFlag & PUSH_DOWN_LEFT_FLT)) {
|
||||
return COND_ACTION_PUSH_LEFT_CHILD;
|
||||
}
|
||||
return COND_ACTION_STAY;
|
||||
}
|
||||
|
||||
if (cxt.haveRightCol) {
|
||||
if (gJoinOpt[t][s].pushDownFlag & PUSH_DOWN_RIGHT_FLT) {
|
||||
if ((!whereCond) || (gJoinOpt[t][s].pushDownFlag & PUSH_DOWN_RIGHT_FLT)) {
|
||||
return COND_ACTION_PUSH_RIGHT_CHILD;
|
||||
}
|
||||
return COND_ACTION_STAY;
|
||||
|
@ -586,7 +586,7 @@ static ECondAction pdcJoinGetCondAction(SJoinLogicNode* pJoin, SSHashObj* pLeftT
|
|||
}
|
||||
|
||||
static int32_t pdcJoinSplitLogicCond(SJoinLogicNode* pJoin, SNode** pSrcCond, SNode** pOnCond, SNode** pLeftChildCond,
|
||||
SNode** pRightChildCond) {
|
||||
SNode** pRightChildCond, bool whereCond) {
|
||||
SLogicConditionNode* pLogicCond = (SLogicConditionNode*)*pSrcCond;
|
||||
if (LOGIC_COND_TYPE_AND != pLogicCond->condType) {
|
||||
return TSDB_CODE_PLAN_NOT_SUPPORT_JOIN_COND;
|
||||
|
@ -604,7 +604,7 @@ static int32_t pdcJoinSplitLogicCond(SJoinLogicNode* pJoin, SNode** pSrcCond, SN
|
|||
SNodeList* pRemainConds = NULL;
|
||||
SNode* pCond = NULL;
|
||||
FOREACH(pCond, pLogicCond->pParameterList) {
|
||||
ECondAction condAction = pdcJoinGetCondAction(pJoin, pLeftTables, pRightTables, pCond);
|
||||
ECondAction condAction = pdcJoinGetCondAction(pJoin, pLeftTables, pRightTables, pCond, whereCond);
|
||||
if (COND_ACTION_PUSH_JOIN == condAction && NULL != pOnCond) {
|
||||
code = nodesListMakeAppend(&pOnConds, nodesCloneNode(pCond));
|
||||
} else if (COND_ACTION_PUSH_LEFT_CHILD == condAction) {
|
||||
|
@ -662,13 +662,13 @@ static int32_t pdcJoinSplitLogicCond(SJoinLogicNode* pJoin, SNode** pSrcCond, SN
|
|||
}
|
||||
|
||||
static int32_t pdcJoinSplitOpCond(SJoinLogicNode* pJoin, SNode** pSrcCond, SNode** pOnCond, SNode** pLeftChildCond,
|
||||
SNode** pRightChildCond) {
|
||||
SNode** pRightChildCond, bool whereCond) {
|
||||
SSHashObj* pLeftTables = NULL;
|
||||
SSHashObj* pRightTables = NULL;
|
||||
collectTableAliasFromNodes(nodesListGetNode(pJoin->node.pChildren, 0), &pLeftTables);
|
||||
collectTableAliasFromNodes(nodesListGetNode(pJoin->node.pChildren, 1), &pRightTables);
|
||||
|
||||
ECondAction condAction = pdcJoinGetCondAction(pJoin, pLeftTables, pRightTables, *pSrcCond);
|
||||
ECondAction condAction = pdcJoinGetCondAction(pJoin, pLeftTables, pRightTables, *pSrcCond, whereCond);
|
||||
|
||||
tSimpleHashCleanup(pLeftTables);
|
||||
tSimpleHashCleanup(pRightTables);
|
||||
|
@ -689,11 +689,11 @@ static int32_t pdcJoinSplitOpCond(SJoinLogicNode* pJoin, SNode** pSrcCond, SNode
|
|||
}
|
||||
|
||||
static int32_t pdcJoinSplitCond(SJoinLogicNode* pJoin, SNode** pSrcCond, SNode** pOnCond, SNode** pLeftChildCond,
|
||||
SNode** pRightChildCond) {
|
||||
SNode** pRightChildCond, bool whereCond) {
|
||||
if (QUERY_NODE_LOGIC_CONDITION == nodeType(*pSrcCond)) {
|
||||
return pdcJoinSplitLogicCond(pJoin, pSrcCond, pOnCond, pLeftChildCond, pRightChildCond);
|
||||
return pdcJoinSplitLogicCond(pJoin, pSrcCond, pOnCond, pLeftChildCond, pRightChildCond, whereCond);
|
||||
} else {
|
||||
return pdcJoinSplitOpCond(pJoin, pSrcCond, pOnCond, pLeftChildCond, pRightChildCond);
|
||||
return pdcJoinSplitOpCond(pJoin, pSrcCond, pOnCond, pLeftChildCond, pRightChildCond, whereCond);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1132,7 +1132,7 @@ static int32_t pdcDealJoin(SOptimizeContext* pCxt, SJoinLogicNode* pJoin) {
|
|||
SNode* pRightChildCond = NULL;
|
||||
int32_t code = pdcJoinCheckAllCond(pCxt, pJoin);
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pJoin->node.pConditions && 0 != gJoinOpt[t][s].pushDownFlag) {
|
||||
code = pdcJoinSplitCond(pJoin, &pJoin->node.pConditions, &pOnCond, &pLeftChildCond, &pRightChildCond);
|
||||
code = pdcJoinSplitCond(pJoin, &pJoin->node.pConditions, &pOnCond, &pLeftChildCond, &pRightChildCond, true);
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pOnCond) {
|
||||
code = pdcJoinPushDownOnCond(pCxt, pJoin, &pOnCond);
|
||||
}
|
||||
|
@ -1145,7 +1145,7 @@ static int32_t pdcDealJoin(SOptimizeContext* pCxt, SJoinLogicNode* pJoin) {
|
|||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = pdcJoinSplitCond(pJoin, &pJoin->pFullOnCond, NULL, &pLeftChildCond, &pRightChildCond);
|
||||
code = pdcJoinSplitCond(pJoin, &pJoin->pFullOnCond, NULL, &pLeftChildCond, &pRightChildCond, false);
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pLeftChildCond) {
|
||||
code = pdcPushDownCondToChild(pCxt, (SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 0), &pLeftChildCond);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
system sh/stop_dnodes.sh
|
||||
system sh/deploy.sh -n dnode1 -i 1
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
sql connect
|
||||
sql drop database if exists test0
|
||||
sql create database test0 vgroups 3;
|
||||
sql use test0;
|
||||
create stable sta (ts timestamp, col1 int) tags(t1 int);
|
||||
create table tba1 using sta tags(1);
|
||||
create table tba2 using sta tags(2);
|
||||
|
||||
insert into tba1 values ('2023-11-17 16:29:00', 1);
|
||||
insert into tba1 values ('2023-11-17 16:29:02', 3);
|
||||
insert into tba1 values ('2023-11-17 16:29:03', 4);
|
||||
insert into tba1 values ('2023-11-17 16:29:04', 5);
|
||||
|
||||
insert into tba2 values ('2023-11-17 16:29:00', 2);
|
||||
insert into tba2 values ('2023-11-17 16:29:01', 3);
|
||||
insert into tba2 values ('2023-11-17 16:29:03', 5);
|
||||
insert into tba2 values ('2023-11-17 16:29:05', 7);
|
||||
|
||||
sql drop database if exists testa
|
||||
sql create database testa vgroups 3;
|
||||
sql use testa;
|
||||
|
||||
sql create table sta1(ts timestamp, f int, g int) tags (t int);
|
||||
sql insert into cta11 using sta1 tags(1) values('2023-10-16 09:10:11', 100111, 1001110);
|
||||
sql insert into cta12 using sta1 tags(2) values('2023-10-16 09:10:12', 100112, 1001120);
|
||||
sql insert into cta13 using sta1 tags(3) values('2023-10-16 09:10:13', 100113, 1001130);
|
||||
sql insert into cta14 using sta1 tags(4) values('2023-10-16 09:10:14', 100114, 1001140);
|
||||
|
||||
sql create table st2(ts timestamp, f int, g int) tags (t int);
|
||||
sql insert into cta21 using st2 tags(1) values('2023-10-16 09:10:11', 100221, 1002210);
|
||||
sql insert into cta22 using st2 tags(2) values('2023-10-16 09:10:12', 100222, 1002220);
|
||||
sql insert into cta23 using st2 tags(3) values('2023-10-16 09:10:13', 100223, 1002230);
|
||||
sql insert into cta24 using st2 tags(4) values('2023-10-16 09:10:14', 100224, 1002240);
|
||||
|
||||
sql create table stt(ts timestamp, f int, g int) tags (t int);
|
||||
sql create table tt using stt tags(99);
|
||||
|
||||
sql create table stv(ts timestamp, h int) tags (t1 int);
|
||||
sql insert into ctv1 using stv tags(1) values('2023-10-16 10:10:10', 1);
|
||||
|
||||
sql drop database if exists testb
|
||||
sql create database testb vgroups 1;
|
||||
sql use testb;
|
||||
|
||||
sql create table stb1(ts timestamp, f int,g int) tags (t int);
|
||||
sql insert into ctb11 using stb1 tags(1) values('2023-10-16 09:10:11', 110111, 1101110);
|
||||
sql insert into ctb12 using stb1 tags(2) values('2023-10-16 09:10:12', 110112, 1101120);
|
||||
sql insert into ctb13 using stb1 tags(3) values('2023-10-16 09:10:13', 110113, 1101130);
|
||||
sql insert into ctb14 using stb1 tags(4) values('2023-10-16 09:10:14', 110114, 1101140);
|
||||
|
||||
sql create table st2(ts timestamp, f int, g int) tags (t int);
|
||||
sql insert into ctb21 using st2 tags(1) values('2023-10-16 09:10:11', 110221, 1102210);
|
||||
sql insert into ctb22 using st2 tags(2) values('2023-10-16 09:10:12', 110222, 1102220);
|
||||
sql insert into ctb23 using st2 tags(3) values('2023-10-16 09:10:13', 110223, 1102230);
|
||||
sql insert into ctb24 using st2 tags(4) values('2023-10-16 09:10:14', 110224, 1102240);
|
||||
|
||||
run tsim/join/left_join.sim
|
||||
|
||||
print ================== restart server to commit data into disk
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
print ================== server restart completed
|
||||
|
||||
run tsim/join/left_join.sim
|
||||
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
|
@ -0,0 +1,96 @@
|
|||
sql connect
|
||||
sql use test0;
|
||||
|
||||
sql select a.col1, b.col1 from sta a left join sta b on a.ts = b.ts and a.ts < '2023-11-17 16:29:02' and b.ts < '2023-11-17 16:29:01' order by a.col1, b.col1;
|
||||
if $rows != 5 then
|
||||
return -1
|
||||
endi
|
||||
if $data00 != 1 then
|
||||
return -1
|
||||
endi
|
||||
if $data01 != 1 then
|
||||
return -1
|
||||
endi
|
||||
if $data10 != 1 then
|
||||
return -1
|
||||
endi
|
||||
if $data11 != 2 then
|
||||
return -1
|
||||
endi
|
||||
if $data20 != 2 then
|
||||
return -1
|
||||
endi
|
||||
if $data21 != 1 then
|
||||
return -1
|
||||
endi
|
||||
if $data30 != 2 then
|
||||
return -1
|
||||
endi
|
||||
if $data31 != 2 then
|
||||
return -1
|
||||
endi
|
||||
if $data40 != 3 then
|
||||
return -1
|
||||
endi
|
||||
if $data41 != NULL then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select a.col1, b.col1 from tba1 a left join tba2 b on a.ts = b.ts order by a.col1, b.col1;
|
||||
if $rows != 4 then
|
||||
return -1
|
||||
endi
|
||||
if $data00 != 1 then
|
||||
return -1
|
||||
endi
|
||||
if $data01 != 2 then
|
||||
return -1
|
||||
endi
|
||||
if $data10 != 3 then
|
||||
return -1
|
||||
endi
|
||||
if $data11 != NULL then
|
||||
return -1
|
||||
endi
|
||||
if $data20 != 4 then
|
||||
return -1
|
||||
endi
|
||||
if $data21 != 5 then
|
||||
return -1
|
||||
endi
|
||||
if $data30 != 5 then
|
||||
return -1
|
||||
endi
|
||||
if $data31 != NULL then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select a.col1, b.col1 from tba2 a left join tba1 b on a.ts = b.ts order by a.col1, b.col1;
|
||||
if $rows != 4 then
|
||||
return -1
|
||||
endi
|
||||
if $data00 != 2 then
|
||||
return -1
|
||||
endi
|
||||
if $data01 != 1 then
|
||||
return -1
|
||||
endi
|
||||
if $data10 != 3 then
|
||||
return -1
|
||||
endi
|
||||
if $data11 != NULL then
|
||||
return -1
|
||||
endi
|
||||
if $data20 != 5 then
|
||||
return -1
|
||||
endi
|
||||
if $data21 != 4 then
|
||||
return -1
|
||||
endi
|
||||
if $data30 != 7 then
|
||||
return -1
|
||||
endi
|
||||
if $data31 != NULL then
|
||||
return -1
|
||||
endi
|
||||
|
Loading…
Reference in New Issue