Merge pull request #12115 from taosdata/feature/3.0_wxy
fix: plan problem of tag scanning
This commit is contained in:
commit
0035bb11f6
|
@ -20,8 +20,8 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "querynodes.h"
|
|
||||||
#include "query.h"
|
#include "query.h"
|
||||||
|
#include "querynodes.h"
|
||||||
|
|
||||||
typedef struct SStmtCallback {
|
typedef struct SStmtCallback {
|
||||||
TAOS_STMT* pStmt;
|
TAOS_STMT* pStmt;
|
||||||
|
@ -34,24 +34,26 @@ typedef struct SStmtCallback {
|
||||||
typedef struct SParseContext {
|
typedef struct SParseContext {
|
||||||
uint64_t requestId;
|
uint64_t requestId;
|
||||||
int32_t acctId;
|
int32_t acctId;
|
||||||
const char *db;
|
const char* db;
|
||||||
bool topicQuery;
|
bool topicQuery;
|
||||||
void *pTransporter;
|
void* pTransporter;
|
||||||
SEpSet mgmtEpSet;
|
SEpSet mgmtEpSet;
|
||||||
const char *pSql; // sql string
|
const char* pSql; // sql string
|
||||||
size_t sqlLen; // length of the sql string
|
size_t sqlLen; // length of the sql string
|
||||||
char *pMsg; // extended error message if exists to help identifying the problem in sql statement.
|
char* pMsg; // extended error message if exists to help identifying the problem in sql statement.
|
||||||
int32_t msgLen; // max length of the msg
|
int32_t msgLen; // max length of the msg
|
||||||
struct SCatalog *pCatalog;
|
struct SCatalog* pCatalog;
|
||||||
SStmtCallback *pStmtCb;
|
SStmtCallback* pStmtCb;
|
||||||
|
const char* pUser;
|
||||||
|
bool isSuperUser;
|
||||||
} SParseContext;
|
} SParseContext;
|
||||||
|
|
||||||
typedef struct SCmdMsgInfo {
|
typedef struct SCmdMsgInfo {
|
||||||
int16_t msgType;
|
int16_t msgType;
|
||||||
SEpSet epSet;
|
SEpSet epSet;
|
||||||
void* pMsg;
|
void* pMsg;
|
||||||
int32_t msgLen;
|
int32_t msgLen;
|
||||||
void* pExtension; // todo remove it soon
|
void* pExtension; // todo remove it soon
|
||||||
} SCmdMsgInfo;
|
} SCmdMsgInfo;
|
||||||
|
|
||||||
typedef enum EQueryExecMode {
|
typedef enum EQueryExecMode {
|
||||||
|
@ -63,21 +65,21 @@ typedef enum EQueryExecMode {
|
||||||
|
|
||||||
typedef struct SQuery {
|
typedef struct SQuery {
|
||||||
EQueryExecMode execMode;
|
EQueryExecMode execMode;
|
||||||
bool haveResultSet;
|
bool haveResultSet;
|
||||||
SNode* pRoot;
|
SNode* pRoot;
|
||||||
int32_t numOfResCols;
|
int32_t numOfResCols;
|
||||||
SSchema* pResSchema;
|
SSchema* pResSchema;
|
||||||
int8_t precision;
|
int8_t precision;
|
||||||
SCmdMsgInfo* pCmdMsg;
|
SCmdMsgInfo* pCmdMsg;
|
||||||
int32_t msgType;
|
int32_t msgType;
|
||||||
SArray* pDbList;
|
SArray* pDbList;
|
||||||
SArray* pTableList;
|
SArray* pTableList;
|
||||||
bool showRewrite;
|
bool showRewrite;
|
||||||
int32_t placeholderNum;
|
int32_t placeholderNum;
|
||||||
} SQuery;
|
} SQuery;
|
||||||
|
|
||||||
int32_t qParseQuerySql(SParseContext* pCxt, SQuery** pQuery);
|
int32_t qParseQuerySql(SParseContext* pCxt, SQuery** pQuery);
|
||||||
bool isInsertSql(const char* pStr, size_t length);
|
bool isInsertSql(const char* pStr, size_t length);
|
||||||
|
|
||||||
void qDestroyQuery(SQuery* pQueryNode);
|
void qDestroyQuery(SQuery* pQueryNode);
|
||||||
|
|
||||||
|
@ -89,14 +91,16 @@ int32_t qCloneStmtDataBlock(void** pDst, void* pSrc);
|
||||||
void qFreeStmtDataBlock(void* pDataBlock);
|
void qFreeStmtDataBlock(void* pDataBlock);
|
||||||
int32_t qRebuildStmtDataBlock(void** pDst, void* pSrc);
|
int32_t qRebuildStmtDataBlock(void** pDst, void* pSrc);
|
||||||
void qDestroyStmtDataBlock(void* pBlock);
|
void qDestroyStmtDataBlock(void* pBlock);
|
||||||
int32_t qBindStmtColsValue(void *pBlock, TAOS_MULTI_BIND *bind, char *msgBuf, int32_t msgBufLen);
|
int32_t qBindStmtColsValue(void* pBlock, TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen);
|
||||||
int32_t qBindStmtSingleColValue(void *pBlock, TAOS_MULTI_BIND *bind, char *msgBuf, int32_t msgBufLen, int32_t colIdx, int32_t rowNum);
|
int32_t qBindStmtSingleColValue(void* pBlock, TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen, int32_t colIdx,
|
||||||
int32_t qBuildStmtColFields(void *pDataBlock, int32_t *fieldNum, TAOS_FIELD** fields);
|
int32_t rowNum);
|
||||||
int32_t qBuildStmtTagFields(void *pBlock, void *boundTags, int32_t *fieldNum, TAOS_FIELD** fields);
|
int32_t qBuildStmtColFields(void* pDataBlock, int32_t* fieldNum, TAOS_FIELD** fields);
|
||||||
int32_t qBindStmtTagsValue(void *pBlock, void *boundTags, int64_t suid, SName *pName, TAOS_MULTI_BIND *bind, char *msgBuf, int32_t msgBufLen);
|
int32_t qBuildStmtTagFields(void* pBlock, void* boundTags, int32_t* fieldNum, TAOS_FIELD** fields);
|
||||||
void destroyBoundColumnInfo(void* pBoundInfo);
|
int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, SName* pName, TAOS_MULTI_BIND* bind,
|
||||||
int32_t qCreateSName(SName* pName, const char* pTableName, int32_t acctId, char* dbName, char *msgBuf, int32_t msgBufLen);
|
char* msgBuf, int32_t msgBufLen);
|
||||||
|
void destroyBoundColumnInfo(void* pBoundInfo);
|
||||||
|
int32_t qCreateSName(SName* pName, const char* pTableName, int32_t acctId, char* dbName, char* msgBuf,
|
||||||
|
int32_t msgBufLen);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -913,7 +913,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
{
|
{
|
||||||
.name = "tbname",
|
.name = "tbname",
|
||||||
.type = FUNCTION_TYPE_TBNAME,
|
.type = FUNCTION_TYPE_TBNAME,
|
||||||
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC,
|
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_SCAN_PC_FUNC,
|
||||||
.translateFunc = translateTbnameColumn,
|
.translateFunc = translateTbnameColumn,
|
||||||
.getEnvFunc = NULL,
|
.getEnvFunc = NULL,
|
||||||
.initFunc = NULL,
|
.initFunc = NULL,
|
||||||
|
|
|
@ -100,6 +100,17 @@ void generateInformationSchema(MockCatalogService* mcs) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Table:t1
|
||||||
|
* Field | Type | DataType | Bytes |
|
||||||
|
* ==========================================================================
|
||||||
|
* ts | column | TIMESTAMP | 8 |
|
||||||
|
* c1 | column | INT | 4 |
|
||||||
|
* c2 | column | VARCHAR | 20 |
|
||||||
|
* c3 | column | BIGINT | 8 |
|
||||||
|
* c4 | column | DOUBLE | 8 |
|
||||||
|
* c5 | column | DOUBLE | 8 |
|
||||||
|
*/
|
||||||
void generateTestT1(MockCatalogService* mcs) {
|
void generateTestT1(MockCatalogService* mcs) {
|
||||||
ITableBuilder& builder = mcs->createTableBuilder("test", "t1", TSDB_NORMAL_TABLE, 6)
|
ITableBuilder& builder = mcs->createTableBuilder("test", "t1", TSDB_NORMAL_TABLE, 6)
|
||||||
.setPrecision(TSDB_TIME_PRECISION_MILLI)
|
.setPrecision(TSDB_TIME_PRECISION_MILLI)
|
||||||
|
@ -113,6 +124,17 @@ void generateTestT1(MockCatalogService* mcs) {
|
||||||
builder.done();
|
builder.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Super Table: st1
|
||||||
|
* Field | Type | DataType | Bytes |
|
||||||
|
* ==========================================================================
|
||||||
|
* ts | column | TIMESTAMP | 8 |
|
||||||
|
* c1 | column | INT | 4 |
|
||||||
|
* c2 | column | VARCHAR | 20 |
|
||||||
|
* tag1 | tag | INT | 4 |
|
||||||
|
* tag2 | tag | VARCHAR | 20 |
|
||||||
|
* Child Table: st1s1, st1s2
|
||||||
|
*/
|
||||||
void generateTestST1(MockCatalogService* mcs) {
|
void generateTestST1(MockCatalogService* mcs) {
|
||||||
ITableBuilder& builder = mcs->createTableBuilder("test", "st1", TSDB_SUPER_TABLE, 3, 2)
|
ITableBuilder& builder = mcs->createTableBuilder("test", "st1", TSDB_SUPER_TABLE, 3, 2)
|
||||||
.setPrecision(TSDB_TIME_PRECISION_MILLI)
|
.setPrecision(TSDB_TIME_PRECISION_MILLI)
|
||||||
|
|
|
@ -23,4 +23,6 @@ TEST_F(PlanSuperTableTest, tbname) {
|
||||||
useDb("root", "test");
|
useDb("root", "test");
|
||||||
|
|
||||||
run("select tbname from st1");
|
run("select tbname from st1");
|
||||||
|
|
||||||
|
run("select tbname, tag1, tag2 from st1");
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,11 +36,11 @@ class PlannerEnv : public testing::Environment {
|
||||||
static void parseArg(int argc, char* argv[]) {
|
static void parseArg(int argc, char* argv[]) {
|
||||||
int opt = 0;
|
int opt = 0;
|
||||||
const char* optstring = "";
|
const char* optstring = "";
|
||||||
static struct option long_options[] = {{"dump", no_argument, NULL, 'd'}, {0, 0, 0, 0}};
|
static struct option long_options[] = {{"dump", optional_argument, NULL, 'd'}, {0, 0, 0, 0}};
|
||||||
while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
|
while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'd':
|
case 'd':
|
||||||
g_isDump = true;
|
setDumpModule(optarg);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -34,7 +34,41 @@ using namespace testing;
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
bool g_isDump = false;
|
enum DumpModule {
|
||||||
|
DUMP_MODULE_NOTHING = 1,
|
||||||
|
DUMP_MODULE_PARSER,
|
||||||
|
DUMP_MODULE_LOGIC,
|
||||||
|
DUMP_MODULE_OPTIMIZED,
|
||||||
|
DUMP_MODULE_SPLIT,
|
||||||
|
DUMP_MODULE_SCALED,
|
||||||
|
DUMP_MODULE_PHYSICAL,
|
||||||
|
DUMP_MODULE_SUBPLAN,
|
||||||
|
DUMP_MODULE_ALL
|
||||||
|
};
|
||||||
|
|
||||||
|
DumpModule g_dumpModule = DUMP_MODULE_NOTHING;
|
||||||
|
|
||||||
|
void setDumpModule(const char* pModule) {
|
||||||
|
if (NULL == pModule) {
|
||||||
|
g_dumpModule = DUMP_MODULE_ALL;
|
||||||
|
} else if (0 == strncasecmp(pModule, "parser", strlen(pModule))) {
|
||||||
|
g_dumpModule = DUMP_MODULE_PARSER;
|
||||||
|
} else if (0 == strncasecmp(pModule, "logic", strlen(pModule))) {
|
||||||
|
g_dumpModule = DUMP_MODULE_LOGIC;
|
||||||
|
} else if (0 == strncasecmp(pModule, "optimized", strlen(pModule))) {
|
||||||
|
g_dumpModule = DUMP_MODULE_OPTIMIZED;
|
||||||
|
} else if (0 == strncasecmp(pModule, "split", strlen(pModule))) {
|
||||||
|
g_dumpModule = DUMP_MODULE_SPLIT;
|
||||||
|
} else if (0 == strncasecmp(pModule, "scaled", strlen(pModule))) {
|
||||||
|
g_dumpModule = DUMP_MODULE_SCALED;
|
||||||
|
} else if (0 == strncasecmp(pModule, "physical", strlen(pModule))) {
|
||||||
|
g_dumpModule = DUMP_MODULE_PHYSICAL;
|
||||||
|
} else if (0 == strncasecmp(pModule, "subplan", strlen(pModule))) {
|
||||||
|
g_dumpModule = DUMP_MODULE_SUBPLAN;
|
||||||
|
} else if (0 == strncasecmp(pModule, "all", strlen(pModule))) {
|
||||||
|
g_dumpModule = DUMP_MODULE_PHYSICAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class PlannerTestBaseImpl {
|
class PlannerTestBaseImpl {
|
||||||
public:
|
public:
|
||||||
|
@ -66,11 +100,9 @@ class PlannerTestBaseImpl {
|
||||||
SQueryPlan* pPlan = nullptr;
|
SQueryPlan* pPlan = nullptr;
|
||||||
doCreatePhysiPlan(&cxt, pLogicPlan, &pPlan);
|
doCreatePhysiPlan(&cxt, pLogicPlan, &pPlan);
|
||||||
|
|
||||||
if (g_isDump) {
|
dump(g_dumpModule);
|
||||||
dump();
|
|
||||||
}
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
dump();
|
dump(DUMP_MODULE_ALL);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,23 +141,48 @@ class PlannerTestBaseImpl {
|
||||||
res_.physiSubplans_.clear();
|
res_.physiSubplans_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump() {
|
void dump(DumpModule module) {
|
||||||
|
if (DUMP_MODULE_NOTHING == module) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
cout << "==========================================sql : [" << stmtEnv_.sql_ << "]" << endl;
|
cout << "==========================================sql : [" << stmtEnv_.sql_ << "]" << endl;
|
||||||
cout << "syntax tree : " << endl;
|
|
||||||
cout << res_.ast_ << endl;
|
if (DUMP_MODULE_ALL == module || DUMP_MODULE_PARSER == module) {
|
||||||
cout << "raw logic plan : " << endl;
|
cout << "syntax tree : " << endl;
|
||||||
cout << res_.rawLogicPlan_ << endl;
|
cout << res_.ast_ << endl;
|
||||||
cout << "optimized logic plan : " << endl;
|
}
|
||||||
cout << res_.optimizedLogicPlan_ << endl;
|
|
||||||
cout << "split logic plan : " << endl;
|
if (DUMP_MODULE_ALL == module || DUMP_MODULE_LOGIC == module) {
|
||||||
cout << res_.splitLogicPlan_ << endl;
|
cout << "raw logic plan : " << endl;
|
||||||
cout << "scaled logic plan : " << endl;
|
cout << res_.rawLogicPlan_ << endl;
|
||||||
cout << res_.scaledLogicPlan_ << endl;
|
}
|
||||||
cout << "physical plan : " << endl;
|
|
||||||
cout << res_.physiPlan_ << endl;
|
if (DUMP_MODULE_ALL == module || DUMP_MODULE_OPTIMIZED == module) {
|
||||||
cout << "physical subplan : " << endl;
|
cout << "optimized logic plan : " << endl;
|
||||||
for (const auto& subplan : res_.physiSubplans_) {
|
cout << res_.optimizedLogicPlan_ << endl;
|
||||||
cout << subplan << endl;
|
}
|
||||||
|
|
||||||
|
if (DUMP_MODULE_ALL == module || DUMP_MODULE_SPLIT == module) {
|
||||||
|
cout << "split logic plan : " << endl;
|
||||||
|
cout << res_.splitLogicPlan_ << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DUMP_MODULE_ALL == module || DUMP_MODULE_SCALED == module) {
|
||||||
|
cout << "scaled logic plan : " << endl;
|
||||||
|
cout << res_.scaledLogicPlan_ << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DUMP_MODULE_ALL == module || DUMP_MODULE_PHYSICAL == module) {
|
||||||
|
cout << "physical plan : " << endl;
|
||||||
|
cout << res_.physiPlan_ << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DUMP_MODULE_ALL == module || DUMP_MODULE_SUBPLAN == module) {
|
||||||
|
cout << "physical subplan : " << endl;
|
||||||
|
for (const auto& subplan : res_.physiSubplans_) {
|
||||||
|
cout << subplan << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,6 @@ class PlannerTestBase : public testing::Test {
|
||||||
std::unique_ptr<PlannerTestBaseImpl> impl_;
|
std::unique_ptr<PlannerTestBaseImpl> impl_;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern bool g_isDump;
|
extern void setDumpModule(const char* pModule);
|
||||||
|
|
||||||
#endif // PLAN_TEST_UTIL_H
|
#endif // PLAN_TEST_UTIL_H
|
||||||
|
|
Loading…
Reference in New Issue