fix: join condition issue
This commit is contained in:
parent
7769bc3d19
commit
1fc0efee83
|
@ -63,7 +63,7 @@ typedef struct SExprNode {
|
||||||
bool asParam;
|
bool asParam;
|
||||||
bool asPosition;
|
bool asPosition;
|
||||||
bool joinSrc;
|
bool joinSrc;
|
||||||
// bool joinConst;
|
//bool constValue;
|
||||||
int32_t projIdx;
|
int32_t projIdx;
|
||||||
int32_t relatedTo;
|
int32_t relatedTo;
|
||||||
int32_t bindExprID;
|
int32_t bindExprID;
|
||||||
|
@ -714,6 +714,8 @@ int32_t mergeJoinConds(SNode** ppDst, SNode** ppSrc);
|
||||||
|
|
||||||
void rewriteExprAliasName(SExprNode* pNode, int64_t num);
|
void rewriteExprAliasName(SExprNode* pNode, int64_t num);
|
||||||
bool isRelatedToOtherExpr(SExprNode* pExpr);
|
bool isRelatedToOtherExpr(SExprNode* pExpr);
|
||||||
|
bool nodesContainsColumn(SNode* pNode);
|
||||||
|
int32_t nodesMergeNode(SNode** pCond, SNode** pAdditionalCond);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -3280,3 +3280,76 @@ void rewriteExprAliasName(SExprNode* pNode, int64_t num) {
|
||||||
bool isRelatedToOtherExpr(SExprNode* pExpr) {
|
bool isRelatedToOtherExpr(SExprNode* pExpr) {
|
||||||
return pExpr->relatedTo != 0;
|
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);
|
SAssociationNode* pAssNode = taosArrayGet(pAssociation, i);
|
||||||
SNode** pCol = pAssNode->pPlace;
|
SNode** pCol = pAssNode->pPlace;
|
||||||
if (((SExprNode*)pAssNode->pAssociationNode)->joinSrc) {
|
if (((SExprNode*)pAssNode->pAssociationNode)->joinSrc) {
|
||||||
// ((SExprNode*)pAssNode->pAssociationNode)->joinConst = true;
|
//((SExprNode*)pAssNode->pAssociationNode)->constValue = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5156,6 +5156,79 @@ int32_t mergeInnerJoinConds(SNode** ppDst, SNode** ppSrc) {
|
||||||
return code;
|
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) {
|
int32_t translateTable(STranslateContext* pCxt, SNode** pTable, bool inJoin) {
|
||||||
SSelectStmt* pCurrSmt = (SSelectStmt*)(pCxt->pCurrStmt);
|
SSelectStmt* pCurrSmt = (SSelectStmt*)(pCxt->pCurrStmt);
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
@ -5243,13 +5316,18 @@ int32_t translateTable(STranslateContext* pCxt, SNode** pTable, bool inJoin) {
|
||||||
code = checkJoinTable(pCxt, pJoinTable);
|
code = checkJoinTable(pCxt, pJoinTable);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code && !inJoin && pCurrSmt->pWhere && JOIN_TYPE_INNER == pJoinTable->joinType) {
|
if (TSDB_CODE_SUCCESS == code && !inJoin && pCurrSmt->pWhere && JOIN_TYPE_INNER == pJoinTable->joinType) {
|
||||||
|
SNode* pPrimCond = NULL;
|
||||||
|
code = splitJoinColPrimaryCond(&pCurrSmt->pWhere, &pPrimCond);
|
||||||
|
if (TSDB_CODE_SUCCESS == code && pPrimCond) {
|
||||||
if (pJoinTable->pOnCond) {
|
if (pJoinTable->pOnCond) {
|
||||||
code = mergeInnerJoinConds(&pJoinTable->pOnCond, &pCurrSmt->pWhere);
|
code = mergeInnerJoinConds(&pJoinTable->pOnCond, &pPrimCond);
|
||||||
} else {
|
} else {
|
||||||
pJoinTable->pOnCond = pCurrSmt->pWhere;
|
pJoinTable->pOnCond = pPrimCond;
|
||||||
pCurrSmt->pWhere = NULL;
|
pPrimCond = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
nodesDestroyNode(pPrimCond);
|
||||||
|
}
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
pJoinTable->table.precision = calcJoinTablePrecision(pJoinTable);
|
pJoinTable->table.precision = calcJoinTablePrecision(pJoinTable);
|
||||||
pJoinTable->table.singleTable = joinTableIsSingleTable(pJoinTable);
|
pJoinTable->table.singleTable = joinTableIsSingleTable(pJoinTable);
|
||||||
|
|
|
@ -503,52 +503,12 @@ static int32_t scanPathOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSub
|
||||||
return code;
|
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,
|
static int32_t pushDownCondOptCalcTimeRange(SOptimizeContext* pCxt, SScanLogicNode* pScan, SNode** pPrimaryKeyCond,
|
||||||
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 = pdcMergeConds(pOtherCond, pPrimaryKeyCond);
|
code = nodesMergeNode(pOtherCond, pPrimaryKeyCond);
|
||||||
} else {
|
} else {
|
||||||
bool isStrict = false;
|
bool isStrict = false;
|
||||||
code = filterGetTimeRange(*pPrimaryKeyCond, &pScan->scanRange, &isStrict);
|
code = filterGetTimeRange(*pPrimaryKeyCond, &pScan->scanRange, &isStrict);
|
||||||
|
@ -556,7 +516,7 @@ static int32_t pushDownCondOptCalcTimeRange(SOptimizeContext* pCxt, SScanLogicNo
|
||||||
if (isStrict) {
|
if (isStrict) {
|
||||||
nodesDestroyNode(*pPrimaryKeyCond);
|
nodesDestroyNode(*pPrimaryKeyCond);
|
||||||
} else {
|
} else {
|
||||||
code = pdcMergeConds(pOtherCond, pPrimaryKeyCond);
|
code = nodesMergeNode(pOtherCond, pPrimaryKeyCond);
|
||||||
}
|
}
|
||||||
*pPrimaryKeyCond = NULL;
|
*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) {
|
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) {
|
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) {
|
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) {
|
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 {
|
typedef struct SRewriteAggGroupKeyCondContext {
|
||||||
|
|
Loading…
Reference in New Issue