fix: support timeline query from union and order by
This commit is contained in:
parent
f9834898c6
commit
6064ea0125
|
@ -415,6 +415,7 @@ typedef struct SSelectStmt {
|
|||
int32_t returnRows; // EFuncReturnRows
|
||||
ETimeLineMode timeLineCurMode;
|
||||
ETimeLineMode timeLineResMode;
|
||||
bool timeLineFromOrderBy;
|
||||
bool isEmptyResult;
|
||||
bool isSubquery;
|
||||
bool hasAggFuncs;
|
||||
|
@ -453,6 +454,7 @@ typedef struct SSetOperator {
|
|||
char stmtName[TSDB_TABLE_NAME_LEN];
|
||||
uint8_t precision;
|
||||
ETimeLineMode timeLineResMode;
|
||||
bool timeLineFromOrderBy;
|
||||
bool joinContains;
|
||||
} SSetOperator;
|
||||
|
||||
|
|
|
@ -845,6 +845,7 @@ static int32_t selectStmtCopy(const SSelectStmt* pSrc, SSelectStmt* pDst) {
|
|||
COPY_SCALAR_FIELD(precision);
|
||||
COPY_SCALAR_FIELD(isEmptyResult);
|
||||
COPY_SCALAR_FIELD(timeLineResMode);
|
||||
COPY_SCALAR_FIELD(timeLineFromOrderBy);
|
||||
COPY_SCALAR_FIELD(timeLineCurMode);
|
||||
COPY_SCALAR_FIELD(hasAggFuncs);
|
||||
COPY_SCALAR_FIELD(hasRepeatScanFuncs);
|
||||
|
@ -862,6 +863,8 @@ static int32_t setOperatorCopy(const SSetOperator* pSrc, SSetOperator* pDst) {
|
|||
COPY_CHAR_ARRAY_FIELD(stmtName);
|
||||
COPY_SCALAR_FIELD(precision);
|
||||
COPY_SCALAR_FIELD(timeLineResMode);
|
||||
COPY_SCALAR_FIELD(timeLineFromOrderBy);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -959,7 +959,8 @@ static bool isTimeLineQuery(SNode* pStmt) {
|
|||
return (TIME_LINE_MULTI == ((SSelectStmt*)pStmt)->timeLineCurMode) ||
|
||||
(TIME_LINE_GLOBAL == ((SSelectStmt*)pStmt)->timeLineCurMode);
|
||||
} else if (QUERY_NODE_SET_OPERATOR == nodeType(pStmt)) {
|
||||
return TIME_LINE_GLOBAL == ((SSetOperator*)pStmt)->timeLineResMode;
|
||||
return (TIME_LINE_MULTI == ((SSetOperator*)pStmt)->timeLineResMode) ||
|
||||
(TIME_LINE_GLOBAL == ((SSetOperator*)pStmt)->timeLineResMode);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -1000,18 +1001,56 @@ static bool isBlockTimeLineAlignedQuery(SNode* pStmt) {
|
|||
return false;
|
||||
}
|
||||
|
||||
SNodeList* buildPartitionListFromOrderList(SNodeList* pOrderList) {
|
||||
SNodeList* pPartitionList = NULL;
|
||||
SNode* pNode = NULL;
|
||||
FOREACH(pNode, pOrderList) {
|
||||
if (pNode == pOrderList->pTail->pNode) {
|
||||
break;
|
||||
}
|
||||
SOrderByExprNode* pOrder = (SOrderByExprNode*)pNode;
|
||||
nodesListMakeStrictAppend(&pPartitionList, nodesCloneNode(pOrder->pExpr));
|
||||
}
|
||||
|
||||
return pPartitionList;
|
||||
}
|
||||
|
||||
|
||||
static bool isTimeLineAlignedQuery(SNode* pStmt) {
|
||||
SSelectStmt* pSelect = (SSelectStmt*)pStmt;
|
||||
if (!isTimeLineQuery(((STempTableNode*)pSelect->pFromTable)->pSubquery)) {
|
||||
return false;
|
||||
}
|
||||
if (QUERY_NODE_SELECT_STMT != nodeType(((STempTableNode*)pSelect->pFromTable)->pSubquery)) {
|
||||
return false;
|
||||
if (QUERY_NODE_SELECT_STMT == nodeType(((STempTableNode*)pSelect->pFromTable)->pSubquery)) {
|
||||
SSelectStmt* pSub = (SSelectStmt*)((STempTableNode*)pSelect->pFromTable)->pSubquery;
|
||||
if (pSelect->pPartitionByList) {
|
||||
if (!pSub->timeLineFromOrderBy && nodesListMatch(pSelect->pPartitionByList, pSub->pPartitionByList)) {
|
||||
return true;
|
||||
}
|
||||
if (pSub->timeLineFromOrderBy && pSub->pOrderByList->length > 1) {
|
||||
SNodeList* pPartitionList = buildPartitionListFromOrderList(pSub->pOrderByList);
|
||||
bool match = nodesListMatch(pSelect->pPartitionByList, pPartitionList);
|
||||
nodesDestroyList(pPartitionList);
|
||||
|
||||
if (match) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SSelectStmt* pSub = (SSelectStmt*)((STempTableNode*)pSelect->pFromTable)->pSubquery;
|
||||
if (pSelect->pPartitionByList && nodesListMatch(pSelect->pPartitionByList, pSub->pPartitionByList)) {
|
||||
return true;
|
||||
if (QUERY_NODE_SET_OPERATOR == nodeType(((STempTableNode*)pSelect->pFromTable)->pSubquery)) {
|
||||
SSetOperator* pSub = (SSetOperator*)((STempTableNode*)pSelect->pFromTable)->pSubquery;
|
||||
if (pSelect->pPartitionByList && pSub->timeLineFromOrderBy && pSub->pOrderByList->length > 1) {
|
||||
SNodeList* pPartitionList = buildPartitionListFromOrderList(pSub->pOrderByList);
|
||||
bool match = nodesListMatch(pSelect->pPartitionByList, pPartitionList);
|
||||
nodesDestroyList(pPartitionList);
|
||||
|
||||
if (match) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -6025,9 +6064,18 @@ static void resetResultTimeline(SSelectStmt* pSelect) {
|
|||
if ((QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable) && isPrimaryKeyImpl(pOrder)) ||
|
||||
(QUERY_NODE_TEMP_TABLE != nodeType(pSelect->pFromTable) && isPrimaryKeyImpl(pOrder))) {
|
||||
pSelect->timeLineResMode = TIME_LINE_GLOBAL;
|
||||
} else {
|
||||
pSelect->timeLineResMode = TIME_LINE_NONE;
|
||||
return;
|
||||
} else if (pSelect->pOrderByList->length > 1) {
|
||||
pOrder = ((SOrderByExprNode*)nodesListGetNode(pSelect->pOrderByList, pSelect->pOrderByList->length - 1))->pExpr;
|
||||
if ((QUERY_NODE_TEMP_TABLE == nodeType(pSelect->pFromTable) && isPrimaryKeyImpl(pOrder)) ||
|
||||
(QUERY_NODE_TEMP_TABLE != nodeType(pSelect->pFromTable) && isPrimaryKeyImpl(pOrder))) {
|
||||
pSelect->timeLineResMode = TIME_LINE_MULTI;
|
||||
pSelect->timeLineFromOrderBy = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
pSelect->timeLineResMode = TIME_LINE_NONE;
|
||||
}
|
||||
|
||||
static int32_t replaceOrderByAliasForSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
|
@ -6180,16 +6228,13 @@ static int32_t translateSetOperProject(STranslateContext* pCxt, SSetOperator* pS
|
|||
}
|
||||
snprintf(pRightExpr->aliasName, sizeof(pRightExpr->aliasName), "%s", pLeftExpr->aliasName);
|
||||
SNode* pProj = createSetOperProject(pSetOperator->stmtName, pLeft);
|
||||
if (QUERY_NODE_COLUMN == nodeType(pLeft) && QUERY_NODE_COLUMN == nodeType(pRight)) {
|
||||
SColumnNode* pLCol = (SColumnNode*)pLeft;
|
||||
SColumnNode* pRCol = (SColumnNode*)pRight;
|
||||
bool isLeftPrimTs = isPrimaryKeyImpl(pLeft);
|
||||
bool isRightPrimTs = isPrimaryKeyImpl(pRight);
|
||||
|
||||
if (isLeftPrimTs && isRightPrimTs) {
|
||||
SColumnNode* pFCol = (SColumnNode*)pProj;
|
||||
if (pLCol->colId == PRIMARYKEY_TIMESTAMP_COL_ID && pRCol->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
|
||||
pFCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
|
||||
if (pLCol->isPrimTs && pRCol->isPrimTs) {
|
||||
pFCol->isPrimTs = true;
|
||||
}
|
||||
}
|
||||
pFCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID;
|
||||
pFCol->isPrimTs = true;
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != nodesListMakeStrictAppend(&pSetOperator->pProjectionList, pProj)) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
@ -6225,9 +6270,17 @@ static int32_t translateSetOperOrderBy(STranslateContext* pCxt, SSetOperator* pS
|
|||
SNode* pOrder = ((SOrderByExprNode*)nodesListGetNode(pSetOperator->pOrderByList, 0))->pExpr;
|
||||
if (isPrimaryKeyImpl(pOrder)) {
|
||||
pSetOperator->timeLineResMode = TIME_LINE_GLOBAL;
|
||||
} else {
|
||||
pSetOperator->timeLineResMode = TIME_LINE_NONE;
|
||||
return code;
|
||||
} else if (pSetOperator->pOrderByList->length > 1) {
|
||||
pOrder = ((SOrderByExprNode*)nodesListGetNode(pSetOperator->pOrderByList, pSetOperator->pOrderByList->length - 1))->pExpr;
|
||||
if (isPrimaryKeyImpl(pOrder)) {
|
||||
pSetOperator->timeLineResMode = TIME_LINE_MULTI;
|
||||
pSetOperator->timeLineFromOrderBy = true;
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
pSetOperator->timeLineResMode = TIME_LINE_NONE;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue