fix: insert syntax error
This commit is contained in:
parent
2a7732b159
commit
115160bbd0
|
@ -22,11 +22,11 @@ struct SToken;
|
||||||
|
|
||||||
#define IS_DATA_COL_ORDERED(spd) ((spd->orderStatus) == (int8_t)ORDER_STATUS_ORDERED)
|
#define IS_DATA_COL_ORDERED(spd) ((spd->orderStatus) == (int8_t)ORDER_STATUS_ORDERED)
|
||||||
|
|
||||||
#define NEXT_TOKEN(pSql, sToken) \
|
#define NEXT_TOKEN(pSql, sToken) \
|
||||||
do { \
|
do { \
|
||||||
int32_t index = 0; \
|
int32_t index = 0; \
|
||||||
sToken = tStrGetToken(pSql, &index, false); \
|
sToken = tStrGetToken(pSql, &index, false, NULL); \
|
||||||
pSql += index; \
|
pSql += index; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define CHECK_CODE(expr) \
|
#define CHECK_CODE(expr) \
|
||||||
|
|
|
@ -55,7 +55,7 @@ uint32_t tGetToken(const char *z, uint32_t *tokenType);
|
||||||
* @param isPrevOptr
|
* @param isPrevOptr
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
SToken tStrGetToken(const char *str, int32_t *i, bool isPrevOptr);
|
SToken tStrGetToken(const char *str, int32_t *i, bool isPrevOptr, bool *pIgnoreComma);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check if it is a keyword or not
|
* check if it is a keyword or not
|
||||||
|
|
|
@ -18,16 +18,23 @@
|
||||||
#include "tglobal.h"
|
#include "tglobal.h"
|
||||||
#include "ttime.h"
|
#include "ttime.h"
|
||||||
|
|
||||||
#define NEXT_TOKEN_WITH_PREV(pSql, token) \
|
#define NEXT_TOKEN_WITH_PREV(pSql, token) \
|
||||||
do { \
|
do { \
|
||||||
int32_t index = 0; \
|
int32_t index = 0; \
|
||||||
token = tStrGetToken(pSql, &index, true); \
|
token = tStrGetToken(pSql, &index, true, NULL); \
|
||||||
pSql += index; \
|
pSql += index; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define NEXT_TOKEN_KEEP_SQL(pSql, token, index) \
|
#define NEXT_TOKEN_WITH_PREV_EXT(pSql, token, pIgnoreComma) \
|
||||||
do { \
|
do { \
|
||||||
token = tStrGetToken(pSql, &index, false); \
|
int32_t index = 0; \
|
||||||
|
token = tStrGetToken(pSql, &index, true, pIgnoreComma); \
|
||||||
|
pSql += index; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define NEXT_TOKEN_KEEP_SQL(pSql, token, index) \
|
||||||
|
do { \
|
||||||
|
token = tStrGetToken(pSql, &index, false, NULL); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define NEXT_VALID_TOKEN(pSql, token) \
|
#define NEXT_VALID_TOKEN(pSql, token) \
|
||||||
|
@ -302,12 +309,12 @@ static int parseTime(const char** end, SToken* pToken, int16_t timePrec, int64_t
|
||||||
* e.g., now+12a, now-5h
|
* e.g., now+12a, now-5h
|
||||||
*/
|
*/
|
||||||
index = 0;
|
index = 0;
|
||||||
SToken token = tStrGetToken(pTokenEnd, &index, false);
|
SToken token = tStrGetToken(pTokenEnd, &index, false, NULL);
|
||||||
pTokenEnd += index;
|
pTokenEnd += index;
|
||||||
|
|
||||||
if (token.type == TK_NK_MINUS || token.type == TK_NK_PLUS) {
|
if (token.type == TK_NK_MINUS || token.type == TK_NK_PLUS) {
|
||||||
index = 0;
|
index = 0;
|
||||||
SToken valueToken = tStrGetToken(pTokenEnd, &index, false);
|
SToken valueToken = tStrGetToken(pTokenEnd, &index, false, NULL);
|
||||||
pTokenEnd += index;
|
pTokenEnd += index;
|
||||||
|
|
||||||
if (valueToken.n < 2) {
|
if (valueToken.n < 2) {
|
||||||
|
@ -1240,10 +1247,14 @@ static int parseOneRow(SInsertParseContext* pCxt, const char** pSql, STableDataB
|
||||||
int32_t code = tdSRowResetBuf(pBuilder, row);
|
int32_t code = tdSRowResetBuf(pBuilder, row);
|
||||||
// 1. set the parsed value from sql string
|
// 1. set the parsed value from sql string
|
||||||
for (int i = 0; i < pCols->numOfBound && TSDB_CODE_SUCCESS == code; ++i) {
|
for (int i = 0; i < pCols->numOfBound && TSDB_CODE_SUCCESS == code; ++i) {
|
||||||
NEXT_TOKEN_WITH_PREV(*pSql, *pToken);
|
const char* pOrigSql = *pSql;
|
||||||
SSchema* pSchema = &pSchemas[pCols->boundColumns[i]];
|
bool ignoreComma = false;
|
||||||
|
NEXT_TOKEN_WITH_PREV_EXT(*pSql, *pToken, &ignoreComma);
|
||||||
|
if (ignoreComma) {
|
||||||
|
code = buildSyntaxErrMsg(&pCxt->msg, "invalid data or symbol", pOrigSql);
|
||||||
|
}
|
||||||
|
|
||||||
if (pToken->type == TK_NK_QUESTION) {
|
if (TSDB_CODE_SUCCESS == code && pToken->type == TK_NK_QUESTION) {
|
||||||
isParseBindParam = true;
|
isParseBindParam = true;
|
||||||
if (NULL == pCxt->pComCxt->pStmtCb) {
|
if (NULL == pCxt->pComCxt->pStmtCb) {
|
||||||
code = buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", pToken->z);
|
code = buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", pToken->z);
|
||||||
|
@ -1260,10 +1271,10 @@ static int parseOneRow(SInsertParseContext* pCxt, const char** pSql, STableDataB
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code) {
|
if (TSDB_CODE_SUCCESS == code) {
|
||||||
param.schema = pSchema;
|
param.schema = &pSchemas[pCols->boundColumns[i]];
|
||||||
insGetSTSRowAppendInfo(pBuilder->rowType, pCols, i, ¶m.toffset, ¶m.colIdx);
|
insGetSTSRowAppendInfo(pBuilder->rowType, pCols, i, ¶m.toffset, ¶m.colIdx);
|
||||||
code = parseValueToken(pCxt, pSql, pToken, pSchema, getTableInfo(pDataBuf->pTableMeta).precision, insMemRowAppend,
|
code = parseValueToken(pCxt, pSql, pToken, param.schema, getTableInfo(pDataBuf->pTableMeta).precision,
|
||||||
¶m);
|
insMemRowAppend, ¶m);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_CODE_SUCCESS == code && i < pCols->numOfBound - 1) {
|
if (TSDB_CODE_SUCCESS == code && i < pCols->numOfBound - 1) {
|
||||||
|
|
|
@ -620,7 +620,7 @@ uint32_t tGetToken(const char* z, uint32_t* tokenId) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SToken tStrGetToken(const char* str, int32_t* i, bool isPrevOptr) {
|
SToken tStrGetToken(const char* str, int32_t* i, bool isPrevOptr, bool* pIgnoreComma) {
|
||||||
SToken t0 = {0};
|
SToken t0 = {0};
|
||||||
|
|
||||||
// here we reach the end of sql string, null-terminated string
|
// here we reach the end of sql string, null-terminated string
|
||||||
|
@ -641,6 +641,10 @@ SToken tStrGetToken(const char* str, int32_t* i, bool isPrevOptr) {
|
||||||
return t0;
|
return t0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NULL != pIgnoreComma && t == ',') {
|
||||||
|
*pIgnoreComma = true;
|
||||||
|
}
|
||||||
|
|
||||||
t = str[++(*i)];
|
t = str[++(*i)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ bool qIsInsertValuesSql(const char* pStr, size_t length) {
|
||||||
const char* pSql = pStr;
|
const char* pSql = pStr;
|
||||||
|
|
||||||
int32_t index = 0;
|
int32_t index = 0;
|
||||||
SToken t = tStrGetToken((char*)pStr, &index, false);
|
SToken t = tStrGetToken((char*)pStr, &index, false, NULL);
|
||||||
if (TK_INSERT != t.type && TK_IMPORT != t.type) {
|
if (TK_INSERT != t.type && TK_IMPORT != t.type) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ bool qIsInsertValuesSql(const char* pStr, size_t length) {
|
||||||
do {
|
do {
|
||||||
pStr += index;
|
pStr += index;
|
||||||
index = 0;
|
index = 0;
|
||||||
t = tStrGetToken((char*)pStr, &index, false);
|
t = tStrGetToken((char*)pStr, &index, false, NULL);
|
||||||
if (TK_USING == t.type || TK_VALUES == t.type || TK_FILE == t.type) {
|
if (TK_USING == t.type || TK_VALUES == t.type || TK_FILE == t.type) {
|
||||||
return true;
|
return true;
|
||||||
} else if (TK_SELECT == t.type) {
|
} else if (TK_SELECT == t.type) {
|
||||||
|
|
Loading…
Reference in New Issue