From 4461275d380866e4458ed8517a2a0ff0cd677be5 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Sun, 19 Dec 2021 15:46:54 -0500 Subject: [PATCH] TD-12194 physical plan of scan subquery ut --- include/libs/parser/parser.h | 1 + source/libs/parser/inc/queryInfoUtil.h | 1 - source/libs/parser/test/insertTest.cpp | 14 +- source/libs/parser/test/mockCatalog.cpp | 32 +++-- source/libs/parser/test/mockCatalog.h | 8 +- .../libs/parser/test/mockCatalogService.cpp | 127 +++++++++-------- source/libs/parser/test/mockCatalogService.h | 16 ++- .../{parserMain.cpp => parserTestMain.cpp} | 6 +- source/libs/planner/inc/plannerInt.h | 1 + source/libs/planner/src/physicalPlan.c | 43 ++++-- source/libs/planner/test/CMakeLists.txt | 8 +- source/libs/planner/test/phyPlanTests.cpp | 131 ++++++++++++++++++ source/libs/planner/test/plannerTests.cpp | 23 ++- 13 files changed, 313 insertions(+), 98 deletions(-) rename source/libs/parser/test/{parserMain.cpp => parserTestMain.cpp} (88%) create mode 100644 source/libs/planner/test/phyPlanTests.cpp diff --git a/include/libs/parser/parser.h b/include/libs/parser/parser.h index 49adaecfdd..8e26fa98c9 100644 --- a/include/libs/parser/parser.h +++ b/include/libs/parser/parser.h @@ -209,6 +209,7 @@ typedef struct SSourceParam { SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, const char* funcName, SSourceParam* pSource, SSchema* pResSchema, int16_t interSize); int32_t copyExprInfoList(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy); +int32_t copyAllExprInfo(SArray* dst, const SArray* src, bool deepcopy); int32_t getExprFunctionLevel(SQueryStmtInfo* pQueryInfo); STableMetaInfo* getMetaInfo(SQueryStmtInfo* pQueryInfo, int32_t tableIndex); diff --git a/source/libs/parser/inc/queryInfoUtil.h b/source/libs/parser/inc/queryInfoUtil.h index 5d51293939..798c9bc97f 100644 --- a/source/libs/parser/inc/queryInfoUtil.h +++ b/source/libs/parser/inc/queryInfoUtil.h @@ -36,7 +36,6 @@ void addExprInfo(SArray* pExprList, int32_t index, SExprInfo* pExprInfo, i void updateExprInfo(SExprInfo* pExprInfo, int16_t functionId, int32_t colId, int16_t srcColumnIndex, int16_t resType, int16_t resSize); SExprInfo* getExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index); -int32_t copyAllExprInfo(SArray* dst, const SArray* src, bool deepcopy); void addExprInfoParam(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes); diff --git a/source/libs/parser/test/insertTest.cpp b/source/libs/parser/test/insertTest.cpp index 5877adf41c..85db46d7bf 100644 --- a/source/libs/parser/test/insertTest.cpp +++ b/source/libs/parser/test/insertTest.cpp @@ -57,17 +57,20 @@ void *__wrap_malloc(size_t c) { // [...]; class InsertTest : public Test { protected: - void setDatabase(const string& db) { + void setDatabase(const string& acctId, const string& db) { + acctId_ = acctId; db_ = db; } void bind(const char* sql) { reset(); - cxt_.sqlLen = strlen(sql); + cxt_.pAcctId = acctId_.c_str(); + cxt_.pDbname = db_.c_str(); strcpy(sqlBuf_, sql); + cxt_.sqlLen = strlen(sql); sqlBuf_[cxt_.sqlLen] = '\0'; cxt_.pSql = sqlBuf_; - cxt_.pDbname = db_.c_str(); + } int32_t run() { @@ -95,6 +98,7 @@ private: res_ = nullptr; } + string acctId_; string db_; char errMagBuf_[max_err_len]; char sqlBuf_[max_sql_len]; @@ -105,7 +109,7 @@ private: // INSERT INTO tb_name VALUES (field1_value, ...) TEST_F(InsertTest, simpleTest) { - setDatabase("test"); + setDatabase("root", "test"); bind("insert into t1 values (now, 1, \"wxy\")"); ASSERT_EQ(run(), TSDB_CODE_SUCCESS); @@ -116,7 +120,7 @@ TEST_F(InsertTest, simpleTest) { } TEST_F(InsertTest, toleranceTest) { - setDatabase("test"); + setDatabase("root", "test"); bind("insert into"); ASSERT_NE(run(), TSDB_CODE_SUCCESS); diff --git a/source/libs/parser/test/mockCatalog.cpp b/source/libs/parser/test/mockCatalog.cpp index f2b34971ef..4e6b94081b 100644 --- a/source/libs/parser/test/mockCatalog.cpp +++ b/source/libs/parser/test/mockCatalog.cpp @@ -20,34 +20,42 @@ namespace { void generateTestT1(MockCatalogService* mcs) { - ITableBuilder& builder = mcs->createTableBuilder("test", "t1", TSDB_NORMAL_TABLE, 3) + ITableBuilder& builder = mcs->createTableBuilder("root.test", "t1", TSDB_NORMAL_TABLE, 3) .setPrecision(TSDB_TIME_PRECISION_MILLI).setVgid(1).addColumn("ts", TSDB_DATA_TYPE_TIMESTAMP) .addColumn("c1", TSDB_DATA_TYPE_INT).addColumn("c2", TSDB_DATA_TYPE_BINARY, 10); builder.done(); } void generateTestST1(MockCatalogService* mcs) { - ITableBuilder& builder = mcs->createTableBuilder("test", "st1", TSDB_SUPER_TABLE, 3, 2) + ITableBuilder& builder = mcs->createTableBuilder("root.test", "st1", TSDB_SUPER_TABLE, 3, 2) .setPrecision(TSDB_TIME_PRECISION_MILLI).addColumn("ts", TSDB_DATA_TYPE_TIMESTAMP) .addTag("tag1", TSDB_DATA_TYPE_INT).addTag("tag2", TSDB_DATA_TYPE_BINARY, 10) .addColumn("c1", TSDB_DATA_TYPE_INT).addColumn("c2", TSDB_DATA_TYPE_BINARY, 10); builder.done(); - mcs->createSubTable("test", "st1", "st1s1", 1); - mcs->createSubTable("test", "st1", "st1s2", 2); + mcs->createSubTable("root.test", "st1", "st1s1", 1); + mcs->createSubTable("root.test", "st1", "st1s2", 2); } } -void generateMetaData(MockCatalogService* mcs) { - generateTestT1(mcs); - generateTestST1(mcs); - mcs->showTables(); +int32_t catalogGetHandle(const char *clusterId, struct SCatalog** catalogHandle) { + return mockCatalogService->catalogGetHandle(clusterId, catalogHandle); } -struct SCatalog* getCatalogHandle(const SEpSet* pMgmtEps) { - return mockCatalogService->getCatalogHandle(pMgmtEps); +int32_t catalogGetTableMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* pDBName, const char* pTableName, STableMeta** pTableMeta) { + return mockCatalogService->catalogGetTableMeta(pCatalog, pRpc, pMgmtEps, pDBName, pTableName, pTableMeta); } -int32_t catalogGetMetaData(struct SCatalog* pCatalog, const SCatalogReq* pMetaReq, SMetaData* pMetaData) { - return mockCatalogService->catalogGetMetaData(pCatalog, pMetaReq, pMetaData); +void initMetaDataEnv() { + mockCatalogService.reset(new MockCatalogService()); +} + +void generateMetaData() { + generateTestT1(mockCatalogService.get()); + generateTestST1(mockCatalogService.get()); + mockCatalogService->showTables(); +} + +void destroyMetaDataEnv() { + mockCatalogService.reset(); } diff --git a/source/libs/parser/test/mockCatalog.h b/source/libs/parser/test/mockCatalog.h index e60f7727e6..c9812d5b94 100644 --- a/source/libs/parser/test/mockCatalog.h +++ b/source/libs/parser/test/mockCatalog.h @@ -18,10 +18,12 @@ #include "mockCatalogService.h" -void generateMetaData(MockCatalogService* mcs); +void initMetaDataEnv(); +void generateMetaData(); +void destroyMetaDataEnv(); // mock -struct SCatalog* getCatalogHandle(const SEpSet* pMgmtEps); -int32_t catalogGetMetaData(struct SCatalog* pCatalog, const SCatalogReq* pMetaReq, SMetaData* pMetaData); +int32_t catalogGetHandle(const char *clusterId, struct SCatalog** catalogHandle); +int32_t catalogGetTableMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* pDBName, const char* pTableName, STableMeta** pTableMeta); #endif // MOCK_CATALOG_H diff --git a/source/libs/parser/test/mockCatalogService.cpp b/source/libs/parser/test/mockCatalogService.cpp index 457f8d88bd..9bc029cbd8 100644 --- a/source/libs/parser/test/mockCatalogService.cpp +++ b/source/libs/parser/test/mockCatalogService.cpp @@ -27,27 +27,28 @@ std::unique_ptr mockCatalogService; class TableBuilder : public ITableBuilder { public: virtual TableBuilder& addColumn(const std::string& name, int8_t type, int32_t bytes) { - assert(colIndex_ < meta_->tableInfo.numOfTags + meta_->tableInfo.numOfColumns); - SSchema* col = meta_->schema + colIndex_; + assert(colId_ < schema()->tableInfo.numOfTags + schema()->tableInfo.numOfColumns); + SSchema* col = schema()->schema + colId_; col->type = type; - col->colId = colIndex_++; + col->colId = colId_++; col->bytes = bytes; strcpy(col->name, name.c_str()); return *this; } virtual TableBuilder& setVgid(int16_t vgid) { - meta_->vgId = vgid; + schema()->vgId = vgid; + meta_->vgs.emplace_back(SVgroupInfo{.vgId = vgid, .numOfEps = 3, .epAddr = {{"dnode_1", 6030}, {"dnode_2", 6030}, {"dnode_3", 6030}}}); return *this; } virtual TableBuilder& setPrecision(uint8_t precision) { - meta_->tableInfo.precision = precision; + schema()->tableInfo.precision = precision; return *this; } virtual void done() { - meta_->tableInfo.rowSize = rowsize_; + schema()->tableInfo.rowSize = rowsize_; } private: @@ -64,61 +65,62 @@ private: return std::unique_ptr(new TableBuilder(meta)); } - TableBuilder(STableMeta* meta) : colIndex_(0), rowsize_(0), meta_(meta) { + TableBuilder(STableMeta* schemaMeta) : colId_(0), rowsize_(0), meta_(new MockTableMeta()) { + meta_->schema.reset(schemaMeta); } - STableMeta* table() { + std::shared_ptr schema() { + return meta_->schema; + } + + std::shared_ptr table() { return meta_; } - int32_t colIndex_; + int32_t colId_; int32_t rowsize_; - STableMeta* meta_; + std::shared_ptr meta_; }; class MockCatalogServiceImpl { public: static const int32_t numOfDataTypes = sizeof(tDataTypes) / sizeof(tDataTypes[0]); - MockCatalogServiceImpl() { + MockCatalogServiceImpl() : id_(1) { } - struct SCatalog* getCatalogHandle(const SEpSet* pMgmtEps) const { - return (struct SCatalog*)0x01; + int32_t catalogGetHandle(const char *clusterId, struct SCatalog** catalogHandle) const { + return 0; } - int32_t catalogGetMetaData(struct SCatalog* pCatalog, const SCatalogReq* pMetaReq, SMetaData* pMetaData) const { - assert(nullptr != pMetaReq && 1 == taosArrayGetSize(pMetaReq->pTableName)); - SName* fullName = (SName*)taosArrayGet(pMetaReq->pTableName, 0); + int32_t catalogGetTableMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* pDBName, const char* pTableName, STableMeta** pTableMeta) const { std::unique_ptr table; - int32_t code = copyTableMeta(fullName->dbname, fullName->tname, &table); + int32_t code = copyTableSchemaMeta(pDBName, pTableName, &table); if (TSDB_CODE_SUCCESS != code) { return code; } - std::unique_ptr tables((SArray*)taosArrayInit(1, sizeof(STableMeta*))); - if (!tables) { - return TSDB_CODE_TSC_OUT_OF_MEMORY; - } - STableMeta* elem = table.release(); - taosArrayPush(tables.get(), &elem); - pMetaData->pTableMeta = tables.release(); + *pTableMeta = table.release(); return TSDB_CODE_SUCCESS; } TableBuilder& createTableBuilder(const std::string& db, const std::string& tbname, int8_t tableType, int32_t numOfColumns, int32_t numOfTags) { builder_ = TableBuilder::createTableBuilder(tableType, numOfColumns, numOfTags); - meta_[db][tbname].reset(builder_->table()); - meta_[db][tbname]->uid = id_++; + meta_[db][tbname] = builder_->table(); + meta_[db][tbname]->schema->uid = id_++; return *(builder_.get()); } void createSubTable(const std::string& db, const std::string& stbname, const std::string& tbname, int16_t vgid) { std::unique_ptr table; - if (TSDB_CODE_SUCCESS != copyTableMeta(db, stbname, &table)) { - throw std::runtime_error("copyTableMeta failed"); + if (TSDB_CODE_SUCCESS != copyTableSchemaMeta(db, stbname, &table)) { + throw std::runtime_error("copyTableSchemaMeta failed"); } - meta_[db][tbname].reset(table.release()); - meta_[db][tbname]->uid = id_++; + meta_[db][tbname].reset(new MockTableMeta()); + meta_[db][tbname]->schema.reset(table.release()); + meta_[db][tbname]->schema->uid = id_++; + meta_[db][tbname]->vgs.emplace_back(SVgroupInfo{.vgId = vgid, .numOfEps = 3, .epAddr = {{"dnode_1", 6030}, {"dnode_2", 6030}, {"dnode_3", 6030}}}); + // super table + meta_[db][stbname]->vgs.emplace_back(SVgroupInfo{.vgId = vgid, .numOfEps = 3, .epAddr = {{"dnode_1", 6030}, {"dnode_2", 6030}, {"dnode_3", 6030}}}); } void showTables() const { @@ -148,29 +150,43 @@ public: std::cout << SH("Table") << SH("Type") << SH("Precision") << IH("Vgid") << std::endl; std::cout << SL(3, 1) << std::endl; for (const auto& table : db.second) { - std::cout << SF(table.first) << SF(ttToString(table.second->tableType)) << SF(pToString(table.second->tableInfo.precision)) << IF(table.second->vgId) << std::endl; + const auto& schema = table.second->schema; + std::cout << SF(table.first) << SF(ttToString(schema->tableType)) << SF(pToString(schema->tableInfo.precision)) << IF(schema->vgId) << std::endl; } std::cout << std::endl; } for (const auto& db : meta_) { for (const auto& table : db.second) { + const auto& schema = table.second->schema; std::cout << "Table:" << table.first << std::endl; std::cout << SH("Field") << SH("Type") << SH("DataType") << IH("Bytes") << std::endl; std::cout << SL(3, 1) << std::endl; - int16_t numOfTags = table.second->tableInfo.numOfTags; - int16_t numOfFields = numOfTags + table.second->tableInfo.numOfColumns; + int16_t numOfTags = schema->tableInfo.numOfTags; + int16_t numOfFields = numOfTags + schema->tableInfo.numOfColumns; for (int16_t i = 0; i < numOfFields; ++i) { - const SSchema* schema = table.second->schema + i; - std::cout << SF(std::string(schema->name)) << SH(ftToString(i, numOfTags)) << SH(dtToString(schema->type)) << IF(schema->bytes) << std::endl; + const SSchema* col = schema->schema + i; + std::cout << SF(std::string(col->name)) << SH(ftToString(i, numOfTags)) << SH(dtToString(col->type)) << IF(col->bytes) << std::endl; } std::cout << std::endl; } } } + std::shared_ptr getTableMeta(const std::string& db, const std::string& tbname) const { + DbMetaCache::const_iterator it = meta_.find(db); + if (meta_.end() == it) { + return std::shared_ptr(); + } + TableMetaCache::const_iterator tit = it->second.find(tbname); + if (it->second.end() == tit) { + return std::shared_ptr(); + } + return tit->second; + } + private: - typedef std::map > TableMetaCache; + typedef std::map> TableMetaCache; typedef std::map DbMetaCache; std::string ttToString(int8_t tableType) const { @@ -207,20 +223,13 @@ private: return (0 == colid ? "column" : (colid <= numOfTags ? "tag" : "column")); } - std::shared_ptr getTableMeta(const std::string& db, const std::string& tbname) const { - DbMetaCache::const_iterator it = meta_.find(db); - if (meta_.end() == it) { - return std::shared_ptr(); - } - TableMetaCache::const_iterator tit = it->second.find(tbname); - if (it->second.end() == tit) { - return std::shared_ptr(); - } - return tit->second; + std::shared_ptr getTableSchemaMeta(const std::string& db, const std::string& tbname) const { + std::shared_ptr table = getTableMeta(db, tbname); + return table ? table->schema : std::shared_ptr(); } - int32_t copyTableMeta(const std::string& db, const std::string& tbname, std::unique_ptr* dst) const { - std::shared_ptr src = getTableMeta(db, tbname); + int32_t copyTableSchemaMeta(const std::string& db, const std::string& tbname, std::unique_ptr* dst) const { + std::shared_ptr src = getTableSchemaMeta(db, tbname); if (!src) { return TSDB_CODE_TSC_INVALID_TABLE_NAME; } @@ -244,14 +253,6 @@ MockCatalogService::MockCatalogService() : impl_(new MockCatalogServiceImpl()) { MockCatalogService::~MockCatalogService() { } -struct SCatalog* MockCatalogService::getCatalogHandle(const SEpSet* pMgmtEps) const { - return impl_->getCatalogHandle(pMgmtEps); -} - -int32_t MockCatalogService::catalogGetMetaData(struct SCatalog* pCatalog, const SCatalogReq* pMetaReq, SMetaData* pMetaData) const { - return impl_->catalogGetMetaData(pCatalog, pMetaReq, pMetaData); -} - ITableBuilder& MockCatalogService::createTableBuilder(const std::string& db, const std::string& tbname, int8_t tableType, int32_t numOfColumns, int32_t numOfTags) { return impl_->createTableBuilder(db, tbname, tableType, numOfColumns, numOfTags); } @@ -262,4 +263,16 @@ void MockCatalogService::createSubTable(const std::string& db, const std::string void MockCatalogService::showTables() const { impl_->showTables(); -} \ No newline at end of file +} + +std::shared_ptr MockCatalogService::getTableMeta(const std::string& db, const std::string& tbname) const { + return impl_->getTableMeta(db, tbname); +} + +int32_t MockCatalogService::catalogGetHandle(const char *clusterId, struct SCatalog** catalogHandle) const { + return impl_->catalogGetHandle(clusterId, catalogHandle); +} + +int32_t MockCatalogService::catalogGetTableMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* pDBName, const char* pTableName, STableMeta** pTableMeta) const { + return impl_->catalogGetTableMeta(pCatalog, pRpc, pMgmtEps, pDBName, pTableName, pTableMeta); +} diff --git a/source/libs/parser/test/mockCatalogService.h b/source/libs/parser/test/mockCatalogService.h index 66b439b3e9..cd01db09cc 100644 --- a/source/libs/parser/test/mockCatalogService.h +++ b/source/libs/parser/test/mockCatalogService.h @@ -18,6 +18,7 @@ #include #include +#include #include "catalog.h" @@ -41,19 +42,24 @@ public: virtual void done() = 0; }; -class MockCatalogServiceImpl; +struct MockTableMeta { + std::shared_ptr schema; + std::vector vgs; +}; +class MockCatalogServiceImpl; class MockCatalogService { public: - static const int32_t numOfDataTypes = sizeof(tDataTypes) / sizeof(tDataTypes[0]); - MockCatalogService(); ~MockCatalogService(); - struct SCatalog* getCatalogHandle(const SEpSet* pMgmtEps) const; - int32_t catalogGetMetaData(struct SCatalog* pCatalog, const SCatalogReq* pMetaReq, SMetaData* pMetaData) const; ITableBuilder& createTableBuilder(const std::string& db, const std::string& tbname, int8_t tableType, int32_t numOfColumns, int32_t numOfTags = 0); void createSubTable(const std::string& db, const std::string& stbname, const std::string& tbname, int16_t vgid); void showTables() const; + std::shared_ptr getTableMeta(const std::string& db, const std::string& tbname) const; + + // mock interface + int32_t catalogGetHandle(const char *clusterId, struct SCatalog** catalogHandle) const; + int32_t catalogGetTableMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* pDBName, const char* pTableName, STableMeta** pTableMeta) const; private: std::unique_ptr impl_; diff --git a/source/libs/parser/test/parserMain.cpp b/source/libs/parser/test/parserTestMain.cpp similarity index 88% rename from source/libs/parser/test/parserMain.cpp rename to source/libs/parser/test/parserTestMain.cpp index 5ec304a006..7de2cb66c2 100644 --- a/source/libs/parser/test/parserMain.cpp +++ b/source/libs/parser/test/parserTestMain.cpp @@ -22,12 +22,12 @@ class ParserEnv : public testing::Environment { public: virtual void SetUp() { - mockCatalogService.reset(new MockCatalogService()); - generateMetaData(mockCatalogService.get()); + initMetaDataEnv(); + generateMetaData(); } virtual void TearDown() { - mockCatalogService.reset(); + destroyMetaDataEnv(); } ParserEnv() {} diff --git a/source/libs/planner/inc/plannerInt.h b/source/libs/planner/inc/plannerInt.h index 19563a8a0c..c6236095f6 100644 --- a/source/libs/planner/inc/plannerInt.h +++ b/source/libs/planner/inc/plannerInt.h @@ -117,6 +117,7 @@ void destroyQueryPlan(struct SQueryPlanNode* pQueryNode); */ void* destroyQueryPhyPlan(struct SPhyNode* pQueryPhyNode); +const char* opTypeToOpName(int32_t type); int32_t opNameToOpType(const char* name); #ifdef __cplusplus diff --git a/source/libs/planner/src/physicalPlan.c b/source/libs/planner/src/physicalPlan.c index f187ec0ec9..e168b40bff 100644 --- a/source/libs/planner/src/physicalPlan.c +++ b/source/libs/planner/src/physicalPlan.c @@ -33,6 +33,10 @@ static const char* gOpName[] = { #undef INCLUDE_AS_NAME }; +const char* opTypeToOpName(int32_t type) { + return gOpName[type]; +} + int32_t opNameToOpType(const char* name) { for (int32_t i = 1; i < sizeof(gOpName) / sizeof(gOpName[0]); ++i) { if (strcmp(name, gOpName[i])) { @@ -42,17 +46,43 @@ int32_t opNameToOpType(const char* name) { return OP_Unknown; } -static void toDataBlockSchema(SQueryPlanNode* pPlanNode, SDataBlockSchema* dataBlockSchema) { - SWAP(dataBlockSchema->pSchema, pPlanNode->pSchema, SSchema*); +static bool toDataBlockSchema(SQueryPlanNode* pPlanNode, SDataBlockSchema* dataBlockSchema) { dataBlockSchema->numOfCols = pPlanNode->numOfCols; + dataBlockSchema->pSchema = malloc(sizeof(SSlotSchema) * pPlanNode->numOfCols); + if (NULL == dataBlockSchema->pSchema) { + return false; + } + memcpy(dataBlockSchema->pSchema, pPlanNode->pSchema, sizeof(SSlotSchema) * pPlanNode->numOfCols); + return true; +} + +static bool cloneExprArray(SArray** dst, SArray* src) { + if (NULL == src) { + return true; + } + size_t size = taosArrayGetSize(src); + if (0 == size) { + return true; + } + *dst = taosArrayInit(size, POINTER_BYTES); + if (NULL == *dst) { + return false; + } + return (TSDB_CODE_SUCCESS == copyAllExprInfo(*dst, src, true) ? true : false); } static SPhyNode* initPhyNode(SQueryPlanNode* pPlanNode, int32_t type, int32_t size) { SPhyNode* node = (SPhyNode*)calloc(1, size); + if (NULL == node) { + return NULL; + } node->info.type = type; - node->info.name = gOpName[type]; - SWAP(node->pTargets, pPlanNode->pExpr, SArray*); - toDataBlockSchema(pPlanNode, &(node->targetSchema)); + node->info.name = opTypeToOpName(type); + if (!cloneExprArray(&node->pTargets, pPlanNode->pExpr) || !toDataBlockSchema(pPlanNode, &(node->targetSchema))) { + free(node); + return NULL; + } + return node; } static SPhyNode* initScanNode(SQueryPlanNode* pPlanNode, SQueryTableInfo* pTable, int32_t type, int32_t size) { @@ -203,9 +233,6 @@ static void createSubplanByLevel(SPlanContext* pCxt, SQueryPlanNode* pRoot) { SSubplan* subplan = initSubplan(pCxt, QUERY_TYPE_MERGE); ++(pCxt->nextId.templateId); subplan->pNode = createPhyNode(pCxt, pRoot); - SArray* l0 = taosArrayInit(TARRAY_MIN_SIZE, POINTER_BYTES); - taosArrayPush(l0, &subplan); - taosArrayPush(pCxt->pDag->pSubplans, &l0); // todo deal subquery } diff --git a/source/libs/planner/test/CMakeLists.txt b/source/libs/planner/test/CMakeLists.txt index 5874356784..7fbfcfe7ef 100644 --- a/source/libs/planner/test/CMakeLists.txt +++ b/source/libs/planner/test/CMakeLists.txt @@ -5,7 +5,12 @@ MESSAGE(STATUS "build planner unit test") SET(CMAKE_CXX_STANDARD 11) AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST) -ADD_EXECUTABLE(plannerTest ${SOURCE_LIST}) +ADD_EXECUTABLE(plannerTest + ${SOURCE_LIST} + "${SOURCE_LIST}/../../../parser/test/mockCatalog.cpp" + "${SOURCE_LIST}/../../../parser/test/mockCatalogService.cpp" +) + TARGET_LINK_LIBRARIES( plannerTest PUBLIC os util common planner parser catalog transport gtest function qcom @@ -15,4 +20,5 @@ TARGET_INCLUDE_DIRECTORIES( plannerTest PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/planner/" PRIVATE "${CMAKE_SOURCE_DIR}/source/libs/planner/inc" + PRIVATE "${CMAKE_SOURCE_DIR}/source/libs/parser/test" ) diff --git a/source/libs/planner/test/phyPlanTests.cpp b/source/libs/planner/test/phyPlanTests.cpp new file mode 100644 index 0000000000..3be3337304 --- /dev/null +++ b/source/libs/planner/test/phyPlanTests.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +#include + +#include "plannerInt.h" +#include "mockCatalogService.h" + +using namespace std; +using namespace testing; + +void* myCalloc(size_t nmemb, size_t size) { + if (void* p = calloc(nmemb, size)) { + return p; + } + throw bad_alloc(); +} + +class PhyPlanTest : public Test { +protected: + void pushScan(const string& db, const string& table, int32_t scanOp) { + shared_ptr meta = mockCatalogService->getTableMeta(db, table); + EXPECT_TRUE(meta); +// typedef struct SQueryPlanNode { +// SArray *pExpr; // the query functions or sql aggregations +// int32_t numOfExpr; // number of result columns, which is also the number of pExprs +// } SQueryPlanNode; + unique_ptr scan((SQueryPlanNode*)calloc(1, sizeof(SQueryPlanNode))); + scan->info.type = scanOp; + scan->numOfCols = meta->schema->tableInfo.numOfColumns; + scan->pSchema = (SSchema*)myCalloc(1, sizeof(SSchema) * scan->numOfCols); + memcpy(scan->pSchema, meta->schema->schema, sizeof(SSchema) * scan->numOfCols); + //todo 'pExpr' 'numOfExpr' + scan->pExtInfo = createScanExtInfo(meta); + pushNode(scan.release()); + } + + int32_t run() { + SQueryDag* dag = nullptr; + int32_t code = createDag(logicPlan_.get(), nullptr, &dag); + dag_.reset(dag); + return code; + } + + void explain() { + size_t level = taosArrayGetSize(dag_->pSubplans); + for (size_t i = 0; i < level; ++i) { + std::cout << "level " << i << ":" << std::endl; + const SArray* subplans = (const SArray*)taosArrayGetP(dag_->pSubplans, i); + size_t num = taosArrayGetSize(subplans); + for (size_t j = 0; j < num; ++j) { + std::cout << "no " << j << ":" << std::endl; + char* str = nullptr; + ASSERT_EQ (TSDB_CODE_SUCCESS, qSubPlanToString((const SSubplan*)taosArrayGetP(subplans, j), &str)); + std::cout << str << std::endl; + free(str); + } + } + } + + SQueryDag* reslut() { + return dag_.get(); + } + +private: + void pushNode(SQueryPlanNode* node) { + if (logicPlan_) { + // todo + } else { + logicPlan_.reset(node); + } + } + + void copySchemaMeta(STableMeta** dst, const STableMeta* src) { + int32_t size = sizeof(STableMeta) + sizeof(SSchema) * (src->tableInfo.numOfTags + src->tableInfo.numOfColumns); + *dst = (STableMeta*)myCalloc(1, size); + memcpy(*dst, src, size); + } + + void copyStorageMeta(SVgroupsInfo** dst, const std::vector& src) { + *dst = (SVgroupsInfo*)myCalloc(1, sizeof(SVgroupsInfo) + sizeof(SVgroupMsg) * src.size()); + (*dst)->numOfVgroups = src.size(); + for (int32_t i = 0; i < src.size(); ++i) { + (*dst)->vgroups[i].vgId = src[i].vgId; + (*dst)->vgroups[i].numOfEps = src[i].numOfEps; + memcpy((*dst)->vgroups[i].epAddr, src[i].epAddr, src[i].numOfEps); + } + } + + SQueryTableInfo* createScanExtInfo(shared_ptr& meta) { + SQueryTableInfo* info = (SQueryTableInfo*)myCalloc(1, sizeof(SQueryTableInfo)); + info->pMeta = (STableMetaInfo*)myCalloc(1, sizeof(STableMetaInfo)); + copySchemaMeta(&info->pMeta->pTableMeta, meta->schema.get()); + copyStorageMeta(&info->pMeta->vgroupList, meta->vgs); + return info; + } + + shared_ptr meta_; + unique_ptr logicPlan_; + unique_ptr dag_; +}; + +// select * from table +TEST_F(PhyPlanTest, tableScanTest) { + pushScan("root.test", "t1", QNODE_TABLESCAN); + ASSERT_EQ(run(), TSDB_CODE_SUCCESS); + explain(); + SQueryDag* dag = reslut(); + // todo check +} + +// select * from supertable +TEST_F(PhyPlanTest, superTableScanTest) { + pushScan("root.test", "st1", QNODE_TABLESCAN); + ASSERT_EQ(run(), TSDB_CODE_SUCCESS); + explain(); + SQueryDag* dag = reslut(); + // todo check +} diff --git a/source/libs/planner/test/plannerTests.cpp b/source/libs/planner/test/plannerTests.cpp index 5ede8dd155..9379b06ac8 100644 --- a/source/libs/planner/test/plannerTests.cpp +++ b/source/libs/planner/test/plannerTests.cpp @@ -20,6 +20,7 @@ #include "taos.h" #include "parser.h" +#include "mockCatalog.h" #pragma GCC diagnostic ignored "-Wwrite-strings" @@ -27,9 +28,25 @@ #pragma GCC diagnostic ignored "-Wunused-variable" #pragma GCC diagnostic ignored "-Wsign-compare" -int main(int argc, char** argv) { - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); +class ParserEnv : public testing::Environment { +public: + virtual void SetUp() { + initMetaDataEnv(); + generateMetaData(); + } + + virtual void TearDown() { + destroyMetaDataEnv(); + } + + ParserEnv() {} + virtual ~ParserEnv() {} +}; + +int main(int argc, char* argv[]) { + testing::AddGlobalTestEnvironment(new ParserEnv()); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); } TEST(testCase, planner_test) {