From 0c82c253be6046b7e7e7de564c9cc44b3833d7b2 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Thu, 23 Dec 2021 04:33:41 -0500 Subject: [PATCH] TD-12450 perfect parser interface --- include/libs/parser/parsenodes.h | 6 +++ include/libs/parser/parser.h | 20 +-------- source/client/src/clientImpl.c | 51 ++++++++++------------- source/libs/parser/inc/parserInt.h | 2 +- source/libs/parser/src/astValidate.c | 22 +++++----- source/libs/parser/src/parser.c | 32 +++++++++----- source/libs/parser/test/parserTests.cpp | 14 ++----- source/libs/planner/test/phyPlanTests.cpp | 8 +--- 8 files changed, 70 insertions(+), 85 deletions(-) diff --git a/include/libs/parser/parsenodes.h b/include/libs/parser/parsenodes.h index 62f36abcee..cc7df465f7 100644 --- a/include/libs/parser/parsenodes.h +++ b/include/libs/parser/parsenodes.h @@ -160,6 +160,12 @@ typedef struct SInsertStmtInfo { const char* sql; // current sql statement position } SInsertStmtInfo; +typedef struct SDclStmtInfo { + int16_t nodeType; + char* pMsg; + int32_t msgLen; +} SDclStmtInfo; + #ifdef __cplusplus } #endif diff --git a/include/libs/parser/parser.h b/include/libs/parser/parser.h index 6fedb6b66b..7834bc6913 100644 --- a/include/libs/parser/parser.h +++ b/include/libs/parser/parser.h @@ -22,14 +22,6 @@ extern "C" { #include "parsenodes.h" -/** - * True will be returned if the input sql string is insert, false otherwise. - * @param pStr sql string - * @param length length of the sql string - * @return - */ -bool qIsInsertSql(const char* pStr, size_t length); - typedef struct SParseContext { SParseBasicCtx ctx; void *pRpc; @@ -50,17 +42,9 @@ typedef struct SParseContext { * @param msg extended error message if exists. * @return error code */ -int32_t qParseQuerySql(const char* pStr, size_t length, SParseBasicCtx* pParseCtx, int32_t* type, void** pOutput, int32_t* outputLen, char* msg, int32_t msgLen); +int32_t qParseQuerySql(SParseContext* pContext, SQueryNode** pQuery); -/** - * Parse the insert sql statement. - * @param pStr sql string - * @param length length of the sql string - * @param id operator id, generated by uuid generator. - * @param msg extended error message if exists to help avoid the problem in sql statement. - * @return data in binary format to submit to vnode directly. - */ - int32_t qParseInsertSql(SParseContext* pContext, struct SInsertStmtInfo** pInfo); +bool qIsDclQuery(const SQueryNode* pQuery); /** * Convert a normal sql statement to only query tags information to enable that the subscribe client can be aware quickly of the true vgroup ids that diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index 42de97fe6a..7cb5ad2e07 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -144,37 +144,32 @@ TAOS_RES *taos_query_l(TAOS *taos, const char *sql, int sqlLen) { tscDebugL("0x%"PRIx64" SQL: %s", pRequest->requestId, pRequest->sqlstr); - int32_t code = 0; - if (qIsInsertSql(pRequest->sqlstr, sqlLen)) { - // todo add - } else { - int32_t type = 0; - void* output = NULL; - int32_t outputLen = 0; - - SParseBasicCtx c = {.requestId = pRequest->requestId, .acctId = pTscObj->acctId, .db = getConnectionDB(pTscObj)}; - code = qParseQuerySql(pRequest->sqlstr, sqlLen, &c, &type, &output, &outputLen, pRequest->msgBuf, ERROR_MSG_BUF_DEFAULT_SIZE); - if (type == TSDB_SQL_CREATE_USER || type == TSDB_SQL_SHOW || type == TSDB_SQL_DROP_USER || - type == TSDB_SQL_DROP_ACCT || type == TSDB_SQL_CREATE_DB || type == TSDB_SQL_CREATE_ACCT || - type == TSDB_SQL_CREATE_TABLE || type == TSDB_SQL_USE_DB) { - pRequest->type = type; - pRequest->body.requestMsg = (SReqMsgInfo){.pMsg = output, .len = outputLen}; - - SRequestMsgBody body = {0}; - buildRequestMsgFp[type](pRequest, &body); - - int64_t transporterId = 0; - sendMsgToServer(pTscObj->pTransporter, &pTscObj->pAppInfo->mgmtEp.epSet, &body, &transporterId); - - tsem_wait(&pRequest->body.rspSem); - destroyRequestMsgBody(&body); - } else { - assert(0); - } + SParseContext cxt = { + .ctx = {.requestId = pRequest->requestId, .acctId = pTscObj->acctId, .db = getConnectionDB(pTscObj)}, + .pSql = pRequest->sqlstr, + .sqlLen = sqlLen, + .pMsg = pRequest->msgBuf, + .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE + }; + SQueryNode* pQuery = NULL; + int32_t code = qParseQuerySql(&cxt, &pQuery); + if (qIsDclQuery(pQuery)) { + SDclStmtInfo* pDcl = (SDclStmtInfo*)pQuery; + pRequest->type = pDcl->nodeType; + pRequest->body.requestMsg = (SReqMsgInfo){.pMsg = pDcl->pMsg, .len = pDcl->msgLen}; - tfree(c.db); + SRequestMsgBody body = {0}; + buildRequestMsgFp[pDcl->nodeType](pRequest, &body); + + int64_t transporterId = 0; + sendMsgToServer(pTscObj->pTransporter, &pTscObj->pAppInfo->mgmtEp.epSet, &body, &transporterId); + + tsem_wait(&pRequest->body.rspSem); + destroyRequestMsgBody(&body); } + tfree(cxt.ctx.db); + if (code != TSDB_CODE_SUCCESS) { pRequest->code = code; return pRequest; diff --git a/source/libs/parser/inc/parserInt.h b/source/libs/parser/inc/parserInt.h index 93df023fba..186a4869e6 100644 --- a/source/libs/parser/inc/parserInt.h +++ b/source/libs/parser/inc/parserInt.h @@ -68,7 +68,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pSqlInfo, SQ * @param type * @return */ -int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, void** output, int32_t* outputLen, int32_t* type, char* msgBuf, int32_t msgBufLen); +int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, SDclStmtInfo* pDcl, char* msgBuf, int32_t msgBufLen); /** * Evaluate the numeric and timestamp arithmetic expression in the WHERE clause. diff --git a/source/libs/parser/src/astValidate.c b/source/libs/parser/src/astValidate.c index 33efeb469d..7cb52bb1d3 100644 --- a/source/libs/parser/src/astValidate.c +++ b/source/libs/parser/src/astValidate.c @@ -4308,13 +4308,13 @@ int32_t doCheckForCreateTable(SSqlInfo* pInfo, SMsgBuf* pMsgBuf) { return TSDB_CODE_SUCCESS; } -int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, void** output, int32_t* outputLen, int32_t* type, char* msgBuf, int32_t msgBufLen) { +int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, SDclStmtInfo* pDcl, char* msgBuf, int32_t msgBufLen) { int32_t code = 0; SMsgBuf m = {.buf = msgBuf, .len = msgBufLen}; SMsgBuf *pMsgBuf = &m; - *type = pInfo->type; + pDcl->nodeType = pInfo->type; switch (pInfo->type) { case TSDB_SQL_CREATE_USER: @@ -4361,7 +4361,7 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, void** } } - *output = buildUserManipulationMsg(pInfo, outputLen, pCtx->requestId, msgBuf, msgBufLen); + pDcl->pMsg = (char*)buildUserManipulationMsg(pInfo, &pDcl->msgLen, pCtx->requestId, msgBuf, msgBufLen); break; } @@ -4397,18 +4397,18 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, void** } } - *output = buildAcctManipulationMsg(pInfo, outputLen, pCtx->requestId, msgBuf, msgBufLen); + pDcl->pMsg = (char*)buildAcctManipulationMsg(pInfo, &pDcl->msgLen, pCtx->requestId, msgBuf, msgBufLen); break; } case TSDB_SQL_DROP_ACCT: case TSDB_SQL_DROP_USER: { - *output = buildDropUserMsg(pInfo, outputLen, pCtx->requestId, msgBuf, msgBufLen); + pDcl->pMsg = (char*)buildDropUserMsg(pInfo, &pDcl->msgLen, pCtx->requestId, msgBuf, msgBufLen); break; } case TSDB_SQL_SHOW: { - code = setShowInfo(pInfo, output, outputLen, pMsgBuf); + code = setShowInfo(pInfo, (void**)&pDcl->pMsg, &pDcl->msgLen, pMsgBuf); break; } @@ -4429,8 +4429,8 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, void** SUseDbMsg *pUseDbMsg = (SUseDbMsg *) calloc(1, sizeof(SUseDbMsg)); tNameExtractFullName(&n, pUseDbMsg->db); - *output = pUseDbMsg; - *outputLen = sizeof(SUseDbMsg); + pDcl->pMsg = (char*)pUseDbMsg; + pDcl->msgLen = sizeof(SUseDbMsg); break; } @@ -4458,8 +4458,8 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, void** strncpy(pCreateMsg->db, token.z, token.n); - *output = pCreateMsg; - *outputLen = sizeof(SCreateDbMsg); + pDcl->pMsg = (char*)pCreateMsg; + pDcl->msgLen = sizeof(SCreateDbMsg); break; } @@ -4470,7 +4470,7 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, void** if ((code = doCheckForCreateTable(pInfo, pMsgBuf)) != TSDB_CODE_SUCCESS) { return code; } - *output = buildCreateTableMsg(pCreateTable, outputLen, pCtx, pMsgBuf); + pDcl->pMsg = (char*)buildCreateTableMsg(pCreateTable, &pDcl->msgLen, pCtx, pMsgBuf); } else if (pCreateTable->type == TSQL_CREATE_CTABLE) { // if ((code = doCheckForCreateFromStable(pSql, pInfo)) != TSDB_CODE_SUCCESS) { // return code; diff --git a/source/libs/parser/src/parser.c b/source/libs/parser/src/parser.c index 3490580f15..25f18ad6f2 100644 --- a/source/libs/parser/src/parser.c +++ b/source/libs/parser/src/parser.c @@ -20,7 +20,7 @@ #include "function.h" #include "insertParser.h" -bool qIsInsertSql(const char* pStr, size_t length) { +bool isInsertSql(const char* pStr, size_t length) { int32_t index = 0; do { @@ -31,18 +31,26 @@ bool qIsInsertSql(const char* pStr, size_t length) { } while (1); } -int32_t qParseQuerySql(const char* pStr, size_t length, SParseBasicCtx* pParseCtx, int32_t *type, void** pOutput, int32_t* outputLen, char* msg, int32_t msgLen) { - SSqlInfo info = doGenerateAST(pStr); +bool qIsDclQuery(const SQueryNode* pQuery) { + int16_t type = pQuery->type; + return type == TSDB_SQL_CREATE_USER || type == TSDB_SQL_SHOW || type == TSDB_SQL_DROP_USER || + type == TSDB_SQL_DROP_ACCT || type == TSDB_SQL_CREATE_DB || type == TSDB_SQL_CREATE_ACCT || + type == TSDB_SQL_CREATE_TABLE || type == TSDB_SQL_USE_DB; +} + +int32_t parseQuerySql(SParseContext* pCxt, SQueryNode** pQuery) { + SSqlInfo info = doGenerateAST(pCxt->pSql); if (!info.valid) { - strncpy(msg, info.msg, msgLen); + strncpy(pCxt->pMsg, info.msg, pCxt->msgLen); terrno = TSDB_CODE_TSC_SQL_SYNTAX_ERROR; return terrno; } if (!isDqlSqlStatement(&info)) { - int32_t code = qParserValidateDclSqlNode(&info, pParseCtx, pOutput, outputLen, type, msg, msgLen); + SDclStmtInfo* pDcl = calloc(1, sizeof(SQueryStmtInfo)); + int32_t code = qParserValidateDclSqlNode(&info, &pCxt->ctx, pDcl, pCxt->pMsg, pCxt->msgLen); if (code == TSDB_CODE_SUCCESS) { - // do nothing + *pQuery = (SQueryNode*)pDcl; } } else { SQueryStmtInfo* pQueryInfo = calloc(1, sizeof(SQueryStmtInfo)); @@ -53,9 +61,9 @@ int32_t qParseQuerySql(const char* pStr, size_t length, SParseBasicCtx* pParseCt struct SCatalog* pCatalog = NULL; int32_t code = catalogGetHandle(NULL, &pCatalog); - code = qParserValidateSqlNode(pCatalog, &info, pQueryInfo, pParseCtx->requestId, msg, msgLen); + code = qParserValidateSqlNode(pCatalog, &info, pQueryInfo, pCxt->ctx.requestId, pCxt->pMsg, pCxt->msgLen); if (code == TSDB_CODE_SUCCESS) { - *pOutput = pQueryInfo; + *pQuery = (SQueryNode*)pQueryInfo; } } @@ -63,8 +71,12 @@ int32_t qParseQuerySql(const char* pStr, size_t length, SParseBasicCtx* pParseCt return TSDB_CODE_SUCCESS; } -int32_t qParseInsertSql(SParseContext* pContext, SInsertStmtInfo** pInfo) { - return parseInsertSql(pContext, pInfo); +int32_t qParseQuerySql(SParseContext* pCxt, SQueryNode** pQuery) { + if (isInsertSql(pCxt->pSql, pCxt->sqlLen)) { + return parseInsertSql(pCxt, (SInsertStmtInfo**)pQuery); + } else { + return parseQuerySql(pCxt, pQuery); + } } int32_t qParserConvertSql(const char* pStr, size_t length, char** pConvertSql) { diff --git a/source/libs/parser/test/parserTests.cpp b/source/libs/parser/test/parserTests.cpp index be68149e09..f2cb4864fb 100644 --- a/source/libs/parser/test/parserTests.cpp +++ b/source/libs/parser/test/parserTests.cpp @@ -714,12 +714,9 @@ TEST(testCase, show_user_Test) { SSqlInfo info1 = doGenerateAST(sql1); ASSERT_EQ(info1.valid, true); - void* output = NULL; - int32_t type = 0; - int32_t len = 0; - + SDclStmtInfo output; SParseBasicCtx ct= {.db= "abc", .acctId = 1, .requestId = 1}; - int32_t code = qParserValidateDclSqlNode(&info1, &ct, &output, &len, &type, msg, buf.len); + int32_t code = qParserValidateDclSqlNode(&info1, &ct, &output, msg, buf.len); ASSERT_EQ(code, 0); // convert the show command to be the select query @@ -738,12 +735,9 @@ TEST(testCase, create_user_Test) { ASSERT_EQ(info1.valid, true); ASSERT_EQ(isDclSqlStatement(&info1), true); - void* output = NULL; - int32_t type = 0; - int32_t len = 0; - + SDclStmtInfo output; SParseBasicCtx ct= {.db= "abc", .acctId = 1, .requestId = 1}; - int32_t code = qParserValidateDclSqlNode(&info1, &ct, &output, &len, &type, msg, buf.len); + int32_t code = qParserValidateDclSqlNode(&info1, &ct, &output, msg, buf.len); ASSERT_EQ(code, 0); destroySqlInfo(&info1); diff --git a/source/libs/planner/test/phyPlanTests.cpp b/source/libs/planner/test/phyPlanTests.cpp index cafa22df24..f14fd50e03 100644 --- a/source/libs/planner/test/phyPlanTests.cpp +++ b/source/libs/planner/test/phyPlanTests.cpp @@ -51,16 +51,10 @@ protected: } int32_t run(const string& db, const string& sql) { - int32_t code = TSDB_CODE_SUCCESS; SParseContext cxt; buildParseContext(db, sql, &cxt); SQueryNode* query; - if (qIsInsertSql(cxt.pSql, cxt.sqlLen)) { - code = qParseInsertSql(&cxt, (SInsertStmtInfo**)&query); - } else { - // todo - code = TSDB_CODE_FAILED; - } + int32_t code = qParseQuerySql(&cxt, &query); if (TSDB_CODE_SUCCESS != code) { cout << "error no:" << code << ", msg:" << cxt.pMsg << endl; return code; -- GitLab