Merge pull request #26324 from xinjiempolde/enh/TD-23926-3.0
enh/td-23926-3.0 insert into db.?
This commit is contained in:
commit
ce4ecb0371
|
@ -101,6 +101,7 @@ typedef struct SParseContext {
|
|||
|
||||
int32_t qParseSql(SParseContext* pCxt, SQuery** pQuery);
|
||||
bool qIsInsertValuesSql(const char* pStr, size_t length);
|
||||
bool qParseDbName(const char* pStr, size_t length, char** pDbName);
|
||||
|
||||
// for async mode
|
||||
int32_t qParseSqlSyntax(SParseContext* pCxt, SQuery** pQuery, struct SCatalogReq* pCatalogReq);
|
||||
|
|
|
@ -219,6 +219,7 @@ const char *stmtErrstr(TAOS_STMT *stmt);
|
|||
int stmtAffectedRows(TAOS_STMT *stmt);
|
||||
int stmtAffectedRowsOnce(TAOS_STMT *stmt);
|
||||
int stmtPrepare(TAOS_STMT *stmt, const char *sql, unsigned long length);
|
||||
int stmtSetDbName(TAOS_STMT* stmt, const char* dbName);
|
||||
int stmtSetTbName(TAOS_STMT *stmt, const char *tbName);
|
||||
int stmtSetTbTags(TAOS_STMT *stmt, TAOS_MULTI_BIND *tags);
|
||||
int stmtGetTagFields(TAOS_STMT *stmt, int *nums, TAOS_FIELD_E **fields);
|
||||
|
|
|
@ -896,6 +896,12 @@ int stmtPrepare(TAOS_STMT* stmt, const char* sql, unsigned long length) {
|
|||
pStmt->sql.sqlLen = length;
|
||||
pStmt->sql.stbInterlaceMode = pStmt->stbInterlaceMode;
|
||||
|
||||
char* dbName = NULL;
|
||||
if (qParseDbName(sql, length, &dbName)) {
|
||||
stmtSetDbName(stmt, dbName);
|
||||
taosMemoryFreeClear(dbName);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -924,6 +930,22 @@ int32_t stmtInitStbInterlaceTableInfo(STscStmt* pStmt) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int stmtSetDbName(TAOS_STMT* stmt, const char* dbName) {
|
||||
STscStmt *pStmt = (STscStmt *) stmt;
|
||||
|
||||
STMT_DLOG("start to set dbName: %s", dbName);
|
||||
|
||||
STMT_ERR_RET(stmtCreateRequest(pStmt));
|
||||
|
||||
// The SQL statement specifies a database name, overriding the previously specified database
|
||||
taosMemoryFreeClear(pStmt->exec.pRequest->pDb);
|
||||
pStmt->exec.pRequest->pDb = taosStrdup(dbName);
|
||||
if (pStmt->exec.pRequest->pDb == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int stmtSetTbName(TAOS_STMT* stmt, const char* tbName) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
|
||||
|
|
|
@ -2428,6 +2428,20 @@ static int32_t checkTableClauseFirstToken(SInsertParseContext* pCxt, SVnodeModif
|
|||
return buildSyntaxErrMsg(&pCxt->msg, "table_name is expected", pTbName->z);
|
||||
}
|
||||
|
||||
// db.? situation,ensure that the only thing following the '.' mark is '?'
|
||||
char *tbNameAfterDbName = strchr(pTbName->z, '.');
|
||||
if ((tbNameAfterDbName != NULL) && (tbNameAfterDbName + 1 - pTbName->z == pTbName->n - 1) &&
|
||||
(*(tbNameAfterDbName + 1) == '?')) {
|
||||
char *tbName = NULL;
|
||||
int32_t code = (*pCxt->pComCxt->pStmtCb->getTbNameFn)(pCxt->pComCxt->pStmtCb->pStmt, &tbName);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
pTbName->z = tbName;
|
||||
pTbName->n = strlen(tbName);
|
||||
} else {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
*pHasData = true;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -781,8 +781,9 @@ SToken tStrGetToken(const char* str, int32_t* i, bool isPrevOptr, bool* pIgnoreC
|
|||
if ('.' == str[*i + t0.n]) {
|
||||
len = tGetToken(&str[*i + t0.n + 1], &type);
|
||||
|
||||
// only id and string are valid
|
||||
if (((TK_NK_STRING != t0.type) && (TK_NK_ID != t0.type)) || ((TK_NK_STRING != type) && (TK_NK_ID != type))) {
|
||||
// only id、string and ? are valid
|
||||
if (((TK_NK_STRING != t0.type) && (TK_NK_ID != t0.type)) ||
|
||||
((TK_NK_STRING != type) && (TK_NK_ID != type) && (TK_NK_QUESTION != type))) {
|
||||
t0.type = TK_NK_ILLEGAL;
|
||||
t0.n = 0;
|
||||
|
||||
|
|
|
@ -48,6 +48,47 @@ bool qIsInsertValuesSql(const char* pStr, size_t length) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool qParseDbName(const char* pStr, size_t length, char** pDbName) {
|
||||
(void) length;
|
||||
int32_t index = 0;
|
||||
SToken t;
|
||||
|
||||
if (NULL == pStr) {
|
||||
*pDbName = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
t = tStrGetToken((char *) pStr, &index, false, NULL);
|
||||
if (TK_INSERT != t.type && TK_IMPORT != t.type) {
|
||||
*pDbName = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
t = tStrGetToken((char *) pStr, &index, false, NULL);
|
||||
if (TK_INTO != t.type) {
|
||||
*pDbName = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
t = tStrGetToken((char *) pStr, &index, false, NULL);
|
||||
if (t.n == 0 || t.z == NULL) {
|
||||
*pDbName = NULL;
|
||||
return false;
|
||||
}
|
||||
char *dotPos = strnchr(t.z, '.', t.n, true);
|
||||
if (dotPos != NULL) {
|
||||
int dbNameLen = dotPos - t.z;
|
||||
*pDbName = taosMemoryMalloc(dbNameLen + 1);
|
||||
if (*pDbName == NULL) {
|
||||
return false;
|
||||
}
|
||||
strncpy(*pDbName, t.z, dbNameLen);
|
||||
(*pDbName)[dbNameLen] = '\0';
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int32_t analyseSemantic(SParseContext* pCxt, SQuery* pQuery, SParseMetaCache* pMetaCache) {
|
||||
int32_t code = authenticate(pCxt, pQuery, pMetaCache);
|
||||
|
||||
|
|
Loading…
Reference in New Issue