enh: support timetruncate function

This commit is contained in:
dapan1121 2024-02-29 17:52:53 +08:00
parent 479279b75e
commit 85cca872a5
20 changed files with 427 additions and 108 deletions

View File

@ -131,7 +131,7 @@ typedef struct SJoinLogicNode {
SNode* pWindowOffset; SNode* pWindowOffset;
SNode* pJLimit; SNode* pJLimit;
EJoinAlgorithm joinAlgo; EJoinAlgorithm joinAlgo;
SNode* winPrimEqCond; SNode* addPrimEqCond;
SNode* pPrimKeyEqCond; SNode* pPrimKeyEqCond;
SNode* pColEqCond; SNode* pColEqCond;
SNode* pColOnCond; SNode* pColOnCond;

View File

@ -245,7 +245,7 @@ typedef struct SJoinTableNode {
EJoinSubType subType; EJoinSubType subType;
SNode* pWindowOffset; SNode* pWindowOffset;
SNode* pJLimit; SNode* pJLimit;
SNode* winPrimCond; SNode* addPrimCond;
bool hasSubQuery; bool hasSubQuery;
bool isLowLevelJoin; bool isLowLevelJoin;
SNode* pParent; SNode* pParent;

View File

@ -82,6 +82,7 @@ int32_t toUnixtimestampFunction(SScalarParam *pInput, int32_t inputNum, SScalarP
int32_t toJsonFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t toJsonFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t toTimestampFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t toTimestampFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t toCharFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t toCharFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int64_t offsetFromTz(char *timezone, int64_t factor);
int32_t timeTruncateFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t timeTruncateFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t timeDiffFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t timeDiffFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
int32_t nowFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t nowFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);

View File

@ -82,51 +82,59 @@ typedef struct SMJoinNMatchCtx {
int32_t grpIdx; int32_t grpIdx;
} SMJoinNMatchCtx; } SMJoinNMatchCtx;
// for now timetruncate only
typedef struct SMJoinPrimExprCtx {
int64_t truncateUnit;
int64_t timezoneUnit;
int32_t targetSlotId;
} SMJoinPrimExprCtx;
typedef struct SMJoinTableCtx { typedef struct SMJoinTableCtx {
EJoinTableType type; EJoinTableType type;
int32_t downStreamIdx; int32_t downStreamIdx;
SOperatorInfo* downStream; SOperatorInfo* downStream;
bool dsInitDone; bool dsInitDone;
bool dsFetchDone; bool dsFetchDone;
SNode* primExpr;
SMJoinPrimExprCtx primCtx;
int32_t blkId; int32_t blkId;
SQueryStat inputStat; SQueryStat inputStat;
uint64_t lastInGid; uint64_t lastInGid;
SSDataBlock* remainInBlk; SSDataBlock* remainInBlk;
SMJoinColMap* primCol; SMJoinColMap* primCol;
char* primData; char* primData;
int32_t finNum; int32_t finNum;
SMJoinColMap* finCols; SMJoinColMap* finCols;
int32_t keyNum; int32_t keyNum;
int32_t keyNullSize; int32_t keyNullSize;
SMJoinColInfo* keyCols; SMJoinColInfo* keyCols;
char* keyBuf; char* keyBuf;
char* keyData; char* keyData;
bool newBlk; bool newBlk;
SSDataBlock* blk; SSDataBlock* blk;
int32_t blkRowIdx; int32_t blkRowIdx;
// merge join // merge join
int64_t grpTotalRows; int64_t grpTotalRows;
int32_t grpIdx; int32_t grpIdx;
bool noKeepEqGrpRows; bool noKeepEqGrpRows;
bool multiEqGrpRows; bool multiEqGrpRows;
int64_t eqRowLimit; int64_t eqRowLimit;
int64_t eqRowNum; int64_t eqRowNum;
SArray* eqGrps; SArray* eqGrps;
SArray* createdBlks; SArray* createdBlks;
// hash join // hash join
int32_t grpArrayIdx; int32_t grpArrayIdx;
SArray* pGrpArrays; SArray* pGrpArrays;
bool multiRowsGrp; bool multiRowsGrp;
int32_t grpRowIdx; int32_t grpRowIdx;
@ -134,11 +142,11 @@ typedef struct SMJoinTableCtx {
SMJoinHashGrpRows* pHashGrpRows; SMJoinHashGrpRows* pHashGrpRows;
SSHashObj* pGrpHash; SSHashObj* pGrpHash;
int64_t rowBitmapSize; int64_t rowBitmapSize;
int64_t rowBitmapOffset; int64_t rowBitmapOffset;
char* pRowBitmap; char* pRowBitmap;
SMJoinNMatchCtx nMatchCtx; SMJoinNMatchCtx nMatchCtx;
} SMJoinTableCtx; } SMJoinTableCtx;
typedef struct SMJoinMatchInfo { typedef struct SMJoinMatchInfo {
@ -321,6 +329,7 @@ typedef struct SMJoinOperatorInfo {
#define MJOIN_PROBE_TB_ROWS_DONE(_tb) ((_tb)->blkRowIdx >= (_tb)->blk->info.rows) #define MJOIN_PROBE_TB_ROWS_DONE(_tb) ((_tb)->blkRowIdx >= (_tb)->blk->info.rows)
#define FJOIN_PROBE_TB_ROWS_DONE(_tb) ((NULL == (_tb)->blk) || ((_tb)->blkRowIdx >= (_tb)->blk->info.rows)) #define FJOIN_PROBE_TB_ROWS_DONE(_tb) ((NULL == (_tb)->blk) || ((_tb)->blkRowIdx >= (_tb)->blk->info.rows))
#define MJOIN_BUILD_TB_ROWS_DONE(_tb) ((NULL == (_tb)->blk) || ((_tb)->blkRowIdx >= (_tb)->blk->info.rows)) #define MJOIN_BUILD_TB_ROWS_DONE(_tb) ((NULL == (_tb)->blk) || ((_tb)->blkRowIdx >= (_tb)->blk->info.rows))
#define MJOIN_TB_GRP_ROWS_DONE(_tb, _grpJoin) ((_tb)->dsFetchDone || ((_grpJoin) && NULL == (_tb)->blk && NULL != (_tb)->remainInBlk))
#define BLK_IS_FULL(_blk) ((_blk)->info.rows == (_blk)->info.capacity) #define BLK_IS_FULL(_blk) ((_blk)->info.rows == (_blk)->info.capacity)
@ -378,7 +387,7 @@ typedef struct SMJoinOperatorInfo {
#define MJOIN_GET_TB_COL_TS(_col, _ts, _tb) \ #define MJOIN_GET_TB_COL_TS(_col, _ts, _tb) \
do { \ do { \
if (NULL != (_tb)->blk && (_tb)->blkRowIdx < (_tb)->blk->info.rows) { \ if (NULL != (_tb)->blk && (_tb)->blkRowIdx < (_tb)->blk->info.rows) { \
(_col) = taosArrayGet((_tb)->blk->pDataBlock, (_tb)->primCol->srcSlot); \ (_col) = taosArrayGet((_tb)->blk->pDataBlock, (_tb)->primCtx.targetSlotId); \
(_ts) = *((int64_t*)(_col)->pData + (_tb)->blkRowIdx); \ (_ts) = *((int64_t*)(_col)->pData + (_tb)->blkRowIdx); \
} else { \ } else { \
(_ts) = INT64_MAX; \ (_ts) = INT64_MAX; \
@ -423,6 +432,7 @@ SSDataBlock* mAntiJoinDo(struct SOperatorInfo* pOperator);
SSDataBlock* mWinJoinDo(struct SOperatorInfo* pOperator); SSDataBlock* mWinJoinDo(struct SOperatorInfo* pOperator);
void mJoinResetGroupTableCtx(SMJoinTableCtx* pCtx); void mJoinResetGroupTableCtx(SMJoinTableCtx* pCtx);
void mJoinResetTableCtx(SMJoinTableCtx* pCtx); void mJoinResetTableCtx(SMJoinTableCtx* pCtx);
void mLeftJoinGroupReset(SMJoinOperatorInfo* pJoin);
void mWinJoinGroupReset(SMJoinOperatorInfo* pJoin); void mWinJoinGroupReset(SMJoinOperatorInfo* pJoin);
bool mJoinRetrieveBlk(SMJoinOperatorInfo* pJoin, int32_t* pIdx, SSDataBlock** ppBlk, SMJoinTableCtx* pTb); bool mJoinRetrieveBlk(SMJoinOperatorInfo* pJoin, int32_t* pIdx, SSDataBlock** ppBlk, SMJoinTableCtx* pTb);
void mJoinSetDone(SOperatorInfo* pOperator); void mJoinSetDone(SOperatorInfo* pOperator);

View File

@ -480,8 +480,8 @@ static bool mLeftJoinRetrieve(SOperatorInfo* pOperator, SMJoinOperatorInfo* pJoi
} }
if (buildGot) { if (buildGot) {
SColumnInfoData* pProbeCol = taosArrayGet(pJoin->probe->blk->pDataBlock, pJoin->probe->primCol->srcSlot); SColumnInfoData* pProbeCol = taosArrayGet(pJoin->probe->blk->pDataBlock, pJoin->probe->primCtx.targetSlotId);
SColumnInfoData* pBuildCol = taosArrayGet(pJoin->build->blk->pDataBlock, pJoin->build->primCol->srcSlot); SColumnInfoData* pBuildCol = taosArrayGet(pJoin->build->blk->pDataBlock, pJoin->build->primCtx.targetSlotId);
if (*((int64_t*)pProbeCol->pData + pJoin->probe->blkRowIdx) > *((int64_t*)pBuildCol->pData + pJoin->build->blk->info.rows - 1)) { if (*((int64_t*)pProbeCol->pData + pJoin->probe->blkRowIdx) > *((int64_t*)pBuildCol->pData + pJoin->build->blk->info.rows - 1)) {
pJoin->build->blkRowIdx = pJoin->build->blk->info.rows; pJoin->build->blkRowIdx = pJoin->build->blk->info.rows;
continue; continue;
@ -585,7 +585,7 @@ SSDataBlock* mLeftJoinDo(struct SOperatorInfo* pOperator) {
} }
} }
if (!MJOIN_PROBE_TB_ROWS_DONE(pJoin->probe) && (pJoin->build->dsFetchDone || (pCtx->groupJoin && NULL == pJoin->build->blk))) { if (!MJOIN_PROBE_TB_ROWS_DONE(pJoin->probe) && MJOIN_TB_GRP_ROWS_DONE(pJoin->build, pCtx->groupJoin)) {
pCtx->probeNEqGrp.blk = pJoin->probe->blk; pCtx->probeNEqGrp.blk = pJoin->probe->blk;
pCtx->probeNEqGrp.beginIdx = pJoin->probe->blkRowIdx; pCtx->probeNEqGrp.beginIdx = pJoin->probe->blkRowIdx;
pCtx->probeNEqGrp.readIdx = pCtx->probeNEqGrp.beginIdx; pCtx->probeNEqGrp.readIdx = pCtx->probeNEqGrp.beginIdx;
@ -1856,7 +1856,7 @@ int32_t mAsofLowerAddEqRowsToCache(struct SOperatorInfo* pOperator, SMJoinWindow
do { do {
grp.blk = pTable->blk; grp.blk = pTable->blk;
SColumnInfoData* pCol = taosArrayGet(pTable->blk->pDataBlock, pTable->primCol->srcSlot); SColumnInfoData* pCol = taosArrayGet(pTable->blk->pDataBlock, pTable->primCtx.targetSlotId);
if (*(int64_t*)colDataGetNumData(pCol, pTable->blkRowIdx) != timestamp) { if (*(int64_t*)colDataGetNumData(pCol, pTable->blkRowIdx) != timestamp) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
@ -2176,7 +2176,7 @@ SSDataBlock* mAsofLowerJoinDo(struct SOperatorInfo* pOperator) {
} }
} }
if (!MJOIN_PROBE_TB_ROWS_DONE(pJoin->probe) && (pJoin->build->dsFetchDone || (pCtx->groupJoin && NULL == pJoin->build->blk))) { if (!MJOIN_PROBE_TB_ROWS_DONE(pJoin->probe) && MJOIN_TB_GRP_ROWS_DONE(pJoin->build, pCtx->groupJoin)) {
pCtx->probeGrp.beginIdx = pJoin->probe->blkRowIdx; pCtx->probeGrp.beginIdx = pJoin->probe->blkRowIdx;
pCtx->probeGrp.readIdx = pCtx->probeGrp.beginIdx; pCtx->probeGrp.readIdx = pCtx->probeGrp.beginIdx;
pCtx->probeGrp.endIdx = pJoin->probe->blk->info.rows - 1; pCtx->probeGrp.endIdx = pJoin->probe->blk->info.rows - 1;
@ -2312,7 +2312,7 @@ int32_t mAsofGreaterFillDumpGrpCache(SMJoinWindowCtx* pCtx, bool lastBuildGrp) {
} }
int32_t mAsofGreaterSkipEqRows(SMJoinWindowCtx* pCtx, SMJoinTableCtx* pTable, int64_t timestamp, bool* wholeBlk) { int32_t mAsofGreaterSkipEqRows(SMJoinWindowCtx* pCtx, SMJoinTableCtx* pTable, int64_t timestamp, bool* wholeBlk) {
SColumnInfoData* pCol = taosArrayGet(pTable->blk->pDataBlock, pTable->primCol->srcSlot); SColumnInfoData* pCol = taosArrayGet(pTable->blk->pDataBlock, pTable->primCtx.targetSlotId);
if (*(int64_t*)colDataGetNumData(pCol, pTable->blkRowIdx) != timestamp) { if (*(int64_t*)colDataGetNumData(pCol, pTable->blkRowIdx) != timestamp) {
*wholeBlk = false; *wholeBlk = false;
@ -2468,8 +2468,8 @@ static bool mAsofGreaterRetrieve(SOperatorInfo* pOperator, SMJoinOperatorInfo* p
} }
if (buildGot) { if (buildGot) {
SColumnInfoData* pProbeCol = taosArrayGet(pJoin->probe->blk->pDataBlock, pJoin->probe->primCol->srcSlot); SColumnInfoData* pProbeCol = taosArrayGet(pJoin->probe->blk->pDataBlock, pJoin->probe->primCtx.targetSlotId);
SColumnInfoData* pBuildCol = taosArrayGet(pJoin->build->blk->pDataBlock, pJoin->build->primCol->srcSlot); SColumnInfoData* pBuildCol = taosArrayGet(pJoin->build->blk->pDataBlock, pJoin->build->primCtx.targetSlotId);
if (*((int64_t*)pProbeCol->pData + pJoin->probe->blkRowIdx) > *((int64_t*)pBuildCol->pData + pJoin->build->blk->info.rows - 1)) { if (*((int64_t*)pProbeCol->pData + pJoin->probe->blkRowIdx) > *((int64_t*)pBuildCol->pData + pJoin->build->blk->info.rows - 1)) {
pJoin->build->blkRowIdx = pJoin->build->blk->info.rows; pJoin->build->blkRowIdx = pJoin->build->blk->info.rows;
MJOIN_POP_TB_BLK(&pCtx->cache); MJOIN_POP_TB_BLK(&pCtx->cache);
@ -2564,7 +2564,7 @@ SSDataBlock* mAsofGreaterJoinDo(struct SOperatorInfo* pOperator) {
} }
} }
if (!MJOIN_PROBE_TB_ROWS_DONE(pJoin->probe) && (pJoin->build->dsFetchDone || (pCtx->groupJoin && NULL == pJoin->build->blk))) { if (!MJOIN_PROBE_TB_ROWS_DONE(pJoin->probe) && MJOIN_TB_GRP_ROWS_DONE(pJoin->build, pCtx->groupJoin)) {
pCtx->probeGrp.beginIdx = pJoin->probe->blkRowIdx; pCtx->probeGrp.beginIdx = pJoin->probe->blkRowIdx;
pCtx->probeGrp.readIdx = pCtx->probeGrp.beginIdx; pCtx->probeGrp.readIdx = pCtx->probeGrp.beginIdx;
pCtx->probeGrp.endIdx = pJoin->probe->blk->info.rows - 1; pCtx->probeGrp.endIdx = pJoin->probe->blk->info.rows - 1;
@ -2663,8 +2663,8 @@ static bool mWinJoinRetrieve(SOperatorInfo* pOperator, SMJoinOperatorInfo* pJoin
} }
if (buildGot && !pCtx->lowerRowsAcq) { if (buildGot && !pCtx->lowerRowsAcq) {
SColumnInfoData* pProbeCol = taosArrayGet(pJoin->probe->blk->pDataBlock, pJoin->probe->primCol->srcSlot); SColumnInfoData* pProbeCol = taosArrayGet(pJoin->probe->blk->pDataBlock, pJoin->probe->primCtx.targetSlotId);
SColumnInfoData* pBuildCol = taosArrayGet(pJoin->build->blk->pDataBlock, pJoin->build->primCol->srcSlot); SColumnInfoData* pBuildCol = taosArrayGet(pJoin->build->blk->pDataBlock, pJoin->build->primCtx.targetSlotId);
if (*((int64_t*)pProbeCol->pData + pJoin->probe->blkRowIdx) > *((int64_t*)pBuildCol->pData + pJoin->build->blk->info.rows - 1)) { if (*((int64_t*)pProbeCol->pData + pJoin->probe->blkRowIdx) > *((int64_t*)pBuildCol->pData + pJoin->build->blk->info.rows - 1)) {
pJoin->build->blkRowIdx = pJoin->build->blk->info.rows; pJoin->build->blkRowIdx = pJoin->build->blk->info.rows;
continue; continue;
@ -2681,7 +2681,7 @@ static bool mWinJoinRetrieve(SOperatorInfo* pOperator, SMJoinOperatorInfo* pJoin
int32_t mWinJoinAddWinBeginBlk(SMJoinWindowCtx* pCtx, SMJoinWinCache* pCache, SMJoinTableCtx* build, bool* winEnd) { int32_t mWinJoinAddWinBeginBlk(SMJoinWindowCtx* pCtx, SMJoinWinCache* pCache, SMJoinTableCtx* build, bool* winEnd) {
SSDataBlock* pBlk = build->blk; SSDataBlock* pBlk = build->blk;
SColumnInfoData* pCol = taosArrayGet(pBlk->pDataBlock, build->primCol->srcSlot); SColumnInfoData* pCol = taosArrayGet(pBlk->pDataBlock, build->primCtx.targetSlotId);
if (*((int64_t*)pCol->pData + pBlk->info.rows - 1) >= pCtx->winBeginTs) { if (*((int64_t*)pCol->pData + pBlk->info.rows - 1) >= pCtx->winBeginTs) {
for (; build->blkRowIdx < pBlk->info.rows; build->blkRowIdx++) { for (; build->blkRowIdx < pBlk->info.rows; build->blkRowIdx++) {
if (*((int64_t*)pCol->pData + build->blkRowIdx) < pCtx->winBeginTs) { if (*((int64_t*)pCol->pData + build->blkRowIdx) < pCtx->winBeginTs) {
@ -2715,7 +2715,7 @@ int32_t mWinJoinAddWinBeginBlk(SMJoinWindowCtx* pCtx, SMJoinWinCache* pCache, SM
int32_t mWinJoinAddWinEndBlk(SMJoinWindowCtx* pCtx, SMJoinWinCache* pCache, SMJoinTableCtx* build, bool* winEnd) { int32_t mWinJoinAddWinEndBlk(SMJoinWindowCtx* pCtx, SMJoinWinCache* pCache, SMJoinTableCtx* build, bool* winEnd) {
SSDataBlock* pBlk = build->blk; SSDataBlock* pBlk = build->blk;
SColumnInfoData* pCol = taosArrayGet(pBlk->pDataBlock, build->primCol->srcSlot); SColumnInfoData* pCol = taosArrayGet(pBlk->pDataBlock, build->primCtx.targetSlotId);
SMJoinGrpRows grp = {.blk = pBlk, .beginIdx = build->blkRowIdx}; SMJoinGrpRows grp = {.blk = pBlk, .beginIdx = build->blkRowIdx};
if (*((int64_t*)pCol->pData + build->blkRowIdx) > pCtx->winEndTs) { if (*((int64_t*)pCol->pData + build->blkRowIdx) > pCtx->winEndTs) {
@ -2771,7 +2771,7 @@ int32_t mWinJoinMoveWinBegin(SMJoinWindowCtx* pCtx) {
int32_t grpNum = taosArrayGetSize(pCache->grps); int32_t grpNum = taosArrayGetSize(pCache->grps);
for (int32_t i = 0; i < grpNum; ++i) { for (int32_t i = 0; i < grpNum; ++i) {
SMJoinGrpRows* pGrp = taosArrayGet(pCache->grps, i); SMJoinGrpRows* pGrp = taosArrayGet(pCache->grps, i);
SColumnInfoData* pCol = taosArrayGet(pGrp->blk->pDataBlock, pCtx->pJoin->build->primCol->srcSlot); SColumnInfoData* pCol = taosArrayGet(pGrp->blk->pDataBlock, pCtx->pJoin->build->primCtx.targetSlotId);
if (*((int64_t*)pCol->pData + pGrp->blk->info.rows - 1) < pCtx->winBeginTs) { if (*((int64_t*)pCol->pData + pGrp->blk->info.rows - 1) < pCtx->winBeginTs) {
pCache->rowNum -= (pGrp->blk->info.rows - pGrp->beginIdx); pCache->rowNum -= (pGrp->blk->info.rows - pGrp->beginIdx);
if (pGrp->blk == pCache->outBlk) { if (pGrp->blk == pCache->outBlk) {
@ -2861,7 +2861,7 @@ int32_t mWinJoinMoveWinEnd(SMJoinWindowCtx* pCtx) {
} }
SMJoinGrpRows* pGrp = taosArrayGetLast(pCache->grps); SMJoinGrpRows* pGrp = taosArrayGetLast(pCache->grps);
SColumnInfoData* pCol = taosArrayGet(pGrp->blk->pDataBlock, pCtx->pJoin->build->primCol->srcSlot); SColumnInfoData* pCol = taosArrayGet(pGrp->blk->pDataBlock, pCtx->pJoin->build->primCtx.targetSlotId);
if (*((int64_t*)pCol->pData + pGrp->blk->info.rows - 1) <= pCtx->winEndTs) { if (*((int64_t*)pCol->pData + pGrp->blk->info.rows - 1) <= pCtx->winEndTs) {
pCache->rowNum += pGrp->blk->info.rows - pGrp->endIdx - 1; pCache->rowNum += pGrp->blk->info.rows - pGrp->endIdx - 1;
if (pCache->rowNum >= pCtx->jLimit) { if (pCache->rowNum >= pCtx->jLimit) {

View File

@ -25,11 +25,12 @@
#include "thash.h" #include "thash.h"
#include "tmsg.h" #include "tmsg.h"
#include "ttypes.h" #include "ttypes.h"
#include "functionMgt.h"
#include "mergejoin.h" #include "mergejoin.h"
int32_t mJoinBuildEqGrp(SMJoinTableCtx* pTable, int64_t timestamp, bool* wholeBlk, SMJoinGrpRows* pGrp) { int32_t mJoinBuildEqGrp(SMJoinTableCtx* pTable, int64_t timestamp, bool* wholeBlk, SMJoinGrpRows* pGrp) {
SColumnInfoData* pCol = taosArrayGet(pTable->blk->pDataBlock, pTable->primCol->srcSlot); SColumnInfoData* pCol = taosArrayGet(pTable->blk->pDataBlock, pTable->primCtx.targetSlotId);
pGrp->beginIdx = pTable->blkRowIdx; pGrp->beginIdx = pTable->blkRowIdx;
pGrp->readIdx = pTable->blkRowIdx; pGrp->readIdx = pTable->blkRowIdx;
@ -768,6 +769,44 @@ static int32_t mJoinInitFinColsInfo(SMJoinTableCtx* pTable, SNodeList* pList) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int32_t mJoinInitPrimExprCtx(SNode* pNode, SMJoinPrimExprCtx* pCtx, SMJoinTableCtx* pTable) {
if (NULL == pNode) {
pCtx->targetSlotId = pTable->primCol->srcSlot;
return TSDB_CODE_SUCCESS;
}
if (QUERY_NODE_TARGET != nodeType(pNode)) {
return TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
}
STargetNode* pTarget = (STargetNode*)pNode;
if (QUERY_NODE_FUNCTION != nodeType(pTarget->pExpr)) {
return TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
}
SFunctionNode* pFunc = (SFunctionNode*)pTarget->pExpr;
if (FUNCTION_TYPE_TIMETRUNCATE != pFunc->funcType) {
return TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
}
if (4 != pFunc->pParameterList->length && 5 != pFunc->pParameterList->length) {
return TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
}
SValueNode* pUnit = (SValueNode*)nodesListGetNode(pFunc->pParameterList, 1);
SValueNode* pCurrTz = (5 == pFunc->pParameterList->length) ? (SValueNode*)nodesListGetNode(pFunc->pParameterList, 2) : NULL;
SValueNode* pTimeZone = (5 == pFunc->pParameterList->length) ? (SValueNode*)nodesListGetNode(pFunc->pParameterList, 4) : (SValueNode*)nodesListGetNode(pFunc->pParameterList, 3);
pCtx->truncateUnit = pUnit->typeData;
if (NULL != pCurrTz && 0 == pCurrTz->typeData) {
pCtx->timezoneUnit = offsetFromTz(pTimeZone->datum.p, TSDB_TICK_PER_SECOND(pFunc->node.resType.precision));
}
pCtx->targetSlotId = pTarget->slotId;
return TSDB_CODE_SUCCESS;
}
static int32_t mJoinInitTableInfo(SMJoinOperatorInfo* pJoin, SSortMergeJoinPhysiNode* pJoinNode, SOperatorInfo** pDownstream, int32_t idx, SQueryStat* pStat) { static int32_t mJoinInitTableInfo(SMJoinOperatorInfo* pJoin, SSortMergeJoinPhysiNode* pJoinNode, SOperatorInfo** pDownstream, int32_t idx, SQueryStat* pStat) {
SMJoinTableCtx* pTable = &pJoin->tbs[idx]; SMJoinTableCtx* pTable = &pJoin->tbs[idx];
pTable->downStream = pDownstream[idx]; pTable->downStream = pDownstream[idx];
@ -807,6 +846,8 @@ static int32_t mJoinInitTableInfo(SMJoinOperatorInfo* pJoin, SSortMergeJoinPhysi
} else { } else {
pTable->multiEqGrpRows = true; pTable->multiEqGrpRows = true;
} }
MJ_ERR_RET(mJoinInitPrimExprCtx(pTable->primExpr, &pTable->primCtx, pTable));
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
@ -842,26 +883,56 @@ static void mJoinSetBuildAndProbeTable(SMJoinOperatorInfo* pInfo, SSortMergeJoin
pInfo->build->downStreamIdx = buildIdx; pInfo->build->downStreamIdx = buildIdx;
pInfo->probe->downStreamIdx = probeIdx; pInfo->probe->downStreamIdx = probeIdx;
if (0 == buildIdx) {
pInfo->build->primExpr = pJoinNode->leftPrimExpr;
pInfo->probe->primExpr = pJoinNode->rightPrimExpr;
} else {
pInfo->build->primExpr = pJoinNode->rightPrimExpr;
pInfo->probe->primExpr = pJoinNode->leftPrimExpr;
}
pInfo->build->type = E_JOIN_TB_BUILD; pInfo->build->type = E_JOIN_TB_BUILD;
pInfo->probe->type = E_JOIN_TB_PROBE; pInfo->probe->type = E_JOIN_TB_PROBE;
} }
int32_t mJoinLaunchPrimExpr(SSDataBlock* pBlock, SMJoinTableCtx* pTable) {
if (NULL == pTable->primExpr) {
return TSDB_CODE_SUCCESS;
}
SMJoinPrimExprCtx* pCtx = &pTable->primCtx;
SColumnInfoData* pPrimIn = taosArrayGet(pBlock->pDataBlock, pTable->primCol->srcSlot);
SColumnInfoData* pPrimOut = taosArrayGet(pBlock->pDataBlock, pTable->primCtx.targetSlotId);
if (0 != pCtx->timezoneUnit) {
for (int32_t i = 0; i < pBlock->info.rows; ++i) {
((int64_t*)pPrimOut->pData)[i] = (((int64_t*)pPrimIn->pData)[i] - pCtx->timezoneUnit) / pCtx->truncateUnit * pCtx->truncateUnit;
}
} else {
for (int32_t i = 0; i < pBlock->info.rows; ++i) {
((int64_t*)pPrimOut->pData)[i] = ((int64_t*)pPrimIn->pData)[i] / pCtx->truncateUnit * pCtx->truncateUnit;
}
}
return TSDB_CODE_SUCCESS;
}
SSDataBlock* mJoinGrpRetrieveImpl(SMJoinOperatorInfo* pJoin, SMJoinTableCtx* pTable) { SSDataBlock* mJoinGrpRetrieveImpl(SMJoinOperatorInfo* pJoin, SMJoinTableCtx* pTable) {
SSDataBlock* pTmp = NULL;
int32_t dsIdx = pTable->downStreamIdx; int32_t dsIdx = pTable->downStreamIdx;
if (E_JOIN_TB_PROBE == pTable->type) { if (E_JOIN_TB_PROBE == pTable->type) {
if (pTable->remainInBlk) { if (pTable->remainInBlk) {
SSDataBlock* pTmp = pTable->remainInBlk; pTmp = pTable->remainInBlk;
pTable->remainInBlk = NULL; pTable->remainInBlk = NULL;
(*pJoin->grpResetFp)(pJoin); (*pJoin->grpResetFp)(pJoin);
pTable->lastInGid = pTmp->info.id.groupId; pTable->lastInGid = pTmp->info.id.groupId;
return pTmp; goto _return;
} }
if (pTable->dsFetchDone) { if (pTable->dsFetchDone) {
return NULL; return NULL;
} }
SSDataBlock* pTmp = getNextBlockFromDownstreamRemain(pJoin->pOperator, dsIdx); pTmp = getNextBlockFromDownstreamRemain(pJoin->pOperator, dsIdx);
if (NULL == pTmp) { if (NULL == pTmp) {
pTable->dsFetchDone = true; pTable->dsFetchDone = true;
return NULL; return NULL;
@ -869,11 +940,11 @@ SSDataBlock* mJoinGrpRetrieveImpl(SMJoinOperatorInfo* pJoin, SMJoinTableCtx* pTa
if (0 == pTable->lastInGid) { if (0 == pTable->lastInGid) {
pTable->lastInGid = pTmp->info.id.groupId; pTable->lastInGid = pTmp->info.id.groupId;
return pTmp; goto _return;
} }
if (pTable->lastInGid == pTmp->info.id.groupId) { if (pTable->lastInGid == pTmp->info.id.groupId) {
return pTmp; goto _return;
} }
pTable->remainInBlk = pTmp; pTable->remainInBlk = pTmp;
@ -886,10 +957,10 @@ SSDataBlock* mJoinGrpRetrieveImpl(SMJoinOperatorInfo* pJoin, SMJoinTableCtx* pTa
while (true) { while (true) {
if (pTable->remainInBlk) { if (pTable->remainInBlk) {
if (pTable->remainInBlk->info.id.groupId == pProbe->lastInGid) { if (pTable->remainInBlk->info.id.groupId == pProbe->lastInGid) {
SSDataBlock* pTmp = pTable->remainInBlk; pTmp = pTable->remainInBlk;
pTable->remainInBlk = NULL; pTable->remainInBlk = NULL;
pTable->lastInGid = pTmp->info.id.groupId; pTable->lastInGid = pTmp->info.id.groupId;
return pTmp; goto _return;
} }
if (pTable->remainInBlk->info.id.groupId > pProbe->lastInGid) { if (pTable->remainInBlk->info.id.groupId > pProbe->lastInGid) {
@ -912,7 +983,10 @@ SSDataBlock* mJoinGrpRetrieveImpl(SMJoinOperatorInfo* pJoin, SMJoinTableCtx* pTa
pTable->remainInBlk = pTmp; pTable->remainInBlk = pTmp;
} }
return NULL; _return:
mJoinLaunchPrimExpr(pTmp, pTable);
return pTmp;
} }
static FORCE_INLINE SSDataBlock* mJoinRetrieveImpl(SMJoinOperatorInfo* pJoin, SMJoinTableCtx* pTable) { static FORCE_INLINE SSDataBlock* mJoinRetrieveImpl(SMJoinOperatorInfo* pJoin, SMJoinTableCtx* pTable) {
@ -923,6 +997,8 @@ static FORCE_INLINE SSDataBlock* mJoinRetrieveImpl(SMJoinOperatorInfo* pJoin, SM
SSDataBlock* pTmp = getNextBlockFromDownstreamRemain(pJoin->pOperator, pTable->downStreamIdx); SSDataBlock* pTmp = getNextBlockFromDownstreamRemain(pJoin->pOperator, pTable->downStreamIdx);
if (NULL == pTmp) { if (NULL == pTmp) {
pTable->dsFetchDone = true; pTable->dsFetchDone = true;
} else {
mJoinLaunchPrimExpr(pTmp, pTable);
} }
return pTmp; return pTmp;
@ -1022,7 +1098,7 @@ void mJoinResetForBuildTable(SMJoinTableCtx* pTable) {
} }
int32_t mJoinBuildEqGroups(SMJoinTableCtx* pTable, int64_t timestamp, bool* wholeBlk, bool restart) { int32_t mJoinBuildEqGroups(SMJoinTableCtx* pTable, int64_t timestamp, bool* wholeBlk, bool restart) {
SColumnInfoData* pCol = taosArrayGet(pTable->blk->pDataBlock, pTable->primCol->srcSlot); SColumnInfoData* pCol = taosArrayGet(pTable->blk->pDataBlock, pTable->primCtx.targetSlotId);
SMJoinGrpRows* pGrp = NULL; SMJoinGrpRows* pGrp = NULL;
if (*(int64_t*)colDataGetNumData(pCol, pTable->blkRowIdx) != timestamp) { if (*(int64_t*)colDataGetNumData(pCol, pTable->blkRowIdx) != timestamp) {
@ -1496,6 +1572,7 @@ int32_t mJoinSetImplFp(SMJoinOperatorInfo* pJoin) {
switch (pJoin->subType) { switch (pJoin->subType) {
case JOIN_STYPE_OUTER: case JOIN_STYPE_OUTER:
pJoin->joinFp = mLeftJoinDo; pJoin->joinFp = mLeftJoinDo;
pJoin->grpResetFp = mLeftJoinGroupReset;
break; break;
case JOIN_STYPE_SEMI: case JOIN_STYPE_SEMI:
pJoin->joinFp = mSemiJoinDo; pJoin->joinFp = mSemiJoinDo;

View File

@ -66,7 +66,7 @@ enum {
}; };
#define COL_DISPLAY_WIDTH 18 #define COL_DISPLAY_WIDTH 18
#define JT_MAX_LOOP 10000 #define JT_MAX_LOOP 20000
#define LEFT_BLK_ID 0 #define LEFT_BLK_ID 0
#define RIGHT_BLK_ID 1 #define RIGHT_BLK_ID 1
@ -107,6 +107,7 @@ typedef struct {
typedef struct { typedef struct {
bool filter; bool filter;
bool asc; bool asc;
bool grpJoin;
int32_t leftMaxRows; int32_t leftMaxRows;
int32_t leftMaxGrpRows; int32_t leftMaxGrpRows;
int32_t rightMaxRows; int32_t rightMaxRows;
@ -119,6 +120,7 @@ typedef struct {
int64_t jLimit; int64_t jLimit;
int64_t winStartOffset; int64_t winStartOffset;
int64_t winEndOffset; int64_t winEndOffset;
int64_t inGrpId;
int32_t leftTotalRows; int32_t leftTotalRows;
int32_t rightTotalRows; int32_t rightTotalRows;
@ -194,12 +196,13 @@ typedef struct {
int32_t cond; int32_t cond;
bool filter; bool filter;
bool asc; bool asc;
bool grpJoin;
SExecTaskInfo* pTask; SExecTaskInfo* pTask;
} SJoinTestParam; } SJoinTestParam;
SJoinTestCtx jtCtx = {0}; SJoinTestCtx jtCtx = {0};
SJoinTestCtrl jtCtrl = {0, 0, 0, 0}; SJoinTestCtrl jtCtrl = {1, 1, 1, 0};
SJoinTestStat jtStat = {0}; SJoinTestStat jtStat = {0};
SJoinTestResInfo jtRes = {0}; SJoinTestResInfo jtRes = {0};
@ -794,6 +797,7 @@ SSortMergeJoinPhysiNode* createDummySortMergeJoinPhysiNode(SJoinTestParam* param
p->joinType = param->joinType; p->joinType = param->joinType;
p->subType = param->subType; p->subType = param->subType;
p->asofOpType = param->asofOp; p->asofOpType = param->asofOp;
p->grpJoin = param->grpJoin;
if (p->subType == JOIN_STYPE_WIN || param->jLimit > 1 || taosRand() % 2) { if (p->subType == JOIN_STYPE_WIN || param->jLimit > 1 || taosRand() % 2) {
SLimitNode* limitNode = (SLimitNode*)nodesMakeNode(QUERY_NODE_LIMIT); SLimitNode* limitNode = (SLimitNode*)nodesMakeNode(QUERY_NODE_LIMIT);
limitNode->limit = param->jLimit; limitNode->limit = param->jLimit;
@ -824,6 +828,7 @@ SSortMergeJoinPhysiNode* createDummySortMergeJoinPhysiNode(SJoinTestParam* param
jtCtx.winEndOffset = pEnd->datum.i; jtCtx.winEndOffset = pEnd->datum.i;
} }
jtCtx.grpJoin = param->grpJoin;
jtCtx.joinType = param->joinType; jtCtx.joinType = param->joinType;
jtCtx.subType = param->subType; jtCtx.subType = param->subType;
jtCtx.asc = param->asc; jtCtx.asc = param->asc;
@ -831,6 +836,7 @@ SSortMergeJoinPhysiNode* createDummySortMergeJoinPhysiNode(SJoinTestParam* param
jtCtx.asofOpType = param->asofOp; jtCtx.asofOpType = param->asofOp;
jtCtx.leftColOnly = (JOIN_TYPE_LEFT == param->joinType && JOIN_STYPE_SEMI == param->subType); jtCtx.leftColOnly = (JOIN_TYPE_LEFT == param->joinType && JOIN_STYPE_SEMI == param->subType);
jtCtx.rightColOnly = (JOIN_TYPE_RIGHT == param->joinType && JOIN_STYPE_SEMI == param->subType); jtCtx.rightColOnly = (JOIN_TYPE_RIGHT == param->joinType && JOIN_STYPE_SEMI == param->subType);
jtCtx.inGrpId = 1;
createColCond(p, param->cond); createColCond(p, param->cond);
createFilterStart(p, param->filter); createFilterStart(p, param->filter);
@ -1137,6 +1143,10 @@ void createGrpRows(SSDataBlock** ppBlk, int32_t blkId, int32_t grpRows) {
taosArrayPush((blkId == LEFT_BLK_ID) ? jtCtx.leftBlkList : jtCtx.rightBlkList, ppBlk); taosArrayPush((blkId == LEFT_BLK_ID) ? jtCtx.leftBlkList : jtCtx.rightBlkList, ppBlk);
} }
if (jtCtx.grpJoin) {
(*ppBlk)->info.id.groupId = jtCtx.inGrpId;
}
jtCtx.inputStat |= (1 << blkId); jtCtx.inputStat |= (1 << blkId);
SArray* pTableRows = NULL; SArray* pTableRows = NULL;
@ -1184,6 +1194,9 @@ void createGrpRows(SSDataBlock** ppBlk, int32_t blkId, int32_t grpRows) {
*ppBlk = createDummyBlock((blkId == LEFT_BLK_ID) ? LEFT_BLK_ID : RIGHT_BLK_ID); *ppBlk = createDummyBlock((blkId == LEFT_BLK_ID) ? LEFT_BLK_ID : RIGHT_BLK_ID);
blockDataEnsureCapacity(*ppBlk, jtCtx.blkRows); blockDataEnsureCapacity(*ppBlk, jtCtx.blkRows);
taosArrayPush((blkId == LEFT_BLK_ID) ? jtCtx.leftBlkList : jtCtx.rightBlkList, ppBlk); taosArrayPush((blkId == LEFT_BLK_ID) ? jtCtx.leftBlkList : jtCtx.rightBlkList, ppBlk);
if (jtCtx.grpJoin) {
(*ppBlk)->info.id.groupId = jtCtx.inGrpId;
}
} }
filterOut = (peerFilterNum > 0 && (jtCtx.subType != JOIN_STYPE_ASOF && jtCtx.subType != JOIN_STYPE_WIN)) ? true : false; filterOut = (peerFilterNum > 0 && (jtCtx.subType != JOIN_STYPE_ASOF && jtCtx.subType != JOIN_STYPE_WIN)) ? true : false;
@ -1350,6 +1363,9 @@ void makeAppendBlkData(SSDataBlock** ppLeft, SSDataBlock** ppRight, int32_t left
*ppLeft = createDummyBlock(LEFT_BLK_ID); *ppLeft = createDummyBlock(LEFT_BLK_ID);
blockDataEnsureCapacity(*ppLeft, jtCtx.blkRows); blockDataEnsureCapacity(*ppLeft, jtCtx.blkRows);
taosArrayPush(jtCtx.leftBlkList, ppLeft); taosArrayPush(jtCtx.leftBlkList, ppLeft);
if (jtCtx.grpJoin) {
(*ppLeft)->info.id.groupId = jtCtx.inGrpId;
}
} }
createRowData(*ppLeft, 0, i, vRange); createRowData(*ppLeft, 0, i, vRange);
@ -1361,6 +1377,9 @@ void makeAppendBlkData(SSDataBlock** ppLeft, SSDataBlock** ppRight, int32_t left
*ppRight = createDummyBlock(RIGHT_BLK_ID); *ppRight = createDummyBlock(RIGHT_BLK_ID);
blockDataEnsureCapacity(*ppRight, jtCtx.blkRows); blockDataEnsureCapacity(*ppRight, jtCtx.blkRows);
taosArrayPush(jtCtx.rightBlkList, ppRight); taosArrayPush(jtCtx.rightBlkList, ppRight);
if (jtCtx.grpJoin) {
(*ppRight)->info.id.groupId = jtCtx.inGrpId;
}
} }
createRowData(*ppRight, rightOffset, i, vRange); createRowData(*ppRight, rightOffset, i, vRange);
@ -2215,18 +2234,39 @@ void createTsEqGrpRows(SSDataBlock** ppLeft, SSDataBlock** ppRight, int32_t left
taosArrayPush(jtCtx.leftBlkList, ppLeft); taosArrayPush(jtCtx.leftBlkList, ppLeft);
} }
if (jtCtx.grpJoin) {
(*ppLeft)->info.id.groupId = jtCtx.inGrpId;
}
if (NULL == *ppRight && rightGrpRows > 0) { if (NULL == *ppRight && rightGrpRows > 0) {
*ppRight = createDummyBlock(RIGHT_BLK_ID); *ppRight = createDummyBlock(RIGHT_BLK_ID);
blockDataEnsureCapacity(*ppRight, jtCtx.blkRows); blockDataEnsureCapacity(*ppRight, jtCtx.blkRows);
taosArrayPush(jtCtx.rightBlkList, ppRight); taosArrayPush(jtCtx.rightBlkList, ppRight);
} }
if (jtCtx.grpJoin) {
(*ppRight)->info.id.groupId = jtCtx.inGrpId;
}
makeAppendBlkData(ppLeft, ppRight, leftGrpRows, rightGrpRows); makeAppendBlkData(ppLeft, ppRight, leftGrpRows, rightGrpRows);
appendEqGrpRes(leftGrpRows, rightGrpRows); appendEqGrpRes(leftGrpRows, rightGrpRows);
} }
void forceFlushResRows() {
if (JOIN_STYPE_ASOF == jtCtx.subType && taosArrayGetSize(jtCtx.leftRowsList) > 0) {
ASSERT(OP_TYPE_LOWER_EQUAL == jtCtx.asofOpType || OP_TYPE_LOWER_THAN == jtCtx.asofOpType);
chkAppendAsofGreaterResRows(true);
} else if (JOIN_STYPE_WIN == jtCtx.subType && taosArrayGetSize(jtCtx.leftRowsList) > 0) {
chkAppendWinResRows(true);
}
taosArrayClear(jtCtx.rightRowsList);
taosArrayClear(jtCtx.rightFilterOut);
taosArrayClear(jtCtx.leftRowsList);
}
void createBothBlkRowsData(void) { void createBothBlkRowsData(void) {
SSDataBlock* pLeft = NULL; SSDataBlock* pLeft = NULL;
@ -2269,6 +2309,13 @@ void createBothBlkRowsData(void) {
} }
} }
if (jtCtx.grpJoin && (0 == taosRand() % 3)) {
forceFlushResRows();
jtCtx.inGrpId++;
pLeft = NULL;
pRight = NULL;
}
switch (grpType) { switch (grpType) {
case 0: case 0:
createGrpRows(&pLeft, LEFT_BLK_ID, leftGrpRows); createGrpRows(&pLeft, LEFT_BLK_ID, leftGrpRows);
@ -2286,12 +2333,7 @@ void createBothBlkRowsData(void) {
} }
} }
if (JOIN_STYPE_ASOF == jtCtx.subType && taosArrayGetSize(jtCtx.leftRowsList) > 0) { forceFlushResRows();
ASSERT(OP_TYPE_LOWER_EQUAL == jtCtx.asofOpType || OP_TYPE_LOWER_THAN == jtCtx.asofOpType);
chkAppendAsofGreaterResRows(true);
} else if (JOIN_STYPE_WIN == jtCtx.subType && taosArrayGetSize(jtCtx.leftRowsList) > 0) {
chkAppendWinResRows(true);
}
} }
void createDummyBlkList(int32_t leftMaxRows, int32_t leftMaxGrpRows, int32_t rightMaxRows, int32_t rightMaxGrpRows, int32_t blkRows) { void createDummyBlkList(int32_t leftMaxRows, int32_t leftMaxGrpRows, int32_t rightMaxRows, int32_t rightMaxGrpRows, int32_t blkRows) {
@ -2382,6 +2424,9 @@ void printColList(char* title, bool left, int32_t* colList, bool filter, char* o
} }
void printInputRowData(SSDataBlock* pBlk, int32_t* rowIdx) { void printInputRowData(SSDataBlock* pBlk, int32_t* rowIdx) {
if (jtCtx.grpJoin) {
printf("%5" PRIu64, pBlk->info.id.groupId);
}
for (int32_t c = 0; c < MAX_SLOT_NUM; ++c) { for (int32_t c = 0; c < MAX_SLOT_NUM; ++c) {
SColumnInfoData* pCol = (SColumnInfoData*)taosArrayGet(pBlk->pDataBlock, c); SColumnInfoData* pCol = (SColumnInfoData*)taosArrayGet(pBlk->pDataBlock, c);
ASSERT(pCol->info.type == jtInputColType[c]); ASSERT(pCol->info.type == jtInputColType[c]);
@ -2418,13 +2463,13 @@ void printInputData() {
break; break;
} }
printf("\t--------------------------blk end-------------------------------"); printf("\t--------------------------blk end------------------------------- ");
jtCtx.leftBlkReadIdx++; jtCtx.leftBlkReadIdx++;
leftRowIdx = 0; leftRowIdx = 0;
break; break;
} }
} else { } else {
printf("%72s", " "); printf("%*s", jtCtx.grpJoin ? 77 : 72, " ");
} }
if (jtCtx.rightBlkReadIdx < taosArrayGetSize(jtCtx.rightBlkList)) { if (jtCtx.rightBlkReadIdx < taosArrayGetSize(jtCtx.rightBlkList)) {
@ -2435,7 +2480,7 @@ void printInputData() {
break; break;
} }
printf("\t--------------------------blk end----------------------------\t"); printf("\t%*s--------------------------blk end----------------------------\t", jtCtx.grpJoin ? 5 : 0, " ");
jtCtx.rightBlkReadIdx++; jtCtx.rightBlkReadIdx++;
rightRowIdx = 0; rightRowIdx = 0;
break; break;
@ -2486,9 +2531,9 @@ void printBasicInfo(char* caseName) {
char inputStat[4] = {0}; char inputStat[4] = {0};
printf("\n%dth TEST [%s] START\nBasic Info:\n\t asc:%d\n\t filter:%d\n\t maxRows:left-%d right-%d\n\t " printf("\n%dth TEST [%s] START\nBasic Info:\n\t asc:%d\n\t filter:%d\n\t maxRows:left-%d right-%d\n\t "
"maxGrpRows:left-%d right-%d\n\t blkRows:%d\n\t colCond:%s\n\t joinType:%s\n\t " "maxGrpRows:left-%d right-%d\n\t blkRows:%d\n\t colCond:%s\n\t joinType:%s\n\t "
"subType:%s\n\t inputStat:%s\n", jtCtx.loopIdx, caseName, jtCtx.asc, jtCtx.filter, jtCtx.leftMaxRows, jtCtx.rightMaxRows, "subType:%s\n\t inputStat:%s\n\t groupJoin:%s\n", jtCtx.loopIdx, caseName, jtCtx.asc, jtCtx.filter, jtCtx.leftMaxRows, jtCtx.rightMaxRows,
jtCtx.leftMaxGrpRows, jtCtx.rightMaxGrpRows, jtCtx.blkRows, jtColCondStr[jtCtx.colCond], jtJoinTypeStr[jtCtx.joinType], jtCtx.leftMaxGrpRows, jtCtx.rightMaxGrpRows, jtCtx.blkRows, jtColCondStr[jtCtx.colCond], jtJoinTypeStr[jtCtx.joinType],
jtSubTypeStr[jtCtx.subType], getInputStatStr(inputStat)); jtSubTypeStr[jtCtx.subType], getInputStatStr(inputStat), jtCtx.grpJoin ? "true" : "false");
if (JOIN_STYPE_ASOF == jtCtx.subType) { if (JOIN_STYPE_ASOF == jtCtx.subType) {
printf("\t asofOp:%s\n\t JLimit:%" PRId64 "\n", getAsofOpStr(), jtCtx.jLimit); printf("\t asofOp:%s\n\t JLimit:%" PRId64 "\n", getAsofOpStr(), jtCtx.jLimit);
@ -2755,7 +2800,7 @@ void runSingleTest(char* caseName, SJoinTestParam* param) {
bool contLoop = true; bool contLoop = true;
SSortMergeJoinPhysiNode* pNode = createDummySortMergeJoinPhysiNode(param); SSortMergeJoinPhysiNode* pNode = createDummySortMergeJoinPhysiNode(param);
createDummyBlkList(200, 200, 200, 200, 20); createDummyBlkList(12, 3, 12, 3, 3);
while (contLoop) { while (contLoop) {
rerunBlockedHere(); rerunBlockedHere();
@ -2799,6 +2844,7 @@ TEST(innerJoin, noCondTest) {
param.subType = JOIN_STYPE_NONE; param.subType = JOIN_STYPE_NONE;
param.cond = TEST_NO_COND; param.cond = TEST_NO_COND;
param.asc = true; param.asc = true;
param.grpJoin = false;
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.filter = false; param.filter = false;
@ -2824,6 +2870,7 @@ TEST(innerJoin, eqCondTest) {
param.subType = JOIN_STYPE_NONE; param.subType = JOIN_STYPE_NONE;
param.cond = TEST_EQ_COND; param.cond = TEST_EQ_COND;
param.asc = true; param.asc = true;
param.grpJoin = false;
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.filter = false; param.filter = false;
@ -2849,6 +2896,7 @@ TEST(innerJoin, onCondTest) {
param.subType = JOIN_STYPE_NONE; param.subType = JOIN_STYPE_NONE;
param.cond = TEST_ON_COND; param.cond = TEST_ON_COND;
param.asc = true; param.asc = true;
param.grpJoin = false;
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.filter = false; param.filter = false;
@ -2874,6 +2922,7 @@ TEST(innerJoin, fullCondTest) {
param.subType = JOIN_STYPE_NONE; param.subType = JOIN_STYPE_NONE;
param.cond = TEST_FULL_COND; param.cond = TEST_FULL_COND;
param.asc = true; param.asc = true;
param.grpJoin = false;
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.filter = false; param.filter = false;
@ -2904,9 +2953,11 @@ TEST(leftOuterJoin, noCondTest) {
param.asc = true; param.asc = true;
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.grpJoin = taosRand() % 2 ? true : false;
param.filter = false; param.filter = false;
runSingleTest(caseName, &param); runSingleTest(caseName, &param);
param.grpJoin = taosRand() % 2 ? true : false;
param.filter = true; param.filter = true;
runSingleTest(caseName, &param); runSingleTest(caseName, &param);
} }
@ -2927,6 +2978,7 @@ TEST(leftOuterJoin, eqCondTest) {
param.subType = JOIN_STYPE_OUTER; param.subType = JOIN_STYPE_OUTER;
param.cond = TEST_EQ_COND; param.cond = TEST_EQ_COND;
param.asc = true; param.asc = true;
param.grpJoin = false;
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.filter = false; param.filter = false;
@ -2952,6 +3004,7 @@ TEST(leftOuterJoin, onCondTest) {
param.subType = JOIN_STYPE_OUTER; param.subType = JOIN_STYPE_OUTER;
param.cond = TEST_ON_COND; param.cond = TEST_ON_COND;
param.asc = true; param.asc = true;
param.grpJoin = false;
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.filter = false; param.filter = false;
@ -2977,6 +3030,7 @@ TEST(leftOuterJoin, fullCondTest) {
param.subType = JOIN_STYPE_OUTER; param.subType = JOIN_STYPE_OUTER;
param.cond = TEST_FULL_COND; param.cond = TEST_FULL_COND;
param.asc = true; param.asc = true;
param.grpJoin = false;
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.filter = false; param.filter = false;
@ -3004,6 +3058,7 @@ TEST(fullOuterJoin, noCondTest) {
param.subType = JOIN_STYPE_OUTER; param.subType = JOIN_STYPE_OUTER;
param.cond = TEST_NO_COND; param.cond = TEST_NO_COND;
param.asc = true; param.asc = true;
param.grpJoin = false;
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.filter = false; param.filter = false;
@ -3029,6 +3084,7 @@ TEST(fullOuterJoin, eqCondTest) {
param.subType = JOIN_STYPE_OUTER; param.subType = JOIN_STYPE_OUTER;
param.cond = TEST_EQ_COND; param.cond = TEST_EQ_COND;
param.asc = true; param.asc = true;
param.grpJoin = false;
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.filter = false; param.filter = false;
@ -3055,6 +3111,7 @@ TEST(fullOuterJoin, onCondTest) {
param.subType = JOIN_STYPE_OUTER; param.subType = JOIN_STYPE_OUTER;
param.cond = TEST_ON_COND; param.cond = TEST_ON_COND;
param.asc = true; param.asc = true;
param.grpJoin = false;
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.filter = false; param.filter = false;
@ -3080,6 +3137,7 @@ TEST(fullOuterJoin, fullCondTest) {
param.subType = JOIN_STYPE_OUTER; param.subType = JOIN_STYPE_OUTER;
param.cond = TEST_FULL_COND; param.cond = TEST_FULL_COND;
param.asc = true; param.asc = true;
param.grpJoin = false;
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.filter = false; param.filter = false;
@ -3107,6 +3165,7 @@ TEST(leftSemiJoin, noCondTest) {
param.subType = JOIN_STYPE_SEMI; param.subType = JOIN_STYPE_SEMI;
param.cond = TEST_NO_COND; param.cond = TEST_NO_COND;
param.asc = true; param.asc = true;
param.grpJoin = false;
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.filter = false; param.filter = false;
@ -3132,6 +3191,7 @@ TEST(leftSemiJoin, eqCondTest) {
param.subType = JOIN_STYPE_SEMI; param.subType = JOIN_STYPE_SEMI;
param.cond = TEST_EQ_COND; param.cond = TEST_EQ_COND;
param.asc = true; param.asc = true;
param.grpJoin = false;
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.filter = false; param.filter = false;
@ -3158,6 +3218,7 @@ TEST(leftSemiJoin, onCondTest) {
param.subType = JOIN_STYPE_SEMI; param.subType = JOIN_STYPE_SEMI;
param.cond = TEST_ON_COND; param.cond = TEST_ON_COND;
param.asc = true; param.asc = true;
param.grpJoin = false;
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.filter = false; param.filter = false;
@ -3183,6 +3244,7 @@ TEST(leftSemiJoin, fullCondTest) {
param.subType = JOIN_STYPE_SEMI; param.subType = JOIN_STYPE_SEMI;
param.cond = TEST_FULL_COND; param.cond = TEST_FULL_COND;
param.asc = true; param.asc = true;
param.grpJoin = false;
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.filter = false; param.filter = false;
@ -3210,6 +3272,7 @@ TEST(leftAntiJoin, noCondTest) {
param.subType = JOIN_STYPE_ANTI; param.subType = JOIN_STYPE_ANTI;
param.cond = TEST_NO_COND; param.cond = TEST_NO_COND;
param.asc = true; param.asc = true;
param.grpJoin = false;
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.filter = false; param.filter = false;
@ -3235,6 +3298,7 @@ TEST(leftAntiJoin, eqCondTest) {
param.subType = JOIN_STYPE_ANTI; param.subType = JOIN_STYPE_ANTI;
param.cond = TEST_EQ_COND; param.cond = TEST_EQ_COND;
param.asc = true; param.asc = true;
param.grpJoin = false;
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.filter = false; param.filter = false;
@ -3261,6 +3325,7 @@ TEST(leftAntiJoin, onCondTest) {
param.subType = JOIN_STYPE_ANTI; param.subType = JOIN_STYPE_ANTI;
param.cond = TEST_ON_COND; param.cond = TEST_ON_COND;
param.asc = true; param.asc = true;
param.grpJoin = false;
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.filter = false; param.filter = false;
@ -3286,6 +3351,7 @@ TEST(leftAntiJoin, fullCondTest) {
param.subType = JOIN_STYPE_ANTI; param.subType = JOIN_STYPE_ANTI;
param.cond = TEST_FULL_COND; param.cond = TEST_FULL_COND;
param.asc = true; param.asc = true;
param.grpJoin = false;
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.filter = false; param.filter = false;
@ -3317,10 +3383,12 @@ TEST(leftAsofJoin, noCondGreaterThanTest) {
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.jLimit = taosRand() % 2 ? (1 + (taosRand() % JT_MAX_JLIMIT)) : 1; param.jLimit = taosRand() % 2 ? (1 + (taosRand() % JT_MAX_JLIMIT)) : 1;
param.grpJoin = taosRand() % 2 ? true : false;
param.filter = false; param.filter = false;
runSingleTest(caseName, &param); runSingleTest(caseName, &param);
param.grpJoin = taosRand() % 2 ? true : false;
param.filter = true; param.filter = true;
runSingleTest(caseName, &param); runSingleTest(caseName, &param);
} }
@ -3345,10 +3413,12 @@ TEST(leftAsofJoin, noCondGreaterEqTest) {
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.jLimit = taosRand() % 2 ? (1 + (taosRand() % JT_MAX_JLIMIT)) : 1; param.jLimit = taosRand() % 2 ? (1 + (taosRand() % JT_MAX_JLIMIT)) : 1;
param.grpJoin = taosRand() % 2 ? true : false;
param.filter = false; param.filter = false;
runSingleTest(caseName, &param); runSingleTest(caseName, &param);
param.grpJoin = taosRand() % 2 ? true : false;
param.filter = true; param.filter = true;
runSingleTest(caseName, &param); runSingleTest(caseName, &param);
} }
@ -3374,9 +3444,11 @@ TEST(leftAsofJoin, noCondEqTest) {
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.jLimit = taosRand() % 2 ? (1 + (taosRand() % JT_MAX_JLIMIT)) : 1; param.jLimit = taosRand() % 2 ? (1 + (taosRand() % JT_MAX_JLIMIT)) : 1;
param.grpJoin = taosRand() % 2 ? true : false;
param.filter = false; param.filter = false;
runSingleTest(caseName, &param); runSingleTest(caseName, &param);
param.grpJoin = taosRand() % 2 ? true : false;
param.filter = true; param.filter = true;
runSingleTest(caseName, &param); runSingleTest(caseName, &param);
} }
@ -3402,9 +3474,11 @@ TEST(leftAsofJoin, noCondLowerThanTest) {
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.jLimit = taosRand() % 2 ? (1 + (taosRand() % JT_MAX_JLIMIT)) : 1; param.jLimit = taosRand() % 2 ? (1 + (taosRand() % JT_MAX_JLIMIT)) : 1;
param.grpJoin = taosRand() % 2 ? true : false;
param.filter = false; param.filter = false;
runSingleTest(caseName, &param); runSingleTest(caseName, &param);
param.grpJoin = taosRand() % 2 ? true : false;
param.filter = true; param.filter = true;
runSingleTest(caseName, &param); runSingleTest(caseName, &param);
} }
@ -3431,9 +3505,11 @@ TEST(leftAsofJoin, noCondLowerEqTest) {
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.jLimit = taosRand() % 2 ? (1 + (taosRand() % JT_MAX_JLIMIT)) : 1; param.jLimit = taosRand() % 2 ? (1 + (taosRand() % JT_MAX_JLIMIT)) : 1;
param.grpJoin = taosRand() % 2 ? true : false;
param.filter = false; param.filter = false;
runSingleTest(caseName, &param); runSingleTest(caseName, &param);
param.grpJoin = taosRand() % 2 ? true : false;
param.filter = true; param.filter = true;
runSingleTest(caseName, &param); runSingleTest(caseName, &param);
} }
@ -3462,9 +3538,11 @@ TEST(leftWinJoin, noCondProjectionTest) {
for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) { for (jtCtx.loopIdx = 0; jtCtx.loopIdx < JT_MAX_LOOP; ++jtCtx.loopIdx) {
param.jLimit = taosRand() % 2 ? (1 + (taosRand() % JT_MAX_JLIMIT)) : 1; param.jLimit = taosRand() % 2 ? (1 + (taosRand() % JT_MAX_JLIMIT)) : 1;
param.grpJoin = taosRand() % 2 ? true : false;
param.filter = false; param.filter = false;
runSingleTest(caseName, &param); runSingleTest(caseName, &param);
param.grpJoin = taosRand() % 2 ? true : false;
param.filter = true; param.filter = true;
runSingleTest(caseName, &param); runSingleTest(caseName, &param);
} }

View File

@ -476,7 +476,7 @@ static int32_t logicJoinCopy(const SJoinLogicNode* pSrc, SJoinLogicNode* pDst) {
COPY_SCALAR_FIELD(joinAlgo); COPY_SCALAR_FIELD(joinAlgo);
CLONE_NODE_FIELD(pWindowOffset); CLONE_NODE_FIELD(pWindowOffset);
CLONE_NODE_FIELD(pJLimit); CLONE_NODE_FIELD(pJLimit);
CLONE_NODE_FIELD(winPrimEqCond); CLONE_NODE_FIELD(addPrimEqCond);
CLONE_NODE_FIELD(pPrimKeyEqCond); CLONE_NODE_FIELD(pPrimKeyEqCond);
CLONE_NODE_FIELD(pColEqCond); CLONE_NODE_FIELD(pColEqCond);
CLONE_NODE_FIELD(pColOnCond); CLONE_NODE_FIELD(pColOnCond);

View File

@ -56,7 +56,6 @@ char* getJoinSTypeString(EJoinSubType type) {
char* getFullJoinTypeString(EJoinType type, EJoinSubType stype) { char* getFullJoinTypeString(EJoinType type, EJoinSubType stype) {
static char* joinFullType[][8] = { static char* joinFullType[][8] = {
{},
{"INNER", "INNER", "INNER", "INNER", "INNER", "INNER ANY", "INNER", "INNER"}, {"INNER", "INNER", "INNER", "INNER", "INNER", "INNER ANY", "INNER", "INNER"},
{"LEFT", "LEFT", "LEFT OUTER", "LEFT SEMI", "LEFT ANTI", "LEFT ANY", "LEFT ASOF", "LEFT WINDOW"}, {"LEFT", "LEFT", "LEFT OUTER", "LEFT SEMI", "LEFT ANTI", "LEFT ANY", "LEFT ASOF", "LEFT WINDOW"},
{"RIGHT", "RIGHT", "RIGHT OUTER", "RIGHT SEMI", "RIGHT ANTI", "RIGHT ANY", "RIGHT ASOF", "RIGHT WINDOW"}, {"RIGHT", "RIGHT", "RIGHT OUTER", "RIGHT SEMI", "RIGHT ANTI", "RIGHT ANY", "RIGHT ASOF", "RIGHT WINDOW"},
@ -816,7 +815,7 @@ void nodesDestroyNode(SNode* pNode) {
SJoinTableNode* pJoin = (SJoinTableNode*)pNode; SJoinTableNode* pJoin = (SJoinTableNode*)pNode;
nodesDestroyNode(pJoin->pWindowOffset); nodesDestroyNode(pJoin->pWindowOffset);
nodesDestroyNode(pJoin->pJLimit); nodesDestroyNode(pJoin->pJLimit);
nodesDestroyNode(pJoin->winPrimCond); nodesDestroyNode(pJoin->addPrimCond);
nodesDestroyNode(pJoin->pLeft); nodesDestroyNode(pJoin->pLeft);
nodesDestroyNode(pJoin->pRight); nodesDestroyNode(pJoin->pRight);
nodesDestroyNode(pJoin->pOnCond); nodesDestroyNode(pJoin->pOnCond);
@ -1286,7 +1285,7 @@ void nodesDestroyNode(SNode* pNode) {
destroyLogicNode((SLogicNode*)pLogicNode); destroyLogicNode((SLogicNode*)pLogicNode);
nodesDestroyNode(pLogicNode->pWindowOffset); nodesDestroyNode(pLogicNode->pWindowOffset);
nodesDestroyNode(pLogicNode->pJLimit); nodesDestroyNode(pLogicNode->pJLimit);
nodesDestroyNode(pLogicNode->winPrimEqCond); nodesDestroyNode(pLogicNode->addPrimEqCond);
nodesDestroyNode(pLogicNode->pPrimKeyEqCond); nodesDestroyNode(pLogicNode->pPrimKeyEqCond);
nodesDestroyNode(pLogicNode->pColEqCond); nodesDestroyNode(pLogicNode->pColEqCond);
nodesDestroyNode(pLogicNode->pColOnCond); nodesDestroyNode(pLogicNode->pColOnCond);

View File

@ -3244,7 +3244,7 @@ static int32_t replaceTbName(STranslateContext* pCxt, SSelectStmt* pSelect) {
return pRewriteCxt.errCode; return pRewriteCxt.errCode;
} }
static int32_t addPrimEqCond(SNode** pCond, SRealTableNode* leftTable, SRealTableNode* rightTable) { static int32_t addPrimJoinEqCond(SNode** pCond, SRealTableNode* leftTable, SRealTableNode* rightTable, EJoinType joinType, EJoinSubType subType) {
struct STableMeta* pLMeta = leftTable->pMeta; struct STableMeta* pLMeta = leftTable->pMeta;
struct STableMeta* pRMeta = rightTable->pMeta; struct STableMeta* pRMeta = rightTable->pMeta;
@ -3256,7 +3256,13 @@ static int32_t addPrimEqCond(SNode** pCond, SRealTableNode* leftTable, SRealTabl
SOperatorNode* pOp = (SOperatorNode*)*pCond; SOperatorNode* pOp = (SOperatorNode*)*pCond;
pOp->node.resType.type = TSDB_DATA_TYPE_BOOL; pOp->node.resType.type = TSDB_DATA_TYPE_BOOL;
pOp->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes; pOp->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes;
pOp->opType = OP_TYPE_EQUAL; if (IS_WINDOW_JOIN(subType)) {
pOp->opType = OP_TYPE_EQUAL;
} else if (JOIN_TYPE_LEFT == joinType) {
pOp->opType = OP_TYPE_GREATER_EQUAL;
} else {
pOp->opType = OP_TYPE_LOWER_EQUAL;
}
SColumnNode* pLeft = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN); SColumnNode* pLeft = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
if (NULL == pLeft) { if (NULL == pLeft) {
@ -3302,25 +3308,25 @@ static int32_t checkJoinTable(STranslateContext* pCxt, SJoinTableNode* pJoinTabl
"Join requires valid time series input"); "Join requires valid time series input");
} }
if (JOIN_STYPE_WIN == pJoinTable->subType) { if (IS_ASOF_JOIN(pJoinTable->subType) || IS_WINDOW_JOIN(pJoinTable->subType)) {
if (QUERY_NODE_REAL_TABLE != nodeType(pJoinTable->pLeft) || QUERY_NODE_REAL_TABLE != nodeType(pJoinTable->pRight)) { if (QUERY_NODE_REAL_TABLE != nodeType(pJoinTable->pLeft) || QUERY_NODE_REAL_TABLE != nodeType(pJoinTable->pRight)) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SUPPORT_JOIN, return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SUPPORT_JOIN,
"Only support WINDOW join between tables"); "Only support ASOF/WINDOW join between tables");
} }
SRealTableNode* pLeft = (SRealTableNode*)pJoinTable->pLeft; SRealTableNode* pLeft = (SRealTableNode*)pJoinTable->pLeft;
if (TSDB_SUPER_TABLE != pLeft->pMeta->tableType && TSDB_CHILD_TABLE != pLeft->pMeta->tableType && TSDB_NORMAL_TABLE != pLeft->pMeta->tableType) { if (TSDB_SUPER_TABLE != pLeft->pMeta->tableType && TSDB_CHILD_TABLE != pLeft->pMeta->tableType && TSDB_NORMAL_TABLE != pLeft->pMeta->tableType) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SUPPORT_JOIN, return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SUPPORT_JOIN,
"Unsupported WINDOW join table type"); "Unsupported ASOF/WINDOW join table type");
} }
SRealTableNode* pRight = (SRealTableNode*)pJoinTable->pRight; SRealTableNode* pRight = (SRealTableNode*)pJoinTable->pRight;
if (TSDB_SUPER_TABLE != pRight->pMeta->tableType && TSDB_CHILD_TABLE != pRight->pMeta->tableType && TSDB_NORMAL_TABLE != pRight->pMeta->tableType) { if (TSDB_SUPER_TABLE != pRight->pMeta->tableType && TSDB_CHILD_TABLE != pRight->pMeta->tableType && TSDB_NORMAL_TABLE != pRight->pMeta->tableType) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SUPPORT_JOIN, return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_SUPPORT_JOIN,
"Unsupported WINDOW join table type"); "Unsupported ASOF/WINDOW join table type");
} }
return addPrimEqCond(&pJoinTable->winPrimCond, pLeft, pRight); return addPrimJoinEqCond(&pJoinTable->addPrimCond, pLeft, pRight, pJoinTable->joinType, pJoinTable->subType);
} }
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;

View File

@ -549,7 +549,7 @@ static int32_t createJoinLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
pJoin->isLowLevelJoin = pJoinTable->isLowLevelJoin; pJoin->isLowLevelJoin = pJoinTable->isLowLevelJoin;
pJoin->pWindowOffset = nodesCloneNode(pJoinTable->pWindowOffset); pJoin->pWindowOffset = nodesCloneNode(pJoinTable->pWindowOffset);
pJoin->pJLimit = nodesCloneNode(pJoinTable->pJLimit); pJoin->pJLimit = nodesCloneNode(pJoinTable->pJLimit);
pJoin->winPrimEqCond = nodesCloneNode(pJoinTable->winPrimCond); pJoin->addPrimEqCond = nodesCloneNode(pJoinTable->addPrimCond);
pJoin->node.pChildren = nodesMakeList(); pJoin->node.pChildren = nodesMakeList();
pJoin->seqWinGroup = (JOIN_STYPE_WIN == pJoinTable->subType) && pSelect->hasAggFuncs; pJoin->seqWinGroup = (JOIN_STYPE_WIN == pJoinTable->subType) && pSelect->hasAggFuncs;
if (NULL == pJoin->node.pChildren) { if (NULL == pJoin->node.pChildren) {

View File

@ -98,8 +98,8 @@ static SJoinOptimizeOpt gJoinOpt[JOIN_TYPE_MAX_VALUE][JOIN_STYPE_MAX_VALUE] = {
static SJoinOptimizeOpt gJoinWhereOpt[JOIN_TYPE_MAX_VALUE][JOIN_STYPE_MAX_VALUE] = { static SJoinOptimizeOpt gJoinWhereOpt[JOIN_TYPE_MAX_VALUE][JOIN_STYPE_MAX_VALUE] = {
/* NONE OUTER SEMI ANTI ASOF WINDOW */ /* NONE OUTER SEMI ANTI ASOF WINDOW */
/*INNER*/ {{PUSH_DOWN_ALL_COND}, {0}, {0}, {0}, {0}, {0}}, /*INNER*/ {{PUSH_DOWN_ALL_COND}, {0}, {0}, {0}, {0}, {0}},
/*LEFT*/ {{0}, {PUSH_DOWN_LEFT_FLT}, {PUSH_DOWN_ALL_COND}, {PUSH_DOWN_LEFT_FLT}, {PUSH_DOWN_LEFT_FLT}, {PUSH_DOWN_LEFT_FLT}}, /*LEFT*/ {{0}, {PUSH_DOWN_LEFT_FLT}, {PUSH_DOWN_LEFT_FLT}, {PUSH_DOWN_LEFT_FLT}, {PUSH_DOWN_LEFT_FLT}, {PUSH_DOWN_LEFT_FLT}},
/*RIGHT*/ {{0}, {PUSH_DOWN_RIGHT_FLT}, {PUSH_DOWN_ALL_COND}, {PUSH_DOWN_RIGHT_FLT}, {PUSH_DOWN_RIGHT_FLT}, {PUSH_DOWN_RIGHT_FLT}}, /*RIGHT*/ {{0}, {PUSH_DOWN_RIGHT_FLT}, {PUSH_DOWN_RIGHT_FLT}, {PUSH_DOWN_RIGHT_FLT}, {PUSH_DOWN_RIGHT_FLT}, {PUSH_DOWN_RIGHT_FLT}},
/*FULL*/ {{0}, {0}, {0}, {0}, {0}, {0}}, /*FULL*/ {{0}, {0}, {0}, {0}, {0}, {0}},
}; };
@ -757,8 +757,14 @@ static bool pdcJoinIsPrimEqualCond(SJoinLogicNode* pJoin, SNode* pCond) {
} }
SOperatorNode* pOper = (SOperatorNode*)pCond; SOperatorNode* pOper = (SOperatorNode*)pCond;
if (OP_TYPE_EQUAL != pOper->opType && JOIN_STYPE_ASOF != pJoin->subType) { if (OP_TYPE_EQUAL != pOper->opType) {
return false; if (JOIN_STYPE_ASOF != pJoin->subType) {
return false;
}
if (OP_TYPE_GREATER_THAN != pOper->opType && OP_TYPE_GREATER_EQUAL != pOper->opType &&
OP_TYPE_LOWER_THAN != pOper->opType && OP_TYPE_LOWER_EQUAL != pOper->opType) {
return false;
}
} }
SSHashObj* pLeftTables = NULL; SSHashObj* pLeftTables = NULL;
@ -809,8 +815,7 @@ static int32_t pdcJoinSplitPrimInLogicCond(SJoinLogicNode* pJoin, SNode** ppPrim
SNodeList* pOnConds = NULL; SNodeList* pOnConds = NULL;
SNode* pCond = NULL; SNode* pCond = NULL;
WHERE_EACH(pCond, pLogicCond->pParameterList) { WHERE_EACH(pCond, pLogicCond->pParameterList) {
if (pdcJoinIsPrimEqualCond(pJoin, pCond)) { if (pdcJoinIsPrimEqualCond(pJoin, pCond) && (NULL == *ppPrimEqCond)) {
nodesDestroyNode(*ppPrimEqCond);
*ppPrimEqCond = nodesCloneNode(pCond); *ppPrimEqCond = nodesCloneNode(pCond);
ERASE_NODE(pLogicCond->pParameterList); ERASE_NODE(pLogicCond->pParameterList);
} else { } else {
@ -1195,11 +1200,15 @@ static int32_t pdcJoinAddWhereFilterColsToTarget(SOptimizeContext* pCxt, SJoinLo
static int32_t pdcJoinCheckAllCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin) { static int32_t pdcJoinCheckAllCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin) {
if (NULL == pJoin->pFullOnCond) { if (NULL == pJoin->pFullOnCond) {
if (IS_WINDOW_JOIN(pJoin->subType)) { if (IS_WINDOW_JOIN(pJoin->subType) || IS_ASOF_JOIN(pJoin->subType)) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
if (NULL == pJoin->node.pConditions) {
return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN);
}
if ((!IS_INNER_NONE_JOIN(pJoin->joinType, pJoin->subType)) || NULL == pJoin->node.pConditions) { if (!IS_INNER_NONE_JOIN(pJoin->joinType, pJoin->subType)) {
return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN); return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN);
} }
} }
@ -1210,15 +1219,22 @@ static int32_t pdcJoinCheckAllCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin
if (errCond) { if (errCond) {
return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_NOT_SUPPORT_JOIN_COND); return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_NOT_SUPPORT_JOIN_COND);
} }
if (IS_WINDOW_JOIN(pJoin->subType)) { if (IS_WINDOW_JOIN(pJoin->subType) || IS_ASOF_JOIN(pJoin->subType)) {
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_EXPECTED_TS_EQUAL); return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_EXPECTED_TS_EQUAL);
} else if (IS_WINDOW_JOIN(pJoin->subType)) {
return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_NOT_SUPPORT_JOIN_COND);
} }
if (IS_ASOF_JOIN(pJoin->subType)) {
nodesDestroyNode(pJoin->addPrimEqCond);
pJoin->addPrimEqCond = NULL;
}
if (IS_WINDOW_JOIN(pJoin->subType)) {
return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_NOT_SUPPORT_JOIN_COND);
}
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
@ -1235,6 +1251,21 @@ static int32_t pdcJoinHandleGrpJoinCond(SOptimizeContext* pCxt, SJoinLogicNode*
pJoin->pTagEqCond = NULL; pJoin->pTagEqCond = NULL;
nodesDestroyNode(pJoin->pFullOnCond); nodesDestroyNode(pJoin->pFullOnCond);
pJoin->pFullOnCond = NULL; pJoin->pFullOnCond = NULL;
if (!pJoin->allEqTags) {
SNode* pNode = NULL;
FOREACH(pNode, pJoin->pLeftEqNodes) {
SColumnNode* pCol = (SColumnNode*)pNode;
if (COLUMN_TYPE_TAG != pCol->colType && PRIMARYKEY_TIMESTAMP_COL_ID == pCol->colId) {
return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_NOT_SUPPORT_JOIN_COND);
}
}
FOREACH(pNode, pJoin->pRightEqNodes) {
SColumnNode* pCol = (SColumnNode*)pNode;
if (COLUMN_TYPE_TAG != pCol->colType && PRIMARYKEY_TIMESTAMP_COL_ID == pCol->colId) {
return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_NOT_SUPPORT_JOIN_COND);
}
}
}
break; break;
default: default:
break; break;

View File

@ -812,7 +812,7 @@ static int32_t setColEqCond(SNode* pEqCond, int32_t subType, int16_t leftBlkId,
return TSDB_CODE_PLAN_INTERNAL_ERROR; return TSDB_CODE_PLAN_INTERNAL_ERROR;
} }
SNode* pParam = nodesListGetNode(pFunc->pParameterList, 0); SNode* pParam = nodesListGetNode(pFunc->pParameterList, 0);
if (QUERY_NODE_COLUMN == nodeType(pParam)) { if (QUERY_NODE_COLUMN != nodeType(pParam)) {
planError("invalid primary cond left timetruncate param type, leftParamType:%d", nodeType(pParam)); planError("invalid primary cond left timetruncate param type, leftParamType:%d", nodeType(pParam));
return TSDB_CODE_PLAN_INTERNAL_ERROR; return TSDB_CODE_PLAN_INTERNAL_ERROR;
} }
@ -856,7 +856,7 @@ static int32_t setColEqCond(SNode* pEqCond, int32_t subType, int16_t leftBlkId,
return TSDB_CODE_PLAN_INTERNAL_ERROR; return TSDB_CODE_PLAN_INTERNAL_ERROR;
} }
SNode* pParam = nodesListGetNode(pFunc->pParameterList, 0); SNode* pParam = nodesListGetNode(pFunc->pParameterList, 0);
if (QUERY_NODE_COLUMN == nodeType(pParam)) { if (QUERY_NODE_COLUMN != nodeType(pParam)) {
planError("invalid primary cond right timetruncate param type, rightParamType:%d", nodeType(pParam)); planError("invalid primary cond right timetruncate param type, rightParamType:%d", nodeType(pParam));
return TSDB_CODE_PLAN_INTERNAL_ERROR; return TSDB_CODE_PLAN_INTERNAL_ERROR;
} }
@ -915,11 +915,17 @@ static int32_t createMergeJoinPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChi
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = setColEqCond(pJoin->pPrimKeyCond, pJoin->subType, pLeftDesc->dataBlockId, pRightDesc->dataBlockId, pJoin); code = setColEqCond(pJoin->pPrimKeyCond, pJoin->subType, pLeftDesc->dataBlockId, pRightDesc->dataBlockId, pJoin);
} }
if (TSDB_CODE_SUCCESS == code && NULL != pJoin->leftPrimExpr) {
code = addDataBlockSlot(pCxt, &pJoin->leftPrimExpr, pLeftDesc);
}
if (TSDB_CODE_SUCCESS == code && NULL != pJoin->rightPrimExpr) {
code = addDataBlockSlot(pCxt, &pJoin->rightPrimExpr, pRightDesc);
}
} }
if (TSDB_CODE_SUCCESS == code && NULL != pJoinLogicNode->winPrimEqCond) { if (TSDB_CODE_SUCCESS == code && NULL != pJoinLogicNode->addPrimEqCond) {
SNode* pPrimKeyCond = NULL; SNode* pPrimKeyCond = NULL;
code = setNodeSlotId(pCxt, pLeftDesc->dataBlockId, pRightDesc->dataBlockId, pJoinLogicNode->winPrimEqCond, code = setNodeSlotId(pCxt, pLeftDesc->dataBlockId, pRightDesc->dataBlockId, pJoinLogicNode->addPrimEqCond,
&pPrimKeyCond); &pPrimKeyCond);
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = setColEqCond(pPrimKeyCond, pJoin->subType, pLeftDesc->dataBlockId, pRightDesc->dataBlockId, pJoin); code = setColEqCond(pPrimKeyCond, pJoin->subType, pLeftDesc->dataBlockId, pRightDesc->dataBlockId, pJoin);

View File

@ -19,7 +19,7 @@
static char* getUsageErrFormat(int32_t errCode) { static char* getUsageErrFormat(int32_t errCode) {
switch (errCode) { switch (errCode) {
case TSDB_CODE_PLAN_EXPECTED_TS_EQUAL: case TSDB_CODE_PLAN_EXPECTED_TS_EQUAL:
return "left.ts = right.ts is expected in join expression"; return "primary timestamp equal condition is expected in join conditions";
case TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN: case TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN:
return "not support cross join"; return "not support cross join";
case TSDB_CODE_PLAN_NOT_SUPPORT_JOIN_COND: case TSDB_CODE_PLAN_NOT_SUPPORT_JOIN_COND:

View File

@ -1285,7 +1285,7 @@ int32_t toCharFunction(SScalarParam* pInput, int32_t inputNum, SScalarParam* pOu
} }
/** Time functions **/ /** Time functions **/
static int64_t offsetFromTz(char *timezone, int64_t factor) { int64_t offsetFromTz(char *timezone, int64_t factor) {
char *minStr = &timezone[3]; char *minStr = &timezone[3];
int64_t minutes = taosStr2Int64(minStr, NULL, 10); int64_t minutes = taosStr2Int64(minStr, NULL, 10);
memset(minStr, 0, strlen(minStr)); memset(minStr, 0, strlen(minStr));

View File

@ -69,6 +69,7 @@ run tsim/join/left_asof_join.sim
run tsim/join/right_asof_join.sim run tsim/join/right_asof_join.sim
run tsim/join/left_win_join.sim run tsim/join/left_win_join.sim
run tsim/join/right_win_join.sim run tsim/join/right_win_join.sim
run tsim/join/join_scalar.sim
print ================== restart server to commit data into disk 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 stop -x SIGINT
@ -87,5 +88,6 @@ run tsim/join/left_asof_join.sim
run tsim/join/right_asof_join.sim run tsim/join/right_asof_join.sim
run tsim/join/left_win_join.sim run tsim/join/left_win_join.sim
run tsim/join/right_win_join.sim run tsim/join/right_win_join.sim
run tsim/join/join_scalar.sim
system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode1 -s stop -x SIGINT

View File

@ -0,0 +1,81 @@
sql connect
sql use test0;
sql select a.ts, a.col1, b.ts, b.col1 from sta a left join sta b on timetruncate(a.ts, 1h) = timetruncate(b.ts, 1h);
if $rows != 64 then
return -1
endi
sql select a.ts, a.col1, b.ts, b.col1 from sta a join sta b on timetruncate(a.ts, 1h) = timetruncate(b.ts, 1h);
if $rows != 64 then
return -1
endi
sql select a.ts, a.col1, b.ts, b.col1 from sta a join sta b on timetruncate(a.ts, 1h) = timetruncate(b.ts, 1h) and a.col1=b.col1;
if $rows != 12 then
return -1
endi
sql select a.ts, a.col1, b.ts, b.col1 from sta a join sta b on timetruncate(a.ts, 1m) = b.ts;
if $rows != 16 then
return -1
endi
sql select a.ts, b.col1 from sta a left join sta b on timetruncate(b.ts, 1h) = a.ts;
if $rows != 8 then
return -1
endi
sql select a.ts, b.col1,timetruncate(a.col1, 1h) from sta a left join sta b on a.ts = b.ts and timetruncate(a.col1, 1h) = timetruncate(a.col1, 1h);
if $rows != 12 then
return -1
endi
sql select a.ts, b.col1 from sta a left semi join sta b on timetruncate(a.ts, 1h) = timetruncate(b.ts, 1h);
if $rows != 8 then
return -1
endi
sql select a.ts, b.col1 from sta a left anti join sta b on timetruncate(a.ts, 1h) = timetruncate(b.ts, 1h);
if $rows != 0 then
return -1
endi
sql select a.ts, b.col1 from sta a left asof join sta b on timetruncate(a.ts, 1h) > timetruncate(b.ts, 1h);
if $rows != 8 then
return -1
endi
sql select a.ts, b.col1 from sta a left asof join sta b on timetruncate(a.ts, 1h) >= timetruncate(b.ts, 1h) jlimit 2;
if $rows != 16 then
return -1
endi
sql select a.ts, b.col1 from sta a left asof join sta b on timetruncate(a.ts, 1h) >= timetruncate(b.ts, 1h) jlimit 8;
if $rows != 64 then
return -1
endi
sql select a.ts, b.col1 from sta a left asof join sta b on timetruncate(a.ts, 1h) >= timetruncate(b.ts, 1h) jlimit 9;
if $rows != 64 then
return -1
endi
sql select a.ts, b.ts from sta a left asof join sta b on a.col1 =b.col1 and timetruncate(a.ts, 1h) > timetruncate(b.ts, 1h) jlimit 2;
if $rows != 8 then
return -1
endi
sql select a.ts, b.ts from sta a left asof join sta b on timetruncate(a.ts, 1h) >= timetruncate(b.ts, 1h) jlimit 2 where timetruncate(a.ts, 1h) >= timetruncate(b.ts, 1h);
if $rows != 16 then
return -1
endi
sql_error select a.ts, b.ts from sta a left asof join sta b on a.ts=b.ts and a.ts=b.ts;
sql_error select a.ts, b.ts from sta a left asof join sta b on timetruncate(a.ts, 1h) > timetruncate(b.ts, 1h) and timetruncate(a.ts, 1h) > timetruncate(b.ts, 1h);
sql_error select a.ts, b.ts from sta a left asof join sta b on timetruncate(a.ts, 1h) >= timetruncate(b.ts, 1h) and a.ts > timetruncate(b.ts, 1s) jlimit 2;
sql_error select a.ts, b.ts from sta a left asof join sta b on a.ts > timetruncate(b.ts, 1s) and timetruncate(a.ts, 1h) >= timetruncate(b.ts, 1h) jlimit 2;
sql_error select a.ts, b.ts from sta a left asof join sta b on timetruncate(a.ts, 1h) >= timetruncate(b.ts, 1h) and a.ts =b.col1 jlimit 2;
sql_error select a.ts, b.col1 from sta a left join sta b on timetruncate(b.ts, 1h) + 1 = a.ts;
sql_error select a.ts, b.col1 from sta a left join sta b on timetruncate(b.ts, 1h) = a.ts + 1;
sql_error select a.ts, b.col1 from sta a left join sta b on b.ts + 1 = a.ts + 1;

View File

@ -960,10 +960,31 @@ if $data11 != 2 then
return -1 return -1
endi endi
sql select a.ts, b.ts from sta a left asof join sta b;
if $rows != 8 then
return -1
endi
sql select a.ts, b.ts from sta a left asof join sta b jlimit 3;
if $rows != 22 then
return -1
endi
sql select a.ts, b.ts from sta a left asof join sta b where a.ts > b.ts;
if $rows != 0 then
return -1
endi
sql select a.ts, b.ts from sta a left asof join sta b jlimit 3 where a.ts > b.ts;
if $rows != 10 then
return -1
endi
sql_error select a.ts, b.ts from sta a asof join sta b on a.ts = b.ts;
sql_error select a.ts, b.ts from sta a full asof join sta b on a.ts = b.ts;
sql_error select a.ts, b.ts from sta a left asof join sta b on a.ts != b.ts;
sql_error select a.ts, b.ts from sta a left asof join sta b on a.ts >=b.ts and a.col1=a.ts; sql_error select a.ts, b.ts from sta a left asof join sta b on a.ts >=b.ts and a.col1=a.ts;
sql_error select a.ts, b.ts from sta a left asof join sta b on a.ts >=b.ts and a.col1 > 1; sql_error select a.ts, b.ts from sta a left asof join sta b on a.ts >=b.ts and a.col1 > 1;
sql_error select a.ts, b.ts from tba1 a left asof join tba2 b on a.ts > b.ts and a.col1 > b.col1 jlimit 2 order by a.ts; sql_error select a.ts, b.ts from tba1 a left asof join tba2 b on a.ts > b.ts and a.col1 > b.col1 jlimit 2 order by a.ts;
sql_error select a.ts, b.ts from tba1 a left asof join tba2 b on a.ts > b.ts and a.col1 = 1 jlimit 2 order by a.ts; sql_error select a.ts, b.ts from tba1 a left asof join tba2 b on a.ts > b.ts and a.col1 = 1 jlimit 2 order by a.ts;
sql_error select a.t1, a.ts, b.ts from sta a left asof join sta b on a.ts <= b.ts and a.t1=b.t1 and a.col1=b.col1 jlimit 2 having(a.ts>0) order by a.t1, a.ts, b.ts; sql_error select a.t1, a.ts, b.ts from sta a left asof join sta b on a.ts <= b.ts and a.t1=b.t1 and a.col1=b.col1 jlimit 2 having(a.ts>0) order by a.t1, a.ts, b.ts;
sql_error select count(*) from sta a left asof join sta b on a.ts <= b.ts and a.t1=b.t1 and a.col1=b.col1 jlimit 2 where a.ts > '2023-11-17 16:29:00.000' slimit 1; sql_error select count(*) from sta a left asof join sta b on a.ts <= b.ts and a.t1=b.t1 and a.col1=b.col1 jlimit 2 where a.ts > '2023-11-17 16:29:00.000' slimit 1;
sql_error select a.ts, b.ts from (select * from sta) a left asof join sta b where a.ts = b.ts;

View File

@ -74,3 +74,6 @@ if $data11 != 4 then
return -1 return -1
endi endi
sql_error select a.ts, b.ts from sta a left semi join sta b jlimit 3 where a.ts > b.ts;
sql_error select a.ts, b.ts from sta a left semi join sta b where a.ts > b.ts;
sql_error select a.ts, b.ts from sta a left semi join sta b on a.ts > 1 where a.ts = b.ts;

View File

@ -581,3 +581,7 @@ sql_error select a.ts, b.ts from sta a left window join sta b window_offset(-1s,
sql_error select a.ts from sta a left window join sta b window_offset(-1s, 1s) where b.col1 between 2 and 4 having(a.ts > 0) order by count(*); sql_error select a.ts from sta a left window join sta b window_offset(-1s, 1s) where b.col1 between 2 and 4 having(a.ts > 0) order by count(*);
sql_error select a.ts, count(*),last(b.ts) from sta a left window join sta b window_offset(-1s, 1s) slimit 1; sql_error select a.ts, count(*),last(b.ts) from sta a left window join sta b window_offset(-1s, 1s) slimit 1;
sql_error select a.ts, b.ts from sta a left window join sta b on a.t1=1 window_offset(-1s, 1s) order by a.t1, a.ts; sql_error select a.ts, b.ts from sta a left window join sta b on a.t1=1 window_offset(-1s, 1s) order by a.t1, a.ts;
sql_error select a.ts, b.ts from sta a left window join sta b on a.ts > 1 window_offset(-1s, 1s) where a.ts = b.ts;
sql_error select a.ts, b.ts from sta a left window join sta b on a.ts =b.ts window_offset(-1s, 1s) where a.ts = b.ts;
sql_error select a.ts, b.ts from sta a left window join sta b window_offset(-1, 1) where a.ts = b.ts;
sql_error select a.ts, b.ts from (select * from sta) a left window join sta b window_offset(-1s, 1s) where a.ts = b.ts;