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);
|
||||
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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -27,27 +27,28 @@ std::unique_ptr<MockCatalogService> 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<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_;
|
||||
}
|
||||
|
||||
int32_t colIndex_;
|
||||
int32_t colId_;
|
||||
int32_t rowsize_;
|
||||
STableMeta* meta_;
|
||||
std::shared_ptr<MockTableMeta> 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<STableMeta> 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<SArray> 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<STableMeta> 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<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:
|
||||
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;
|
||||
|
||||
std::string ttToString(int8_t tableType) const {
|
||||
|
@ -207,20 +223,13 @@ private:
|
|||
return (0 == colid ? "column" : (colid <= numOfTags ? "tag" : "column"));
|
||||
}
|
||||
|
||||
std::shared_ptr<STableMeta> 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<STableMeta>();
|
||||
}
|
||||
TableMetaCache::const_iterator tit = it->second.find(tbname);
|
||||
if (it->second.end() == tit) {
|
||||
return std::shared_ptr<STableMeta>();
|
||||
}
|
||||
return tit->second;
|
||||
std::shared_ptr<STableMeta> getTableSchemaMeta(const std::string& db, const std::string& tbname) const {
|
||||
std::shared_ptr<MockTableMeta> table = getTableMeta(db, tbname);
|
||||
return table ? table->schema : std::shared_ptr<STableMeta>();
|
||||
}
|
||||
|
||||
int32_t copyTableMeta(const std::string& db, const std::string& tbname, std::unique_ptr<STableMeta>* dst) const {
|
||||
std::shared_ptr<STableMeta> src = getTableMeta(db, tbname);
|
||||
int32_t copyTableSchemaMeta(const std::string& db, const std::string& tbname, std::unique_ptr<STableMeta>* dst) const {
|
||||
std::shared_ptr<STableMeta> 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();
|
||||
}
|
||||
}
|
||||
|
||||
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 <string>
|
||||
#include <vector>
|
||||
|
||||
#include "catalog.h"
|
||||
|
||||
|
@ -41,19 +42,24 @@ public:
|
|||
virtual void done() = 0;
|
||||
};
|
||||
|
||||
class MockCatalogServiceImpl;
|
||||
struct MockTableMeta {
|
||||
std::shared_ptr<STableMeta> schema;
|
||||
std::vector<SVgroupInfo> 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<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:
|
||||
std::unique_ptr<MockCatalogServiceImpl> impl_;
|
||||
|
|
|
@ -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() {}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
|
|
@ -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 "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) {
|
||||
|
|
Loading…
Reference in New Issue