fix subquery with same name caused data error
This commit is contained in:
parent
2dffbe488b
commit
9713094bb2
|
@ -61,6 +61,7 @@ typedef struct SExprNode {
|
|||
bool asAlias;
|
||||
bool asParam;
|
||||
bool asPosition;
|
||||
int32_t projIdx;
|
||||
} SExprNode;
|
||||
|
||||
typedef enum EColumnType {
|
||||
|
@ -91,6 +92,7 @@ typedef struct SColumnNode {
|
|||
int16_t numOfPKs;
|
||||
bool tableHasPk;
|
||||
bool isPk;
|
||||
int32_t projRefIdx;
|
||||
} SColumnNode;
|
||||
|
||||
typedef struct SColumnRefNode {
|
||||
|
|
|
@ -103,6 +103,7 @@ static int32_t exprNodeCopy(const SExprNode* pSrc, SExprNode* pDst) {
|
|||
COPY_CHAR_ARRAY_FIELD(aliasName);
|
||||
COPY_CHAR_ARRAY_FIELD(userAlias);
|
||||
COPY_SCALAR_FIELD(orderAlias);
|
||||
COPY_SCALAR_FIELD(projIdx);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -124,6 +125,7 @@ static int32_t columnNodeCopy(const SColumnNode* pSrc, SColumnNode* pDst) {
|
|||
COPY_SCALAR_FIELD(tableHasPk);
|
||||
COPY_SCALAR_FIELD(isPk);
|
||||
COPY_SCALAR_FIELD(numOfPKs);
|
||||
COPY_SCALAR_FIELD(projRefIdx);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -1305,7 +1305,11 @@ static int32_t createColumnsByTable(STranslateContext* pCxt, const STableNode* p
|
|||
SListCell* pCell = nodesListGetCell(pList, LIST_LENGTH(pList) - 1);
|
||||
code = setColumnInfoByExpr(pTempTable, (SExprNode*)pNode, (SColumnNode**)&pCell->pNode);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != code) break;
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
pCol->projRefIdx = ((SExprNode*)pNode)->projIdx;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return code;
|
||||
|
@ -5174,6 +5178,11 @@ static int32_t translateProjectionList(STranslateContext* pCxt, SSelectStmt* pSe
|
|||
if (!pSelect->isSubquery) {
|
||||
return rewriteProjectAlias(pSelect->pProjectionList);
|
||||
} else {
|
||||
SNode* pNode;
|
||||
int32_t projIdx = 1;
|
||||
FOREACH(pNode, pSelect->pProjectionList) {
|
||||
((SExprNode*)pNode)->projIdx = projIdx++;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,6 +68,7 @@ int32_t tagScanSetExecutionMode(SScanLogicNode* pScan);
|
|||
int32_t cloneLimit(SLogicNode* pParent, SLogicNode* pChild, uint8_t cloneWhat, bool* pCloned);
|
||||
int32_t sortPriKeyOptGetSequencingNodesImpl(SLogicNode* pNode, bool groupSort, SSortLogicNode* pSort,
|
||||
bool* pNotOptimize, SNodeList** pSequencingNodes, bool* keepSort);
|
||||
bool isColRefExpr(const SColumnNode* pCol, const SExprNode* pExpr);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -1390,11 +1390,14 @@ static int32_t createColumnByProjections(SLogicPlanContext* pCxt, const char* pS
|
|||
}
|
||||
|
||||
SNode* pNode;
|
||||
int32_t projIdx = 1;
|
||||
FOREACH(pNode, pExprs) {
|
||||
if (TSDB_CODE_SUCCESS != (code = nodesListStrictAppend(pList, (SNode*)createColumnByExpr(pStmtName, (SExprNode*)pNode)))) {
|
||||
SColumnNode* pCol = createColumnByExpr(pStmtName, (SExprNode*)pNode);
|
||||
if (TSDB_CODE_SUCCESS != (code = nodesListStrictAppend(pList, (SNode*)pCol))) {
|
||||
nodesDestroyList(pList);
|
||||
return code;
|
||||
}
|
||||
pCol->projRefIdx = ((SExprNode*)pNode)->projIdx;
|
||||
}
|
||||
|
||||
*pCols = pList;
|
||||
|
|
|
@ -4883,13 +4883,41 @@ typedef struct SMergeProjectionsContext {
|
|||
int32_t errCode;
|
||||
} SMergeProjectionsContext;
|
||||
|
||||
static EDealRes mergeProjectionsExpr2(SNode** pNode, void* pContext) {
|
||||
SMergeProjectionsContext* pCxt = pContext;
|
||||
SProjectLogicNode* pChildProj = pCxt->pChildProj;
|
||||
if (QUERY_NODE_COLUMN == nodeType(*pNode)) {
|
||||
SColumnNode* pProjCol = (SColumnNode*)(*pNode);
|
||||
SNode* pProjection;
|
||||
int32_t projIdx = 1;
|
||||
FOREACH(pProjection, pChildProj->pProjections) {
|
||||
if (isColRefExpr(pProjCol, (SExprNode*)pProjection)) {
|
||||
|
||||
//}
|
||||
//if (0 == strcmp(((SColumnNode*)(*pNode))->colName, ((SExprNode*)pProjection)->aliasName)) {
|
||||
SNode* pExpr = NULL;
|
||||
pCxt->errCode = nodesCloneNode(pProjection, &pExpr);
|
||||
if (pExpr == NULL) {
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
snprintf(((SExprNode*)pExpr)->aliasName, sizeof(((SExprNode*)pExpr)->aliasName), "%s",
|
||||
((SExprNode*)*pNode)->aliasName);// 保留外层project的aliasname, 外层project的aliasName是被改写过的.
|
||||
nodesDestroyNode(*pNode);
|
||||
*pNode = pExpr;
|
||||
return DEAL_RES_IGNORE_CHILD;
|
||||
}
|
||||
}
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static EDealRes mergeProjectionsExpr(SNode** pNode, void* pContext) {
|
||||
SMergeProjectionsContext* pCxt = pContext;
|
||||
SProjectLogicNode* pChildProj = pCxt->pChildProj;
|
||||
if (QUERY_NODE_COLUMN == nodeType(*pNode)) {
|
||||
SNode* pTarget;
|
||||
FOREACH(pTarget, ((SLogicNode*)pChildProj)->pTargets) {
|
||||
if (nodesEqualNode(pTarget, *pNode)) {
|
||||
if (nodesEqualNode(pTarget, *pNode)) { // pNode是projectlist里的, aliasName被改写成了expr_#, 而pTarget是根据childProject的projectlist生成的, node里面啥都没有
|
||||
SNode* pProjection;
|
||||
FOREACH(pProjection, pChildProj->pProjections) {
|
||||
if (0 == strcmp(((SColumnNode*)pTarget)->colName, ((SExprNode*)pProjection)->aliasName)) {
|
||||
|
@ -4917,7 +4945,7 @@ static int32_t mergeProjectsOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan*
|
|||
((SProjectLogicNode*)pSelfNode)->inputIgnoreGroup = true;
|
||||
}
|
||||
SMergeProjectionsContext cxt = {.pChildProj = (SProjectLogicNode*)pChild, .errCode = TSDB_CODE_SUCCESS};
|
||||
nodesRewriteExprs(((SProjectLogicNode*)pSelfNode)->pProjections, mergeProjectionsExpr, &cxt);
|
||||
nodesRewriteExprs(((SProjectLogicNode*)pSelfNode)->pProjections, mergeProjectionsExpr2, &cxt);
|
||||
int32_t code = cxt.errCode;
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
|
|
@ -166,6 +166,7 @@ static int32_t createTarget(SNode* pNode, int16_t dataBlockId, int16_t slotId, S
|
|||
}
|
||||
|
||||
static int32_t putSlotToHashImpl(int16_t dataBlockId, int16_t slotId, const char* pName, int32_t len, SHashObj* pHash) {
|
||||
qInfo("wjm put slot into hash: %p, name: %s, slotId: %d", pHash, pName, slotId);
|
||||
SSlotIndex* pIndex = taosHashGet(pHash, pName, len);
|
||||
if (NULL != pIndex) {
|
||||
SSlotIdInfo info = {.slotId = slotId, .set = false};
|
||||
|
@ -223,8 +224,16 @@ static int32_t buildDataBlockSlots(SPhysiPlanContext* pCxt, SNodeList* pList, SD
|
|||
code = nodesListStrictAppend(pDataBlockDesc->pSlots, createSlotDesc(pCxt, name, pNode, slotId, true, false));
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
qInfo("wjm append slot name: %s, slotId: %d, aliasName: %s", name, slotId, ((SExprNode*)pNode)->aliasName);
|
||||
code = putSlotToHash(name, len, pDataBlockDesc->dataBlockId, slotId, pNode, pHash);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
if (nodeType(pNode) == QUERY_NODE_COLUMN && ((SColumnNode*)pNode)->projRefIdx > 0) {
|
||||
sprintf(name + strlen(name), "%d", ((SColumnNode*)pNode)->projRefIdx);
|
||||
}
|
||||
qInfo("wjm append slot name: %s, slotId: %d, aliasName: %s", name, slotId, ((SExprNode*)pNode)->aliasName);
|
||||
code = putSlotToHash(name, strlen(name), pDataBlockDesc->dataBlockId, slotId, pNode, pHash);
|
||||
}
|
||||
taosMemoryFree(name);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
pDataBlockDesc->totalRowSize += ((SExprNode*)pNode)->resType.bytes;
|
||||
|
@ -306,6 +315,7 @@ static int32_t addDataBlockSlotsImpl(SPhysiPlanContext* pCxt, SNodeList* pList,
|
|||
}
|
||||
}
|
||||
|
||||
qInfo("wjm add datablock slots for: %s id: %d, aliasName: %s", name, slotId, ((SExprNode*)pNode)->aliasName);
|
||||
taosMemoryFree(name);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
SNode* pTarget = NULL;
|
||||
|
@ -383,9 +393,12 @@ static EDealRes doSetSlotId(SNode* pNode, void* pContext) {
|
|||
if (TSDB_CODE_SUCCESS != pCxt->errCode) {
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
SSlotIndex* pIndex = taosHashGet(pCxt->pLeftHash, name, len);
|
||||
if (((SColumnNode*)pNode)->projRefIdx > 0) {
|
||||
sprintf(name + strlen(name), "%d", ((SColumnNode*)pNode)->projRefIdx);
|
||||
}
|
||||
SSlotIndex* pIndex = taosHashGet(pCxt->pLeftHash, name, strlen(name));
|
||||
if (NULL == pIndex) {
|
||||
pIndex = taosHashGet(pCxt->pRightHash, name, len);
|
||||
pIndex = taosHashGet(pCxt->pRightHash, name, strlen(name));
|
||||
}
|
||||
// pIndex is definitely not NULL, otherwise it is a bug
|
||||
if (NULL == pIndex) {
|
||||
|
@ -396,9 +409,10 @@ static EDealRes doSetSlotId(SNode* pNode, void* pContext) {
|
|||
taosMemoryFree(name);
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
taosMemoryFree(name);
|
||||
((SColumnNode*)pNode)->dataBlockId = pIndex->dataBlockId;
|
||||
((SColumnNode*)pNode)->slotId = ((SSlotIdInfo*)taosArrayGet(pIndex->pSlotIdsInfo, 0))->slotId;
|
||||
qInfo("wjm set slotId for %s, slotId: %d, aliasName: %s", name, ((SColumnNode*)pNode)->slotId, ((SExprNode*)pNode)->aliasName);
|
||||
taosMemoryFree(name);
|
||||
return DEAL_RES_IGNORE_CHILD;
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
|
@ -462,6 +476,7 @@ static SPhysiNode* makePhysiNode(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode
|
|||
terrno = code;
|
||||
return NULL;
|
||||
}
|
||||
qInfo("wjm create node: %s", nodesNodeName(type));
|
||||
|
||||
TSWAP(pPhysiNode->pLimit, pLogicNode->pLimit);
|
||||
TSWAP(pPhysiNode->pSlimit, pLogicNode->pSlimit);
|
||||
|
|
|
@ -716,5 +716,8 @@ int32_t tagScanSetExecutionMode(SScanLogicNode* pScan) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
bool isColRefExpr(const SColumnNode* pCol, const SExprNode* pExpr) {
|
||||
if (pCol->projRefIdx > 0) return pCol->projRefIdx == pExpr->projIdx;
|
||||
|
||||
|
||||
return 0 == strcmp(pCol->colName, pExpr->aliasName);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue