TD-12450 perfect parser interface
This commit is contained in:
parent
53928fffd9
commit
0c82c253be
|
@ -160,6 +160,12 @@ typedef struct SInsertStmtInfo {
|
||||||
const char* sql; // current sql statement position
|
const char* sql; // current sql statement position
|
||||||
} SInsertStmtInfo;
|
} SInsertStmtInfo;
|
||||||
|
|
||||||
|
typedef struct SDclStmtInfo {
|
||||||
|
int16_t nodeType;
|
||||||
|
char* pMsg;
|
||||||
|
int32_t msgLen;
|
||||||
|
} SDclStmtInfo;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,14 +22,6 @@ extern "C" {
|
||||||
|
|
||||||
#include "parsenodes.h"
|
#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 {
|
typedef struct SParseContext {
|
||||||
SParseBasicCtx ctx;
|
SParseBasicCtx ctx;
|
||||||
void *pRpc;
|
void *pRpc;
|
||||||
|
@ -50,17 +42,9 @@ typedef struct SParseContext {
|
||||||
* @param msg extended error message if exists.
|
* @param msg extended error message if exists.
|
||||||
* @return error code
|
* @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);
|
||||||
|
|
||||||
/**
|
bool qIsDclQuery(const 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);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
* 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
|
||||||
|
|
|
@ -144,36 +144,31 @@ TAOS_RES *taos_query_l(TAOS *taos, const char *sql, int sqlLen) {
|
||||||
|
|
||||||
tscDebugL("0x%"PRIx64" SQL: %s", pRequest->requestId, pRequest->sqlstr);
|
tscDebugL("0x%"PRIx64" SQL: %s", pRequest->requestId, pRequest->sqlstr);
|
||||||
|
|
||||||
int32_t code = 0;
|
SParseContext cxt = {
|
||||||
if (qIsInsertSql(pRequest->sqlstr, sqlLen)) {
|
.ctx = {.requestId = pRequest->requestId, .acctId = pTscObj->acctId, .db = getConnectionDB(pTscObj)},
|
||||||
// todo add
|
.pSql = pRequest->sqlstr,
|
||||||
} else {
|
.sqlLen = sqlLen,
|
||||||
int32_t type = 0;
|
.pMsg = pRequest->msgBuf,
|
||||||
void* output = NULL;
|
.msgLen = ERROR_MSG_BUF_DEFAULT_SIZE
|
||||||
int32_t outputLen = 0;
|
};
|
||||||
|
SQueryNode* pQuery = NULL;
|
||||||
SParseBasicCtx c = {.requestId = pRequest->requestId, .acctId = pTscObj->acctId, .db = getConnectionDB(pTscObj)};
|
int32_t code = qParseQuerySql(&cxt, &pQuery);
|
||||||
code = qParseQuerySql(pRequest->sqlstr, sqlLen, &c, &type, &output, &outputLen, pRequest->msgBuf, ERROR_MSG_BUF_DEFAULT_SIZE);
|
if (qIsDclQuery(pQuery)) {
|
||||||
if (type == TSDB_SQL_CREATE_USER || type == TSDB_SQL_SHOW || type == TSDB_SQL_DROP_USER ||
|
SDclStmtInfo* pDcl = (SDclStmtInfo*)pQuery;
|
||||||
type == TSDB_SQL_DROP_ACCT || type == TSDB_SQL_CREATE_DB || type == TSDB_SQL_CREATE_ACCT ||
|
pRequest->type = pDcl->nodeType;
|
||||||
type == TSDB_SQL_CREATE_TABLE || type == TSDB_SQL_USE_DB) {
|
pRequest->body.requestMsg = (SReqMsgInfo){.pMsg = pDcl->pMsg, .len = pDcl->msgLen};
|
||||||
pRequest->type = type;
|
|
||||||
pRequest->body.requestMsg = (SReqMsgInfo){.pMsg = output, .len = outputLen};
|
|
||||||
|
|
||||||
SRequestMsgBody body = {0};
|
SRequestMsgBody body = {0};
|
||||||
buildRequestMsgFp[type](pRequest, &body);
|
buildRequestMsgFp[pDcl->nodeType](pRequest, &body);
|
||||||
|
|
||||||
int64_t transporterId = 0;
|
int64_t transporterId = 0;
|
||||||
sendMsgToServer(pTscObj->pTransporter, &pTscObj->pAppInfo->mgmtEp.epSet, &body, &transporterId);
|
sendMsgToServer(pTscObj->pTransporter, &pTscObj->pAppInfo->mgmtEp.epSet, &body, &transporterId);
|
||||||
|
|
||||||
tsem_wait(&pRequest->body.rspSem);
|
tsem_wait(&pRequest->body.rspSem);
|
||||||
destroyRequestMsgBody(&body);
|
destroyRequestMsgBody(&body);
|
||||||
} else {
|
|
||||||
assert(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tfree(c.db);
|
tfree(cxt.ctx.db);
|
||||||
}
|
|
||||||
|
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
pRequest->code = code;
|
pRequest->code = code;
|
||||||
|
|
|
@ -68,7 +68,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pSqlInfo, SQ
|
||||||
* @param type
|
* @param type
|
||||||
* @return
|
* @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.
|
* Evaluate the numeric and timestamp arithmetic expression in the WHERE clause.
|
||||||
|
|
|
@ -4308,13 +4308,13 @@ int32_t doCheckForCreateTable(SSqlInfo* pInfo, SMsgBuf* pMsgBuf) {
|
||||||
return TSDB_CODE_SUCCESS;
|
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;
|
int32_t code = 0;
|
||||||
|
|
||||||
SMsgBuf m = {.buf = msgBuf, .len = msgBufLen};
|
SMsgBuf m = {.buf = msgBuf, .len = msgBufLen};
|
||||||
SMsgBuf *pMsgBuf = &m;
|
SMsgBuf *pMsgBuf = &m;
|
||||||
|
|
||||||
*type = pInfo->type;
|
pDcl->nodeType = pInfo->type;
|
||||||
|
|
||||||
switch (pInfo->type) {
|
switch (pInfo->type) {
|
||||||
case TSDB_SQL_CREATE_USER:
|
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;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TSDB_SQL_DROP_ACCT:
|
case TSDB_SQL_DROP_ACCT:
|
||||||
case TSDB_SQL_DROP_USER: {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TSDB_SQL_SHOW: {
|
case TSDB_SQL_SHOW: {
|
||||||
code = setShowInfo(pInfo, output, outputLen, pMsgBuf);
|
code = setShowInfo(pInfo, (void**)&pDcl->pMsg, &pDcl->msgLen, pMsgBuf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4429,8 +4429,8 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, void**
|
||||||
SUseDbMsg *pUseDbMsg = (SUseDbMsg *) calloc(1, sizeof(SUseDbMsg));
|
SUseDbMsg *pUseDbMsg = (SUseDbMsg *) calloc(1, sizeof(SUseDbMsg));
|
||||||
tNameExtractFullName(&n, pUseDbMsg->db);
|
tNameExtractFullName(&n, pUseDbMsg->db);
|
||||||
|
|
||||||
*output = pUseDbMsg;
|
pDcl->pMsg = (char*)pUseDbMsg;
|
||||||
*outputLen = sizeof(SUseDbMsg);
|
pDcl->msgLen = sizeof(SUseDbMsg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4458,8 +4458,8 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, void**
|
||||||
|
|
||||||
strncpy(pCreateMsg->db, token.z, token.n);
|
strncpy(pCreateMsg->db, token.z, token.n);
|
||||||
|
|
||||||
*output = pCreateMsg;
|
pDcl->pMsg = (char*)pCreateMsg;
|
||||||
*outputLen = sizeof(SCreateDbMsg);
|
pDcl->msgLen = sizeof(SCreateDbMsg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4470,7 +4470,7 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, SParseBasicCtx* pCtx, void**
|
||||||
if ((code = doCheckForCreateTable(pInfo, pMsgBuf)) != TSDB_CODE_SUCCESS) {
|
if ((code = doCheckForCreateTable(pInfo, pMsgBuf)) != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
*output = buildCreateTableMsg(pCreateTable, outputLen, pCtx, pMsgBuf);
|
pDcl->pMsg = (char*)buildCreateTableMsg(pCreateTable, &pDcl->msgLen, pCtx, pMsgBuf);
|
||||||
} else if (pCreateTable->type == TSQL_CREATE_CTABLE) {
|
} else if (pCreateTable->type == TSQL_CREATE_CTABLE) {
|
||||||
// if ((code = doCheckForCreateFromStable(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
|
// if ((code = doCheckForCreateFromStable(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
|
||||||
// return code;
|
// return code;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "function.h"
|
#include "function.h"
|
||||||
#include "insertParser.h"
|
#include "insertParser.h"
|
||||||
|
|
||||||
bool qIsInsertSql(const char* pStr, size_t length) {
|
bool isInsertSql(const char* pStr, size_t length) {
|
||||||
int32_t index = 0;
|
int32_t index = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -31,18 +31,26 @@ bool qIsInsertSql(const char* pStr, size_t length) {
|
||||||
} while (1);
|
} 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) {
|
bool qIsDclQuery(const SQueryNode* pQuery) {
|
||||||
SSqlInfo info = doGenerateAST(pStr);
|
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) {
|
if (!info.valid) {
|
||||||
strncpy(msg, info.msg, msgLen);
|
strncpy(pCxt->pMsg, info.msg, pCxt->msgLen);
|
||||||
terrno = TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
|
terrno = TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
|
||||||
return terrno;
|
return terrno;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isDqlSqlStatement(&info)) {
|
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) {
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
// do nothing
|
*pQuery = (SQueryNode*)pDcl;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SQueryStmtInfo* pQueryInfo = calloc(1, sizeof(SQueryStmtInfo));
|
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;
|
struct SCatalog* pCatalog = NULL;
|
||||||
int32_t code = catalogGetHandle(NULL, &pCatalog);
|
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) {
|
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;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t qParseInsertSql(SParseContext* pContext, SInsertStmtInfo** pInfo) {
|
int32_t qParseQuerySql(SParseContext* pCxt, SQueryNode** pQuery) {
|
||||||
return parseInsertSql(pContext, pInfo);
|
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) {
|
int32_t qParserConvertSql(const char* pStr, size_t length, char** pConvertSql) {
|
||||||
|
|
|
@ -714,12 +714,9 @@ TEST(testCase, show_user_Test) {
|
||||||
SSqlInfo info1 = doGenerateAST(sql1);
|
SSqlInfo info1 = doGenerateAST(sql1);
|
||||||
ASSERT_EQ(info1.valid, true);
|
ASSERT_EQ(info1.valid, true);
|
||||||
|
|
||||||
void* output = NULL;
|
SDclStmtInfo output;
|
||||||
int32_t type = 0;
|
|
||||||
int32_t len = 0;
|
|
||||||
|
|
||||||
SParseBasicCtx ct= {.db= "abc", .acctId = 1, .requestId = 1};
|
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);
|
ASSERT_EQ(code, 0);
|
||||||
|
|
||||||
// convert the show command to be the select query
|
// 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(info1.valid, true);
|
||||||
ASSERT_EQ(isDclSqlStatement(&info1), true);
|
ASSERT_EQ(isDclSqlStatement(&info1), true);
|
||||||
|
|
||||||
void* output = NULL;
|
SDclStmtInfo output;
|
||||||
int32_t type = 0;
|
|
||||||
int32_t len = 0;
|
|
||||||
|
|
||||||
SParseBasicCtx ct= {.db= "abc", .acctId = 1, .requestId = 1};
|
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);
|
ASSERT_EQ(code, 0);
|
||||||
|
|
||||||
destroySqlInfo(&info1);
|
destroySqlInfo(&info1);
|
||||||
|
|
|
@ -51,16 +51,10 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t run(const string& db, const string& sql) {
|
int32_t run(const string& db, const string& sql) {
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
|
||||||
SParseContext cxt;
|
SParseContext cxt;
|
||||||
buildParseContext(db, sql, &cxt);
|
buildParseContext(db, sql, &cxt);
|
||||||
SQueryNode* query;
|
SQueryNode* query;
|
||||||
if (qIsInsertSql(cxt.pSql, cxt.sqlLen)) {
|
int32_t code = qParseQuerySql(&cxt, &query);
|
||||||
code = qParseInsertSql(&cxt, (SInsertStmtInfo**)&query);
|
|
||||||
} else {
|
|
||||||
// todo
|
|
||||||
code = TSDB_CODE_FAILED;
|
|
||||||
}
|
|
||||||
if (TSDB_CODE_SUCCESS != code) {
|
if (TSDB_CODE_SUCCESS != code) {
|
||||||
cout << "error no:" << code << ", msg:" << cxt.pMsg << endl;
|
cout << "error no:" << code << ", msg:" << cxt.pMsg << endl;
|
||||||
return code;
|
return code;
|
||||||
|
|
Loading…
Reference in New Issue