fix: join condition issue
This commit is contained in:
parent
7769bc3d19
commit
1fc0efee83
|
@ -63,7 +63,7 @@ typedef struct SExprNode {
|
|||
bool asParam;
|
||||
bool asPosition;
|
||||
bool joinSrc;
|
||||
// bool joinConst;
|
||||
//bool constValue;
|
||||
int32_t projIdx;
|
||||
int32_t relatedTo;
|
||||
int32_t bindExprID;
|
||||
|
@ -714,6 +714,8 @@ int32_t mergeJoinConds(SNode** ppDst, SNode** ppSrc);
|
|||
|
||||
void rewriteExprAliasName(SExprNode* pNode, int64_t num);
|
||||
bool isRelatedToOtherExpr(SExprNode* pExpr);
|
||||
bool nodesContainsColumn(SNode* pNode);
|
||||
int32_t nodesMergeNode(SNode** pCond, SNode** pAdditionalCond);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -3280,3 +3280,76 @@ void rewriteExprAliasName(SExprNode* pNode, int64_t num) {
|
|||
bool isRelatedToOtherExpr(SExprNode* pExpr) {
|
||||
return pExpr->relatedTo != 0;
|
||||
}
|
||||
|
||||
typedef struct SContainsColCxt {
|
||||
bool containsCol;
|
||||
} SContainsColCxt;
|
||||
|
||||
static EDealRes nodeContainsCol(SNode* pNode, void* pContext) {
|
||||
SContainsColCxt* pCxt = pContext;
|
||||
if (QUERY_NODE_COLUMN == nodeType(pNode)) {
|
||||
pCxt->containsCol = true;
|
||||
return DEAL_RES_END;
|
||||
}
|
||||
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
bool nodesContainsColumn(SNode* pNode) {
|
||||
if (NULL == pNode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SContainsColCxt cxt = {0};
|
||||
nodesWalkExpr(pNode, nodeContainsCol, &cxt);
|
||||
|
||||
return cxt.containsCol;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int32_t mergeNodeToLogic(SNode** pDst, SNode** pSrc) {
|
||||
SLogicConditionNode* pLogicCond = NULL;
|
||||
int32_t code = nodesMakeNode(QUERY_NODE_LOGIC_CONDITION, (SNode**)&pLogicCond);
|
||||
if (NULL == pLogicCond) {
|
||||
return code;
|
||||
}
|
||||
pLogicCond->node.resType.type = TSDB_DATA_TYPE_BOOL;
|
||||
pLogicCond->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes;
|
||||
pLogicCond->condType = LOGIC_COND_TYPE_AND;
|
||||
code = nodesListMakeAppend(&pLogicCond->pParameterList, *pSrc);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
*pSrc = NULL;
|
||||
code = nodesListMakeAppend(&pLogicCond->pParameterList, *pDst);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
*pDst = (SNode*)pLogicCond;
|
||||
} else {
|
||||
nodesDestroyNode((SNode*)pLogicCond);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
int32_t nodesMergeNode(SNode** pCond, SNode** pAdditionalCond) {
|
||||
if (NULL == *pCond) {
|
||||
TSWAP(*pCond, *pAdditionalCond);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (QUERY_NODE_LOGIC_CONDITION == nodeType(*pCond) &&
|
||||
LOGIC_COND_TYPE_AND == ((SLogicConditionNode*)*pCond)->condType) {
|
||||
code = nodesListAppend(((SLogicConditionNode*)*pCond)->pParameterList, *pAdditionalCond);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
*pAdditionalCond = NULL;
|
||||
}
|
||||
} else {
|
||||
code = mergeNodeToLogic(pCond, pAdditionalCond);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -281,7 +281,7 @@ static int32_t calcConstProject(SCalcConstContext* pCxt, SNode* pProject, bool d
|
|||
SAssociationNode* pAssNode = taosArrayGet(pAssociation, i);
|
||||
SNode** pCol = pAssNode->pPlace;
|
||||
if (((SExprNode*)pAssNode->pAssociationNode)->joinSrc) {
|
||||
// ((SExprNode*)pAssNode->pAssociationNode)->joinConst = true;
|
||||
//((SExprNode*)pAssNode->pAssociationNode)->constValue = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -5156,6 +5156,79 @@ int32_t mergeInnerJoinConds(SNode** ppDst, SNode** ppSrc) {
|
|||
return code;
|
||||
}
|
||||
|
||||
bool isColumnExpr(SNode* pNode) {
|
||||
SExprNode* pExpr = (SExprNode*)pNode;
|
||||
if (QUERY_NODE_COLUMN != nodeType(pNode) && QUERY_NODE_FUNCTION != nodeType(pNode)) {
|
||||
return false;
|
||||
}
|
||||
if (QUERY_NODE_FUNCTION == nodeType(pNode)) {
|
||||
SFunctionNode* pFunc = (SFunctionNode*)pNode;
|
||||
if (FUNCTION_TYPE_TIMETRUNCATE != pFunc->funcType && strcasecmp(((SFunctionNode*)pNode)->functionName, "timetruncate")) {
|
||||
return false;
|
||||
}
|
||||
if (!nodesContainsColumn(nodesListGetNode(pFunc->pParameterList, 0))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t splitJoinColPrimaryCond(SNode** ppSrc, SNode** ppDst) {
|
||||
if (NULL == *ppSrc) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t code = 0;
|
||||
switch (nodeType(*ppSrc)) {
|
||||
case QUERY_NODE_OPERATOR: {
|
||||
SOperatorNode* pOp = (SOperatorNode*)*ppSrc;
|
||||
if (OP_TYPE_EQUAL != pOp->opType) {
|
||||
break;
|
||||
}
|
||||
if (isColumnExpr(pOp->pLeft) && isColumnExpr(pOp->pRight)) {
|
||||
TSWAP(*ppSrc, *ppDst);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_LOGIC_CONDITION: {
|
||||
SLogicConditionNode* pLogic = (SLogicConditionNode*)*ppSrc;
|
||||
if (LOGIC_COND_TYPE_AND != pLogic->condType) {
|
||||
break;
|
||||
}
|
||||
SNode* pTmp = NULL;
|
||||
SNode* pTmpRes = NULL;
|
||||
WHERE_EACH(pTmp, pLogic->pParameterList) {
|
||||
code = splitJoinColPrimaryCond(&pTmp, &pTmpRes);
|
||||
if (code) {
|
||||
break;
|
||||
}
|
||||
if (NULL == pTmp && NULL != pTmpRes) {
|
||||
cell->pNode = NULL;
|
||||
ERASE_NODE(pLogic->pParameterList);
|
||||
code = nodesMergeNode(ppDst, &pTmpRes);
|
||||
if (code) {
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
WHERE_NEXT;
|
||||
}
|
||||
if (pLogic->pParameterList->length <= 0) {
|
||||
nodesDestroyNode(*ppSrc);
|
||||
*ppSrc = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t translateTable(STranslateContext* pCxt, SNode** pTable, bool inJoin) {
|
||||
SSelectStmt* pCurrSmt = (SSelectStmt*)(pCxt->pCurrStmt);
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
@ -5243,12 +5316,17 @@ int32_t translateTable(STranslateContext* pCxt, SNode** pTable, bool inJoin) {
|
|||
code = checkJoinTable(pCxt, pJoinTable);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code && !inJoin && pCurrSmt->pWhere && JOIN_TYPE_INNER == pJoinTable->joinType) {
|
||||
if (pJoinTable->pOnCond) {
|
||||
code = mergeInnerJoinConds(&pJoinTable->pOnCond, &pCurrSmt->pWhere);
|
||||
} else {
|
||||
pJoinTable->pOnCond = pCurrSmt->pWhere;
|
||||
pCurrSmt->pWhere = NULL;
|
||||
SNode* pPrimCond = NULL;
|
||||
code = splitJoinColPrimaryCond(&pCurrSmt->pWhere, &pPrimCond);
|
||||
if (TSDB_CODE_SUCCESS == code && pPrimCond) {
|
||||
if (pJoinTable->pOnCond) {
|
||||
code = mergeInnerJoinConds(&pJoinTable->pOnCond, &pPrimCond);
|
||||
} else {
|
||||
pJoinTable->pOnCond = pPrimCond;
|
||||
pPrimCond = NULL;
|
||||
}
|
||||
}
|
||||
nodesDestroyNode(pPrimCond);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
pJoinTable->table.precision = calcJoinTablePrecision(pJoinTable);
|
||||
|
|
|
@ -503,52 +503,12 @@ static int32_t scanPathOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSub
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t pdcMergeCondsToLogic(SNode** pDst, SNode** pSrc) {
|
||||
SLogicConditionNode* pLogicCond = NULL;
|
||||
int32_t code = nodesMakeNode(QUERY_NODE_LOGIC_CONDITION, (SNode**)&pLogicCond);
|
||||
if (NULL == pLogicCond) {
|
||||
return code;
|
||||
}
|
||||
pLogicCond->node.resType.type = TSDB_DATA_TYPE_BOOL;
|
||||
pLogicCond->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes;
|
||||
pLogicCond->condType = LOGIC_COND_TYPE_AND;
|
||||
code = nodesListMakeAppend(&pLogicCond->pParameterList, *pSrc);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
*pSrc = NULL;
|
||||
code = nodesListMakeAppend(&pLogicCond->pParameterList, *pDst);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
*pDst = (SNode*)pLogicCond;
|
||||
} else {
|
||||
nodesDestroyNode((SNode*)pLogicCond);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t pdcMergeConds(SNode** pCond, SNode** pAdditionalCond) {
|
||||
if (NULL == *pCond) {
|
||||
TSWAP(*pCond, *pAdditionalCond);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (QUERY_NODE_LOGIC_CONDITION == nodeType(*pCond) &&
|
||||
LOGIC_COND_TYPE_AND == ((SLogicConditionNode*)*pCond)->condType) {
|
||||
code = nodesListAppend(((SLogicConditionNode*)*pCond)->pParameterList, *pAdditionalCond);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
*pAdditionalCond = NULL;
|
||||
}
|
||||
} else {
|
||||
code = pdcMergeCondsToLogic(pCond, pAdditionalCond);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t pushDownCondOptCalcTimeRange(SOptimizeContext* pCxt, SScanLogicNode* pScan, SNode** pPrimaryKeyCond,
|
||||
SNode** pOtherCond) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (pCxt->pPlanCxt->topicQuery || pCxt->pPlanCxt->streamQuery) {
|
||||
code = pdcMergeConds(pOtherCond, pPrimaryKeyCond);
|
||||
code = nodesMergeNode(pOtherCond, pPrimaryKeyCond);
|
||||
} else {
|
||||
bool isStrict = false;
|
||||
code = filterGetTimeRange(*pPrimaryKeyCond, &pScan->scanRange, &isStrict);
|
||||
|
@ -556,7 +516,7 @@ static int32_t pushDownCondOptCalcTimeRange(SOptimizeContext* pCxt, SScanLogicNo
|
|||
if (isStrict) {
|
||||
nodesDestroyNode(*pPrimaryKeyCond);
|
||||
} else {
|
||||
code = pdcMergeConds(pOtherCond, pPrimaryKeyCond);
|
||||
code = nodesMergeNode(pOtherCond, pPrimaryKeyCond);
|
||||
}
|
||||
*pPrimaryKeyCond = NULL;
|
||||
}
|
||||
|
@ -828,11 +788,11 @@ static int32_t pdcJoinSplitCond(SJoinLogicNode* pJoin, SNode** pSrcCond, SNode**
|
|||
}
|
||||
|
||||
static int32_t pdcJoinPushDownOnCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin, SNode** pCond) {
|
||||
return pdcMergeConds(&pJoin->pFullOnCond, pCond);
|
||||
return nodesMergeNode(&pJoin->pFullOnCond, pCond);
|
||||
}
|
||||
|
||||
static int32_t pdcPushDownCondToChild(SOptimizeContext* pCxt, SLogicNode* pChild, SNode** pCond) {
|
||||
return pdcMergeConds(&pChild->pConditions, pCond);
|
||||
return nodesMergeNode(&pChild->pConditions, pCond);
|
||||
}
|
||||
|
||||
static bool pdcJoinIsPrim(SNode* pNode, SSHashObj* pTables, bool constAsPrim, bool* constPrimGot) {
|
||||
|
@ -2073,7 +2033,7 @@ static int32_t partitionAggCond(SAggLogicNode* pAgg, SNode** ppAggFunCond, SNode
|
|||
}
|
||||
|
||||
static int32_t pushCondToAggCond(SOptimizeContext* pCxt, SAggLogicNode* pAgg, SNode** pAggFuncCond) {
|
||||
return pdcMergeConds(&pAgg->node.pConditions, pAggFuncCond);
|
||||
return nodesMergeNode(&pAgg->node.pConditions, pAggFuncCond);
|
||||
}
|
||||
|
||||
typedef struct SRewriteAggGroupKeyCondContext {
|
||||
|
|
Loading…
Reference in New Issue