fix: join condition push down issue
This commit is contained in:
parent
8fc0f1bbd6
commit
91d6734b34
|
@ -276,87 +276,85 @@
|
||||||
#define TK_JOIN 258
|
#define TK_JOIN 258
|
||||||
#define TK_INNER 259
|
#define TK_INNER 259
|
||||||
#define TK_SELECT 260
|
#define TK_SELECT 260
|
||||||
#define TK_NO_BATCH_SCAN 261
|
#define TK_NK_HINT 261
|
||||||
#define TK_BATCH_SCAN 262
|
#define TK_DISTINCT 262
|
||||||
#define TK_NK_HINT_BEGIN 263
|
#define TK_WHERE 263
|
||||||
#define TK_NK_HINT_END 264
|
#define TK_PARTITION 264
|
||||||
#define TK_DISTINCT 265
|
#define TK_BY 265
|
||||||
#define TK_WHERE 266
|
#define TK_SESSION 266
|
||||||
#define TK_PARTITION 267
|
#define TK_STATE_WINDOW 267
|
||||||
#define TK_BY 268
|
#define TK_EVENT_WINDOW 268
|
||||||
#define TK_SESSION 269
|
#define TK_SLIDING 269
|
||||||
#define TK_STATE_WINDOW 270
|
#define TK_FILL 270
|
||||||
#define TK_EVENT_WINDOW 271
|
#define TK_VALUE 271
|
||||||
#define TK_SLIDING 272
|
#define TK_VALUE_F 272
|
||||||
#define TK_FILL 273
|
#define TK_NONE 273
|
||||||
#define TK_VALUE 274
|
#define TK_PREV 274
|
||||||
#define TK_VALUE_F 275
|
#define TK_NULL_F 275
|
||||||
#define TK_NONE 276
|
#define TK_LINEAR 276
|
||||||
#define TK_PREV 277
|
#define TK_NEXT 277
|
||||||
#define TK_NULL_F 278
|
#define TK_HAVING 278
|
||||||
#define TK_LINEAR 279
|
#define TK_RANGE 279
|
||||||
#define TK_NEXT 280
|
#define TK_EVERY 280
|
||||||
#define TK_HAVING 281
|
#define TK_ORDER 281
|
||||||
#define TK_RANGE 282
|
#define TK_SLIMIT 282
|
||||||
#define TK_EVERY 283
|
#define TK_SOFFSET 283
|
||||||
#define TK_ORDER 284
|
#define TK_LIMIT 284
|
||||||
#define TK_SLIMIT 285
|
#define TK_OFFSET 285
|
||||||
#define TK_SOFFSET 286
|
#define TK_ASC 286
|
||||||
#define TK_LIMIT 287
|
#define TK_NULLS 287
|
||||||
#define TK_OFFSET 288
|
#define TK_ABORT 288
|
||||||
#define TK_ASC 289
|
#define TK_AFTER 289
|
||||||
#define TK_NULLS 290
|
#define TK_ATTACH 290
|
||||||
#define TK_ABORT 291
|
#define TK_BEFORE 291
|
||||||
#define TK_AFTER 292
|
#define TK_BEGIN 292
|
||||||
#define TK_ATTACH 293
|
#define TK_BITAND 293
|
||||||
#define TK_BEFORE 294
|
#define TK_BITNOT 294
|
||||||
#define TK_BEGIN 295
|
#define TK_BITOR 295
|
||||||
#define TK_BITAND 296
|
#define TK_BLOCKS 296
|
||||||
#define TK_BITNOT 297
|
#define TK_CHANGE 297
|
||||||
#define TK_BITOR 298
|
#define TK_COMMA 298
|
||||||
#define TK_BLOCKS 299
|
#define TK_CONCAT 299
|
||||||
#define TK_CHANGE 300
|
#define TK_CONFLICT 300
|
||||||
#define TK_COMMA 301
|
#define TK_COPY 301
|
||||||
#define TK_CONCAT 302
|
#define TK_DEFERRED 302
|
||||||
#define TK_CONFLICT 303
|
#define TK_DELIMITERS 303
|
||||||
#define TK_COPY 304
|
#define TK_DETACH 304
|
||||||
#define TK_DEFERRED 305
|
#define TK_DIVIDE 305
|
||||||
#define TK_DELIMITERS 306
|
#define TK_DOT 306
|
||||||
#define TK_DETACH 307
|
#define TK_EACH 307
|
||||||
#define TK_DIVIDE 308
|
#define TK_FAIL 308
|
||||||
#define TK_DOT 309
|
#define TK_FILE 309
|
||||||
#define TK_EACH 310
|
#define TK_FOR 310
|
||||||
#define TK_FAIL 311
|
#define TK_GLOB 311
|
||||||
#define TK_FILE 312
|
#define TK_ID 312
|
||||||
#define TK_FOR 313
|
#define TK_IMMEDIATE 313
|
||||||
#define TK_GLOB 314
|
#define TK_IMPORT 314
|
||||||
#define TK_ID 315
|
#define TK_INITIALLY 315
|
||||||
#define TK_IMMEDIATE 316
|
#define TK_INSTEAD 316
|
||||||
#define TK_IMPORT 317
|
#define TK_ISNULL 317
|
||||||
#define TK_INITIALLY 318
|
#define TK_KEY 318
|
||||||
#define TK_INSTEAD 319
|
#define TK_MODULES 319
|
||||||
#define TK_ISNULL 320
|
#define TK_NK_BITNOT 320
|
||||||
#define TK_KEY 321
|
#define TK_NK_SEMI 321
|
||||||
#define TK_MODULES 322
|
#define TK_NOTNULL 322
|
||||||
#define TK_NK_BITNOT 323
|
#define TK_OF 323
|
||||||
#define TK_NK_SEMI 324
|
#define TK_PLUS 324
|
||||||
#define TK_NOTNULL 325
|
#define TK_PRIVILEGE 325
|
||||||
#define TK_OF 326
|
#define TK_RAISE 326
|
||||||
#define TK_PLUS 327
|
#define TK_RESTRICT 327
|
||||||
#define TK_PRIVILEGE 328
|
#define TK_ROW 328
|
||||||
#define TK_RAISE 329
|
#define TK_SEMI 329
|
||||||
#define TK_RESTRICT 330
|
#define TK_STAR 330
|
||||||
#define TK_ROW 331
|
#define TK_STATEMENT 331
|
||||||
#define TK_SEMI 332
|
#define TK_STRICT 332
|
||||||
#define TK_STAR 333
|
#define TK_STRING 333
|
||||||
#define TK_STATEMENT 334
|
#define TK_TIMES 334
|
||||||
#define TK_STRICT 335
|
#define TK_VALUES 335
|
||||||
#define TK_STRING 336
|
#define TK_VARIABLE 336
|
||||||
#define TK_TIMES 337
|
#define TK_VIEW 337
|
||||||
#define TK_VALUES 338
|
#define TK_WAL 338
|
||||||
#define TK_VARIABLE 339
|
|
||||||
#define TK_VIEW 340
|
|
||||||
#define TK_WAL 341
|
|
||||||
|
|
||||||
|
|
||||||
#define TK_NK_SPACE 600
|
#define TK_NK_SPACE 600
|
||||||
|
@ -365,6 +363,9 @@
|
||||||
#define TK_NK_HEX 603 // hex number 0x123
|
#define TK_NK_HEX 603 // hex number 0x123
|
||||||
#define TK_NK_OCT 604 // oct number
|
#define TK_NK_OCT 604 // oct number
|
||||||
#define TK_NK_BIN 605 // bin format data 0b111
|
#define TK_NK_BIN 605 // bin format data 0b111
|
||||||
|
#define TK_BATCH_SCAN 606
|
||||||
|
#define TK_NO_BATCH_SCAN 607
|
||||||
|
|
||||||
|
|
||||||
#define TK_NK_NIL 65535
|
#define TK_NK_NIL 65535
|
||||||
|
|
||||||
|
|
|
@ -43,10 +43,12 @@ typedef enum EGroupAction {
|
||||||
typedef struct SLogicNode {
|
typedef struct SLogicNode {
|
||||||
ENodeType type;
|
ENodeType type;
|
||||||
bool dynamicOp;
|
bool dynamicOp;
|
||||||
|
bool stmtRoot;
|
||||||
SNodeList* pTargets; // SColumnNode
|
SNodeList* pTargets; // SColumnNode
|
||||||
SNode* pConditions;
|
SNode* pConditions;
|
||||||
SNodeList* pChildren;
|
SNodeList* pChildren;
|
||||||
struct SLogicNode* pParent;
|
struct SLogicNode* pParent;
|
||||||
|
SNodeList* pHint;
|
||||||
int32_t optimizedFlag;
|
int32_t optimizedFlag;
|
||||||
uint8_t precision;
|
uint8_t precision;
|
||||||
SNode* pLimit;
|
SNode* pLimit;
|
||||||
|
|
|
@ -124,7 +124,6 @@ typedef enum EHintOption {
|
||||||
typedef struct SHintNode {
|
typedef struct SHintNode {
|
||||||
ENodeType type;
|
ENodeType type;
|
||||||
EHintOption option;
|
EHintOption option;
|
||||||
char* literal;
|
|
||||||
void* value;
|
void* value;
|
||||||
} SHintNode;
|
} SHintNode;
|
||||||
|
|
||||||
|
|
|
@ -162,7 +162,7 @@ typedef struct SLimitInfo {
|
||||||
} SLimitInfo;
|
} SLimitInfo;
|
||||||
|
|
||||||
typedef struct SSortMergeJoinOperatorParam {
|
typedef struct SSortMergeJoinOperatorParam {
|
||||||
int32_t initDownstreamNum;
|
bool initDownstream;
|
||||||
} SSortMergeJoinOperatorParam;
|
} SSortMergeJoinOperatorParam;
|
||||||
|
|
||||||
typedef struct SExchangeOperatorBasicParam {
|
typedef struct SExchangeOperatorBasicParam {
|
||||||
|
|
|
@ -306,7 +306,7 @@ static int32_t buildMergeJoinOperatorParam(SOperatorParam** ppRes, bool initPara
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
pJoin->initDownstreamNum = initParam ? 2 : 0;
|
pJoin->initDownstream = initParam;
|
||||||
|
|
||||||
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN;
|
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN;
|
||||||
(*ppRes)->value = pJoin;
|
(*ppRes)->value = pJoin;
|
||||||
|
|
|
@ -143,11 +143,32 @@ static void destroyGroupCacheDownstreamCtx(SGroupCacheOperatorInfo* pGrpCacheOpe
|
||||||
taosMemoryFree(pGrpCacheOperator->pDownstreams);
|
taosMemoryFree(pGrpCacheOperator->pDownstreams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void blockDataDeepCleanup(SSDataBlock* pDataBlock) {
|
||||||
|
size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock);
|
||||||
|
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||||
|
SColumnInfoData* p = taosArrayGet(pDataBlock->pDataBlock, i);
|
||||||
|
taosMemoryFreeClear(p->pData);
|
||||||
|
if (IS_VAR_DATA_TYPE(p->info.type)) {
|
||||||
|
taosMemoryFreeClear(p->varmeta.offset);
|
||||||
|
p->varmeta.length = 0;
|
||||||
|
p->varmeta.allocLen = 0;
|
||||||
|
} else {
|
||||||
|
taosMemoryFreeClear(p->nullbitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pDataBlock->info.capacity = 0;
|
||||||
|
pDataBlock->info.rows = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void destroySGcBlkCacheInfo(SGcBlkCacheInfo* pBlkCache) {
|
static void destroySGcBlkCacheInfo(SGcBlkCacheInfo* pBlkCache) {
|
||||||
taosHashCleanup(pBlkCache->pDirtyBlk);
|
taosHashCleanup(pBlkCache->pDirtyBlk);
|
||||||
|
|
||||||
void* p = NULL;
|
void* p = NULL;
|
||||||
while (p = taosHashIterate(pBlkCache->pReadBlk, p)) {
|
while (p = taosHashIterate(pBlkCache->pReadBlk, p)) {
|
||||||
|
blockDataDeepCleanup(*(SSDataBlock**)p);
|
||||||
freeGcBlockInList(p);
|
freeGcBlockInList(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,25 +453,6 @@ void blockDataDeepClear(SSDataBlock* pDataBlock) {
|
||||||
pDataBlock->info.rows = 0;
|
pDataBlock->info.rows = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void blockDataDeepCleanup(SSDataBlock* pDataBlock) {
|
|
||||||
size_t numOfCols = taosArrayGetSize(pDataBlock->pDataBlock);
|
|
||||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
|
||||||
SColumnInfoData* p = taosArrayGet(pDataBlock->pDataBlock, i);
|
|
||||||
taosMemoryFreeClear(p->pData);
|
|
||||||
if (IS_VAR_DATA_TYPE(p->info.type)) {
|
|
||||||
taosMemoryFreeClear(p->varmeta.offset);
|
|
||||||
p->varmeta.length = 0;
|
|
||||||
p->varmeta.allocLen = 0;
|
|
||||||
} else {
|
|
||||||
taosMemoryFreeClear(p->nullbitmap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pDataBlock->info.capacity = 0;
|
|
||||||
pDataBlock->info.rows = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int32_t buildGroupCacheBaseBlock(SSDataBlock** ppDst, SSDataBlock* pSrc) {
|
static int32_t buildGroupCacheBaseBlock(SSDataBlock** ppDst, SSDataBlock* pSrc) {
|
||||||
*ppDst = taosMemoryMalloc(sizeof(*pSrc));
|
*ppDst = taosMemoryMalloc(sizeof(*pSrc));
|
||||||
if (NULL == *ppDst) {
|
if (NULL == *ppDst) {
|
||||||
|
@ -708,7 +710,7 @@ static int32_t addFileRefTableNum(SGcFileCacheCtx* pFileCtx, int32_t fileId, int
|
||||||
SGroupCacheFileInfo newFile = {0};
|
SGroupCacheFileInfo newFile = {0};
|
||||||
newFile.groupNum = 1;
|
newFile.groupNum = 1;
|
||||||
taosHashPut(pFileCtx->pCacheFile, &fileId, sizeof(fileId), &newFile, sizeof(newFile));
|
taosHashPut(pFileCtx->pCacheFile, &fileId, sizeof(fileId), &newFile, sizeof(newFile));
|
||||||
pTmp = &newFile;
|
pTmp = taosHashGet(pFileCtx->pCacheFile, &fileId, sizeof(fileId));
|
||||||
} else {
|
} else {
|
||||||
pTmp->groupNum++;
|
pTmp->groupNum++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ typedef struct SMJoinOperatorInfo {
|
||||||
SSDataBlock* pRes;
|
SSDataBlock* pRes;
|
||||||
int32_t joinType;
|
int32_t joinType;
|
||||||
int32_t inputOrder;
|
int32_t inputOrder;
|
||||||
|
bool downstreamInitDone[2];
|
||||||
bool downstreamFetchDone[2];
|
bool downstreamFetchDone[2];
|
||||||
int16_t downstreamResBlkId[2];
|
int16_t downstreamResBlkId[2];
|
||||||
|
|
||||||
|
@ -671,6 +672,7 @@ static bool mergeJoinGetNextTimestamp(SOperatorInfo* pOperator, int64_t* pLeftTs
|
||||||
if (pJoinInfo->pLeft == NULL || pJoinInfo->leftPos >= pJoinInfo->pLeft->info.rows) {
|
if (pJoinInfo->pLeft == NULL || pJoinInfo->leftPos >= pJoinInfo->pLeft->info.rows) {
|
||||||
if (!pJoinInfo->downstreamFetchDone[0]) {
|
if (!pJoinInfo->downstreamFetchDone[0]) {
|
||||||
pJoinInfo->pLeft = getNextBlockFromDownstreamRemain(pOperator, 0);
|
pJoinInfo->pLeft = getNextBlockFromDownstreamRemain(pOperator, 0);
|
||||||
|
pJoinInfo->downstreamInitDone[0] = true;
|
||||||
|
|
||||||
pJoinInfo->leftPos = 0;
|
pJoinInfo->leftPos = 0;
|
||||||
qError("merge join left got block, rows:%" PRId64, pJoinInfo->pLeft ? pJoinInfo->pLeft->info.rows : 0);
|
qError("merge join left got block, rows:%" PRId64, pJoinInfo->pLeft ? pJoinInfo->pLeft->info.rows : 0);
|
||||||
|
@ -679,9 +681,8 @@ static bool mergeJoinGetNextTimestamp(SOperatorInfo* pOperator, int64_t* pLeftTs
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pJoinInfo->pLeft == NULL) {
|
if (pJoinInfo->pLeft == NULL) {
|
||||||
if (pOperator->pOperatorGetParam && ((SSortMergeJoinOperatorParam*)pOperator->pOperatorGetParam->value)->initDownstreamNum > 0) {
|
if (pOperator->pOperatorGetParam && ((SSortMergeJoinOperatorParam*)pOperator->pOperatorGetParam->value)->initDownstream && !pJoinInfo->downstreamInitDone[1]) {
|
||||||
leftEmpty = true;
|
leftEmpty = true;
|
||||||
((SSortMergeJoinOperatorParam*)pOperator->pOperatorGetParam->value)->initDownstreamNum--;
|
|
||||||
} else {
|
} else {
|
||||||
setMergeJoinDone(pOperator);
|
setMergeJoinDone(pOperator);
|
||||||
return false;
|
return false;
|
||||||
|
@ -692,10 +693,7 @@ static bool mergeJoinGetNextTimestamp(SOperatorInfo* pOperator, int64_t* pLeftTs
|
||||||
if (pJoinInfo->pRight == NULL || pJoinInfo->rightPos >= pJoinInfo->pRight->info.rows) {
|
if (pJoinInfo->pRight == NULL || pJoinInfo->rightPos >= pJoinInfo->pRight->info.rows) {
|
||||||
if (!pJoinInfo->downstreamFetchDone[1]) {
|
if (!pJoinInfo->downstreamFetchDone[1]) {
|
||||||
pJoinInfo->pRight = getNextBlockFromDownstreamRemain(pOperator, 1);
|
pJoinInfo->pRight = getNextBlockFromDownstreamRemain(pOperator, 1);
|
||||||
|
pJoinInfo->downstreamInitDone[1] = true;
|
||||||
if (pOperator->pOperatorGetParam && ((SSortMergeJoinOperatorParam*)pOperator->pOperatorGetParam->value)->initDownstreamNum > 0) {
|
|
||||||
((SSortMergeJoinOperatorParam*)pOperator->pOperatorGetParam->value)->initDownstreamNum--;
|
|
||||||
}
|
|
||||||
|
|
||||||
pJoinInfo->rightPos = 0;
|
pJoinInfo->rightPos = 0;
|
||||||
qError("merge join right got block, rows:%" PRId64, pJoinInfo->pRight ? pJoinInfo->pRight->info.rows : 0);
|
qError("merge join right got block, rows:%" PRId64, pJoinInfo->pRight ? pJoinInfo->pRight->info.rows : 0);
|
||||||
|
@ -783,6 +781,8 @@ void resetMergeJoinOperator(struct SOperatorInfo* pOperator) {
|
||||||
pJoinInfo->rightPos = 0;
|
pJoinInfo->rightPos = 0;
|
||||||
pJoinInfo->downstreamFetchDone[0] = false;
|
pJoinInfo->downstreamFetchDone[0] = false;
|
||||||
pJoinInfo->downstreamFetchDone[1] = false;
|
pJoinInfo->downstreamFetchDone[1] = false;
|
||||||
|
pJoinInfo->downstreamInitDone[0] = false;
|
||||||
|
pJoinInfo->downstreamInitDone[1] = false;
|
||||||
pJoinInfo->resRows = 0;
|
pJoinInfo->resRows = 0;
|
||||||
pOperator->status = OP_OPENED;
|
pOperator->status = OP_OPENED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,6 +348,24 @@ static int32_t caseWhenNodeCopy(const SCaseWhenNode* pSrc, SCaseWhenNode* pDst)
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t copyHintValue(const SHintNode* pSrc, SHintNode* pDst) {
|
||||||
|
if (NULL == pSrc->value) {
|
||||||
|
pDst->value = NULL;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
switch (pSrc->option) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t hintNodeCopy(const SHintNode* pSrc, SHintNode* pDst) {
|
||||||
|
COPY_SCALAR_FIELD(type);
|
||||||
|
COPY_SCALAR_FIELD(option);
|
||||||
|
return copyHintValue(pSrc, pDst);
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t logicNodeCopy(const SLogicNode* pSrc, SLogicNode* pDst) {
|
static int32_t logicNodeCopy(const SLogicNode* pSrc, SLogicNode* pDst) {
|
||||||
CLONE_NODE_LIST_FIELD(pTargets);
|
CLONE_NODE_LIST_FIELD(pTargets);
|
||||||
CLONE_NODE_FIELD(pConditions);
|
CLONE_NODE_FIELD(pConditions);
|
||||||
|
@ -363,6 +381,7 @@ static int32_t logicNodeCopy(const SLogicNode* pSrc, SLogicNode* pDst) {
|
||||||
COPY_SCALAR_FIELD(outputTsOrder);
|
COPY_SCALAR_FIELD(outputTsOrder);
|
||||||
COPY_SCALAR_FIELD(dynamicOp);
|
COPY_SCALAR_FIELD(dynamicOp);
|
||||||
COPY_SCALAR_FIELD(forceCreateNonBlockingOptr);
|
COPY_SCALAR_FIELD(forceCreateNonBlockingOptr);
|
||||||
|
CLONE_NODE_LIST_FIELD(pHint);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -703,6 +722,7 @@ static int32_t selectStmtCopy(const SSelectStmt* pSrc, SSelectStmt* pDst) {
|
||||||
COPY_SCALAR_FIELD(timeLineResMode);
|
COPY_SCALAR_FIELD(timeLineResMode);
|
||||||
COPY_SCALAR_FIELD(hasAggFuncs);
|
COPY_SCALAR_FIELD(hasAggFuncs);
|
||||||
COPY_SCALAR_FIELD(hasRepeatScanFuncs);
|
COPY_SCALAR_FIELD(hasRepeatScanFuncs);
|
||||||
|
CLONE_NODE_LIST_FIELD(pHint);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -791,6 +811,9 @@ SNode* nodesCloneNode(const SNode* pNode) {
|
||||||
case QUERY_NODE_CASE_WHEN:
|
case QUERY_NODE_CASE_WHEN:
|
||||||
code = caseWhenNodeCopy((const SCaseWhenNode*)pNode, (SCaseWhenNode*)pDst);
|
code = caseWhenNodeCopy((const SCaseWhenNode*)pNode, (SCaseWhenNode*)pDst);
|
||||||
break;
|
break;
|
||||||
|
case QUERY_NODE_HINT:
|
||||||
|
code = hintNodeCopy((const SHintNode*)pNode, (SHintNode*)pDst);
|
||||||
|
break;
|
||||||
case QUERY_NODE_SELECT_STMT:
|
case QUERY_NODE_SELECT_STMT:
|
||||||
code = selectStmtCopy((const SSelectStmt*)pNode, (SSelectStmt*)pDst);
|
code = selectStmtCopy((const SSelectStmt*)pNode, (SSelectStmt*)pDst);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -610,6 +610,7 @@ static void destroyLogicNode(SLogicNode* pNode) {
|
||||||
nodesDestroyList(pNode->pChildren);
|
nodesDestroyList(pNode->pChildren);
|
||||||
nodesDestroyNode(pNode->pLimit);
|
nodesDestroyNode(pNode->pLimit);
|
||||||
nodesDestroyNode(pNode->pSlimit);
|
nodesDestroyNode(pNode->pSlimit);
|
||||||
|
nodesDestroyList(pNode->pHint);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroyPhysiNode(SPhysiNode* pNode) {
|
static void destroyPhysiNode(SPhysiNode* pNode) {
|
||||||
|
@ -827,7 +828,6 @@ void nodesDestroyNode(SNode* pNode) {
|
||||||
}
|
}
|
||||||
case QUERY_NODE_HINT: {
|
case QUERY_NODE_HINT: {
|
||||||
SHintNode* pHint = (SHintNode*)pNode;
|
SHintNode* pHint = (SHintNode*)pNode;
|
||||||
taosMemoryFreeClear(pHint->literal);
|
|
||||||
destroyHintValue(pHint->option, pHint->value);
|
destroyHintValue(pHint->option, pHint->value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,7 @@ SNodeList* addNodeToList(SAstCreateContext* pCxt, SNodeList* pList, SNode* pNode
|
||||||
|
|
||||||
SNode* createColumnNode(SAstCreateContext* pCxt, SToken* pTableAlias, SToken* pColumnName);
|
SNode* createColumnNode(SAstCreateContext* pCxt, SToken* pTableAlias, SToken* pColumnName);
|
||||||
SNode* createValueNode(SAstCreateContext* pCxt, int32_t dataType, const SToken* pLiteral);
|
SNode* createValueNode(SAstCreateContext* pCxt, int32_t dataType, const SToken* pLiteral);
|
||||||
SNode* createHintNode(SAstCreateContext* pCxt, EHintOption option, const SToken* pLiteral);
|
SNodeList* createHintNodeList(SAstCreateContext* pCxt, const SToken* pLiteral);
|
||||||
SNode* createIdentifierValueNode(SAstCreateContext* pCxt, SToken* pLiteral);
|
SNode* createIdentifierValueNode(SAstCreateContext* pCxt, SToken* pLiteral);
|
||||||
SNode* createDurationValueNode(SAstCreateContext* pCxt, const SToken* pLiteral);
|
SNode* createDurationValueNode(SAstCreateContext* pCxt, const SToken* pLiteral);
|
||||||
SNode* createDefaultDatabaseCondValue(SAstCreateContext* pCxt);
|
SNode* createDefaultDatabaseCondValue(SAstCreateContext* pCxt);
|
||||||
|
|
|
@ -1025,8 +1025,8 @@ query_specification(A) ::=
|
||||||
|
|
||||||
%type hint_list { SNodeList* }
|
%type hint_list { SNodeList* }
|
||||||
%destructor hint_list { nodesDestroyList($$); }
|
%destructor hint_list { nodesDestroyList($$); }
|
||||||
hint_list(A) ::= . { createHintNodeList(pCxt, NULL); }
|
hint_list(A) ::= . { A = createHintNodeList(pCxt, NULL); }
|
||||||
hint_list(A) ::= NK_HINT(B). { createHintNodeList(pCxt, &B); }
|
hint_list(A) ::= NK_HINT(B). { A = createHintNodeList(pCxt, &B); }
|
||||||
|
|
||||||
%type set_quantifier_opt { bool }
|
%type set_quantifier_opt { bool }
|
||||||
%destructor set_quantifier_opt { }
|
%destructor set_quantifier_opt { }
|
||||||
|
|
|
@ -348,15 +348,121 @@ SNode* createValueNode(SAstCreateContext* pCxt, int32_t dataType, const SToken*
|
||||||
return (SNode*)val;
|
return (SNode*)val;
|
||||||
}
|
}
|
||||||
|
|
||||||
SNode* createHintNode(SAstCreateContext* pCxt, EHintOption option, const SToken* pLiteral) {
|
bool addHintNodeToList(SAstCreateContext* pCxt, SNodeList** ppHintList, EHintOption opt, SToken* paramList, int32_t paramNum) {
|
||||||
CHECK_PARSER_STATUS(pCxt);
|
void* value = NULL;
|
||||||
|
switch (opt) {
|
||||||
|
case HINT_BATCH_SCAN:
|
||||||
|
case HINT_NO_BATCH_SCAN: {
|
||||||
|
if (paramNum > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
SHintNode* hint = (SHintNode*)nodesMakeNode(QUERY_NODE_HINT);
|
SHintNode* hint = (SHintNode*)nodesMakeNode(QUERY_NODE_HINT);
|
||||||
CHECK_OUT_OF_MEM(hint);
|
CHECK_OUT_OF_MEM(hint);
|
||||||
hint->option = option;
|
hint->option = opt;
|
||||||
hint->literal = strndup(pLiteral->z, pLiteral->n);
|
hint->value = value;
|
||||||
trimString(pLiteral->z, pLiteral->n, hint->literal, pLiteral->n);
|
|
||||||
CHECK_OUT_OF_MEM(hint->literal);
|
if (NULL == *ppHintList) {
|
||||||
return (SNode*)hint;
|
*ppHintList = nodesMakeList();
|
||||||
|
CHECK_OUT_OF_MEM(*ppHintList);
|
||||||
|
}
|
||||||
|
|
||||||
|
pCxt->errCode = nodesListStrictAppend(*ppHintList, (SNode*)hint);
|
||||||
|
if (pCxt->errCode) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SNodeList* createHintNodeList(SAstCreateContext* pCxt, const SToken* pLiteral) {
|
||||||
|
CHECK_PARSER_STATUS(pCxt);
|
||||||
|
if (NULL == pLiteral || pLiteral->n <= 5) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
SNodeList* pHintList = NULL;
|
||||||
|
char* hint = strndup(pLiteral->z + 3, pLiteral->n - 5);
|
||||||
|
int32_t i = 0;
|
||||||
|
bool quit = false;
|
||||||
|
bool inParamList = false;
|
||||||
|
bool lastComma = false;
|
||||||
|
EHintOption opt = 0;
|
||||||
|
int32_t paramNum = 0;
|
||||||
|
SToken paramList[10];
|
||||||
|
while (!quit) {
|
||||||
|
SToken t0 = {0};
|
||||||
|
if (hint[i] == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
t0.n = tGetToken(&hint[i], &t0.type);
|
||||||
|
t0.z = hint + i;
|
||||||
|
i += t0.n;
|
||||||
|
|
||||||
|
switch (t0.type) {
|
||||||
|
case TK_BATCH_SCAN:
|
||||||
|
lastComma = false;
|
||||||
|
if (0 != opt || inParamList) {
|
||||||
|
quit = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
opt = HINT_BATCH_SCAN;
|
||||||
|
break;
|
||||||
|
case TK_NO_BATCH_SCAN:
|
||||||
|
lastComma = false;
|
||||||
|
if (0 != opt || inParamList) {
|
||||||
|
quit = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
opt = HINT_NO_BATCH_SCAN;
|
||||||
|
break;
|
||||||
|
case TK_NK_LP:
|
||||||
|
lastComma = false;
|
||||||
|
if (0 == opt || inParamList) {
|
||||||
|
quit = true;
|
||||||
|
}
|
||||||
|
inParamList = true;
|
||||||
|
break;
|
||||||
|
case TK_NK_RP:
|
||||||
|
lastComma = false;
|
||||||
|
if (0 == opt || !inParamList) {
|
||||||
|
quit = true;
|
||||||
|
} else {
|
||||||
|
quit = addHintNodeToList(pCxt, &pHintList, opt, paramList, paramNum);
|
||||||
|
inParamList = false;
|
||||||
|
paramNum = 0;
|
||||||
|
opt = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TK_NK_ID:
|
||||||
|
lastComma = false;
|
||||||
|
if (0 == opt || !inParamList) {
|
||||||
|
quit = true;
|
||||||
|
} else {
|
||||||
|
paramList[paramNum++] = t0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TK_NK_COMMA:
|
||||||
|
if (lastComma) {
|
||||||
|
quit = true;
|
||||||
|
}
|
||||||
|
lastComma = true;
|
||||||
|
break;
|
||||||
|
case TK_NK_SPACE:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
lastComma = false;
|
||||||
|
quit = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
taosMemoryFree(hint);
|
||||||
|
return pHintList;
|
||||||
}
|
}
|
||||||
|
|
||||||
SNode* createIdentifierValueNode(SAstCreateContext* pCxt, SToken* pLiteral) {
|
SNode* createIdentifierValueNode(SAstCreateContext* pCxt, SToken* pLiteral) {
|
||||||
|
|
|
@ -392,10 +392,6 @@ uint32_t tGetToken(const char* z, uint32_t* tokenId) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
case '*': {
|
case '*': {
|
||||||
if (z[1] == '/') {
|
|
||||||
*tokenId = TK_NK_HINT_END;
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
*tokenId = TK_NK_STAR;
|
*tokenId = TK_NK_STAR;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -406,13 +402,12 @@ uint32_t tGetToken(const char* z, uint32_t* tokenId) {
|
||||||
}
|
}
|
||||||
bool isHint = false;
|
bool isHint = false;
|
||||||
if (z[2] == '+') {
|
if (z[2] == '+') {
|
||||||
*tokenId = TK_NK_HINT_BEGIN;
|
isHint = true;
|
||||||
return 3;
|
|
||||||
}
|
}
|
||||||
for (i = 3; z[i] && (z[i] != '/' || z[i - 1] != '*'); i++) {
|
for (i = 3; z[i] && (z[i] != '/' || z[i - 1] != '*'); i++) {
|
||||||
}
|
}
|
||||||
if (z[i]) i++;
|
if (z[i]) i++;
|
||||||
*tokenId = TK_NK_COMMENT;
|
*tokenId = isHint ? TK_NK_HINT : TK_NK_COMMENT;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
case '%': {
|
case '%': {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -21,6 +21,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "planner.h"
|
#include "planner.h"
|
||||||
|
#include "tsimplehash.h"
|
||||||
#include "taoserror.h"
|
#include "taoserror.h"
|
||||||
|
|
||||||
#define planFatal(param, ...) qFatal("PLAN: " param, ##__VA_ARGS__)
|
#define planFatal(param, ...) qFatal("PLAN: " param, ##__VA_ARGS__)
|
||||||
|
@ -46,6 +47,8 @@ int32_t createPhysiPlan(SPlanContext* pCxt, SQueryLogicPlan* pLogicPlan, SQueryP
|
||||||
bool isPartTableAgg(SAggLogicNode* pAgg);
|
bool isPartTableAgg(SAggLogicNode* pAgg);
|
||||||
bool isPartTableWinodw(SWindowLogicNode* pWindow);
|
bool isPartTableWinodw(SWindowLogicNode* pWindow);
|
||||||
bool getBatchScanOptionFromHint(SNodeList* pList);
|
bool getBatchScanOptionFromHint(SNodeList* pList);
|
||||||
|
SLogicNode* getLogicNodeRootNode(SLogicNode* pCurr);
|
||||||
|
int32_t collectTableAliasFromNodes(SNode* pNode, SSHashObj** ppRes);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -478,10 +478,34 @@ static int32_t createJoinLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
|
||||||
// set the output
|
// set the output
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
SNodeList* pColList = NULL;
|
SNodeList* pColList = NULL;
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (QUERY_NODE_REAL_TABLE == nodeType(pJoinTable->pLeft)) {
|
||||||
code = nodesCollectColumns(pSelect, SQL_CLAUSE_WHERE, NULL, COLLECT_COL_TYPE_ALL, &pColList);
|
code = nodesCollectColumns(pSelect, SQL_CLAUSE_WHERE, ((SRealTableNode*)pJoinTable->pLeft)->table.tableAlias, COLLECT_COL_TYPE_ALL, &pColList);
|
||||||
|
} else {
|
||||||
|
pJoin->node.pTargets = nodesCloneList(pLeft->pTargets);
|
||||||
|
if (NULL == pJoin->node.pTargets) {
|
||||||
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code && NULL != pColList) {
|
||||||
|
code = createColumnByRewriteExprs(pColList, &pJoin->node.pTargets);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
SNodeList* pColList = NULL;
|
||||||
|
if (QUERY_NODE_REAL_TABLE == nodeType(pJoinTable->pRight)) {
|
||||||
|
code = nodesCollectColumns(pSelect, SQL_CLAUSE_WHERE, ((SRealTableNode*)pJoinTable->pRight)->table.tableAlias, COLLECT_COL_TYPE_ALL, &pColList);
|
||||||
|
} else {
|
||||||
|
if (pJoin->node.pTargets) {
|
||||||
|
nodesListStrictAppendList(pJoin->node.pTargets, nodesCloneList(pRight->pTargets));
|
||||||
|
} else {
|
||||||
|
pJoin->node.pTargets = nodesCloneList(pRight->pTargets);
|
||||||
|
if (NULL == pJoin->node.pTargets) {
|
||||||
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code && NULL != pColList) {
|
||||||
code = createColumnByRewriteExprs(pColList, &pJoin->node.pTargets);
|
code = createColumnByRewriteExprs(pColList, &pJoin->node.pTargets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1277,11 +1301,17 @@ static int32_t createSelectFromLogicNode(SLogicPlanContext* pCxt, SSelectStmt* p
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
|
static int32_t createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
if (NULL == pSelect->pFromTable) {
|
if (NULL == pSelect->pFromTable) {
|
||||||
return createSelectWithoutFromLogicNode(pCxt, pSelect, pLogicNode);
|
code = createSelectWithoutFromLogicNode(pCxt, pSelect, pLogicNode);
|
||||||
} else {
|
} else {
|
||||||
return createSelectFromLogicNode(pCxt, pSelect, pLogicNode);
|
code = createSelectFromLogicNode(pCxt, pSelect, pLogicNode);
|
||||||
}
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code && NULL != *pLogicNode) {
|
||||||
|
(*pLogicNode)->stmtRoot = true;
|
||||||
|
TSWAP((*pLogicNode)->pHint, pSelect->pHint);
|
||||||
|
}
|
||||||
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t createSetOpRootLogicNode(SLogicPlanContext* pCxt, SSetOperator* pSetOperator, FCreateSetOpLogicNode func,
|
static int32_t createSetOpRootLogicNode(SLogicPlanContext* pCxt, SSetOperator* pSetOperator, FCreateSetOpLogicNode func,
|
||||||
|
|
|
@ -50,8 +50,8 @@ typedef struct SOsdInfo {
|
||||||
} SOsdInfo;
|
} SOsdInfo;
|
||||||
|
|
||||||
typedef struct SCpdIsMultiTableCondCxt {
|
typedef struct SCpdIsMultiTableCondCxt {
|
||||||
SNodeList* pLeftCols;
|
SSHashObj* pLeftTbls;
|
||||||
SNodeList* pRightCols;
|
SSHashObj* pRightTbls;
|
||||||
bool havaLeftCol;
|
bool havaLeftCol;
|
||||||
bool haveRightCol;
|
bool haveRightCol;
|
||||||
} SCpdIsMultiTableCondCxt;
|
} SCpdIsMultiTableCondCxt;
|
||||||
|
@ -505,12 +505,21 @@ static bool pushDownCondOptBelongThisTable(SNode* pCondCol, SNodeList* pTableCol
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool pushDownCondOptColInTableList(SNode* pCondCol, SSHashObj* pTables) {
|
||||||
|
SColumnNode* pTableCol = (SColumnNode*)pCondCol;
|
||||||
|
if (NULL == tSimpleHashGet(pTables, pTableCol->tableAlias, strlen(pTableCol->tableAlias))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static EDealRes pushDownCondOptIsCrossTableCond(SNode* pNode, void* pContext) {
|
static EDealRes pushDownCondOptIsCrossTableCond(SNode* pNode, void* pContext) {
|
||||||
SCpdIsMultiTableCondCxt* pCxt = pContext;
|
SCpdIsMultiTableCondCxt* pCxt = pContext;
|
||||||
if (QUERY_NODE_COLUMN == nodeType(pNode)) {
|
if (QUERY_NODE_COLUMN == nodeType(pNode)) {
|
||||||
if (pushDownCondOptBelongThisTable(pNode, pCxt->pLeftCols)) {
|
if (pushDownCondOptColInTableList(pNode, pCxt->pLeftTbls)) {
|
||||||
pCxt->havaLeftCol = true;
|
pCxt->havaLeftCol = true;
|
||||||
} else if (pushDownCondOptBelongThisTable(pNode, pCxt->pRightCols)) {
|
} else if (pushDownCondOptColInTableList(pNode, pCxt->pRightTbls)) {
|
||||||
pCxt->haveRightCol = true;
|
pCxt->haveRightCol = true;
|
||||||
}
|
}
|
||||||
return pCxt->havaLeftCol && pCxt->haveRightCol ? DEAL_RES_END : DEAL_RES_CONTINUE;
|
return pCxt->havaLeftCol && pCxt->haveRightCol ? DEAL_RES_END : DEAL_RES_CONTINUE;
|
||||||
|
@ -518,10 +527,10 @@ static EDealRes pushDownCondOptIsCrossTableCond(SNode* pNode, void* pContext) {
|
||||||
return DEAL_RES_CONTINUE;
|
return DEAL_RES_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ECondAction pushDownCondOptGetCondAction(EJoinType joinType, SNodeList* pLeftCols, SNodeList* pRightCols,
|
static ECondAction pushDownCondOptGetCondAction(EJoinType joinType, SSHashObj* pLeftTbls, SSHashObj* pRightTbls,
|
||||||
SNode* pNode) {
|
SNode* pNode) {
|
||||||
SCpdIsMultiTableCondCxt cxt = {
|
SCpdIsMultiTableCondCxt cxt = {
|
||||||
.pLeftCols = pLeftCols, .pRightCols = pRightCols, .havaLeftCol = false, .haveRightCol = false};
|
.pLeftTbls = pLeftTbls, .pRightTbls = pRightTbls, .havaLeftCol = false, .haveRightCol = false};
|
||||||
nodesWalkExpr(pNode, pushDownCondOptIsCrossTableCond, &cxt);
|
nodesWalkExpr(pNode, pushDownCondOptIsCrossTableCond, &cxt);
|
||||||
return (JOIN_TYPE_INNER != joinType
|
return (JOIN_TYPE_INNER != joinType
|
||||||
? COND_ACTION_STAY
|
? COND_ACTION_STAY
|
||||||
|
@ -537,9 +546,11 @@ static int32_t pushDownCondOptPartLogicCond(SJoinLogicNode* pJoin, SNode** pOnCo
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
SNodeList* pLeftCols = ((SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 0))->pTargets;
|
|
||||||
SNodeList* pRightCols = ((SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 1))->pTargets;
|
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
SSHashObj* pLeftTables = NULL;
|
||||||
|
SSHashObj* pRightTables = NULL;
|
||||||
|
collectTableAliasFromNodes(nodesListGetNode(pJoin->node.pChildren, 0), &pLeftTables);
|
||||||
|
collectTableAliasFromNodes(nodesListGetNode(pJoin->node.pChildren, 1), &pRightTables);
|
||||||
|
|
||||||
SNodeList* pOnConds = NULL;
|
SNodeList* pOnConds = NULL;
|
||||||
SNodeList* pLeftChildConds = NULL;
|
SNodeList* pLeftChildConds = NULL;
|
||||||
|
@ -547,7 +558,7 @@ static int32_t pushDownCondOptPartLogicCond(SJoinLogicNode* pJoin, SNode** pOnCo
|
||||||
SNodeList* pRemainConds = NULL;
|
SNodeList* pRemainConds = NULL;
|
||||||
SNode* pCond = NULL;
|
SNode* pCond = NULL;
|
||||||
FOREACH(pCond, pLogicCond->pParameterList) {
|
FOREACH(pCond, pLogicCond->pParameterList) {
|
||||||
ECondAction condAction = pushDownCondOptGetCondAction(pJoin->joinType, pLeftCols, pRightCols, pCond);
|
ECondAction condAction = pushDownCondOptGetCondAction(pJoin->joinType, pLeftTables, pRightTables, pCond);
|
||||||
if (COND_ACTION_PUSH_JOIN == condAction) {
|
if (COND_ACTION_PUSH_JOIN == condAction) {
|
||||||
code = nodesListMakeAppend(&pOnConds, nodesCloneNode(pCond));
|
code = nodesListMakeAppend(&pOnConds, nodesCloneNode(pCond));
|
||||||
} else if (COND_ACTION_PUSH_LEFT_CHILD == condAction) {
|
} else if (COND_ACTION_PUSH_LEFT_CHILD == condAction) {
|
||||||
|
@ -562,6 +573,9 @@ static int32_t pushDownCondOptPartLogicCond(SJoinLogicNode* pJoin, SNode** pOnCo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tSimpleHashCleanup(pLeftTables);
|
||||||
|
tSimpleHashCleanup(pRightTables);
|
||||||
|
|
||||||
SNode* pTempOnCond = NULL;
|
SNode* pTempOnCond = NULL;
|
||||||
SNode* pTempLeftChildCond = NULL;
|
SNode* pTempLeftChildCond = NULL;
|
||||||
SNode* pTempRightChildCond = NULL;
|
SNode* pTempRightChildCond = NULL;
|
||||||
|
@ -601,10 +615,17 @@ static int32_t pushDownCondOptPartLogicCond(SJoinLogicNode* pJoin, SNode** pOnCo
|
||||||
|
|
||||||
static int32_t pushDownCondOptPartOpCond(SJoinLogicNode* pJoin, SNode** pOnCond, SNode** pLeftChildCond,
|
static int32_t pushDownCondOptPartOpCond(SJoinLogicNode* pJoin, SNode** pOnCond, SNode** pLeftChildCond,
|
||||||
SNode** pRightChildCond) {
|
SNode** pRightChildCond) {
|
||||||
SNodeList* pLeftCols = ((SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 0))->pTargets;
|
SSHashObj* pLeftTables = NULL;
|
||||||
SNodeList* pRightCols = ((SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 1))->pTargets;
|
SSHashObj* pRightTables = NULL;
|
||||||
|
collectTableAliasFromNodes(nodesListGetNode(pJoin->node.pChildren, 0), &pLeftTables);
|
||||||
|
collectTableAliasFromNodes(nodesListGetNode(pJoin->node.pChildren, 1), &pRightTables);
|
||||||
|
|
||||||
ECondAction condAction =
|
ECondAction condAction =
|
||||||
pushDownCondOptGetCondAction(pJoin->joinType, pLeftCols, pRightCols, pJoin->node.pConditions);
|
pushDownCondOptGetCondAction(pJoin->joinType, pLeftTables, pRightTables, pJoin->node.pConditions);
|
||||||
|
|
||||||
|
tSimpleHashCleanup(pLeftTables);
|
||||||
|
tSimpleHashCleanup(pRightTables);
|
||||||
|
|
||||||
if (COND_ACTION_STAY == condAction) {
|
if (COND_ACTION_STAY == condAction) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
} else if (COND_ACTION_PUSH_JOIN == condAction) {
|
} else if (COND_ACTION_PUSH_JOIN == condAction) {
|
||||||
|
@ -930,7 +951,6 @@ static int32_t pushDownCondOptDealJoin(SOptimizeContext* pCxt, SJoinLogicNode* p
|
||||||
if (pJoin->joinAlgo != JOIN_ALGO_UNKNOWN) {
|
if (pJoin->joinAlgo != JOIN_ALGO_UNKNOWN) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
pJoin->joinAlgo = JOIN_ALGO_MERGE;
|
|
||||||
|
|
||||||
if (NULL == pJoin->node.pConditions) {
|
if (NULL == pJoin->node.pConditions) {
|
||||||
int32_t code = pushDownCondOptJoinExtractCond(pCxt, pJoin);
|
int32_t code = pushDownCondOptJoinExtractCond(pCxt, pJoin);
|
||||||
|
@ -1320,6 +1340,7 @@ static int32_t sortPriKeyOptGetSequencingNodesImpl(SLogicNode* pNode, bool group
|
||||||
}
|
}
|
||||||
case QUERY_NODE_LOGIC_PLAN_AGG:
|
case QUERY_NODE_LOGIC_PLAN_AGG:
|
||||||
case QUERY_NODE_LOGIC_PLAN_PARTITION:
|
case QUERY_NODE_LOGIC_PLAN_PARTITION:
|
||||||
|
case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL:
|
||||||
*pNotOptimize = true;
|
*pNotOptimize = true;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
default:
|
default:
|
||||||
|
@ -3160,7 +3181,11 @@ static bool stbJoinOptShouldBeOptimized(SLogicNode* pNode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SJoinLogicNode* pJoin = (SJoinLogicNode*)pNode;
|
SJoinLogicNode* pJoin = (SJoinLogicNode*)pNode;
|
||||||
if (pJoin->isSingleTableJoin || NULL == pJoin->pTagEqCond || pNode->pChildren->length != 2 || pJoin->hasSubQuery || pJoin->joinAlgo != JOIN_ALGO_UNKNOWN) {
|
if (pJoin->isSingleTableJoin || NULL == pJoin->pTagEqCond || pNode->pChildren->length != 2
|
||||||
|
|| pJoin->hasSubQuery || pJoin->joinAlgo != JOIN_ALGO_UNKNOWN || (pNode->pParent && nodeType(pNode->pParent) == QUERY_NODE_LOGIC_PLAN_JOIN)) {
|
||||||
|
if (pJoin->joinAlgo == JOIN_ALGO_UNKNOWN) {
|
||||||
|
pJoin->joinAlgo = JOIN_ALGO_MERGE;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3329,7 +3354,7 @@ static int32_t stbJoinOptCreateTableScanNodes(SLogicNode* pJoin, SNodeList** ppL
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t stbJoinOptCreateGroupCacheNode(SOptimizeContext* pCxt, SNodeList* pChildren, SLogicNode** ppLogic) {
|
static int32_t stbJoinOptCreateGroupCacheNode(SLogicNode* pRoot, SNodeList* pChildren, SLogicNode** ppLogic) {
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
SGroupCacheLogicNode* pGrpCache = (SGroupCacheLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_GROUP_CACHE);
|
SGroupCacheLogicNode* pGrpCache = (SGroupCacheLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_GROUP_CACHE);
|
||||||
if (NULL == pGrpCache) {
|
if (NULL == pGrpCache) {
|
||||||
|
@ -3339,7 +3364,7 @@ static int32_t stbJoinOptCreateGroupCacheNode(SOptimizeContext* pCxt, SNodeList*
|
||||||
//pGrpCache->node.dynamicOp = true;
|
//pGrpCache->node.dynamicOp = true;
|
||||||
pGrpCache->grpColsMayBeNull = false;
|
pGrpCache->grpColsMayBeNull = false;
|
||||||
pGrpCache->grpByUid = true;
|
pGrpCache->grpByUid = true;
|
||||||
pGrpCache->batchFetch = getBatchScanOptionFromHint(((SSelectStmt*)pCxt->pPlanCxt->pAstRoot)->pHint);
|
pGrpCache->batchFetch = getBatchScanOptionFromHint(pRoot->pHint);
|
||||||
pGrpCache->node.pChildren = pChildren;
|
pGrpCache->node.pChildren = pChildren;
|
||||||
pGrpCache->node.pTargets = nodesMakeList();
|
pGrpCache->node.pTargets = nodesMakeList();
|
||||||
if (NULL == pGrpCache->node.pTargets) {
|
if (NULL == pGrpCache->node.pTargets) {
|
||||||
|
@ -3436,7 +3461,7 @@ static int32_t stbJoinOptCreateMergeJoinNode(SLogicNode* pOrig, SLogicNode* pChi
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t stbJoinOptCreateDynQueryCtrlNode(SOptimizeContext* pCxt, SLogicNode* pPrev, SLogicNode* pPost, bool* srcScan, SLogicNode** ppDynNode) {
|
static int32_t stbJoinOptCreateDynQueryCtrlNode(SLogicNode* pRoot, SLogicNode* pPrev, SLogicNode* pPost, bool* srcScan, SLogicNode** ppDynNode) {
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
SDynQueryCtrlLogicNode* pDynCtrl = (SDynQueryCtrlLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL);
|
SDynQueryCtrlLogicNode* pDynCtrl = (SDynQueryCtrlLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL);
|
||||||
if (NULL == pDynCtrl) {
|
if (NULL == pDynCtrl) {
|
||||||
|
@ -3444,7 +3469,7 @@ static int32_t stbJoinOptCreateDynQueryCtrlNode(SOptimizeContext* pCxt, SLogicNo
|
||||||
}
|
}
|
||||||
|
|
||||||
pDynCtrl->qType = DYN_QTYPE_STB_HASH;
|
pDynCtrl->qType = DYN_QTYPE_STB_HASH;
|
||||||
pDynCtrl->stbJoin.batchFetch = getBatchScanOptionFromHint(((SSelectStmt*)pCxt->pPlanCxt->pAstRoot)->pHint);
|
pDynCtrl->stbJoin.batchFetch = getBatchScanOptionFromHint(pRoot->pHint);
|
||||||
memcpy(pDynCtrl->stbJoin.srcScan, srcScan, sizeof(pDynCtrl->stbJoin.srcScan));
|
memcpy(pDynCtrl->stbJoin.srcScan, srcScan, sizeof(pDynCtrl->stbJoin.srcScan));
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
@ -3510,13 +3535,13 @@ static int32_t stbJoinOptRewriteStableJoin(SOptimizeContext* pCxt, SLogicNode* p
|
||||||
code = stbJoinOptCreateTableScanNodes(pJoin, &pTbScanNodes, srcScan);
|
code = stbJoinOptCreateTableScanNodes(pJoin, &pTbScanNodes, srcScan);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = stbJoinOptCreateGroupCacheNode(pCxt, pTbScanNodes, &pGrpCacheNode);
|
code = stbJoinOptCreateGroupCacheNode(getLogicNodeRootNode(pJoin), pTbScanNodes, &pGrpCacheNode);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = stbJoinOptCreateMergeJoinNode(pJoin, pGrpCacheNode, &pMJoinNode);
|
code = stbJoinOptCreateMergeJoinNode(pJoin, pGrpCacheNode, &pMJoinNode);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = stbJoinOptCreateDynQueryCtrlNode(pCxt, pHJoinNode, pMJoinNode, srcScan, &pDynNode);
|
code = stbJoinOptCreateDynQueryCtrlNode(getLogicNodeRootNode(pJoin), pHJoinNode, pMJoinNode, srcScan, &pDynNode);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = replaceLogicNode(pLogicSubplan, pJoin, (SLogicNode*)pDynNode);
|
code = replaceLogicNode(pLogicSubplan, pJoin, (SLogicNode*)pDynNode);
|
||||||
|
@ -3542,12 +3567,12 @@ static int32_t stableJoinOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicS
|
||||||
static const SOptimizeRule optimizeRuleSet[] = {
|
static const SOptimizeRule optimizeRuleSet[] = {
|
||||||
{.pName = "ScanPath", .optimizeFunc = scanPathOptimize},
|
{.pName = "ScanPath", .optimizeFunc = scanPathOptimize},
|
||||||
{.pName = "PushDownCondition", .optimizeFunc = pushDownCondOptimize},
|
{.pName = "PushDownCondition", .optimizeFunc = pushDownCondOptimize},
|
||||||
|
{.pName = "StableJoin", .optimizeFunc = stableJoinOptimize},
|
||||||
{.pName = "sortNonPriKeyOptimize", .optimizeFunc = sortNonPriKeyOptimize},
|
{.pName = "sortNonPriKeyOptimize", .optimizeFunc = sortNonPriKeyOptimize},
|
||||||
{.pName = "SortPrimaryKey", .optimizeFunc = sortPrimaryKeyOptimize},
|
{.pName = "SortPrimaryKey", .optimizeFunc = sortPrimaryKeyOptimize},
|
||||||
{.pName = "SmaIndex", .optimizeFunc = smaIndexOptimize},
|
{.pName = "SmaIndex", .optimizeFunc = smaIndexOptimize},
|
||||||
{.pName = "PushDownLimit", .optimizeFunc = pushDownLimitOptimize},
|
{.pName = "PushDownLimit", .optimizeFunc = pushDownLimitOptimize},
|
||||||
{.pName = "PartitionTags", .optimizeFunc = partTagsOptimize},
|
{.pName = "PartitionTags", .optimizeFunc = partTagsOptimize},
|
||||||
{.pName = "StableJoin", .optimizeFunc = stableJoinOptimize},
|
|
||||||
{.pName = "MergeProjects", .optimizeFunc = mergeProjectsOptimize},
|
{.pName = "MergeProjects", .optimizeFunc = mergeProjectsOptimize},
|
||||||
{.pName = "RewriteTail", .optimizeFunc = rewriteTailOptimize},
|
{.pName = "RewriteTail", .optimizeFunc = rewriteTailOptimize},
|
||||||
{.pName = "RewriteUnique", .optimizeFunc = rewriteUniqueOptimize},
|
{.pName = "RewriteUnique", .optimizeFunc = rewriteUniqueOptimize},
|
||||||
|
|
|
@ -108,6 +108,7 @@ int32_t createColumnByRewriteExpr(SNode* pExpr, SNodeList** pList) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t replaceLogicNode(SLogicSubplan* pSubplan, SLogicNode* pOld, SLogicNode* pNew) {
|
int32_t replaceLogicNode(SLogicSubplan* pSubplan, SLogicNode* pOld, SLogicNode* pNew) {
|
||||||
|
pNew->stmtRoot = pOld->stmtRoot;
|
||||||
if (NULL == pOld->pParent) {
|
if (NULL == pOld->pParent) {
|
||||||
pSubplan->pNode = (SLogicNode*)pNew;
|
pSubplan->pNode = (SLogicNode*)pNew;
|
||||||
pNew->pParent = NULL;
|
pNew->pParent = NULL;
|
||||||
|
@ -125,6 +126,19 @@ int32_t replaceLogicNode(SLogicSubplan* pSubplan, SLogicNode* pOld, SLogicNode*
|
||||||
return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SLogicNode* getLogicNodeRootNode(SLogicNode* pCurr) {
|
||||||
|
while (pCurr) {
|
||||||
|
if (pCurr->stmtRoot || NULL == pCurr->pParent) {
|
||||||
|
return pCurr;
|
||||||
|
}
|
||||||
|
|
||||||
|
pCurr = pCurr->pParent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int32_t adjustScanDataRequirement(SScanLogicNode* pScan, EDataOrderLevel requirement) {
|
static int32_t adjustScanDataRequirement(SScanLogicNode* pScan, EDataOrderLevel requirement) {
|
||||||
if ((SCAN_TYPE_TABLE != pScan->scanType && SCAN_TYPE_TABLE_MERGE != pScan->scanType) ||
|
if ((SCAN_TYPE_TABLE != pScan->scanType && SCAN_TYPE_TABLE_MERGE != pScan->scanType) ||
|
||||||
DATA_ORDER_LEVEL_GLOBAL == pScan->node.requireDataOrder) {
|
DATA_ORDER_LEVEL_GLOBAL == pScan->node.requireDataOrder) {
|
||||||
|
@ -391,4 +405,30 @@ bool getBatchScanOptionFromHint(SNodeList* pList) {
|
||||||
return batchScan;
|
return batchScan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t collectTableAliasFromNodes(SNode* pNode, SSHashObj** ppRes) {
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
SLogicNode* pCurr = (SLogicNode*)pNode;
|
||||||
|
FOREACH(pNode, pCurr->pTargets) {
|
||||||
|
SColumnNode* pCol = (SColumnNode*)pNode;
|
||||||
|
if (NULL == *ppRes) {
|
||||||
|
*ppRes = tSimpleHashInit(5, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY));
|
||||||
|
if (NULL == *ppRes) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tSimpleHashPut(*ppRes, pCol->tableAlias, strlen(pCol->tableAlias), NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
FOREACH(pNode, pCurr->pChildren) {
|
||||||
|
code = collectTableAliasFromNodes(pNode, ppRes);
|
||||||
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -406,7 +406,7 @@ sql insert into tbb_5 values('2021-03-03 05:00:00.000', 99115,99115.0,'b5');
|
||||||
sql insert into tbb_5 values('2021-03-04 05:00:00.000', 99115,99115.0,'b5');
|
sql insert into tbb_5 values('2021-03-04 05:00:00.000', 99115,99115.0,'b5');
|
||||||
sql insert into tbb_5 values('2021-03-05 05:00:00.000', 99115,99115.0,'b5');
|
sql insert into tbb_5 values('2021-03-05 05:00:00.000', 99115,99115.0,'b5');
|
||||||
|
|
||||||
sql select * from st0, st1 where st0.ts=st1.ts and st0.id1=st1.id1;
|
sql select * from st0, st1 where st0.ts=st1.ts and st0.id1=st1.id1 order by st0.ts;
|
||||||
if $rows != 25 then
|
if $rows != 25 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
@ -442,7 +442,7 @@ if $data09 != @21-03-01 01:00:00.000@ then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
sql select * from st0, st1 where st0.ts=st1.ts and st0.id2=st1.id2;
|
sql select * from st0, st1 where st0.ts=st1.ts and st0.id2=st1.id2 order by st0.ts;
|
||||||
if $rows != 25 then
|
if $rows != 25 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
@ -478,7 +478,7 @@ if $data09 != @21-03-01 01:00:00.000@ then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
sql select * from st0, st1 where st0.id3=st1.id3 and st1.ts=st0.ts;
|
sql select * from st0, st1 where st0.id3=st1.id3 and st1.ts=st0.ts order by st0.ts;
|
||||||
if $rows != 25 then
|
if $rows != 25 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
@ -514,7 +514,7 @@ if $data09 != @21-03-01 01:00:00.000@ then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
sql select * from st0, st1 where st1.id5=st0.id5 and st0.ts=st1.ts;
|
sql select * from st0, st1 where st1.id5=st0.id5 and st0.ts=st1.ts order by st0.ts;
|
||||||
if $rows != 25 then
|
if $rows != 25 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
@ -550,7 +550,7 @@ if $data09 != @21-03-01 01:00:00.000@ then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
sql select st0.* from st0, st1 where st0.ts=st1.ts and st0.id1=st1.id1;
|
sql select st0.* from st0, st1 where st0.ts=st1.ts and st0.id1=st1.id1 order by st0.ts;
|
||||||
if $rows != 25 then
|
if $rows != 25 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
@ -583,7 +583,7 @@ if $data08 != 3 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
sql select st0.* from st0, st1 where st0.ts=st1.ts and st1.id2=st0.id2;
|
sql select st0.* from st0, st1 where st0.ts=st1.ts and st1.id2=st0.id2 order by st0.ts;
|
||||||
if $rows != 25 then
|
if $rows != 25 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
@ -616,7 +616,7 @@ if $data08 != 3 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
sql select st0.* from st0, st1 where st0.id3=st1.id3 and st1.ts=st0.ts;
|
sql select st0.* from st0, st1 where st0.id3=st1.id3 and st1.ts=st0.ts order by st0.ts;
|
||||||
if $rows != 25 then
|
if $rows != 25 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
@ -649,7 +649,7 @@ if $data08 != 3 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
sql select st1.* from st0, st1 where st1.id5=st0.id5 and st0.ts=st1.ts;
|
sql select st1.* from st0, st1 where st1.id5=st0.id5 and st0.ts=st1.ts order by st1.ts;
|
||||||
if $rows != 25 then
|
if $rows != 25 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
@ -711,7 +711,7 @@ if $data31 != 9911 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
sql select st0.ts,st1.ts from st0, st1 where st0.ts=st1.ts and st1.id2=st0.id2;
|
sql select st0.ts,st1.ts from st0, st1 where st0.ts=st1.ts and st1.id2=st0.id2 order by st1.ts;
|
||||||
if $rows != 25 then
|
if $rows != 25 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
@ -728,7 +728,7 @@ if $data51 != @21-03-02 01:00:00.000@ then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
sql select st1.ts,st0.ts,st0.id3,st1.id3,st0.f3,st1.f3 from st0, st1 where st0.id3=st1.id3 and st1.ts=st0.ts;
|
sql select st1.ts,st0.ts,st0.id3,st1.id3,st0.f3,st1.f3 from st0, st1 where st0.id3=st1.id3 and st1.ts=st0.ts order by st1.ts;
|
||||||
if $rows != 25 then
|
if $rows != 25 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
@ -751,7 +751,7 @@ if $data05 != 11 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
sql select st0.ts,st0.f2,st1.f3,st1.f2,st0.f3 from st0, st1 where st1.id5=st0.id5 and st0.ts=st1.ts;
|
sql select st0.ts,st0.f2,st1.f3,st1.f2,st0.f3 from st0, st1 where st1.id5=st0.id5 and st0.ts=st1.ts order by st1.ts;
|
||||||
if $rows != 25 then
|
if $rows != 25 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
@ -850,7 +850,7 @@ if $data08 != 15 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
||||||
sql select st0.*,st1.* from st0, st1 where st1.id1=st0.id1 and st0.ts=st1.ts and st1.ts=st0.ts and st0.id1=st1.id1;
|
sql select st0.*,st1.* from st0, st1 where st1.id1=st0.id1 and st0.ts=st1.ts and st1.ts=st0.ts and st0.id1=st1.id1 order by st0.ts;
|
||||||
if $rows != 25 then
|
if $rows != 25 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
@ -1085,7 +1085,7 @@ endi
|
||||||
# return -1
|
# return -1
|
||||||
#endi
|
#endi
|
||||||
|
|
||||||
sql select st0.*,st1.*,st2.*,st3.*,st4.*,st5.*,st6.*,st7.*,st8.*,st9.* from st0,st1,st2,st3,st4,st5,st6,st7,st8,st9 where st0.ts=st2.ts and st0.ts=st4.ts and st0.ts=st6.ts and st0.ts=st8.ts and st1.ts=st3.ts and st3.ts=st5.ts and st5.ts=st7.ts and st7.ts=st9.ts and st0.ts=st1.ts and st0.id1=st2.id1 and st0.id1=st4.id1 and st0.id1=st6.id1 and st0.id1=st8.id1 and st1.id1=st3.id1 and st3.id1=st5.id1 and st5.id1=st7.id1 and st7.id1=st9.id1 and st0.id1=st1.id1;
|
sql select st0.*,st1.*,st2.*,st3.*,st4.*,st5.*,st6.*,st7.*,st8.*,st9.* from st0,st1,st2,st3,st4,st5,st6,st7,st8,st9 where st0.ts=st2.ts and st0.ts=st4.ts and st0.ts=st6.ts and st0.ts=st8.ts and st1.ts=st3.ts and st3.ts=st5.ts and st5.ts=st7.ts and st7.ts=st9.ts and st0.ts=st1.ts and st0.id1=st2.id1 and st0.id1=st4.id1 and st0.id1=st6.id1 and st0.id1=st8.id1 and st1.id1=st3.id1 and st3.id1=st5.id1 and st5.id1=st7.id1 and st7.id1=st9.id1 and st0.id1=st1.id1 order by st1.ts;
|
||||||
if $rows != 25 then
|
if $rows != 25 then
|
||||||
return -1
|
return -1
|
||||||
endi
|
endi
|
||||||
|
|
Loading…
Reference in New Issue