301 lines
11 KiB
C++
301 lines
11 KiB
C++
/*
|
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
|
*
|
|
* This program is free software: you can use, redistribute, AND/or modify
|
|
* it under the terms of the GNU Affero General Public License, version 3
|
|
* or later ("AGPL"), as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "nodes.h"
|
|
#include "plannodes.h"
|
|
#include "querynodes.h"
|
|
|
|
class NodesCloneTest : public testing::Test {
|
|
public:
|
|
void registerCheckFunc(const std::function<void(const SNode*, const SNode*)>& func) { checkFunc_ = func; }
|
|
|
|
void run(const SNode* pSrc) {
|
|
std::unique_ptr<SNode, void (*)(SNode*)> pDst(nodesCloneNode(pSrc), nodesDestroyNode);
|
|
checkFunc_(pSrc, pDst.get());
|
|
}
|
|
|
|
private:
|
|
std::function<void(const SNode*, const SNode*)> checkFunc_;
|
|
};
|
|
|
|
TEST_F(NodesCloneTest, tempTable) {
|
|
registerCheckFunc([](const SNode* pSrc, const SNode* pDst) {
|
|
ASSERT_EQ(nodeType(pSrc), nodeType(pDst));
|
|
STempTableNode* pSrcNode = (STempTableNode*)pSrc;
|
|
STempTableNode* pDstNode = (STempTableNode*)pDst;
|
|
ASSERT_EQ(nodeType(pSrcNode->pSubquery), nodeType(pDstNode->pSubquery));
|
|
});
|
|
|
|
std::unique_ptr<SNode, void (*)(SNode*)> srcNode(nullptr, nodesDestroyNode);
|
|
|
|
run([&]() {
|
|
srcNode.reset(nodesMakeNode(QUERY_NODE_TEMP_TABLE));
|
|
STempTableNode* pNode = (STempTableNode*)srcNode.get();
|
|
pNode->pSubquery = nodesMakeNode(QUERY_NODE_SELECT_STMT);
|
|
return srcNode.get();
|
|
}());
|
|
}
|
|
|
|
TEST_F(NodesCloneTest, joinTable) {
|
|
registerCheckFunc([](const SNode* pSrc, const SNode* pDst) {
|
|
ASSERT_EQ(nodeType(pSrc), nodeType(pDst));
|
|
SJoinTableNode* pSrcNode = (SJoinTableNode*)pSrc;
|
|
SJoinTableNode* pDstNode = (SJoinTableNode*)pDst;
|
|
ASSERT_EQ(pSrcNode->joinType, pDstNode->joinType);
|
|
ASSERT_EQ(nodeType(pSrcNode->pLeft), nodeType(pDstNode->pLeft));
|
|
ASSERT_EQ(nodeType(pSrcNode->pRight), nodeType(pDstNode->pRight));
|
|
if (NULL != pSrcNode->pOnCond) {
|
|
ASSERT_EQ(nodeType(pSrcNode->pOnCond), nodeType(pDstNode->pOnCond));
|
|
}
|
|
});
|
|
|
|
std::unique_ptr<SNode, void (*)(SNode*)> srcNode(nullptr, nodesDestroyNode);
|
|
|
|
run([&]() {
|
|
srcNode.reset(nodesMakeNode(QUERY_NODE_JOIN_TABLE));
|
|
SJoinTableNode* pNode = (SJoinTableNode*)srcNode.get();
|
|
pNode->joinType = JOIN_TYPE_INNER;
|
|
pNode->pLeft = nodesMakeNode(QUERY_NODE_REAL_TABLE);
|
|
pNode->pRight = nodesMakeNode(QUERY_NODE_REAL_TABLE);
|
|
pNode->pOnCond = nodesMakeNode(QUERY_NODE_OPERATOR);
|
|
return srcNode.get();
|
|
}());
|
|
}
|
|
|
|
TEST_F(NodesCloneTest, stateWindow) {
|
|
registerCheckFunc([](const SNode* pSrc, const SNode* pDst) {
|
|
ASSERT_EQ(nodeType(pSrc), nodeType(pDst));
|
|
SStateWindowNode* pSrcNode = (SStateWindowNode*)pSrc;
|
|
SStateWindowNode* pDstNode = (SStateWindowNode*)pDst;
|
|
ASSERT_EQ(nodeType(pSrcNode->pCol), nodeType(pDstNode->pCol));
|
|
ASSERT_EQ(nodeType(pSrcNode->pExpr), nodeType(pDstNode->pExpr));
|
|
});
|
|
|
|
std::unique_ptr<SNode, void (*)(SNode*)> srcNode(nullptr, nodesDestroyNode);
|
|
|
|
run([&]() {
|
|
srcNode.reset(nodesMakeNode(QUERY_NODE_STATE_WINDOW));
|
|
SStateWindowNode* pNode = (SStateWindowNode*)srcNode.get();
|
|
pNode->pCol = nodesMakeNode(QUERY_NODE_COLUMN);
|
|
pNode->pExpr = nodesMakeNode(QUERY_NODE_OPERATOR);
|
|
return srcNode.get();
|
|
}());
|
|
}
|
|
|
|
TEST_F(NodesCloneTest, sessionWindow) {
|
|
registerCheckFunc([](const SNode* pSrc, const SNode* pDst) {
|
|
ASSERT_EQ(nodeType(pSrc), nodeType(pDst));
|
|
SSessionWindowNode* pSrcNode = (SSessionWindowNode*)pSrc;
|
|
SSessionWindowNode* pDstNode = (SSessionWindowNode*)pDst;
|
|
ASSERT_EQ(nodeType(pSrcNode->pCol), nodeType(pDstNode->pCol));
|
|
ASSERT_EQ(nodeType(pSrcNode->pGap), nodeType(pDstNode->pGap));
|
|
});
|
|
|
|
std::unique_ptr<SNode, void (*)(SNode*)> srcNode(nullptr, nodesDestroyNode);
|
|
|
|
run([&]() {
|
|
srcNode.reset(nodesMakeNode(QUERY_NODE_SESSION_WINDOW));
|
|
SSessionWindowNode* pNode = (SSessionWindowNode*)srcNode.get();
|
|
pNode->pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
|
|
pNode->pGap = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE);
|
|
return srcNode.get();
|
|
}());
|
|
}
|
|
|
|
TEST_F(NodesCloneTest, intervalWindow) {
|
|
registerCheckFunc([](const SNode* pSrc, const SNode* pDst) {
|
|
ASSERT_EQ(nodeType(pSrc), nodeType(pDst));
|
|
SIntervalWindowNode* pSrcNode = (SIntervalWindowNode*)pSrc;
|
|
SIntervalWindowNode* pDstNode = (SIntervalWindowNode*)pDst;
|
|
ASSERT_EQ(nodeType(pSrcNode->pInterval), nodeType(pDstNode->pInterval));
|
|
if (NULL != pSrcNode->pOffset) {
|
|
ASSERT_EQ(nodeType(pSrcNode->pOffset), nodeType(pDstNode->pOffset));
|
|
}
|
|
if (NULL != pSrcNode->pSliding) {
|
|
ASSERT_EQ(nodeType(pSrcNode->pSliding), nodeType(pDstNode->pSliding));
|
|
}
|
|
if (NULL != pSrcNode->pFill) {
|
|
ASSERT_EQ(nodeType(pSrcNode->pFill), nodeType(pDstNode->pFill));
|
|
}
|
|
});
|
|
|
|
std::unique_ptr<SNode, void (*)(SNode*)> srcNode(nullptr, nodesDestroyNode);
|
|
|
|
run([&]() {
|
|
srcNode.reset(nodesMakeNode(QUERY_NODE_INTERVAL_WINDOW));
|
|
SIntervalWindowNode* pNode = (SIntervalWindowNode*)srcNode.get();
|
|
pNode->pInterval = nodesMakeNode(QUERY_NODE_VALUE);
|
|
pNode->pOffset = nodesMakeNode(QUERY_NODE_VALUE);
|
|
pNode->pSliding = nodesMakeNode(QUERY_NODE_VALUE);
|
|
pNode->pFill = nodesMakeNode(QUERY_NODE_FILL);
|
|
return srcNode.get();
|
|
}());
|
|
}
|
|
|
|
TEST_F(NodesCloneTest, fill) {
|
|
registerCheckFunc([](const SNode* pSrc, const SNode* pDst) {
|
|
ASSERT_EQ(nodeType(pSrc), nodeType(pDst));
|
|
SFillNode* pSrcNode = (SFillNode*)pSrc;
|
|
SFillNode* pDstNode = (SFillNode*)pDst;
|
|
ASSERT_EQ(pSrcNode->mode, pDstNode->mode);
|
|
if (NULL != pSrcNode->pValues) {
|
|
ASSERT_EQ(nodeType(pSrcNode->pValues), nodeType(pDstNode->pValues));
|
|
}
|
|
ASSERT_EQ(nodeType(pSrcNode->pWStartTs), nodeType(pDstNode->pWStartTs));
|
|
ASSERT_EQ(pSrcNode->timeRange.skey, pDstNode->timeRange.skey);
|
|
ASSERT_EQ(pSrcNode->timeRange.ekey, pDstNode->timeRange.ekey);
|
|
});
|
|
|
|
std::unique_ptr<SNode, void (*)(SNode*)> srcNode(nullptr, nodesDestroyNode);
|
|
|
|
run([&]() {
|
|
srcNode.reset(nodesMakeNode(QUERY_NODE_FILL));
|
|
SFillNode* pNode = (SFillNode*)srcNode.get();
|
|
pNode->mode = FILL_MODE_VALUE;
|
|
pNode->pValues = nodesMakeNode(QUERY_NODE_NODE_LIST);
|
|
pNode->pWStartTs = nodesMakeNode(QUERY_NODE_COLUMN);
|
|
pNode->timeRange.skey = 1666756692907;
|
|
pNode->timeRange.ekey = 1666756699907;
|
|
return srcNode.get();
|
|
}());
|
|
}
|
|
|
|
TEST_F(NodesCloneTest, logicSubplan) {
|
|
registerCheckFunc([](const SNode* pSrc, const SNode* pDst) {
|
|
ASSERT_EQ(nodeType(pSrc), nodeType(pDst));
|
|
SLogicSubplan* pSrcNode = (SLogicSubplan*)pSrc;
|
|
SLogicSubplan* pDstNode = (SLogicSubplan*)pDst;
|
|
ASSERT_EQ(pSrcNode->subplanType, pDstNode->subplanType);
|
|
ASSERT_EQ(pSrcNode->level, pDstNode->level);
|
|
ASSERT_EQ(pSrcNode->splitFlag, pDstNode->splitFlag);
|
|
ASSERT_EQ(pSrcNode->numOfComputeNodes, pDstNode->numOfComputeNodes);
|
|
});
|
|
|
|
std::unique_ptr<SNode, void (*)(SNode*)> srcNode(nullptr, nodesDestroyNode);
|
|
|
|
run([&]() {
|
|
srcNode.reset(nodesMakeNode(QUERY_NODE_LOGIC_SUBPLAN));
|
|
SLogicSubplan* pNode = (SLogicSubplan*)srcNode.get();
|
|
return srcNode.get();
|
|
}());
|
|
}
|
|
|
|
TEST_F(NodesCloneTest, physiScan) {
|
|
registerCheckFunc([](const SNode* pSrc, const SNode* pDst) {
|
|
ASSERT_EQ(nodeType(pSrc), nodeType(pDst));
|
|
STagScanPhysiNode* pSrcNode = (STagScanPhysiNode*)pSrc;
|
|
STagScanPhysiNode* pDstNode = (STagScanPhysiNode*)pDst;
|
|
ASSERT_EQ(pSrcNode->scan.uid, pDstNode->scan.uid);
|
|
ASSERT_EQ(pSrcNode->scan.suid, pDstNode->scan.suid);
|
|
ASSERT_EQ(pSrcNode->scan.tableType, pDstNode->scan.tableType);
|
|
ASSERT_EQ(pSrcNode->onlyMetaCtbIdx, pDstNode->onlyMetaCtbIdx);
|
|
});
|
|
|
|
std::unique_ptr<SNode, void (*)(SNode*)> srcNode(nullptr, nodesDestroyNode);
|
|
|
|
run([&]() {
|
|
srcNode.reset(nodesMakeNode(QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN));
|
|
STagScanPhysiNode* pNode = (STagScanPhysiNode*)srcNode.get();
|
|
return srcNode.get();
|
|
}());
|
|
}
|
|
|
|
TEST_F(NodesCloneTest, physiSystemTableScan) {
|
|
registerCheckFunc([](const SNode* pSrc, const SNode* pDst) {
|
|
ASSERT_EQ(nodeType(pSrc), nodeType(pDst));
|
|
SSystemTableScanPhysiNode* pSrcNode = (SSystemTableScanPhysiNode*)pSrc;
|
|
SSystemTableScanPhysiNode* pDstNode = (SSystemTableScanPhysiNode*)pDst;
|
|
ASSERT_EQ(pSrcNode->showRewrite, pDstNode->showRewrite);
|
|
ASSERT_EQ(pSrcNode->accountId, pDstNode->accountId);
|
|
ASSERT_EQ(pSrcNode->sysInfo, pDstNode->sysInfo);
|
|
});
|
|
|
|
std::unique_ptr<SNode, void (*)(SNode*)> srcNode(nullptr, nodesDestroyNode);
|
|
|
|
run([&]() {
|
|
srcNode.reset(nodesMakeNode(QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN));
|
|
SSystemTableScanPhysiNode* pNode = (SSystemTableScanPhysiNode*)srcNode.get();
|
|
return srcNode.get();
|
|
}());
|
|
}
|
|
|
|
TEST_F(NodesCloneTest, physiStreamSemiSessionWinodw) {
|
|
registerCheckFunc([](const SNode* pSrc, const SNode* pDst) {
|
|
ASSERT_EQ(nodeType(pSrc), nodeType(pDst));
|
|
SStreamSemiSessionWinodwPhysiNode* pSrcNode = (SStreamSemiSessionWinodwPhysiNode*)pSrc;
|
|
SStreamSemiSessionWinodwPhysiNode* pDstNode = (SStreamSemiSessionWinodwPhysiNode*)pDst;
|
|
ASSERT_EQ(pSrcNode->gap, pDstNode->gap);
|
|
});
|
|
|
|
std::unique_ptr<SNode, void (*)(SNode*)> srcNode(nullptr, nodesDestroyNode);
|
|
|
|
run([&]() {
|
|
srcNode.reset(nodesMakeNode(QUERY_NODE_PHYSICAL_PLAN_STREAM_SEMI_SESSION));
|
|
SStreamSemiSessionWinodwPhysiNode* pNode = (SStreamSemiSessionWinodwPhysiNode*)srcNode.get();
|
|
return srcNode.get();
|
|
}());
|
|
}
|
|
|
|
TEST_F(NodesCloneTest, physiStreamFinalSessionWinodw) {
|
|
registerCheckFunc([](const SNode* pSrc, const SNode* pDst) {
|
|
ASSERT_EQ(nodeType(pSrc), nodeType(pDst));
|
|
SStreamFinalSessionWinodwPhysiNode* pSrcNode = (SStreamFinalSessionWinodwPhysiNode*)pSrc;
|
|
SStreamFinalSessionWinodwPhysiNode* pDstNode = (SStreamFinalSessionWinodwPhysiNode*)pDst;
|
|
ASSERT_EQ(pSrcNode->gap, pDstNode->gap);
|
|
});
|
|
|
|
std::unique_ptr<SNode, void (*)(SNode*)> srcNode(nullptr, nodesDestroyNode);
|
|
|
|
run([&]() {
|
|
srcNode.reset(nodesMakeNode(QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_SESSION));
|
|
SStreamFinalSessionWinodwPhysiNode* pNode = (SStreamFinalSessionWinodwPhysiNode*)srcNode.get();
|
|
return srcNode.get();
|
|
}());
|
|
}
|
|
|
|
TEST_F(NodesCloneTest, physiStreamPartition) {
|
|
registerCheckFunc([](const SNode* pSrc, const SNode* pDst) {
|
|
ASSERT_EQ(nodeType(pSrc), nodeType(pDst));
|
|
SStreamPartitionPhysiNode* pSrcNode = (SStreamPartitionPhysiNode*)pSrc;
|
|
SStreamPartitionPhysiNode* pDstNode = (SStreamPartitionPhysiNode*)pDst;
|
|
});
|
|
|
|
std::unique_ptr<SNode, void (*)(SNode*)> srcNode(nullptr, nodesDestroyNode);
|
|
|
|
run([&]() {
|
|
srcNode.reset(nodesMakeNode(QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION));
|
|
SStreamPartitionPhysiNode* pNode = (SStreamPartitionPhysiNode*)srcNode.get();
|
|
return srcNode.get();
|
|
}());
|
|
}
|
|
|
|
TEST_F(NodesCloneTest, physiPartition) {
|
|
registerCheckFunc([](const SNode* pSrc, const SNode* pDst) {
|
|
ASSERT_EQ(nodeType(pSrc), nodeType(pDst));
|
|
SPartitionPhysiNode* pSrcNode = (SPartitionPhysiNode*)pSrc;
|
|
SPartitionPhysiNode* pDstNode = (SPartitionPhysiNode*)pDst;
|
|
});
|
|
|
|
std::unique_ptr<SNode, void (*)(SNode*)> srcNode(nullptr, nodesDestroyNode);
|
|
|
|
run([&]() {
|
|
srcNode.reset(nodesMakeNode(QUERY_NODE_PHYSICAL_PLAN_PARTITION));
|
|
SPartitionPhysiNode* pNode = (SPartitionPhysiNode*)srcNode.get();
|
|
return srcNode.get();
|
|
}());
|
|
}
|