Merge pull request #9205 from taosdata/feature/3.0_wxy
TD-12194 physical plan of scan subquery ut
This commit is contained in:
commit
5787ec5b8e
|
@ -209,6 +209,7 @@ typedef struct SSourceParam {
|
||||||
|
|
||||||
SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, const char* funcName, SSourceParam* pSource, SSchema* pResSchema, int16_t interSize);
|
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 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);
|
int32_t getExprFunctionLevel(SQueryStmtInfo* pQueryInfo);
|
||||||
|
|
||||||
STableMetaInfo* getMetaInfo(SQueryStmtInfo* pQueryInfo, int32_t tableIndex);
|
STableMetaInfo* getMetaInfo(SQueryStmtInfo* pQueryInfo, int32_t tableIndex);
|
||||||
|
|
|
@ -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);
|
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);
|
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);
|
void addExprInfoParam(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes);
|
||||||
|
|
||||||
|
|
|
@ -57,17 +57,20 @@ void *__wrap_malloc(size_t c) {
|
||||||
// [...];
|
// [...];
|
||||||
class InsertTest : public Test {
|
class InsertTest : public Test {
|
||||||
protected:
|
protected:
|
||||||
void setDatabase(const string& db) {
|
void setDatabase(const string& acctId, const string& db) {
|
||||||
|
acctId_ = acctId;
|
||||||
db_ = db;
|
db_ = db;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bind(const char* sql) {
|
void bind(const char* sql) {
|
||||||
reset();
|
reset();
|
||||||
cxt_.sqlLen = strlen(sql);
|
cxt_.pAcctId = acctId_.c_str();
|
||||||
|
cxt_.pDbname = db_.c_str();
|
||||||
strcpy(sqlBuf_, sql);
|
strcpy(sqlBuf_, sql);
|
||||||
|
cxt_.sqlLen = strlen(sql);
|
||||||
sqlBuf_[cxt_.sqlLen] = '\0';
|
sqlBuf_[cxt_.sqlLen] = '\0';
|
||||||
cxt_.pSql = sqlBuf_;
|
cxt_.pSql = sqlBuf_;
|
||||||
cxt_.pDbname = db_.c_str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t run() {
|
int32_t run() {
|
||||||
|
@ -95,6 +98,7 @@ private:
|
||||||
res_ = nullptr;
|
res_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string acctId_;
|
||||||
string db_;
|
string db_;
|
||||||
char errMagBuf_[max_err_len];
|
char errMagBuf_[max_err_len];
|
||||||
char sqlBuf_[max_sql_len];
|
char sqlBuf_[max_sql_len];
|
||||||
|
@ -105,7 +109,7 @@ private:
|
||||||
|
|
||||||
// INSERT INTO tb_name VALUES (field1_value, ...)
|
// INSERT INTO tb_name VALUES (field1_value, ...)
|
||||||
TEST_F(InsertTest, simpleTest) {
|
TEST_F(InsertTest, simpleTest) {
|
||||||
setDatabase("test");
|
setDatabase("root", "test");
|
||||||
|
|
||||||
bind("insert into t1 values (now, 1, \"wxy\")");
|
bind("insert into t1 values (now, 1, \"wxy\")");
|
||||||
ASSERT_EQ(run(), TSDB_CODE_SUCCESS);
|
ASSERT_EQ(run(), TSDB_CODE_SUCCESS);
|
||||||
|
@ -116,7 +120,7 @@ TEST_F(InsertTest, simpleTest) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(InsertTest, toleranceTest) {
|
TEST_F(InsertTest, toleranceTest) {
|
||||||
setDatabase("test");
|
setDatabase("root", "test");
|
||||||
|
|
||||||
bind("insert into");
|
bind("insert into");
|
||||||
ASSERT_NE(run(), TSDB_CODE_SUCCESS);
|
ASSERT_NE(run(), TSDB_CODE_SUCCESS);
|
||||||
|
|
|
@ -20,34 +20,42 @@
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void generateTestT1(MockCatalogService* mcs) {
|
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)
|
.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);
|
.addColumn("c1", TSDB_DATA_TYPE_INT).addColumn("c2", TSDB_DATA_TYPE_BINARY, 10);
|
||||||
builder.done();
|
builder.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateTestST1(MockCatalogService* mcs) {
|
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)
|
.setPrecision(TSDB_TIME_PRECISION_MILLI).addColumn("ts", TSDB_DATA_TYPE_TIMESTAMP)
|
||||||
.addTag("tag1", TSDB_DATA_TYPE_INT).addTag("tag2", TSDB_DATA_TYPE_BINARY, 10)
|
.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);
|
.addColumn("c1", TSDB_DATA_TYPE_INT).addColumn("c2", TSDB_DATA_TYPE_BINARY, 10);
|
||||||
builder.done();
|
builder.done();
|
||||||
mcs->createSubTable("test", "st1", "st1s1", 1);
|
mcs->createSubTable("root.test", "st1", "st1s1", 1);
|
||||||
mcs->createSubTable("test", "st1", "st1s2", 2);
|
mcs->createSubTable("root.test", "st1", "st1s2", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateMetaData(MockCatalogService* mcs) {
|
int32_t catalogGetHandle(const char *clusterId, struct SCatalog** catalogHandle) {
|
||||||
generateTestT1(mcs);
|
return mockCatalogService->catalogGetHandle(clusterId, catalogHandle);
|
||||||
generateTestST1(mcs);
|
|
||||||
mcs->showTables();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SCatalog* getCatalogHandle(const SEpSet* pMgmtEps) {
|
int32_t catalogGetTableMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* pDBName, const char* pTableName, STableMeta** pTableMeta) {
|
||||||
return mockCatalogService->getCatalogHandle(pMgmtEps);
|
return mockCatalogService->catalogGetTableMeta(pCatalog, pRpc, pMgmtEps, pDBName, pTableName, pTableMeta);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t catalogGetMetaData(struct SCatalog* pCatalog, const SCatalogReq* pMetaReq, SMetaData* pMetaData) {
|
void initMetaDataEnv() {
|
||||||
return mockCatalogService->catalogGetMetaData(pCatalog, pMetaReq, pMetaData);
|
mockCatalogService.reset(new MockCatalogService());
|
||||||
|
}
|
||||||
|
|
||||||
|
void generateMetaData() {
|
||||||
|
generateTestT1(mockCatalogService.get());
|
||||||
|
generateTestST1(mockCatalogService.get());
|
||||||
|
mockCatalogService->showTables();
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroyMetaDataEnv() {
|
||||||
|
mockCatalogService.reset();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,12 @@
|
||||||
|
|
||||||
#include "mockCatalogService.h"
|
#include "mockCatalogService.h"
|
||||||
|
|
||||||
void generateMetaData(MockCatalogService* mcs);
|
void initMetaDataEnv();
|
||||||
|
void generateMetaData();
|
||||||
|
void destroyMetaDataEnv();
|
||||||
|
|
||||||
// mock
|
// mock
|
||||||
struct SCatalog* getCatalogHandle(const SEpSet* pMgmtEps);
|
int32_t catalogGetHandle(const char *clusterId, struct SCatalog** catalogHandle);
|
||||||
int32_t catalogGetMetaData(struct SCatalog* pCatalog, const SCatalogReq* pMetaReq, SMetaData* pMetaData);
|
int32_t catalogGetTableMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* pDBName, const char* pTableName, STableMeta** pTableMeta);
|
||||||
|
|
||||||
#endif // MOCK_CATALOG_H
|
#endif // MOCK_CATALOG_H
|
||||||
|
|
|
@ -27,27 +27,28 @@ std::unique_ptr<MockCatalogService> mockCatalogService;
|
||||||
class TableBuilder : public ITableBuilder {
|
class TableBuilder : public ITableBuilder {
|
||||||
public:
|
public:
|
||||||
virtual TableBuilder& addColumn(const std::string& name, int8_t type, int32_t bytes) {
|
virtual TableBuilder& addColumn(const std::string& name, int8_t type, int32_t bytes) {
|
||||||
assert(colIndex_ < meta_->tableInfo.numOfTags + meta_->tableInfo.numOfColumns);
|
assert(colId_ < schema()->tableInfo.numOfTags + schema()->tableInfo.numOfColumns);
|
||||||
SSchema* col = meta_->schema + colIndex_;
|
SSchema* col = schema()->schema + colId_;
|
||||||
col->type = type;
|
col->type = type;
|
||||||
col->colId = colIndex_++;
|
col->colId = colId_++;
|
||||||
col->bytes = bytes;
|
col->bytes = bytes;
|
||||||
strcpy(col->name, name.c_str());
|
strcpy(col->name, name.c_str());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual TableBuilder& setVgid(int16_t vgid) {
|
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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual TableBuilder& setPrecision(uint8_t precision) {
|
virtual TableBuilder& setPrecision(uint8_t precision) {
|
||||||
meta_->tableInfo.precision = precision;
|
schema()->tableInfo.precision = precision;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void done() {
|
virtual void done() {
|
||||||
meta_->tableInfo.rowSize = rowsize_;
|
schema()->tableInfo.rowSize = rowsize_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -64,61 +65,62 @@ private:
|
||||||
return std::unique_ptr<TableBuilder>(new TableBuilder(meta));
|
return std::unique_ptr<TableBuilder>(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<STableMeta> schema() {
|
||||||
|
return meta_->schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<MockTableMeta> table() {
|
||||||
return meta_;
|
return meta_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t colIndex_;
|
int32_t colId_;
|
||||||
int32_t rowsize_;
|
int32_t rowsize_;
|
||||||
STableMeta* meta_;
|
std::shared_ptr<MockTableMeta> meta_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MockCatalogServiceImpl {
|
class MockCatalogServiceImpl {
|
||||||
public:
|
public:
|
||||||
static const int32_t numOfDataTypes = sizeof(tDataTypes) / sizeof(tDataTypes[0]);
|
static const int32_t numOfDataTypes = sizeof(tDataTypes) / sizeof(tDataTypes[0]);
|
||||||
|
|
||||||
MockCatalogServiceImpl() {
|
MockCatalogServiceImpl() : id_(1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SCatalog* getCatalogHandle(const SEpSet* pMgmtEps) const {
|
int32_t catalogGetHandle(const char *clusterId, struct SCatalog** catalogHandle) const {
|
||||||
return (struct SCatalog*)0x01;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t catalogGetMetaData(struct SCatalog* pCatalog, const SCatalogReq* pMetaReq, SMetaData* pMetaData) const {
|
int32_t catalogGetTableMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* pMgmtEps, const char* pDBName, const char* pTableName, STableMeta** pTableMeta) const {
|
||||||
assert(nullptr != pMetaReq && 1 == taosArrayGetSize(pMetaReq->pTableName));
|
|
||||||
SName* fullName = (SName*)taosArrayGet(pMetaReq->pTableName, 0);
|
|
||||||
std::unique_ptr<STableMeta> table;
|
std::unique_ptr<STableMeta> table;
|
||||||
int32_t code = copyTableMeta(fullName->dbname, fullName->tname, &table);
|
int32_t code = copyTableSchemaMeta(pDBName, pTableName, &table);
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
std::unique_ptr<SArray> tables((SArray*)taosArrayInit(1, sizeof(STableMeta*)));
|
*pTableMeta = table.release();
|
||||||
if (!tables) {
|
|
||||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
STableMeta* elem = table.release();
|
|
||||||
taosArrayPush(tables.get(), &elem);
|
|
||||||
pMetaData->pTableMeta = tables.release();
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
TableBuilder& createTableBuilder(const std::string& db, const std::string& tbname, int8_t tableType, int32_t numOfColumns, int32_t numOfTags) {
|
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);
|
builder_ = TableBuilder::createTableBuilder(tableType, numOfColumns, numOfTags);
|
||||||
meta_[db][tbname].reset(builder_->table());
|
meta_[db][tbname] = builder_->table();
|
||||||
meta_[db][tbname]->uid = id_++;
|
meta_[db][tbname]->schema->uid = id_++;
|
||||||
return *(builder_.get());
|
return *(builder_.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void createSubTable(const std::string& db, const std::string& stbname, const std::string& tbname, int16_t vgid) {
|
void createSubTable(const std::string& db, const std::string& stbname, const std::string& tbname, int16_t vgid) {
|
||||||
std::unique_ptr<STableMeta> table;
|
std::unique_ptr<STableMeta> table;
|
||||||
if (TSDB_CODE_SUCCESS != copyTableMeta(db, stbname, &table)) {
|
if (TSDB_CODE_SUCCESS != copyTableSchemaMeta(db, stbname, &table)) {
|
||||||
throw std::runtime_error("copyTableMeta failed");
|
throw std::runtime_error("copyTableSchemaMeta failed");
|
||||||
}
|
}
|
||||||
meta_[db][tbname].reset(table.release());
|
meta_[db][tbname].reset(new MockTableMeta());
|
||||||
meta_[db][tbname]->uid = id_++;
|
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 {
|
void showTables() const {
|
||||||
|
@ -148,29 +150,43 @@ public:
|
||||||
std::cout << SH("Table") << SH("Type") << SH("Precision") << IH("Vgid") << std::endl;
|
std::cout << SH("Table") << SH("Type") << SH("Precision") << IH("Vgid") << std::endl;
|
||||||
std::cout << SL(3, 1) << std::endl;
|
std::cout << SL(3, 1) << std::endl;
|
||||||
for (const auto& table : db.second) {
|
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;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& db : meta_) {
|
for (const auto& db : meta_) {
|
||||||
for (const auto& table : db.second) {
|
for (const auto& table : db.second) {
|
||||||
|
const auto& schema = table.second->schema;
|
||||||
std::cout << "Table:" << table.first << std::endl;
|
std::cout << "Table:" << table.first << std::endl;
|
||||||
std::cout << SH("Field") << SH("Type") << SH("DataType") << IH("Bytes") << std::endl;
|
std::cout << SH("Field") << SH("Type") << SH("DataType") << IH("Bytes") << std::endl;
|
||||||
std::cout << SL(3, 1) << std::endl;
|
std::cout << SL(3, 1) << std::endl;
|
||||||
int16_t numOfTags = table.second->tableInfo.numOfTags;
|
int16_t numOfTags = schema->tableInfo.numOfTags;
|
||||||
int16_t numOfFields = numOfTags + table.second->tableInfo.numOfColumns;
|
int16_t numOfFields = numOfTags + schema->tableInfo.numOfColumns;
|
||||||
for (int16_t i = 0; i < numOfFields; ++i) {
|
for (int16_t i = 0; i < numOfFields; ++i) {
|
||||||
const SSchema* schema = table.second->schema + i;
|
const SSchema* col = schema->schema + i;
|
||||||
std::cout << SF(std::string(schema->name)) << SH(ftToString(i, numOfTags)) << SH(dtToString(schema->type)) << IF(schema->bytes) << std::endl;
|
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::cout << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<MockTableMeta> 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<MockTableMeta>();
|
||||||
|
}
|
||||||
|
TableMetaCache::const_iterator tit = it->second.find(tbname);
|
||||||
|
if (it->second.end() == tit) {
|
||||||
|
return std::shared_ptr<MockTableMeta>();
|
||||||
|
}
|
||||||
|
return tit->second;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::map<std::string, std::shared_ptr<STableMeta> > TableMetaCache;
|
typedef std::map<std::string, std::shared_ptr<MockTableMeta>> TableMetaCache;
|
||||||
typedef std::map<std::string, TableMetaCache> DbMetaCache;
|
typedef std::map<std::string, TableMetaCache> DbMetaCache;
|
||||||
|
|
||||||
std::string ttToString(int8_t tableType) const {
|
std::string ttToString(int8_t tableType) const {
|
||||||
|
@ -207,20 +223,13 @@ private:
|
||||||
return (0 == colid ? "column" : (colid <= numOfTags ? "tag" : "column"));
|
return (0 == colid ? "column" : (colid <= numOfTags ? "tag" : "column"));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<STableMeta> getTableMeta(const std::string& db, const std::string& tbname) const {
|
std::shared_ptr<STableMeta> getTableSchemaMeta(const std::string& db, const std::string& tbname) const {
|
||||||
DbMetaCache::const_iterator it = meta_.find(db);
|
std::shared_ptr<MockTableMeta> table = getTableMeta(db, tbname);
|
||||||
if (meta_.end() == it) {
|
return table ? table->schema : std::shared_ptr<STableMeta>();
|
||||||
return std::shared_ptr<STableMeta>();
|
|
||||||
}
|
|
||||||
TableMetaCache::const_iterator tit = it->second.find(tbname);
|
|
||||||
if (it->second.end() == tit) {
|
|
||||||
return std::shared_ptr<STableMeta>();
|
|
||||||
}
|
|
||||||
return tit->second;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t copyTableMeta(const std::string& db, const std::string& tbname, std::unique_ptr<STableMeta>* dst) const {
|
int32_t copyTableSchemaMeta(const std::string& db, const std::string& tbname, std::unique_ptr<STableMeta>* dst) const {
|
||||||
std::shared_ptr<STableMeta> src = getTableMeta(db, tbname);
|
std::shared_ptr<STableMeta> src = getTableSchemaMeta(db, tbname);
|
||||||
if (!src) {
|
if (!src) {
|
||||||
return TSDB_CODE_TSC_INVALID_TABLE_NAME;
|
return TSDB_CODE_TSC_INVALID_TABLE_NAME;
|
||||||
}
|
}
|
||||||
|
@ -244,14 +253,6 @@ MockCatalogService::MockCatalogService() : impl_(new MockCatalogServiceImpl()) {
|
||||||
MockCatalogService::~MockCatalogService() {
|
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) {
|
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);
|
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 {
|
void MockCatalogService::showTables() const {
|
||||||
impl_->showTables();
|
impl_->showTables();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<MockTableMeta> 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);
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "catalog.h"
|
#include "catalog.h"
|
||||||
|
|
||||||
|
@ -41,19 +42,24 @@ public:
|
||||||
virtual void done() = 0;
|
virtual void done() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MockCatalogServiceImpl;
|
struct MockTableMeta {
|
||||||
|
std::shared_ptr<STableMeta> schema;
|
||||||
|
std::vector<SVgroupInfo> vgs;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MockCatalogServiceImpl;
|
||||||
class MockCatalogService {
|
class MockCatalogService {
|
||||||
public:
|
public:
|
||||||
static const int32_t numOfDataTypes = sizeof(tDataTypes) / sizeof(tDataTypes[0]);
|
|
||||||
|
|
||||||
MockCatalogService();
|
MockCatalogService();
|
||||||
~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);
|
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 createSubTable(const std::string& db, const std::string& stbname, const std::string& tbname, int16_t vgid);
|
||||||
void showTables() const;
|
void showTables() const;
|
||||||
|
std::shared_ptr<MockTableMeta> 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:
|
private:
|
||||||
std::unique_ptr<MockCatalogServiceImpl> impl_;
|
std::unique_ptr<MockCatalogServiceImpl> impl_;
|
||||||
|
|
|
@ -22,12 +22,12 @@
|
||||||
class ParserEnv : public testing::Environment {
|
class ParserEnv : public testing::Environment {
|
||||||
public:
|
public:
|
||||||
virtual void SetUp() {
|
virtual void SetUp() {
|
||||||
mockCatalogService.reset(new MockCatalogService());
|
initMetaDataEnv();
|
||||||
generateMetaData(mockCatalogService.get());
|
generateMetaData();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void TearDown() {
|
virtual void TearDown() {
|
||||||
mockCatalogService.reset();
|
destroyMetaDataEnv();
|
||||||
}
|
}
|
||||||
|
|
||||||
ParserEnv() {}
|
ParserEnv() {}
|
|
@ -117,6 +117,7 @@ void destroyQueryPlan(struct SQueryPlanNode* pQueryNode);
|
||||||
*/
|
*/
|
||||||
void* destroyQueryPhyPlan(struct SPhyNode* pQueryPhyNode);
|
void* destroyQueryPhyPlan(struct SPhyNode* pQueryPhyNode);
|
||||||
|
|
||||||
|
const char* opTypeToOpName(int32_t type);
|
||||||
int32_t opNameToOpType(const char* name);
|
int32_t opNameToOpType(const char* name);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -33,6 +33,10 @@ static const char* gOpName[] = {
|
||||||
#undef INCLUDE_AS_NAME
|
#undef INCLUDE_AS_NAME
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char* opTypeToOpName(int32_t type) {
|
||||||
|
return gOpName[type];
|
||||||
|
}
|
||||||
|
|
||||||
int32_t opNameToOpType(const char* name) {
|
int32_t opNameToOpType(const char* name) {
|
||||||
for (int32_t i = 1; i < sizeof(gOpName) / sizeof(gOpName[0]); ++i) {
|
for (int32_t i = 1; i < sizeof(gOpName) / sizeof(gOpName[0]); ++i) {
|
||||||
if (strcmp(name, gOpName[i])) {
|
if (strcmp(name, gOpName[i])) {
|
||||||
|
@ -42,17 +46,43 @@ int32_t opNameToOpType(const char* name) {
|
||||||
return OP_Unknown;
|
return OP_Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void toDataBlockSchema(SQueryPlanNode* pPlanNode, SDataBlockSchema* dataBlockSchema) {
|
static bool toDataBlockSchema(SQueryPlanNode* pPlanNode, SDataBlockSchema* dataBlockSchema) {
|
||||||
SWAP(dataBlockSchema->pSchema, pPlanNode->pSchema, SSchema*);
|
|
||||||
dataBlockSchema->numOfCols = pPlanNode->numOfCols;
|
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) {
|
static SPhyNode* initPhyNode(SQueryPlanNode* pPlanNode, int32_t type, int32_t size) {
|
||||||
SPhyNode* node = (SPhyNode*)calloc(1, size);
|
SPhyNode* node = (SPhyNode*)calloc(1, size);
|
||||||
|
if (NULL == node) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
node->info.type = type;
|
node->info.type = type;
|
||||||
node->info.name = gOpName[type];
|
node->info.name = opTypeToOpName(type);
|
||||||
SWAP(node->pTargets, pPlanNode->pExpr, SArray*);
|
if (!cloneExprArray(&node->pTargets, pPlanNode->pExpr) || !toDataBlockSchema(pPlanNode, &(node->targetSchema))) {
|
||||||
toDataBlockSchema(pPlanNode, &(node->targetSchema));
|
free(node);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SPhyNode* initScanNode(SQueryPlanNode* pPlanNode, SQueryTableInfo* pTable, int32_t type, int32_t size) {
|
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);
|
SSubplan* subplan = initSubplan(pCxt, QUERY_TYPE_MERGE);
|
||||||
++(pCxt->nextId.templateId);
|
++(pCxt->nextId.templateId);
|
||||||
subplan->pNode = createPhyNode(pCxt, pRoot);
|
subplan->pNode = createPhyNode(pCxt, pRoot);
|
||||||
SArray* l0 = taosArrayInit(TARRAY_MIN_SIZE, POINTER_BYTES);
|
|
||||||
taosArrayPush(l0, &subplan);
|
|
||||||
taosArrayPush(pCxt->pDag->pSubplans, &l0);
|
|
||||||
// todo deal subquery
|
// todo deal subquery
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,12 @@ MESSAGE(STATUS "build planner unit test")
|
||||||
SET(CMAKE_CXX_STANDARD 11)
|
SET(CMAKE_CXX_STANDARD 11)
|
||||||
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST)
|
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(
|
TARGET_LINK_LIBRARIES(
|
||||||
plannerTest
|
plannerTest
|
||||||
PUBLIC os util common planner parser catalog transport gtest function qcom
|
PUBLIC os util common planner parser catalog transport gtest function qcom
|
||||||
|
@ -15,4 +20,5 @@ TARGET_INCLUDE_DIRECTORIES(
|
||||||
plannerTest
|
plannerTest
|
||||||
PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/planner/"
|
PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/planner/"
|
||||||
PRIVATE "${CMAKE_SOURCE_DIR}/source/libs/planner/inc"
|
PRIVATE "${CMAKE_SOURCE_DIR}/source/libs/planner/inc"
|
||||||
|
PRIVATE "${CMAKE_SOURCE_DIR}/source/libs/parser/test"
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
/*
|
||||||
|
* 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 "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<MockTableMeta> 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<SQueryPlanNode> 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<SVgroupInfo>& 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<MockTableMeta>& 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<MockTableMeta> meta_;
|
||||||
|
unique_ptr<SQueryPlanNode> logicPlan_;
|
||||||
|
unique_ptr<SQueryDag> 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
|
||||||
|
}
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include "taos.h"
|
#include "taos.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
|
#include "mockCatalog.h"
|
||||||
|
|
||||||
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
||||||
|
|
||||||
|
@ -27,9 +28,25 @@
|
||||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
class ParserEnv : public testing::Environment {
|
||||||
testing::InitGoogleTest(&argc, argv);
|
public:
|
||||||
return RUN_ALL_TESTS();
|
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) {
|
TEST(testCase, planner_test) {
|
||||||
|
|
Loading…
Reference in New Issue