enh: push down conditions
This commit is contained in:
parent
75881e0f7c
commit
abdf6d337a
|
@ -123,12 +123,15 @@ typedef struct SScanLogicNode {
|
||||||
typedef struct SJoinLogicNode {
|
typedef struct SJoinLogicNode {
|
||||||
SLogicNode node;
|
SLogicNode node;
|
||||||
EJoinType joinType;
|
EJoinType joinType;
|
||||||
|
EJoinSubType subType;
|
||||||
|
SNode* pWindowOffset;
|
||||||
|
SNode* pJLimit;
|
||||||
EJoinAlgorithm joinAlgo;
|
EJoinAlgorithm joinAlgo;
|
||||||
SNode* pPrimKeyEqCond;
|
SNode* pPrimKeyEqCond;
|
||||||
SNode* pColEqCond;
|
SNode* pColEqCond;
|
||||||
SNode* pTagEqCond;
|
SNode* pTagEqCond;
|
||||||
SNode* pTagOnCond;
|
SNode* pTagOnCond;
|
||||||
SNode* pOtherOnCond;
|
SNode* pFullOnCond;
|
||||||
bool isSingleTableJoin;
|
bool isSingleTableJoin;
|
||||||
bool hasSubQuery;
|
bool hasSubQuery;
|
||||||
bool isLowLevelJoin;
|
bool isLowLevelJoin;
|
||||||
|
@ -468,7 +471,7 @@ typedef struct SSortMergeJoinPhysiNode {
|
||||||
EJoinType joinType;
|
EJoinType joinType;
|
||||||
SNode* pPrimKeyCond;
|
SNode* pPrimKeyCond;
|
||||||
SNode* pColEqCond;
|
SNode* pColEqCond;
|
||||||
SNode* pOtherOnCond;
|
SNode* pFullOnCond;
|
||||||
SNodeList* pTargets;
|
SNodeList* pTargets;
|
||||||
} SSortMergeJoinPhysiNode;
|
} SSortMergeJoinPhysiNode;
|
||||||
|
|
||||||
|
|
|
@ -203,21 +203,25 @@ typedef struct SViewNode {
|
||||||
int8_t cacheLastMode;
|
int8_t cacheLastMode;
|
||||||
} SViewNode;
|
} SViewNode;
|
||||||
|
|
||||||
|
#define IS_INNER_NONE_JOIN(_type, _stype) ((_type) == JOIN_TYPE_INNER && (_stype) == JOIN_STYPE_NONE)
|
||||||
|
|
||||||
typedef enum EJoinType {
|
typedef enum EJoinType {
|
||||||
JOIN_TYPE_INNER = 1,
|
JOIN_TYPE_INNER = 0,
|
||||||
JOIN_TYPE_LEFT,
|
JOIN_TYPE_LEFT,
|
||||||
JOIN_TYPE_RIGHT,
|
JOIN_TYPE_RIGHT,
|
||||||
JOIN_TYPE_FULL,
|
JOIN_TYPE_FULL,
|
||||||
|
JOIN_TYPE_MAX_VALUE
|
||||||
} EJoinType;
|
} EJoinType;
|
||||||
|
|
||||||
typedef enum EJoinSubType {
|
typedef enum EJoinSubType {
|
||||||
JOIN_STYPE_NONE = 1,
|
JOIN_STYPE_NONE = 0,
|
||||||
JOIN_STYPE_OUTER,
|
JOIN_STYPE_OUTER,
|
||||||
JOIN_STYPE_SEMI,
|
JOIN_STYPE_SEMI,
|
||||||
JOIN_STYPE_ANTI,
|
JOIN_STYPE_ANTI,
|
||||||
JOIN_STYPE_ANY,
|
JOIN_STYPE_ANY,
|
||||||
JOIN_STYPE_ASOF,
|
JOIN_STYPE_ASOF,
|
||||||
JOIN_STYPE_WIN,
|
JOIN_STYPE_WIN,
|
||||||
|
JOIN_STYPE_MAX_VALUE
|
||||||
} EJoinSubType;
|
} EJoinSubType;
|
||||||
|
|
||||||
typedef enum EJoinAlgorithm {
|
typedef enum EJoinAlgorithm {
|
||||||
|
@ -238,6 +242,7 @@ typedef struct SJoinTableNode {
|
||||||
SNode* pJLimit;
|
SNode* pJLimit;
|
||||||
bool hasSubQuery;
|
bool hasSubQuery;
|
||||||
bool isLowLevelJoin;
|
bool isLowLevelJoin;
|
||||||
|
SNode* pParent;
|
||||||
SNode* pLeft;
|
SNode* pLeft;
|
||||||
SNode* pRight;
|
SNode* pRight;
|
||||||
SNode* pOnCond;
|
SNode* pOnCond;
|
||||||
|
@ -546,12 +551,15 @@ typedef struct SQuery {
|
||||||
bool stableQuery;
|
bool stableQuery;
|
||||||
} SQuery;
|
} SQuery;
|
||||||
|
|
||||||
|
void nodesWalkSelectStmtImpl(SSelectStmt* pSelect, ESqlClause clause, FNodeWalker walker, void* pContext, bool ignoreFrom);
|
||||||
void nodesWalkSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeWalker walker, void* pContext);
|
void nodesWalkSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeWalker walker, void* pContext);
|
||||||
void nodesRewriteSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeRewriter rewriter, void* pContext);
|
void nodesRewriteSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeRewriter rewriter, void* pContext);
|
||||||
|
|
||||||
typedef enum ECollectColType { COLLECT_COL_TYPE_COL = 1, COLLECT_COL_TYPE_TAG, COLLECT_COL_TYPE_ALL } ECollectColType;
|
typedef enum ECollectColType { COLLECT_COL_TYPE_COL = 1, COLLECT_COL_TYPE_TAG, COLLECT_COL_TYPE_ALL } ECollectColType;
|
||||||
int32_t nodesCollectColumns(SSelectStmt* pSelect, ESqlClause clause, const char* pTableAlias, ECollectColType type,
|
int32_t nodesCollectColumns(SSelectStmt* pSelect, ESqlClause clause, const char* pTableAlias, ECollectColType type,
|
||||||
SNodeList** pCols);
|
SNodeList** pCols);
|
||||||
|
int32_t nodesCollectColumnsExt(SSelectStmt* pSelect, ESqlClause clause, const char* pTableAlias, ECollectColType type,
|
||||||
|
SNodeList** pCols, bool ignoreFrom);
|
||||||
int32_t nodesCollectColumnsFromNode(SNode* node, const char* pTableAlias, ECollectColType type, SNodeList** pCols);
|
int32_t nodesCollectColumnsFromNode(SNode* node, const char* pTableAlias, ECollectColType type, SNodeList** pCols);
|
||||||
|
|
||||||
typedef bool (*FFuncClassifier)(int32_t funcId);
|
typedef bool (*FFuncClassifier)(int32_t funcId);
|
||||||
|
|
|
@ -631,10 +631,10 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
||||||
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ON_CONDITIONS_FORMAT);
|
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_ON_CONDITIONS_FORMAT);
|
||||||
QRY_ERR_RET(
|
QRY_ERR_RET(
|
||||||
nodesNodeToSQL(pJoinNode->pPrimKeyCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
nodesNodeToSQL(pJoinNode->pPrimKeyCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||||
if (pJoinNode->pOtherOnCond) {
|
if (pJoinNode->pFullOnCond) {
|
||||||
EXPLAIN_ROW_APPEND(" AND ");
|
EXPLAIN_ROW_APPEND(" AND ");
|
||||||
QRY_ERR_RET(
|
QRY_ERR_RET(
|
||||||
nodesNodeToSQL(pJoinNode->pOtherOnCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
nodesNodeToSQL(pJoinNode->pFullOnCond, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
|
||||||
}
|
}
|
||||||
EXPLAIN_ROW_END();
|
EXPLAIN_ROW_END();
|
||||||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
|
||||||
|
|
|
@ -255,7 +255,7 @@ SOperatorInfo* createMergeJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t
|
||||||
|
|
||||||
extractTimeCondition(pInfo, pJoinNode, GET_TASKID(pTaskInfo));
|
extractTimeCondition(pInfo, pJoinNode, GET_TASKID(pTaskInfo));
|
||||||
|
|
||||||
if (pJoinNode->pOtherOnCond != NULL && pJoinNode->node.pConditions != NULL) {
|
if (pJoinNode->pFullOnCond != NULL && pJoinNode->node.pConditions != NULL) {
|
||||||
pInfo->pCondAfterMerge = nodesMakeNode(QUERY_NODE_LOGIC_CONDITION);
|
pInfo->pCondAfterMerge = nodesMakeNode(QUERY_NODE_LOGIC_CONDITION);
|
||||||
if (pInfo->pCondAfterMerge == NULL) {
|
if (pInfo->pCondAfterMerge == NULL) {
|
||||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
@ -269,11 +269,11 @@ SOperatorInfo* createMergeJoinOperatorInfo(SOperatorInfo** pDownstream, int32_t
|
||||||
goto _error;
|
goto _error;
|
||||||
}
|
}
|
||||||
|
|
||||||
nodesListMakeAppend(&pLogicCond->pParameterList, nodesCloneNode(pJoinNode->pOtherOnCond));
|
nodesListMakeAppend(&pLogicCond->pParameterList, nodesCloneNode(pJoinNode->pFullOnCond));
|
||||||
nodesListMakeAppend(&pLogicCond->pParameterList, nodesCloneNode(pJoinNode->node.pConditions));
|
nodesListMakeAppend(&pLogicCond->pParameterList, nodesCloneNode(pJoinNode->node.pConditions));
|
||||||
pLogicCond->condType = LOGIC_COND_TYPE_AND;
|
pLogicCond->condType = LOGIC_COND_TYPE_AND;
|
||||||
} else if (pJoinNode->pOtherOnCond != NULL) {
|
} else if (pJoinNode->pFullOnCond != NULL) {
|
||||||
pInfo->pCondAfterMerge = nodesCloneNode(pJoinNode->pOtherOnCond);
|
pInfo->pCondAfterMerge = nodesCloneNode(pJoinNode->pFullOnCond);
|
||||||
} else if (pJoinNode->pColEqCond != NULL) {
|
} else if (pJoinNode->pColEqCond != NULL) {
|
||||||
pInfo->pCondAfterMerge = nodesCloneNode(pJoinNode->pColEqCond);
|
pInfo->pCondAfterMerge = nodesCloneNode(pJoinNode->pColEqCond);
|
||||||
} else if (pJoinNode->node.pConditions != NULL) {
|
} else if (pJoinNode->node.pConditions != NULL) {
|
||||||
|
|
|
@ -443,7 +443,7 @@ static int32_t logicJoinCopy(const SJoinLogicNode* pSrc, SJoinLogicNode* pDst) {
|
||||||
CLONE_NODE_FIELD(pColEqCond);
|
CLONE_NODE_FIELD(pColEqCond);
|
||||||
CLONE_NODE_FIELD(pTagEqCond);
|
CLONE_NODE_FIELD(pTagEqCond);
|
||||||
CLONE_NODE_FIELD(pTagOnCond);
|
CLONE_NODE_FIELD(pTagOnCond);
|
||||||
CLONE_NODE_FIELD(pOtherOnCond);
|
CLONE_NODE_FIELD(pFullOnCond);
|
||||||
COPY_SCALAR_FIELD(isSingleTableJoin);
|
COPY_SCALAR_FIELD(isSingleTableJoin);
|
||||||
COPY_SCALAR_FIELD(hasSubQuery);
|
COPY_SCALAR_FIELD(hasSubQuery);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
|
@ -1567,7 +1567,7 @@ static int32_t logicJoinNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
code = tjsonAddObject(pJson, jkJoinLogicPlanTagEqCondition, nodeToJson, pNode->pTagEqCond);
|
code = tjsonAddObject(pJson, jkJoinLogicPlanTagEqCondition, nodeToJson, pNode->pTagEqCond);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tjsonAddObject(pJson, jkJoinLogicPlanOnConditions, nodeToJson, pNode->pOtherOnCond);
|
code = tjsonAddObject(pJson, jkJoinLogicPlanOnConditions, nodeToJson, pNode->pFullOnCond);
|
||||||
}
|
}
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -1592,7 +1592,7 @@ static int32_t jsonToLogicJoinNode(const SJson* pJson, void* pObj) {
|
||||||
code = jsonToNodeObject(pJson, jkJoinLogicPlanTagEqCondition, &pNode->pTagEqCond);
|
code = jsonToNodeObject(pJson, jkJoinLogicPlanTagEqCondition, &pNode->pTagEqCond);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = jsonToNodeObject(pJson, jkJoinLogicPlanOnConditions, &pNode->pOtherOnCond);
|
code = jsonToNodeObject(pJson, jkJoinLogicPlanOnConditions, &pNode->pFullOnCond);
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
@ -2080,7 +2080,7 @@ static int32_t physiMergeJoinNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
code = tjsonAddObject(pJson, jkJoinPhysiPlanPrimKeyCondition, nodeToJson, pNode->pPrimKeyCond);
|
code = tjsonAddObject(pJson, jkJoinPhysiPlanPrimKeyCondition, nodeToJson, pNode->pPrimKeyCond);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tjsonAddObject(pJson, jkJoinPhysiPlanOnConditions, nodeToJson, pNode->pOtherOnCond);
|
code = tjsonAddObject(pJson, jkJoinPhysiPlanOnConditions, nodeToJson, pNode->pFullOnCond);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = nodeListToJson(pJson, jkJoinPhysiPlanTargets, pNode->pTargets);
|
code = nodeListToJson(pJson, jkJoinPhysiPlanTargets, pNode->pTargets);
|
||||||
|
@ -2099,7 +2099,7 @@ static int32_t jsonToPhysiMergeJoinNode(const SJson* pJson, void* pObj) {
|
||||||
tjsonGetNumberValue(pJson, jkJoinPhysiPlanJoinType, pNode->joinType, code);
|
tjsonGetNumberValue(pJson, jkJoinPhysiPlanJoinType, pNode->joinType, code);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = jsonToNodeObject(pJson, jkJoinPhysiPlanOnConditions, &pNode->pOtherOnCond);
|
code = jsonToNodeObject(pJson, jkJoinPhysiPlanOnConditions, &pNode->pFullOnCond);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = jsonToNodeObject(pJson, jkJoinPhysiPlanPrimKeyCondition, &pNode->pPrimKeyCond);
|
code = jsonToNodeObject(pJson, jkJoinPhysiPlanPrimKeyCondition, &pNode->pPrimKeyCond);
|
||||||
|
|
|
@ -2413,7 +2413,7 @@ static int32_t physiMergeJoinNodeToMsg(const void* pObj, STlvEncoder* pEncoder)
|
||||||
code = tlvEncodeObj(pEncoder, PHY_SORT_MERGE_JOIN_CODE_PRIM_KEY_CONDITION, nodeToMsg, pNode->pPrimKeyCond);
|
code = tlvEncodeObj(pEncoder, PHY_SORT_MERGE_JOIN_CODE_PRIM_KEY_CONDITION, nodeToMsg, pNode->pPrimKeyCond);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tlvEncodeObj(pEncoder, PHY_SORT_MERGE_JOIN_CODE_ON_CONDITIONS, nodeToMsg, pNode->pOtherOnCond);
|
code = tlvEncodeObj(pEncoder, PHY_SORT_MERGE_JOIN_CODE_ON_CONDITIONS, nodeToMsg, pNode->pFullOnCond);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = tlvEncodeObj(pEncoder, PHY_SORT_MERGE_JOIN_CODE_TARGETS, nodeListToMsg, pNode->pTargets);
|
code = tlvEncodeObj(pEncoder, PHY_SORT_MERGE_JOIN_CODE_TARGETS, nodeListToMsg, pNode->pTargets);
|
||||||
|
@ -2441,7 +2441,7 @@ static int32_t msgToPhysiMergeJoinNode(STlvDecoder* pDecoder, void* pObj) {
|
||||||
code = msgToNodeFromTlv(pTlv, (void**)&pNode->pPrimKeyCond);
|
code = msgToNodeFromTlv(pTlv, (void**)&pNode->pPrimKeyCond);
|
||||||
break;
|
break;
|
||||||
case PHY_SORT_MERGE_JOIN_CODE_ON_CONDITIONS:
|
case PHY_SORT_MERGE_JOIN_CODE_ON_CONDITIONS:
|
||||||
code = msgToNodeFromTlv(pTlv, (void**)&pNode->pOtherOnCond);
|
code = msgToNodeFromTlv(pTlv, (void**)&pNode->pFullOnCond);
|
||||||
break;
|
break;
|
||||||
case PHY_SORT_MERGE_JOIN_CODE_TARGETS:
|
case PHY_SORT_MERGE_JOIN_CODE_TARGETS:
|
||||||
code = msgToNodeListFromTlv(pTlv, (void**)&pNode->pTargets);
|
code = msgToNodeListFromTlv(pTlv, (void**)&pNode->pTargets);
|
||||||
|
|
|
@ -412,14 +412,16 @@ void nodesRewriteExprsPostOrder(SNodeList* pList, FNodeRewriter rewriter, void*
|
||||||
(void)rewriteExprs(pList, TRAVERSAL_POSTORDER, rewriter, pContext);
|
(void)rewriteExprs(pList, TRAVERSAL_POSTORDER, rewriter, pContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nodesWalkSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeWalker walker, void* pContext) {
|
void nodesWalkSelectStmtImpl(SSelectStmt* pSelect, ESqlClause clause, FNodeWalker walker, void* pContext, bool ignoreFrom) {
|
||||||
if (NULL == pSelect) {
|
if (NULL == pSelect) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (clause) {
|
switch (clause) {
|
||||||
case SQL_CLAUSE_FROM:
|
case SQL_CLAUSE_FROM:
|
||||||
nodesWalkExpr(pSelect->pFromTable, walker, pContext);
|
if (!ignoreFrom) {
|
||||||
|
nodesWalkExpr(pSelect->pFromTable, walker, pContext);
|
||||||
|
}
|
||||||
nodesWalkExpr(pSelect->pWhere, walker, pContext);
|
nodesWalkExpr(pSelect->pWhere, walker, pContext);
|
||||||
case SQL_CLAUSE_WHERE:
|
case SQL_CLAUSE_WHERE:
|
||||||
nodesWalkExprs(pSelect->pPartitionByList, walker, pContext);
|
nodesWalkExprs(pSelect->pPartitionByList, walker, pContext);
|
||||||
|
@ -448,6 +450,10 @@ void nodesWalkSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeWalker wa
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nodesWalkSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeWalker walker, void* pContext) {
|
||||||
|
nodesWalkSelectStmtImpl(pSelect, clause, walker, pContext, false);
|
||||||
|
}
|
||||||
|
|
||||||
void nodesRewriteSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeRewriter rewriter, void* pContext) {
|
void nodesRewriteSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeRewriter rewriter, void* pContext) {
|
||||||
if (NULL == pSelect) {
|
if (NULL == pSelect) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1194,7 +1194,7 @@ void nodesDestroyNode(SNode* pNode) {
|
||||||
SJoinLogicNode* pLogicNode = (SJoinLogicNode*)pNode;
|
SJoinLogicNode* pLogicNode = (SJoinLogicNode*)pNode;
|
||||||
destroyLogicNode((SLogicNode*)pLogicNode);
|
destroyLogicNode((SLogicNode*)pLogicNode);
|
||||||
nodesDestroyNode(pLogicNode->pPrimKeyEqCond);
|
nodesDestroyNode(pLogicNode->pPrimKeyEqCond);
|
||||||
nodesDestroyNode(pLogicNode->pOtherOnCond);
|
nodesDestroyNode(pLogicNode->pFullOnCond);
|
||||||
nodesDestroyNode(pLogicNode->pColEqCond);
|
nodesDestroyNode(pLogicNode->pColEqCond);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1339,7 +1339,7 @@ void nodesDestroyNode(SNode* pNode) {
|
||||||
SSortMergeJoinPhysiNode* pPhyNode = (SSortMergeJoinPhysiNode*)pNode;
|
SSortMergeJoinPhysiNode* pPhyNode = (SSortMergeJoinPhysiNode*)pNode;
|
||||||
destroyPhysiNode((SPhysiNode*)pPhyNode);
|
destroyPhysiNode((SPhysiNode*)pPhyNode);
|
||||||
nodesDestroyNode(pPhyNode->pPrimKeyCond);
|
nodesDestroyNode(pPhyNode->pPrimKeyCond);
|
||||||
nodesDestroyNode(pPhyNode->pOtherOnCond);
|
nodesDestroyNode(pPhyNode->pFullOnCond);
|
||||||
nodesDestroyList(pPhyNode->pTargets);
|
nodesDestroyList(pPhyNode->pTargets);
|
||||||
nodesDestroyNode(pPhyNode->pColEqCond);
|
nodesDestroyNode(pPhyNode->pColEqCond);
|
||||||
break;
|
break;
|
||||||
|
@ -2071,6 +2071,37 @@ int32_t nodesCollectColumns(SSelectStmt* pSelect, ESqlClause clause, const char*
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t nodesCollectColumnsExt(SSelectStmt* pSelect, ESqlClause clause, const char* pTableAlias, ECollectColType type,
|
||||||
|
SNodeList** pCols, bool ignoreFrom) {
|
||||||
|
if (NULL == pSelect || NULL == pCols) {
|
||||||
|
return TSDB_CODE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
SCollectColumnsCxt cxt = {
|
||||||
|
.errCode = TSDB_CODE_SUCCESS,
|
||||||
|
.pTableAlias = pTableAlias,
|
||||||
|
.collectType = type,
|
||||||
|
.pCols = (NULL == *pCols ? nodesMakeList() : *pCols),
|
||||||
|
.pColHash = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK)};
|
||||||
|
if (NULL == cxt.pCols || NULL == cxt.pColHash) {
|
||||||
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
*pCols = NULL;
|
||||||
|
nodesWalkSelectStmtImpl(pSelect, clause, collectColumns, &cxt, ignoreFrom);
|
||||||
|
taosHashCleanup(cxt.pColHash);
|
||||||
|
if (TSDB_CODE_SUCCESS != cxt.errCode) {
|
||||||
|
nodesDestroyList(cxt.pCols);
|
||||||
|
return cxt.errCode;
|
||||||
|
}
|
||||||
|
if (LIST_LENGTH(cxt.pCols) > 0) {
|
||||||
|
*pCols = cxt.pCols;
|
||||||
|
} else {
|
||||||
|
nodesDestroyList(cxt.pCols);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t nodesCollectColumnsFromNode(SNode* node, const char* pTableAlias, ECollectColType type, SNodeList** pCols) {
|
int32_t nodesCollectColumnsFromNode(SNode* node, const char* pTableAlias, ECollectColType type, SNodeList** pCols) {
|
||||||
if (NULL == pCols) {
|
if (NULL == pCols) {
|
||||||
return TSDB_CODE_FAILED;
|
return TSDB_CODE_FAILED;
|
||||||
|
|
|
@ -38,7 +38,7 @@ int32_t calculateConstant(SParseContext* pParseCxt, SQuery* pQuery);
|
||||||
int32_t translatePostCreateStream(SParseContext* pParseCxt, SQuery* pQuery, void** pResRow);
|
int32_t translatePostCreateStream(SParseContext* pParseCxt, SQuery* pQuery, void** pResRow);
|
||||||
int32_t translatePostCreateSmaIndex(SParseContext* pParseCxt, SQuery* pQuery, void** pResRow);
|
int32_t translatePostCreateSmaIndex(SParseContext* pParseCxt, SQuery* pQuery, void** pResRow);
|
||||||
int32_t buildQueryAfterParse(SQuery** pQuery, SNode* pRootNode, int16_t placeholderNo, SArray** pPlaceholderValues);
|
int32_t buildQueryAfterParse(SQuery** pQuery, SNode* pRootNode, int16_t placeholderNo, SArray** pPlaceholderValues);
|
||||||
int32_t translateTable(STranslateContext* pCxt, SNode** pTable);
|
int32_t translateTable(STranslateContext* pCxt, SNode** pTable, SNode* pJoinParent);
|
||||||
int32_t getMetaDataFromHash(const char* pKey, int32_t len, SHashObj* pHash, void** pOutput);
|
int32_t getMetaDataFromHash(const char* pKey, int32_t len, SHashObj* pHash, void** pOutput);
|
||||||
void tfreeSParseQueryRes(void* p);
|
void tfreeSParseQueryRes(void* p);
|
||||||
|
|
||||||
|
|
|
@ -2963,7 +2963,7 @@ static int32_t translateJoinTable(STranslateContext* pCxt, SJoinTableNode* pJoin
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t translateTable(STranslateContext* pCxt, SNode** pTable) {
|
int32_t translateTable(STranslateContext* pCxt, SNode** pTable, SNode* pJoinParent) {
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
switch (nodeType(*pTable)) {
|
switch (nodeType(*pTable)) {
|
||||||
case QUERY_NODE_REAL_TABLE: {
|
case QUERY_NODE_REAL_TABLE: {
|
||||||
|
@ -3023,12 +3023,13 @@ int32_t translateTable(STranslateContext* pCxt, SNode** pTable) {
|
||||||
}
|
}
|
||||||
case QUERY_NODE_JOIN_TABLE: {
|
case QUERY_NODE_JOIN_TABLE: {
|
||||||
SJoinTableNode* pJoinTable = (SJoinTableNode*)*pTable;
|
SJoinTableNode* pJoinTable = (SJoinTableNode*)*pTable;
|
||||||
|
pJoinTable->pParent = pJoinParent;
|
||||||
code = translateJoinTable(pCxt, pJoinTable);
|
code = translateJoinTable(pCxt, pJoinTable);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = translateTable(pCxt, &pJoinTable->pLeft);
|
code = translateTable(pCxt, &pJoinTable->pLeft, (SNode*)pJoinTable);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = translateTable(pCxt, &pJoinTable->pRight);
|
code = translateTable(pCxt, &pJoinTable->pRight, (SNode*)pJoinTable);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = checkJoinTable(pCxt, pJoinTable);
|
code = checkJoinTable(pCxt, pJoinTable);
|
||||||
|
@ -4275,7 +4276,7 @@ static int32_t translateWhere(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
|
|
||||||
static int32_t translateFrom(STranslateContext* pCxt, SNode** pTable) {
|
static int32_t translateFrom(STranslateContext* pCxt, SNode** pTable) {
|
||||||
pCxt->currClause = SQL_CLAUSE_FROM;
|
pCxt->currClause = SQL_CLAUSE_FROM;
|
||||||
return translateTable(pCxt, pTable);
|
return translateTable(pCxt, pTable, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t checkLimit(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
static int32_t checkLimit(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||||
|
|
|
@ -502,14 +502,26 @@ static int32_t createSubqueryLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSe
|
||||||
return createQueryLogicNode(pCxt, pTable->pSubquery, pLogicNode);
|
return createQueryLogicNode(pCxt, pTable->pSubquery, pLogicNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t collectJoinResColumns(SSelectStmt* pSelect, SJoinTableNode* pJoinTable, SNodeList** pCols) {
|
||||||
|
int32_t code = nodesCollectColumns(pSelect, SQL_CLAUSE_WHERE, ((STableNode*)pJoinTable->pLeft)->tableAlias, COLLECT_COL_TYPE_ALL, pCols);
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
code = nodesCollectColumns(pSelect, SQL_CLAUSE_WHERE, ((STableNode*)pJoinTable->pRight)->tableAlias, COLLECT_COL_TYPE_ALL, pCols);
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int32_t createJoinLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SJoinTableNode* pJoinTable,
|
static int32_t createJoinLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SJoinTableNode* pJoinTable,
|
||||||
SLogicNode** pLogicNode) {
|
SLogicNode** pLogicNode) {
|
||||||
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
SJoinLogicNode* pJoin = (SJoinLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_JOIN);
|
SJoinLogicNode* pJoin = (SJoinLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_JOIN);
|
||||||
if (NULL == pJoin) {
|
if (NULL == pJoin) {
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
pJoin->joinType = pJoinTable->joinType;
|
pJoin->joinType = pJoinTable->joinType;
|
||||||
|
pJoin->subType = pJoinTable->subType;
|
||||||
pJoin->joinAlgo = JOIN_ALGO_UNKNOWN;
|
pJoin->joinAlgo = JOIN_ALGO_UNKNOWN;
|
||||||
pJoin->isSingleTableJoin = pJoinTable->table.singleTable;
|
pJoin->isSingleTableJoin = pJoinTable->table.singleTable;
|
||||||
pJoin->hasSubQuery = pJoinTable->hasSubQuery;
|
pJoin->hasSubQuery = pJoinTable->hasSubQuery;
|
||||||
|
@ -518,10 +530,8 @@ static int32_t createJoinLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
|
||||||
pJoin->node.requireDataOrder = DATA_ORDER_LEVEL_GLOBAL;
|
pJoin->node.requireDataOrder = DATA_ORDER_LEVEL_GLOBAL;
|
||||||
pJoin->node.resultDataOrder = DATA_ORDER_LEVEL_NONE;
|
pJoin->node.resultDataOrder = DATA_ORDER_LEVEL_NONE;
|
||||||
pJoin->isLowLevelJoin = pJoinTable->isLowLevelJoin;
|
pJoin->isLowLevelJoin = pJoinTable->isLowLevelJoin;
|
||||||
|
pJoin->pWindowOffset = nodesCloneNode(pJoinTable->pWindowOffset);
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
pJoin->pJLimit = nodesCloneNode(pJoinTable->pJLimit);
|
||||||
|
|
||||||
// set left and right node
|
|
||||||
pJoin->node.pChildren = nodesMakeList();
|
pJoin->node.pChildren = nodesMakeList();
|
||||||
if (NULL == pJoin->node.pChildren) {
|
if (NULL == pJoin->node.pChildren) {
|
||||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
@ -548,12 +558,13 @@ static int32_t createJoinLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
|
||||||
|
|
||||||
// set on conditions
|
// set on conditions
|
||||||
if (TSDB_CODE_SUCCESS == code && NULL != pJoinTable->pOnCond) {
|
if (TSDB_CODE_SUCCESS == code && NULL != pJoinTable->pOnCond) {
|
||||||
pJoin->pOtherOnCond = nodesCloneNode(pJoinTable->pOnCond);
|
pJoin->pFullOnCond = nodesCloneNode(pJoinTable->pOnCond);
|
||||||
if (NULL == pJoin->pOtherOnCond) {
|
if (NULL == pJoin->pFullOnCond) {
|
||||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
// set the output
|
// set the output
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
SNodeList* pColList = NULL;
|
SNodeList* pColList = NULL;
|
||||||
|
@ -600,6 +611,19 @@ static int32_t createJoinLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
// set the output
|
||||||
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
SNodeList* pColList = NULL;
|
||||||
|
code = collectJoinResColumns(pSelect, pJoinTable, &pColList);
|
||||||
|
if (TSDB_CODE_SUCCESS == code && NULL != pColList) {
|
||||||
|
code = createColumnByRewriteExprs(pColList, &pJoin->node.pTargets);
|
||||||
|
}
|
||||||
|
nodesDestroyList(pColList);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
*pLogicNode = (SLogicNode*)pJoin;
|
*pLogicNode = (SLogicNode*)pJoin;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -65,9 +65,26 @@ typedef enum ECondAction {
|
||||||
// after supporting outer join, there are other possibilities
|
// after supporting outer join, there are other possibilities
|
||||||
} ECondAction;
|
} ECondAction;
|
||||||
|
|
||||||
|
#define PUSH_DOWN_LEFT_FLT (1 << 0)
|
||||||
|
#define PUSH_DOWN_RIGHT_FLT (1 << 1)
|
||||||
|
#define PUSH_DOWN_ON_COND (1 << 2)
|
||||||
|
#define PUSH_DOWN_ALL_COND (PUSH_DOWN_LEFT_FLT | PUSH_DOWN_RIGHT_FLT | PUSH_DOWN_ON_COND)
|
||||||
|
|
||||||
|
typedef struct SJoinOptimizeOpt {
|
||||||
|
int8_t pushDownFlag;
|
||||||
|
} SJoinOptimizeOpt;
|
||||||
|
|
||||||
typedef bool (*FMayBeOptimized)(SLogicNode* pNode);
|
typedef bool (*FMayBeOptimized)(SLogicNode* pNode);
|
||||||
typedef bool (*FShouldBeOptimized)(SLogicNode* pNode, void* pInfo);
|
typedef bool (*FShouldBeOptimized)(SLogicNode* pNode, void* pInfo);
|
||||||
|
|
||||||
|
static SJoinOptimizeOpt gJoinOpt[JOIN_TYPE_MAX_VALUE][JOIN_STYPE_MAX_VALUE] = {
|
||||||
|
/* NONE OUTER SEMI ANTI ANY ASOF WINDOW */
|
||||||
|
/*INNER*/ {{PUSH_DOWN_ALL_COND}, {0}, {0}, {0}, {PUSH_DOWN_ALL_COND}, {0}, {0}},
|
||||||
|
/*LEFT*/ {{0}, {PUSH_DOWN_LEFT_FLT}, {PUSH_DOWN_ALL_COND}, {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}, {PUSH_DOWN_RIGHT_FLT}},
|
||||||
|
/*FULL*/ {{0}, {0}, {0}, {0}, {0}, {0}, {0}},
|
||||||
|
};
|
||||||
|
|
||||||
static SLogicNode* optFindPossibleNode(SLogicNode* pNode, FMayBeOptimized func) {
|
static SLogicNode* optFindPossibleNode(SLogicNode* pNode, FMayBeOptimized func) {
|
||||||
if (func(pNode)) {
|
if (func(pNode)) {
|
||||||
return pNode;
|
return pNode;
|
||||||
|
@ -392,7 +409,7 @@ static int32_t scanPathOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSub
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t pushDownCondOptMergeCond(SNode** pDst, SNode** pSrc) {
|
static int32_t pdcMergeCondsToLogic(SNode** pDst, SNode** pSrc) {
|
||||||
SLogicConditionNode* pLogicCond = (SLogicConditionNode*)nodesMakeNode(QUERY_NODE_LOGIC_CONDITION);
|
SLogicConditionNode* pLogicCond = (SLogicConditionNode*)nodesMakeNode(QUERY_NODE_LOGIC_CONDITION);
|
||||||
if (NULL == pLogicCond) {
|
if (NULL == pLogicCond) {
|
||||||
return TSDB_CODE_OUT_OF_MEMORY;
|
return TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
@ -413,7 +430,7 @@ static int32_t pushDownCondOptMergeCond(SNode** pDst, SNode** pSrc) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t pushDownCondOptAppendCond(SNode** pCond, SNode** pAdditionalCond) {
|
static int32_t pdcMergeConds(SNode** pCond, SNode** pAdditionalCond) {
|
||||||
if (NULL == *pCond) {
|
if (NULL == *pCond) {
|
||||||
TSWAP(*pCond, *pAdditionalCond);
|
TSWAP(*pCond, *pAdditionalCond);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -427,7 +444,7 @@ static int32_t pushDownCondOptAppendCond(SNode** pCond, SNode** pAdditionalCond)
|
||||||
*pAdditionalCond = NULL;
|
*pAdditionalCond = NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
code = pushDownCondOptMergeCond(pCond, pAdditionalCond);
|
code = pdcMergeCondsToLogic(pCond, pAdditionalCond);
|
||||||
}
|
}
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -436,7 +453,7 @@ static int32_t pushDownCondOptCalcTimeRange(SOptimizeContext* pCxt, SScanLogicNo
|
||||||
SNode** pOtherCond) {
|
SNode** pOtherCond) {
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
if (pCxt->pPlanCxt->topicQuery || pCxt->pPlanCxt->streamQuery) {
|
if (pCxt->pPlanCxt->topicQuery || pCxt->pPlanCxt->streamQuery) {
|
||||||
code = pushDownCondOptAppendCond(pOtherCond, pPrimaryKeyCond);
|
code = pdcMergeConds(pOtherCond, pPrimaryKeyCond);
|
||||||
} else {
|
} else {
|
||||||
bool isStrict = false;
|
bool isStrict = false;
|
||||||
code = filterGetTimeRange(*pPrimaryKeyCond, &pScan->scanRange, &isStrict);
|
code = filterGetTimeRange(*pPrimaryKeyCond, &pScan->scanRange, &isStrict);
|
||||||
|
@ -444,7 +461,7 @@ static int32_t pushDownCondOptCalcTimeRange(SOptimizeContext* pCxt, SScanLogicNo
|
||||||
if (isStrict) {
|
if (isStrict) {
|
||||||
nodesDestroyNode(*pPrimaryKeyCond);
|
nodesDestroyNode(*pPrimaryKeyCond);
|
||||||
} else {
|
} else {
|
||||||
code = pushDownCondOptAppendCond(pOtherCond, pPrimaryKeyCond);
|
code = pdcMergeConds(pOtherCond, pPrimaryKeyCond);
|
||||||
}
|
}
|
||||||
*pPrimaryKeyCond = NULL;
|
*pPrimaryKeyCond = NULL;
|
||||||
}
|
}
|
||||||
|
@ -458,7 +475,7 @@ static int32_t pushDownCondOptRebuildTbanme(SNode** pTagCond) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t pushDownCondOptDealScan(SOptimizeContext* pCxt, SScanLogicNode* pScan) {
|
static int32_t pdcDealScan(SOptimizeContext* pCxt, SScanLogicNode* pScan) {
|
||||||
if (NULL == pScan->node.pConditions ||
|
if (NULL == pScan->node.pConditions ||
|
||||||
OPTIMIZE_FLAG_TEST_MASK(pScan->node.optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE) ||
|
OPTIMIZE_FLAG_TEST_MASK(pScan->node.optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE) ||
|
||||||
TSDB_SYSTEM_TABLE == pScan->tableType) {
|
TSDB_SYSTEM_TABLE == pScan->tableType) {
|
||||||
|
@ -490,7 +507,7 @@ static int32_t pushDownCondOptDealScan(SOptimizeContext* pCxt, SScanLogicNode* p
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool pushDownCondOptBelongThisTable(SNode* pCondCol, SNodeList* pTableCols) {
|
static bool pdcColBelongThisTable(SNode* pCondCol, SNodeList* pTableCols) {
|
||||||
SNode* pTableCol = NULL;
|
SNode* pTableCol = NULL;
|
||||||
FOREACH(pTableCol, pTableCols) {
|
FOREACH(pTableCol, pTableCols) {
|
||||||
if (nodesEqualNode(pCondCol, pTableCol)) {
|
if (nodesEqualNode(pCondCol, pTableCol)) {
|
||||||
|
@ -509,7 +526,7 @@ static bool pushDownCondOptColInTableList(SNode* pCondCol, SSHashObj* pTables) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static EDealRes pushDownCondOptIsCrossTableCond(SNode* pNode, void* pContext) {
|
static EDealRes pdcJoinIsCrossTableCond(SNode* pNode, void* pContext) {
|
||||||
SCpdIsMultiTableCondCxt* pCxt = pContext;
|
SCpdIsMultiTableCondCxt* pCxt = pContext;
|
||||||
if (QUERY_NODE_COLUMN == nodeType(pNode)) {
|
if (QUERY_NODE_COLUMN == nodeType(pNode)) {
|
||||||
if (pushDownCondOptColInTableList(pNode, pCxt->pLeftTbls)) {
|
if (pushDownCondOptColInTableList(pNode, pCxt->pLeftTbls)) {
|
||||||
|
@ -522,19 +539,20 @@ static EDealRes pushDownCondOptIsCrossTableCond(SNode* pNode, void* pContext) {
|
||||||
return DEAL_RES_CONTINUE;
|
return DEAL_RES_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ECondAction pushDownCondOptGetCondAction(EJoinType joinType, SSHashObj* pLeftTbls, SSHashObj* pRightTbls,
|
static ECondAction pdcJoinGetCondAction(SJoinLogicNode* pJoin, SSHashObj* pLeftTbls, SSHashObj* pRightTbls,
|
||||||
SNode* pNode) {
|
SNode* pNode) {
|
||||||
|
EJoinType t = pJoin->joinType;
|
||||||
SCpdIsMultiTableCondCxt cxt = {
|
SCpdIsMultiTableCondCxt cxt = {
|
||||||
.pLeftTbls = pLeftTbls, .pRightTbls = pRightTbls, .havaLeftCol = false, .haveRightCol = false};
|
.pLeftTbls = pLeftTbls, .pRightTbls = pRightTbls, .havaLeftCol = false, .haveRightCol = false};
|
||||||
nodesWalkExpr(pNode, pushDownCondOptIsCrossTableCond, &cxt);
|
nodesWalkExpr(pNode, pdcJoinIsCrossTableCond, &cxt);
|
||||||
return (JOIN_TYPE_INNER != joinType
|
return (JOIN_TYPE_INNER != t
|
||||||
? COND_ACTION_STAY
|
? COND_ACTION_STAY
|
||||||
: (cxt.havaLeftCol && cxt.haveRightCol
|
: (cxt.havaLeftCol && cxt.haveRightCol
|
||||||
? COND_ACTION_PUSH_JOIN
|
? COND_ACTION_PUSH_JOIN
|
||||||
: (cxt.havaLeftCol ? COND_ACTION_PUSH_LEFT_CHILD : COND_ACTION_PUSH_RIGHT_CHILD)));
|
: (cxt.havaLeftCol ? COND_ACTION_PUSH_LEFT_CHILD : COND_ACTION_PUSH_RIGHT_CHILD)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t pushDownCondOptPartLogicCond(SJoinLogicNode* pJoin, SNode** pOnCond, SNode** pLeftChildCond,
|
static int32_t pdcJoinSplitLogicCond(SJoinLogicNode* pJoin, SNode** pOnCond, SNode** pLeftChildCond,
|
||||||
SNode** pRightChildCond) {
|
SNode** pRightChildCond) {
|
||||||
SLogicConditionNode* pLogicCond = (SLogicConditionNode*)pJoin->node.pConditions;
|
SLogicConditionNode* pLogicCond = (SLogicConditionNode*)pJoin->node.pConditions;
|
||||||
if (LOGIC_COND_TYPE_AND != pLogicCond->condType) {
|
if (LOGIC_COND_TYPE_AND != pLogicCond->condType) {
|
||||||
|
@ -553,7 +571,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, pLeftTables, pRightTables, pCond);
|
ECondAction condAction = pdcJoinGetCondAction(pJoin, 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) {
|
||||||
|
@ -608,15 +626,14 @@ static int32_t pushDownCondOptPartLogicCond(SJoinLogicNode* pJoin, SNode** pOnCo
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t pushDownCondOptPartOpCond(SJoinLogicNode* pJoin, SNode** pOnCond, SNode** pLeftChildCond,
|
static int32_t pdcJoinSplitOpCond(SJoinLogicNode* pJoin, SNode** pOnCond, SNode** pLeftChildCond,
|
||||||
SNode** pRightChildCond) {
|
SNode** pRightChildCond) {
|
||||||
SSHashObj* pLeftTables = NULL;
|
SSHashObj* pLeftTables = NULL;
|
||||||
SSHashObj* pRightTables = NULL;
|
SSHashObj* pRightTables = NULL;
|
||||||
collectTableAliasFromNodes(nodesListGetNode(pJoin->node.pChildren, 0), &pLeftTables);
|
collectTableAliasFromNodes(nodesListGetNode(pJoin->node.pChildren, 0), &pLeftTables);
|
||||||
collectTableAliasFromNodes(nodesListGetNode(pJoin->node.pChildren, 1), &pRightTables);
|
collectTableAliasFromNodes(nodesListGetNode(pJoin->node.pChildren, 1), &pRightTables);
|
||||||
|
|
||||||
ECondAction condAction =
|
ECondAction condAction = pdcJoinGetCondAction(pJoin, pLeftTables, pRightTables, pJoin->node.pConditions);
|
||||||
pushDownCondOptGetCondAction(pJoin->joinType, pLeftTables, pRightTables, pJoin->node.pConditions);
|
|
||||||
|
|
||||||
tSimpleHashCleanup(pLeftTables);
|
tSimpleHashCleanup(pLeftTables);
|
||||||
tSimpleHashCleanup(pRightTables);
|
tSimpleHashCleanup(pRightTables);
|
||||||
|
@ -634,21 +651,21 @@ static int32_t pushDownCondOptPartOpCond(SJoinLogicNode* pJoin, SNode** pOnCond,
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t pushDownCondOptPartCond(SJoinLogicNode* pJoin, SNode** pOnCond, SNode** pLeftChildCond,
|
static int32_t pdcJoinSplitOrigCond(SJoinLogicNode* pJoin, SNode** pOnCond, SNode** pLeftChildCond,
|
||||||
SNode** pRightChildCond) {
|
SNode** pRightChildCond) {
|
||||||
if (QUERY_NODE_LOGIC_CONDITION == nodeType(pJoin->node.pConditions)) {
|
if (QUERY_NODE_LOGIC_CONDITION == nodeType(pJoin->node.pConditions)) {
|
||||||
return pushDownCondOptPartLogicCond(pJoin, pOnCond, pLeftChildCond, pRightChildCond);
|
return pdcJoinSplitLogicCond(pJoin, pOnCond, pLeftChildCond, pRightChildCond);
|
||||||
} else {
|
} else {
|
||||||
return pushDownCondOptPartOpCond(pJoin, pOnCond, pLeftChildCond, pRightChildCond);
|
return pdcJoinSplitOpCond(pJoin, pOnCond, pLeftChildCond, pRightChildCond);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t pushDownCondOptPushCondToOnCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin, SNode** pCond) {
|
static int32_t pdcJoinPushDownOnCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin, SNode** pCond) {
|
||||||
return pushDownCondOptAppendCond(&pJoin->pOtherOnCond, pCond);
|
return pdcMergeConds(&pJoin->pFullOnCond, pCond);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t pushDownCondOptPushCondToChild(SOptimizeContext* pCxt, SLogicNode* pChild, SNode** pCond) {
|
static int32_t pdcPushDownCondToChild(SOptimizeContext* pCxt, SLogicNode* pChild, SNode** pCond) {
|
||||||
return pushDownCondOptAppendCond(&pChild->pConditions, pCond);
|
return pdcMergeConds(&pChild->pConditions, pCond);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool pushDownCondOptIsPriKey(SNode* pNode, SSHashObj* pTables) {
|
static bool pushDownCondOptIsPriKey(SNode* pNode, SSHashObj* pTables) {
|
||||||
|
@ -662,7 +679,7 @@ static bool pushDownCondOptIsPriKey(SNode* pNode, SSHashObj* pTables) {
|
||||||
return pushDownCondOptColInTableList(pNode, pTables);
|
return pushDownCondOptColInTableList(pNode, pTables);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool pushDownCondOptIsPriKeyEqualCond(SJoinLogicNode* pJoin, SNode* pCond) {
|
static bool pdcJoinIsPrimEqualCond(SJoinLogicNode* pJoin, SNode* pCond) {
|
||||||
if (QUERY_NODE_OPERATOR != nodeType(pCond)) {
|
if (QUERY_NODE_OPERATOR != nodeType(pCond)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -690,7 +707,7 @@ static bool pushDownCondOptIsPriKeyEqualCond(SJoinLogicNode* pJoin, SNode* pCond
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool pushDownCondOptContainPriKeyEqualCond(SJoinLogicNode* pJoin, SNode* pCond, bool* errCond) {
|
static bool pdcJoinHasPrimEqualCond(SJoinLogicNode* pJoin, SNode* pCond, bool* errCond) {
|
||||||
if (QUERY_NODE_LOGIC_CONDITION == nodeType(pCond)) {
|
if (QUERY_NODE_LOGIC_CONDITION == nodeType(pCond)) {
|
||||||
SLogicConditionNode* pLogicCond = (SLogicConditionNode*)pCond;
|
SLogicConditionNode* pLogicCond = (SLogicConditionNode*)pCond;
|
||||||
if (LOGIC_COND_TYPE_AND != pLogicCond->condType) {
|
if (LOGIC_COND_TYPE_AND != pLogicCond->condType) {
|
||||||
|
@ -702,39 +719,25 @@ static bool pushDownCondOptContainPriKeyEqualCond(SJoinLogicNode* pJoin, SNode*
|
||||||
bool hasPrimaryKeyEqualCond = false;
|
bool hasPrimaryKeyEqualCond = false;
|
||||||
SNode* pCond = NULL;
|
SNode* pCond = NULL;
|
||||||
FOREACH(pCond, pLogicCond->pParameterList) {
|
FOREACH(pCond, pLogicCond->pParameterList) {
|
||||||
if (pushDownCondOptContainPriKeyEqualCond(pJoin, pCond, NULL)) {
|
if (pdcJoinHasPrimEqualCond(pJoin, pCond, NULL)) {
|
||||||
hasPrimaryKeyEqualCond = true;
|
hasPrimaryKeyEqualCond = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return hasPrimaryKeyEqualCond;
|
return hasPrimaryKeyEqualCond;
|
||||||
} else {
|
} else {
|
||||||
return pushDownCondOptIsPriKeyEqualCond(pJoin, pCond);
|
return pdcJoinIsPrimEqualCond(pJoin, pCond);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t pushDownCondOptCheckJoinOnCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin) {
|
|
||||||
if (NULL == pJoin->pOtherOnCond) {
|
|
||||||
return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN);
|
|
||||||
}
|
|
||||||
bool errCond = false;
|
|
||||||
if (!pushDownCondOptContainPriKeyEqualCond(pJoin, pJoin->pOtherOnCond, &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_EXPECTED_TS_EQUAL);
|
|
||||||
}
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t pushDownCondOptPartJoinOnCondLogicCond(SJoinLogicNode* pJoin, SNode** ppPrimKeyEqCond, SNode** ppOnCond) {
|
static int32_t pushDownCondOptPartJoinOnCondLogicCond(SJoinLogicNode* pJoin, SNode** ppPrimKeyEqCond, SNode** ppOnCond) {
|
||||||
SLogicConditionNode* pLogicCond = (SLogicConditionNode*)(pJoin->pOtherOnCond);
|
SLogicConditionNode* pLogicCond = (SLogicConditionNode*)(pJoin->pFullOnCond);
|
||||||
|
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
SNodeList* pOnConds = NULL;
|
SNodeList* pOnConds = NULL;
|
||||||
SNode* pCond = NULL;
|
SNode* pCond = NULL;
|
||||||
WHERE_EACH(pCond, pLogicCond->pParameterList) {
|
WHERE_EACH(pCond, pLogicCond->pParameterList) {
|
||||||
if (pushDownCondOptIsPriKeyEqualCond(pJoin, pCond)) {
|
if (pdcJoinIsPrimEqualCond(pJoin, pCond)) {
|
||||||
nodesDestroyNode(*ppPrimKeyEqCond);
|
nodesDestroyNode(*ppPrimKeyEqCond);
|
||||||
*ppPrimKeyEqCond = nodesCloneNode(pCond);
|
*ppPrimKeyEqCond = nodesCloneNode(pCond);
|
||||||
ERASE_NODE(pLogicCond->pParameterList);
|
ERASE_NODE(pLogicCond->pParameterList);
|
||||||
|
@ -751,8 +754,8 @@ static int32_t pushDownCondOptPartJoinOnCondLogicCond(SJoinLogicNode* pJoin, SNo
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code && NULL != *ppPrimKeyEqCond) {
|
if (TSDB_CODE_SUCCESS == code && NULL != *ppPrimKeyEqCond) {
|
||||||
*ppOnCond = pTempOnCond;
|
*ppOnCond = pTempOnCond;
|
||||||
nodesDestroyNode(pJoin->pOtherOnCond);
|
nodesDestroyNode(pJoin->pFullOnCond);
|
||||||
pJoin->pOtherOnCond = NULL;
|
pJoin->pFullOnCond = NULL;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
nodesDestroyList(pOnConds);
|
nodesDestroyList(pOnConds);
|
||||||
|
@ -761,32 +764,29 @@ static int32_t pushDownCondOptPartJoinOnCondLogicCond(SJoinLogicNode* pJoin, SNo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t pushDownCondOptPartJoinOnCond(SJoinLogicNode* pJoin, SNode** ppPrimKeyEqCond, SNode** ppOnCond) {
|
static int32_t pdcPartJoinPrimCond(SJoinLogicNode* pJoin, SNode** ppPrimKeyEqCond, SNode** ppOnCond) {
|
||||||
if (QUERY_NODE_LOGIC_CONDITION == nodeType(pJoin->pOtherOnCond) &&
|
if (QUERY_NODE_LOGIC_CONDITION == nodeType(pJoin->pFullOnCond) &&
|
||||||
LOGIC_COND_TYPE_AND == ((SLogicConditionNode*)(pJoin->pOtherOnCond))->condType) {
|
LOGIC_COND_TYPE_AND == ((SLogicConditionNode*)(pJoin->pFullOnCond))->condType) {
|
||||||
return pushDownCondOptPartJoinOnCondLogicCond(pJoin, ppPrimKeyEqCond, ppOnCond);
|
return pushDownCondOptPartJoinOnCondLogicCond(pJoin, ppPrimKeyEqCond, ppOnCond);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pushDownCondOptIsPriKeyEqualCond(pJoin, pJoin->pOtherOnCond)) {
|
if (pdcJoinIsPrimEqualCond(pJoin, pJoin->pFullOnCond)) {
|
||||||
*ppPrimKeyEqCond = pJoin->pOtherOnCond;
|
*ppPrimKeyEqCond = pJoin->pFullOnCond;
|
||||||
*ppOnCond = NULL;
|
*ppOnCond = NULL;
|
||||||
pJoin->pOtherOnCond = NULL;
|
pJoin->pFullOnCond = NULL;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t pushDownCondOptJoinExtractCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin) {
|
static int32_t pdcJoinCheckPartPrimOnCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin) {
|
||||||
int32_t code = pushDownCondOptCheckJoinOnCond(pCxt, pJoin);
|
|
||||||
SNode* pPrimKeyEqCond = NULL;
|
SNode* pPrimKeyEqCond = NULL;
|
||||||
SNode* pJoinOnCond = NULL;
|
SNode* pJoinOnCond = NULL;
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
int32_t code = pdcPartJoinPrimCond(pJoin, &pPrimKeyEqCond, &pJoinOnCond);
|
||||||
code = pushDownCondOptPartJoinOnCond(pJoin, &pPrimKeyEqCond, &pJoinOnCond);
|
|
||||||
}
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
pJoin->pPrimKeyEqCond = pPrimKeyEqCond;
|
pJoin->pPrimKeyEqCond = pPrimKeyEqCond;
|
||||||
pJoin->pOtherOnCond = pJoinOnCond;
|
pJoin->pFullOnCond = pJoinOnCond;
|
||||||
} else {
|
} else {
|
||||||
nodesDestroyNode(pPrimKeyEqCond);
|
nodesDestroyNode(pPrimKeyEqCond);
|
||||||
nodesDestroyNode(pJoinOnCond);
|
nodesDestroyNode(pJoinOnCond);
|
||||||
|
@ -794,15 +794,15 @@ static int32_t pushDownCondOptJoinExtractCond(SOptimizeContext* pCxt, SJoinLogic
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool pushDownCondOptIsTableColumn(SNode* pNode, SNodeList* pTableCols) {
|
static bool pdcIsTableColumn(SNode* pNode, SNodeList* pTableCols) {
|
||||||
if (QUERY_NODE_COLUMN != nodeType(pNode)) {
|
if (QUERY_NODE_COLUMN != nodeType(pNode)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
SColumnNode* pCol = (SColumnNode*)pNode;
|
SColumnNode* pCol = (SColumnNode*)pNode;
|
||||||
return pushDownCondOptBelongThisTable(pNode, pTableCols);
|
return pdcColBelongThisTable(pNode, pTableCols);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool pushDownCondOptIsColEqualOnCond(SJoinLogicNode* pJoin, SNode* pCond, bool* allTags) {
|
static bool pdcIsEqualOnCond(SJoinLogicNode* pJoin, SNode* pCond, bool* allTags) {
|
||||||
if (QUERY_NODE_OPERATOR != nodeType(pCond)) {
|
if (QUERY_NODE_OPERATOR != nodeType(pCond)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -826,18 +826,17 @@ static bool pushDownCondOptIsColEqualOnCond(SJoinLogicNode* pJoin, SNode* pCond,
|
||||||
SNodeList* pLeftCols = ((SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 0))->pTargets;
|
SNodeList* pLeftCols = ((SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 0))->pTargets;
|
||||||
SNodeList* pRightCols = ((SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 1))->pTargets;
|
SNodeList* pRightCols = ((SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 1))->pTargets;
|
||||||
bool isEqual = false;
|
bool isEqual = false;
|
||||||
if (pushDownCondOptIsTableColumn(pOper->pLeft, pLeftCols)) {
|
if (pdcIsTableColumn(pOper->pLeft, pLeftCols)) {
|
||||||
isEqual = pushDownCondOptIsTableColumn(pOper->pRight, pRightCols);
|
isEqual = pdcIsTableColumn(pOper->pRight, pRightCols);
|
||||||
} else if (pushDownCondOptIsTableColumn(pOper->pLeft, pRightCols)) {
|
} else if (pdcIsTableColumn(pOper->pLeft, pRightCols)) {
|
||||||
isEqual = pushDownCondOptIsTableColumn(pOper->pRight, pLeftCols);
|
isEqual = pdcIsTableColumn(pOper->pRight, pLeftCols);
|
||||||
}
|
|
||||||
if (isEqual) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return isEqual;
|
return isEqual;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t pushDownCondOptJoinExtractEqualOnLogicCond(SJoinLogicNode* pJoin) {
|
static int32_t pdcJoinPartLogicEqualOnCond(SJoinLogicNode* pJoin) {
|
||||||
SLogicConditionNode* pLogicCond = (SLogicConditionNode*)(pJoin->pOtherOnCond);
|
SLogicConditionNode* pLogicCond = (SLogicConditionNode*)(pJoin->pFullOnCond);
|
||||||
|
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
SNodeList* pColEqOnConds = NULL;
|
SNodeList* pColEqOnConds = NULL;
|
||||||
|
@ -847,7 +846,7 @@ static int32_t pushDownCondOptJoinExtractEqualOnLogicCond(SJoinLogicNode* pJoin)
|
||||||
bool allTags = false;
|
bool allTags = false;
|
||||||
FOREACH(pCond, pLogicCond->pParameterList) {
|
FOREACH(pCond, pLogicCond->pParameterList) {
|
||||||
allTags = false;
|
allTags = false;
|
||||||
if (pushDownCondOptIsColEqualOnCond(pJoin, pCond, &allTags)) {
|
if (pdcIsEqualOnCond(pJoin, pCond, &allTags)) {
|
||||||
if (allTags) {
|
if (allTags) {
|
||||||
code = nodesListMakeAppend(&pTagEqOnConds, nodesCloneNode(pCond));
|
code = nodesListMakeAppend(&pTagEqOnConds, nodesCloneNode(pCond));
|
||||||
} else {
|
} else {
|
||||||
|
@ -887,33 +886,33 @@ static int32_t pushDownCondOptJoinExtractEqualOnLogicCond(SJoinLogicNode* pJoin)
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t pushDownCondOptJoinExtractEqualOnCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin) {
|
static int32_t pdcJoinPartEqualOnCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin) {
|
||||||
if (NULL == pJoin->pOtherOnCond) {
|
if (NULL == pJoin->pFullOnCond) {
|
||||||
pJoin->pColEqCond = NULL;
|
pJoin->pColEqCond = NULL;
|
||||||
pJoin->pTagEqCond = NULL;
|
pJoin->pTagEqCond = NULL;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
if (QUERY_NODE_LOGIC_CONDITION == nodeType(pJoin->pOtherOnCond) &&
|
if (QUERY_NODE_LOGIC_CONDITION == nodeType(pJoin->pFullOnCond) &&
|
||||||
LOGIC_COND_TYPE_AND == ((SLogicConditionNode*)(pJoin->pOtherOnCond))->condType) {
|
LOGIC_COND_TYPE_AND == ((SLogicConditionNode*)(pJoin->pFullOnCond))->condType) {
|
||||||
return pushDownCondOptJoinExtractEqualOnLogicCond(pJoin);
|
return pdcJoinPartLogicEqualOnCond(pJoin);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool allTags = false;
|
bool allTags = false;
|
||||||
if (pushDownCondOptIsColEqualOnCond(pJoin, pJoin->pOtherOnCond, &allTags)) {
|
if (pdcIsEqualOnCond(pJoin, pJoin->pFullOnCond, &allTags)) {
|
||||||
if (allTags) {
|
if (allTags) {
|
||||||
pJoin->pTagEqCond = nodesCloneNode(pJoin->pOtherOnCond);
|
pJoin->pTagEqCond = nodesCloneNode(pJoin->pFullOnCond);
|
||||||
} else {
|
} else {
|
||||||
pJoin->pColEqCond = nodesCloneNode(pJoin->pOtherOnCond);
|
pJoin->pColEqCond = nodesCloneNode(pJoin->pFullOnCond);
|
||||||
}
|
}
|
||||||
} else if (allTags) {
|
} else if (allTags) {
|
||||||
pJoin->pTagOnCond = nodesCloneNode(pJoin->pOtherOnCond);
|
pJoin->pTagOnCond = nodesCloneNode(pJoin->pFullOnCond);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t pushDownCondOptAppendFilterCol(SOptimizeContext* pCxt, SJoinLogicNode* pJoin) {
|
static int32_t pdcJoinAddPreFilterColsToTarget(SOptimizeContext* pCxt, SJoinLogicNode* pJoin) {
|
||||||
if (NULL == pJoin->pOtherOnCond) {
|
if (NULL == pJoin->pFullOnCond) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -923,7 +922,7 @@ static int32_t pushDownCondOptAppendFilterCol(SOptimizeContext* pCxt, SJoinLogic
|
||||||
if (NULL == pCondCols) {
|
if (NULL == pCondCols) {
|
||||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
} else {
|
} else {
|
||||||
code = nodesCollectColumnsFromNode(pJoin->pOtherOnCond, NULL, COLLECT_COL_TYPE_ALL, &pCondCols);
|
code = nodesCollectColumnsFromNode(pJoin->pFullOnCond, NULL, COLLECT_COL_TYPE_ALL, &pCondCols);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = createColumnByRewriteExprs(pCondCols, &pTargets);
|
code = createColumnByRewriteExprs(pCondCols, &pTargets);
|
||||||
|
@ -953,8 +952,26 @@ static int32_t pushDownCondOptAppendFilterCol(SOptimizeContext* pCxt, SJoinLogic
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t pdcJoinCheckAllCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin) {
|
||||||
|
if (NULL == pJoin->pFullOnCond) {
|
||||||
|
if ((!IS_INNER_NONE_JOIN(pJoin->joinType, pJoin->subType)) || NULL == pJoin->node.pConditions) {
|
||||||
|
return generateUsageErrMsg(pCxt->pPlanCxt->pMsg, pCxt->pPlanCxt->msgLen, TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t pushDownCondOptDealJoin(SOptimizeContext* pCxt, SJoinLogicNode* pJoin) {
|
SNode* pCond = pJoin->pFullOnCond ? pJoin->pFullOnCond : pJoin->node.pConditions;
|
||||||
|
bool errCond = false;
|
||||||
|
if (!pdcJoinHasPrimEqualCond(pJoin, pCond, &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_EXPECTED_TS_EQUAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t pdcDealJoin(SOptimizeContext* pCxt, SJoinLogicNode* pJoin) {
|
||||||
if (OPTIMIZE_FLAG_TEST_MASK(pJoin->node.optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE)) {
|
if (OPTIMIZE_FLAG_TEST_MASK(pJoin->node.optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE)) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -962,13 +979,33 @@ static int32_t pushDownCondOptDealJoin(SOptimizeContext* pCxt, SJoinLogicNode* p
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EJoinType t = pJoin->joinType;
|
||||||
|
EJoinSubType s = pJoin->subType;
|
||||||
|
SNode* pOnCond = NULL;
|
||||||
|
SNode* pLeftChildCond = NULL;
|
||||||
|
SNode* pRightChildCond = NULL;
|
||||||
|
int32_t code = pdcJoinCheckAllCond(pCxt, pJoin);
|
||||||
|
if (TSDB_CODE_SUCCESS == code && NULL != pJoin->node.pConditions && 0 != gJoinOpt[t][s].pushDownFlag) {
|
||||||
|
code = pdcJoinSplitOrigCond(pJoin, &pOnCond, &pLeftChildCond, &pRightChildCond);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code && NULL != pOnCond) {
|
||||||
|
code = pdcJoinPushDownOnCond(pCxt, pJoin, &pOnCond);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code && NULL != pLeftChildCond) {
|
||||||
|
code = pdcPushDownCondToChild(pCxt, (SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 0), &pLeftChildCond);
|
||||||
|
}
|
||||||
|
if (TSDB_CODE_SUCCESS == code && NULL != pRightChildCond) {
|
||||||
|
code = pdcPushDownCondToChild(pCxt, (SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 1), &pRightChildCond);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (NULL == pJoin->node.pConditions) {
|
if (NULL == pJoin->node.pConditions) {
|
||||||
int32_t code = pushDownCondOptJoinExtractCond(pCxt, pJoin);
|
int32_t code = pdcJoinCheckPartPrimOnCond(pCxt, pJoin);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = pushDownCondOptJoinExtractEqualOnCond(pCxt, pJoin);
|
code = pdcJoinPartEqualOnCond(pCxt, pJoin);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = pushDownCondOptAppendFilterCol(pCxt, pJoin);
|
code = pdcJoinAddPreFilterColsToTarget(pCxt, pJoin);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
OPTIMIZE_FLAG_SET_MASK(pJoin->node.optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE);
|
OPTIMIZE_FLAG_SET_MASK(pJoin->node.optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE);
|
||||||
|
@ -977,32 +1014,18 @@ static int32_t pushDownCondOptDealJoin(SOptimizeContext* pCxt, SJoinLogicNode* p
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
SNode* pOnCond = NULL;
|
|
||||||
SNode* pLeftChildCond = NULL;
|
|
||||||
SNode* pRightChildCond = NULL;
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
int32_t code = pushDownCondOptPartCond(pJoin, &pOnCond, &pLeftChildCond, &pRightChildCond);
|
code = pdcJoinCheckPartPrimOnCond(pCxt, pJoin);
|
||||||
if (TSDB_CODE_SUCCESS == code && NULL != pOnCond) {
|
|
||||||
code = pushDownCondOptPushCondToOnCond(pCxt, pJoin, &pOnCond);
|
|
||||||
}
|
|
||||||
if (TSDB_CODE_SUCCESS == code && NULL != pLeftChildCond) {
|
|
||||||
code =
|
|
||||||
pushDownCondOptPushCondToChild(pCxt, (SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 0), &pLeftChildCond);
|
|
||||||
}
|
|
||||||
if (TSDB_CODE_SUCCESS == code && NULL != pRightChildCond) {
|
|
||||||
code =
|
|
||||||
pushDownCondOptPushCondToChild(pCxt, (SLogicNode*)nodesListGetNode(pJoin->node.pChildren, 1), &pRightChildCond);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = pushDownCondOptJoinExtractCond(pCxt, pJoin);
|
code = pdcJoinPartEqualOnCond(pCxt, pJoin);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = pushDownCondOptJoinExtractEqualOnCond(pCxt, pJoin);
|
code = pdcJoinAddPreFilterColsToTarget(pCxt, pJoin);
|
||||||
}
|
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
|
||||||
code = pushDownCondOptAppendFilterCol(pCxt, pJoin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
@ -1099,7 +1122,7 @@ static int32_t partitionAggCond(SAggLogicNode* pAgg, SNode** ppAggFunCond, SNode
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t pushCondToAggCond(SOptimizeContext* pCxt, SAggLogicNode* pAgg, SNode** pAggFuncCond) {
|
static int32_t pushCondToAggCond(SOptimizeContext* pCxt, SAggLogicNode* pAgg, SNode** pAggFuncCond) {
|
||||||
return pushDownCondOptAppendCond(&pAgg->node.pConditions, pAggFuncCond);
|
return pdcMergeConds(&pAgg->node.pConditions, pAggFuncCond);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct SRewriteAggGroupKeyCondContext {
|
typedef struct SRewriteAggGroupKeyCondContext {
|
||||||
|
@ -1137,7 +1160,7 @@ static int32_t rewriteAggGroupKeyCondForPushDown(SOptimizeContext* pCxt, SAggLog
|
||||||
return cxt.errCode;
|
return cxt.errCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t pushDownCondOptDealAgg(SOptimizeContext* pCxt, SAggLogicNode* pAgg) {
|
static int32_t pdcDealAgg(SOptimizeContext* pCxt, SAggLogicNode* pAgg) {
|
||||||
if (NULL == pAgg->node.pConditions ||
|
if (NULL == pAgg->node.pConditions ||
|
||||||
OPTIMIZE_FLAG_TEST_MASK(pAgg->node.optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE)) {
|
OPTIMIZE_FLAG_TEST_MASK(pAgg->node.optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE)) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -1158,7 +1181,7 @@ static int32_t pushDownCondOptDealAgg(SOptimizeContext* pCxt, SAggLogicNode* pAg
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code && NULL != pGroupKeyCond) {
|
if (TSDB_CODE_SUCCESS == code && NULL != pGroupKeyCond) {
|
||||||
SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0);
|
SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0);
|
||||||
code = pushDownCondOptPushCondToChild(pCxt, pChild, &pGroupKeyCond);
|
code = pdcPushDownCondToChild(pCxt, pChild, &pGroupKeyCond);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
OPTIMIZE_FLAG_SET_MASK(pAgg->node.optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE);
|
OPTIMIZE_FLAG_SET_MASK(pAgg->node.optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE);
|
||||||
|
@ -1211,7 +1234,7 @@ static int32_t rewriteProjectCondForPushDown(SOptimizeContext* pCxt, SProjectLog
|
||||||
return cxt.errCode;
|
return cxt.errCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t pushDownCondOptDealProject(SOptimizeContext* pCxt, SProjectLogicNode* pProject) {
|
static int32_t pdcDealProject(SOptimizeContext* pCxt, SProjectLogicNode* pProject) {
|
||||||
if (NULL == pProject->node.pConditions ||
|
if (NULL == pProject->node.pConditions ||
|
||||||
OPTIMIZE_FLAG_TEST_MASK(pProject->node.optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE)) {
|
OPTIMIZE_FLAG_TEST_MASK(pProject->node.optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE)) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -1230,7 +1253,7 @@ static int32_t pushDownCondOptDealProject(SOptimizeContext* pCxt, SProjectLogicN
|
||||||
code = rewriteProjectCondForPushDown(pCxt, pProject, &pProjCond);
|
code = rewriteProjectCondForPushDown(pCxt, pProject, &pProjCond);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pProject->node.pChildren, 0);
|
SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pProject->node.pChildren, 0);
|
||||||
code = pushDownCondOptPushCondToChild(pCxt, pChild, &pProjCond);
|
code = pdcPushDownCondToChild(pCxt, pChild, &pProjCond);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
|
@ -1242,13 +1265,13 @@ static int32_t pushDownCondOptDealProject(SOptimizeContext* pCxt, SProjectLogicN
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t pushDownCondOptTrivialPushDown(SOptimizeContext* pCxt, SLogicNode* pLogicNode) {
|
static int32_t pdcTrivialPushDown(SOptimizeContext* pCxt, SLogicNode* pLogicNode) {
|
||||||
if (NULL == pLogicNode->pConditions ||
|
if (NULL == pLogicNode->pConditions ||
|
||||||
OPTIMIZE_FLAG_TEST_MASK(pLogicNode->optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE)) {
|
OPTIMIZE_FLAG_TEST_MASK(pLogicNode->optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE)) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pLogicNode->pChildren, 0);
|
SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pLogicNode->pChildren, 0);
|
||||||
int32_t code = pushDownCondOptPushCondToChild(pCxt, pChild, &pLogicNode->pConditions);
|
int32_t code = pdcPushDownCondToChild(pCxt, pChild, &pLogicNode->pConditions);
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
OPTIMIZE_FLAG_SET_MASK(pLogicNode->optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE);
|
OPTIMIZE_FLAG_SET_MASK(pLogicNode->optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE);
|
||||||
pCxt->optimized = true;
|
pCxt->optimized = true;
|
||||||
|
@ -1256,24 +1279,24 @@ static int32_t pushDownCondOptTrivialPushDown(SOptimizeContext* pCxt, SLogicNode
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t pushDownCondOptimizeImpl(SOptimizeContext* pCxt, SLogicNode* pLogicNode) {
|
static int32_t pdcOptimizeImpl(SOptimizeContext* pCxt, SLogicNode* pLogicNode) {
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
switch (nodeType(pLogicNode)) {
|
switch (nodeType(pLogicNode)) {
|
||||||
case QUERY_NODE_LOGIC_PLAN_SCAN:
|
case QUERY_NODE_LOGIC_PLAN_SCAN:
|
||||||
code = pushDownCondOptDealScan(pCxt, (SScanLogicNode*)pLogicNode);
|
code = pdcDealScan(pCxt, (SScanLogicNode*)pLogicNode);
|
||||||
break;
|
break;
|
||||||
case QUERY_NODE_LOGIC_PLAN_JOIN:
|
case QUERY_NODE_LOGIC_PLAN_JOIN:
|
||||||
code = pushDownCondOptDealJoin(pCxt, (SJoinLogicNode*)pLogicNode);
|
code = pdcDealJoin(pCxt, (SJoinLogicNode*)pLogicNode);
|
||||||
break;
|
break;
|
||||||
case QUERY_NODE_LOGIC_PLAN_AGG:
|
case QUERY_NODE_LOGIC_PLAN_AGG:
|
||||||
code = pushDownCondOptDealAgg(pCxt, (SAggLogicNode*)pLogicNode);
|
code = pdcDealAgg(pCxt, (SAggLogicNode*)pLogicNode);
|
||||||
break;
|
break;
|
||||||
case QUERY_NODE_LOGIC_PLAN_PROJECT:
|
case QUERY_NODE_LOGIC_PLAN_PROJECT:
|
||||||
code = pushDownCondOptDealProject(pCxt, (SProjectLogicNode*)pLogicNode);
|
code = pdcDealProject(pCxt, (SProjectLogicNode*)pLogicNode);
|
||||||
break;
|
break;
|
||||||
case QUERY_NODE_LOGIC_PLAN_SORT:
|
case QUERY_NODE_LOGIC_PLAN_SORT:
|
||||||
case QUERY_NODE_LOGIC_PLAN_PARTITION:
|
case QUERY_NODE_LOGIC_PLAN_PARTITION:
|
||||||
code = pushDownCondOptTrivialPushDown(pCxt, pLogicNode);
|
code = pdcTrivialPushDown(pCxt, pLogicNode);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -1281,7 +1304,7 @@ static int32_t pushDownCondOptimizeImpl(SOptimizeContext* pCxt, SLogicNode* pLog
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
SNode* pChild = NULL;
|
SNode* pChild = NULL;
|
||||||
FOREACH(pChild, pLogicNode->pChildren) {
|
FOREACH(pChild, pLogicNode->pChildren) {
|
||||||
code = pushDownCondOptimizeImpl(pCxt, (SLogicNode*)pChild);
|
code = pdcOptimizeImpl(pCxt, (SLogicNode*)pChild);
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1290,8 +1313,8 @@ static int32_t pushDownCondOptimizeImpl(SOptimizeContext* pCxt, SLogicNode* pLog
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t pushDownCondOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) {
|
static int32_t pdcOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) {
|
||||||
return pushDownCondOptimizeImpl(pCxt, pLogicSubplan->pNode);
|
return pdcOptimizeImpl(pCxt, pLogicSubplan->pNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool sortPriKeyOptIsPriKeyOrderBy(SNodeList* pSortKeys) {
|
static bool sortPriKeyOptIsPriKeyOrderBy(SNodeList* pSortKeys) {
|
||||||
|
@ -1966,10 +1989,10 @@ static bool eliminateProjOptCanChildConditionUseChildTargets(SLogicNode* pChild,
|
||||||
if (QUERY_NODE_LOGIC_PLAN_JOIN == nodeType(pChild) && ((SJoinLogicNode*)pChild)->joinAlgo != JOIN_ALGO_UNKNOWN) {
|
if (QUERY_NODE_LOGIC_PLAN_JOIN == nodeType(pChild) && ((SJoinLogicNode*)pChild)->joinAlgo != JOIN_ALGO_UNKNOWN) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (QUERY_NODE_LOGIC_PLAN_JOIN == nodeType(pChild) && ((SJoinLogicNode*)pChild)->pOtherOnCond) {
|
if (QUERY_NODE_LOGIC_PLAN_JOIN == nodeType(pChild) && ((SJoinLogicNode*)pChild)->pFullOnCond) {
|
||||||
SJoinLogicNode* pJoinLogicNode = (SJoinLogicNode*)pChild;
|
SJoinLogicNode* pJoinLogicNode = (SJoinLogicNode*)pChild;
|
||||||
CheckNewChildTargetsCxt cxt = {.pNewChildTargets = pNewChildTargets, .canUse = false};
|
CheckNewChildTargetsCxt cxt = {.pNewChildTargets = pNewChildTargets, .canUse = false};
|
||||||
nodesWalkExpr(pJoinLogicNode->pOtherOnCond, eliminateProjOptCanUseNewChildTargetsImpl, &cxt);
|
nodesWalkExpr(pJoinLogicNode->pFullOnCond, eliminateProjOptCanUseNewChildTargetsImpl, &cxt);
|
||||||
if (!cxt.canUse) return false;
|
if (!cxt.canUse) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -3629,7 +3652,7 @@ static int32_t stbJoinOptCreateTagHashJoinNode(SLogicNode* pOrig, SNodeList* pCh
|
||||||
pJoin->node.requireDataOrder = DATA_ORDER_LEVEL_NONE;
|
pJoin->node.requireDataOrder = DATA_ORDER_LEVEL_NONE;
|
||||||
pJoin->node.resultDataOrder = DATA_ORDER_LEVEL_NONE;
|
pJoin->node.resultDataOrder = DATA_ORDER_LEVEL_NONE;
|
||||||
pJoin->pTagEqCond = nodesCloneNode(pOrigJoin->pTagEqCond);
|
pJoin->pTagEqCond = nodesCloneNode(pOrigJoin->pTagEqCond);
|
||||||
pJoin->pOtherOnCond = nodesCloneNode(pOrigJoin->pTagOnCond);
|
pJoin->pFullOnCond = nodesCloneNode(pOrigJoin->pTagOnCond);
|
||||||
|
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
pJoin->node.pChildren = pChildren;
|
pJoin->node.pChildren = pChildren;
|
||||||
|
@ -3741,12 +3764,12 @@ static int32_t stbJoinOptCreateGroupCacheNode(SLogicNode* pRoot, SNodeList* pChi
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stbJoinOptRemoveTagEqCond(SJoinLogicNode* pJoin) {
|
static void stbJoinOptRemoveTagEqCond(SJoinLogicNode* pJoin) {
|
||||||
if (QUERY_NODE_OPERATOR == nodeType(pJoin->pOtherOnCond) && nodesEqualNode(pJoin->pOtherOnCond, pJoin->pTagEqCond)) {
|
if (QUERY_NODE_OPERATOR == nodeType(pJoin->pFullOnCond) && nodesEqualNode(pJoin->pFullOnCond, pJoin->pTagEqCond)) {
|
||||||
NODES_DESTORY_NODE(pJoin->pOtherOnCond);
|
NODES_DESTORY_NODE(pJoin->pFullOnCond);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (QUERY_NODE_LOGIC_CONDITION == nodeType(pJoin->pOtherOnCond)) {
|
if (QUERY_NODE_LOGIC_CONDITION == nodeType(pJoin->pFullOnCond)) {
|
||||||
SLogicConditionNode* pLogic = (SLogicConditionNode*)pJoin->pOtherOnCond;
|
SLogicConditionNode* pLogic = (SLogicConditionNode*)pJoin->pFullOnCond;
|
||||||
SNode* pNode = NULL;
|
SNode* pNode = NULL;
|
||||||
FOREACH(pNode, pLogic->pParameterList) {
|
FOREACH(pNode, pLogic->pParameterList) {
|
||||||
if (nodesEqualNode(pNode, pJoin->pTagEqCond)) {
|
if (nodesEqualNode(pNode, pJoin->pTagEqCond)) {
|
||||||
|
@ -3765,7 +3788,7 @@ static void stbJoinOptRemoveTagEqCond(SJoinLogicNode* pJoin) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pLogic->pParameterList->length <= 0) {
|
if (pLogic->pParameterList->length <= 0) {
|
||||||
NODES_DESTORY_NODE(pJoin->pOtherOnCond);
|
NODES_DESTORY_NODE(pJoin->pFullOnCond);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4042,7 +4065,7 @@ static int32_t partitionColsOpt(SOptimizeContext* pCxt, SLogicSubplan* pLogicSub
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const SOptimizeRule optimizeRuleSet[] = {
|
static const SOptimizeRule optimizeRuleSet[] = {
|
||||||
{.pName = "ScanPath", .optimizeFunc = scanPathOptimize},
|
{.pName = "ScanPath", .optimizeFunc = scanPathOptimize},
|
||||||
{.pName = "PushDownCondition", .optimizeFunc = pushDownCondOptimize},
|
{.pName = "PushDownCondition", .optimizeFunc = pdcOptimize},
|
||||||
{.pName = "StableJoin", .optimizeFunc = stableJoinOptimize},
|
{.pName = "StableJoin", .optimizeFunc = stableJoinOptimize},
|
||||||
{.pName = "sortNonPriKeyOptimize", .optimizeFunc = sortNonPriKeyOptimize},
|
{.pName = "sortNonPriKeyOptimize", .optimizeFunc = sortNonPriKeyOptimize},
|
||||||
{.pName = "SortPrimaryKey", .optimizeFunc = sortPrimaryKeyOptimize},
|
{.pName = "SortPrimaryKey", .optimizeFunc = sortPrimaryKeyOptimize},
|
||||||
|
|
|
@ -787,9 +787,9 @@ static int32_t createMergeJoinPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChi
|
||||||
&pJoin->pTargets);
|
&pJoin->pTargets);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code && NULL != pJoinLogicNode->pOtherOnCond) {
|
if (TSDB_CODE_SUCCESS == code && NULL != pJoinLogicNode->pFullOnCond) {
|
||||||
code = setNodeSlotId(pCxt, ((SPhysiNode*)pJoin)->pOutputDataBlockDesc->dataBlockId, -1,
|
code = setNodeSlotId(pCxt, ((SPhysiNode*)pJoin)->pOutputDataBlockDesc->dataBlockId, -1,
|
||||||
pJoinLogicNode->pOtherOnCond, &pJoin->pOtherOnCond);
|
pJoinLogicNode->pFullOnCond, &pJoin->pFullOnCond);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code && ((NULL != pJoinLogicNode->pColEqCond) || (NULL != pJoinLogicNode->pTagEqCond))) {
|
if (TSDB_CODE_SUCCESS == code && ((NULL != pJoinLogicNode->pColEqCond) || (NULL != pJoinLogicNode->pTagEqCond))) {
|
||||||
|
@ -963,8 +963,8 @@ static int32_t createHashJoinPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChil
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = setNodeSlotId(pCxt, pLeftDesc->dataBlockId, pRightDesc->dataBlockId, pJoinLogicNode->pTagEqCond, &pJoin->pTagEqCond);
|
code = setNodeSlotId(pCxt, pLeftDesc->dataBlockId, pRightDesc->dataBlockId, pJoinLogicNode->pTagEqCond, &pJoin->pTagEqCond);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code && NULL != pJoinLogicNode->pOtherOnCond) {
|
if (TSDB_CODE_SUCCESS == code && NULL != pJoinLogicNode->pFullOnCond) {
|
||||||
code = setNodeSlotId(pCxt, ((SPhysiNode*)pJoin)->pOutputDataBlockDesc->dataBlockId, -1, pJoinLogicNode->pOtherOnCond, &pJoin->pFilterConditions);
|
code = setNodeSlotId(pCxt, ((SPhysiNode*)pJoin)->pOutputDataBlockDesc->dataBlockId, -1, pJoinLogicNode->pFullOnCond, &pJoin->pFilterConditions);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
code = setListSlotId(pCxt, pLeftDesc->dataBlockId, pRightDesc->dataBlockId, pJoinLogicNode->node.pTargets, &pJoin->pTargets);
|
code = setListSlotId(pCxt, pLeftDesc->dataBlockId, pRightDesc->dataBlockId, pJoinLogicNode->node.pTargets, &pJoin->pTargets);
|
||||||
|
|
|
@ -20,6 +20,11 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define VALIDNUMOFCOLS(x) ((x) >= TSDB_MIN_COLUMNS && (x) <= TSDB_MAX_COLUMNS)
|
||||||
|
#define VALIDNUMOFTAGS(x) ((x) >= 0 && (x) <= TSDB_MAX_TAGS)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -21,18 +21,17 @@
|
||||||
#include "tsched.h"
|
#include "tsched.h"
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#include "cJSON.h"
|
#include "cJSON.h"
|
||||||
|
#include "queryInt.h"
|
||||||
|
|
||||||
#define VALIDNUMOFCOLS(x) ((x) >= TSDB_MIN_COLUMNS && (x) <= TSDB_MAX_COLUMNS)
|
const SSchema* tGetTbnameColumnSchema() {
|
||||||
#define VALIDNUMOFTAGS(x) ((x) >= 0 && (x) <= TSDB_MAX_TAGS)
|
static struct SSchema _s = {
|
||||||
|
.colId = TSDB_TBNAME_COLUMN_INDEX,
|
||||||
static struct SSchema _s = {
|
.type = TSDB_DATA_TYPE_BINARY,
|
||||||
.colId = TSDB_TBNAME_COLUMN_INDEX,
|
.bytes = TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE,
|
||||||
.type = TSDB_DATA_TYPE_BINARY,
|
.name = "tbname",
|
||||||
.bytes = TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE,
|
};
|
||||||
.name = "tbname",
|
return &_s;
|
||||||
};
|
}
|
||||||
|
|
||||||
const SSchema* tGetTbnameColumnSchema() { return &_s; }
|
|
||||||
|
|
||||||
static bool doValidateSchema(SSchema* pSchema, int32_t numOfCols, int32_t maxLen) {
|
static bool doValidateSchema(SSchema* pSchema, int32_t numOfCols, int32_t maxLen) {
|
||||||
int32_t rowLen = 0;
|
int32_t rowLen = 0;
|
||||||
|
|
Loading…
Reference in New Issue