fix(stmt2):stmt2 get fields return wrong when tag is value(3.3.6) (#30308)
* fix: add case * fix: stmt2 get fields return wrong when tag is value * enh: replace preCtb bool to flag,handle more situation * fix: some unit test error * diff: add case and fix some problem * fix: remove async test, handle in TD-34077 * fix: review --------- Co-authored-by: Simon Guan <slguan@taosdata.com>
This commit is contained in:
parent
2e42a4b046
commit
d3f537275f
|
@ -49,10 +49,16 @@ extern "C" {
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
#define HAS_BIND_VALUE ((uint8_t)0x1)
|
||||
#define IS_FIXED_VALUE ((uint8_t)0x2)
|
||||
#define USING_CLAUSE ((uint8_t)0x4)
|
||||
#define IS_FIXED_TAG ((uint8_t)0x8)
|
||||
#define NO_DATA_USING_CLAUSE ((uint8_t)0x7)
|
||||
|
||||
typedef struct SStmtCallback {
|
||||
TAOS_STMT* pStmt;
|
||||
int32_t (*getTbNameFn)(TAOS_STMT*, char**);
|
||||
int32_t (*setInfoFn)(TAOS_STMT*, STableMeta*, void*, SName*, bool, SHashObj*, SHashObj*, const char*, bool);
|
||||
int32_t (*setInfoFn)(TAOS_STMT*, STableMeta*, void*, SName*, bool, SHashObj*, SHashObj*, const char*, uint8_t);
|
||||
int32_t (*getExecInfoFn)(TAOS_STMT*, SHashObj**, SHashObj**);
|
||||
} SStmtCallback;
|
||||
|
||||
|
@ -175,7 +181,7 @@ int32_t qBindStmtColsValue(void* pBlock, SArray* pCols, TAOS_MULTI_BIND* bind, c
|
|||
int32_t qBindStmtSingleColValue(void* pBlock, SArray* pCols, TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen,
|
||||
int32_t colIdx, int32_t rowNum, void* charsetCxt);
|
||||
int32_t qBuildStmtColFields(void* pDataBlock, int32_t* fieldNum, TAOS_FIELD_E** fields);
|
||||
int32_t qBuildStmtStbColFields(void* pBlock, void* boundTags, bool hasCtbName, int32_t* fieldNum,
|
||||
int32_t qBuildStmtStbColFields(void* pBlock, void* boundTags, uint8_t tbNameFlag, int32_t* fieldNum,
|
||||
TAOS_FIELD_ALL** fields);
|
||||
int32_t qBuildStmtTagFields(void* pBlock, void* boundTags, int32_t* fieldNum, TAOS_FIELD_E** fields);
|
||||
int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, const char* sTableName, char* tName,
|
||||
|
|
|
@ -64,7 +64,7 @@ typedef struct SStmtBindInfo {
|
|||
int32_t sBindLastIdx;
|
||||
int8_t tbType;
|
||||
bool tagsCached;
|
||||
bool preCtbname;
|
||||
uint8_t tbNameFlag;
|
||||
void *boundTags;
|
||||
char tbName[TSDB_TABLE_FNAME_LEN];
|
||||
char tbFName[TSDB_TABLE_FNAME_LEN];
|
||||
|
|
|
@ -238,7 +238,7 @@ int32_t stmtRestoreQueryFields(STscStmt* pStmt) {
|
|||
}
|
||||
*/
|
||||
int32_t stmtUpdateBindInfo(TAOS_STMT* stmt, STableMeta* pTableMeta, void* tags, SName* tbName, const char* sTableName,
|
||||
bool autoCreateTbl) {
|
||||
bool autoCreateTbl, uint8_t tbNameFlag) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
char tbFName[TSDB_TABLE_FNAME_LEN];
|
||||
int32_t code = tNameExtractFullName(tbName, tbFName);
|
||||
|
@ -256,6 +256,7 @@ int32_t stmtUpdateBindInfo(TAOS_STMT* stmt, STableMeta* pTableMeta, void* tags,
|
|||
pStmt->bInfo.tbType = pTableMeta->tableType;
|
||||
pStmt->bInfo.boundTags = tags;
|
||||
pStmt->bInfo.tagsCached = false;
|
||||
pStmt->bInfo.tbNameFlag = tbNameFlag;
|
||||
tstrncpy(pStmt->bInfo.stbFName, sTableName, sizeof(pStmt->bInfo.stbFName));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -271,10 +272,10 @@ int32_t stmtUpdateExecInfo(TAOS_STMT* stmt, SHashObj* pVgHash, SHashObj* pBlockH
|
|||
}
|
||||
|
||||
int32_t stmtUpdateInfo(TAOS_STMT* stmt, STableMeta* pTableMeta, void* tags, SName* tbName, bool autoCreateTbl,
|
||||
SHashObj* pVgHash, SHashObj* pBlockHash, const char* sTableName, bool preCtbname) {
|
||||
SHashObj* pVgHash, SHashObj* pBlockHash, const char* sTableName, uint8_t tbNameFlag) {
|
||||
STscStmt* pStmt = (STscStmt*)stmt;
|
||||
|
||||
STMT_ERR_RET(stmtUpdateBindInfo(stmt, pTableMeta, tags, tbName, sTableName, autoCreateTbl));
|
||||
STMT_ERR_RET(stmtUpdateBindInfo(stmt, pTableMeta, tags, tbName, sTableName, autoCreateTbl, tbNameFlag));
|
||||
STMT_ERR_RET(stmtUpdateExecInfo(stmt, pVgHash, pBlockHash));
|
||||
|
||||
pStmt->sql.autoCreateTbl = autoCreateTbl;
|
||||
|
@ -1729,7 +1730,10 @@ int stmtGetTagFields(TAOS_STMT* stmt, int* nums, TAOS_FIELD_E** fields) {
|
|||
STMT_ERRI_JRET(stmtFetchTagFields(stmt, nums, fields));
|
||||
|
||||
_return:
|
||||
|
||||
// compatible with previous versions
|
||||
if (code == TSDB_CODE_PAR_TABLE_NOT_EXIST && (pStmt->bInfo.tbNameFlag & NO_DATA_USING_CLAUSE) == 0x0) {
|
||||
code = TSDB_CODE_TSC_STMT_TBNAME_ERROR;
|
||||
}
|
||||
pStmt->errCode = preCode;
|
||||
|
||||
return code;
|
||||
|
|
|
@ -193,7 +193,7 @@ static int32_t stmtGetTbName(TAOS_STMT2* stmt, char** tbName) {
|
|||
}
|
||||
|
||||
static int32_t stmtUpdateBindInfo(TAOS_STMT2* stmt, STableMeta* pTableMeta, void* tags, SName* tbName,
|
||||
const char* sTableName, bool autoCreateTbl, bool preCtbname) {
|
||||
const char* sTableName, bool autoCreateTbl, int8_t tbNameFlag) {
|
||||
STscStmt2* pStmt = (STscStmt2*)stmt;
|
||||
char tbFName[TSDB_TABLE_FNAME_LEN];
|
||||
int32_t code = tNameExtractFullName(tbName, tbFName);
|
||||
|
@ -217,7 +217,7 @@ static int32_t stmtUpdateBindInfo(TAOS_STMT2* stmt, STableMeta* pTableMeta, void
|
|||
|
||||
pStmt->bInfo.boundTags = tags;
|
||||
pStmt->bInfo.tagsCached = false;
|
||||
pStmt->bInfo.preCtbname = preCtbname;
|
||||
pStmt->bInfo.tbNameFlag = tbNameFlag;
|
||||
tstrncpy(pStmt->bInfo.stbFName, sTableName, sizeof(pStmt->bInfo.stbFName));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -233,10 +233,10 @@ static int32_t stmtUpdateExecInfo(TAOS_STMT2* stmt, SHashObj* pVgHash, SHashObj*
|
|||
}
|
||||
|
||||
static int32_t stmtUpdateInfo(TAOS_STMT2* stmt, STableMeta* pTableMeta, void* tags, SName* tbName, bool autoCreateTbl,
|
||||
SHashObj* pVgHash, SHashObj* pBlockHash, const char* sTableName, bool preCtbname) {
|
||||
SHashObj* pVgHash, SHashObj* pBlockHash, const char* sTableName, uint8_t tbNameFlag) {
|
||||
STscStmt2* pStmt = (STscStmt2*)stmt;
|
||||
|
||||
STMT_ERR_RET(stmtUpdateBindInfo(stmt, pTableMeta, tags, tbName, sTableName, autoCreateTbl, preCtbname));
|
||||
STMT_ERR_RET(stmtUpdateBindInfo(stmt, pTableMeta, tags, tbName, sTableName, autoCreateTbl, tbNameFlag));
|
||||
STMT_ERR_RET(stmtUpdateExecInfo(stmt, pVgHash, pBlockHash));
|
||||
|
||||
pStmt->sql.autoCreateTbl = autoCreateTbl;
|
||||
|
@ -1233,7 +1233,8 @@ static int stmtFetchStbColFields2(STscStmt2* pStmt, int32_t* fieldNum, TAOS_FIEL
|
|||
}
|
||||
|
||||
STMT_ERRI_JRET(
|
||||
qBuildStmtStbColFields(*pDataBlock, pStmt->bInfo.boundTags, pStmt->bInfo.preCtbname, fieldNum, fields));
|
||||
qBuildStmtStbColFields(*pDataBlock, pStmt->bInfo.boundTags, pStmt->bInfo.tbNameFlag, fieldNum, fields));
|
||||
|
||||
if (pStmt->bInfo.tbType == TSDB_SUPER_TABLE && cleanStb) {
|
||||
pStmt->bInfo.needParse = true;
|
||||
qDestroyStmtDataBlock(*pDataBlock);
|
||||
|
@ -2022,7 +2023,9 @@ int stmtParseColFields2(TAOS_STMT2* stmt) {
|
|||
STMT_TYPE_MULTI_INSERT != pStmt->sql.type) {
|
||||
pStmt->bInfo.needParse = false;
|
||||
}
|
||||
|
||||
if (pStmt->sql.stbInterlaceMode && pStmt->sql.siInfo.pDataCtx != NULL) {
|
||||
pStmt->bInfo.needParse = false;
|
||||
}
|
||||
if (pStmt->exec.pRequest && STMT_TYPE_QUERY == pStmt->sql.type && pStmt->sql.runTimes) {
|
||||
taos_free_result(pStmt->exec.pRequest);
|
||||
pStmt->exec.pRequest = NULL;
|
||||
|
@ -2036,6 +2039,10 @@ int stmtParseColFields2(TAOS_STMT2* stmt) {
|
|||
}
|
||||
|
||||
_return:
|
||||
// compatible with previous versions
|
||||
if (code == TSDB_CODE_PAR_TABLE_NOT_EXIST && (pStmt->bInfo.tbNameFlag & NO_DATA_USING_CLAUSE) == 0x0) {
|
||||
code = TSDB_CODE_TSC_STMT_TBNAME_ERROR;
|
||||
}
|
||||
|
||||
pStmt->errCode = preCode;
|
||||
|
||||
|
|
|
@ -634,9 +634,20 @@ TEST(stmt2Case, insert_ctb_using_get_fields_Test) {
|
|||
printf("case 9 : %s\n", sql);
|
||||
getFieldsSuccess(taos, sql, expectedFields, 5);
|
||||
}
|
||||
// case 11: TD-34097
|
||||
{
|
||||
do_query(taos, "use stmt2_testdb_3");
|
||||
const char* sql = "INSERT INTO ? using stb (t1,t2) TAGS(1,'abc') (ts,b)VALUES(?,?)";
|
||||
TAOS_FIELD_ALL expectedFields[3] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME},
|
||||
{"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL},
|
||||
{"b", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL}};
|
||||
printf("case 11 : %s\n", sql);
|
||||
getFieldsSuccess(taos, sql, expectedFields, 3);
|
||||
}
|
||||
|
||||
// case 10 : test all types
|
||||
{
|
||||
do_query(taos, "use stmt2_testdb_3");
|
||||
const char* sql =
|
||||
"insert into ? using all_stb tags(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
|
||||
TAOS_FIELD_ALL expectedFields[33] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME},
|
||||
|
@ -711,7 +722,27 @@ TEST(stmt2Case, insert_ctb_using_get_fields_Test) {
|
|||
printf("case 5 : %s\n", sql);
|
||||
getFieldsError(taos, sql, TSDB_CODE_TSC_SQL_SYNTAX_ERROR);
|
||||
}
|
||||
|
||||
// case 6 : mix value and ?
|
||||
{
|
||||
do_query(taos, "use stmt2_testdb_3");
|
||||
const char* sql = "INSERT INTO ? using stb (t1,t2) TAGS(1,?) (ts,b)VALUES(?,?)";
|
||||
printf("case 6 : %s\n", sql);
|
||||
getFieldsError(taos, sql, TSDB_CODE_TSC_SQL_SYNTAX_ERROR);
|
||||
}
|
||||
// case 7 : mix value and ?
|
||||
{
|
||||
do_query(taos, "use stmt2_testdb_3");
|
||||
const char* sql = "INSERT INTO ? using stb (t1,t2) TAGS(?,?) (ts,b)VALUES(15910606280001,?)";
|
||||
printf("case 7 : %s\n", sql);
|
||||
getFieldsError(taos, sql, TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
}
|
||||
// case 8 : mix value and ?
|
||||
{
|
||||
do_query(taos, "use stmt2_testdb_3");
|
||||
const char* sql = "INSERT INTO ? using stb (t1,t2) TAGS(?,?) (ts,b)VALUES(15910606280001,'abc')";
|
||||
printf("case 8 : %s\n", sql);
|
||||
getFieldsError(taos, sql, TSDB_CODE_TSC_INVALID_OPERATION);
|
||||
}
|
||||
do_query(taos, "drop database if exists stmt2_testdb_3");
|
||||
taos_close(taos);
|
||||
}
|
||||
|
@ -1002,6 +1033,15 @@ TEST(stmt2Case, stmt2_insert_non_statndard) {
|
|||
printf("stmt2 [%s] : %s\n", "less params", sql);
|
||||
int code = taos_stmt2_prepare(stmt, sql, 0);
|
||||
checkError(stmt, code);
|
||||
// test get fields
|
||||
int fieldNum = 0;
|
||||
TAOS_FIELD_ALL* pFields = NULL;
|
||||
code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
|
||||
checkError(stmt, code);
|
||||
ASSERT_EQ(fieldNum, 2);
|
||||
ASSERT_STREQ(pFields[0].name, "tbname");
|
||||
ASSERT_STREQ(pFields[1].name, "ts");
|
||||
|
||||
int total_affect_rows = 0;
|
||||
|
||||
int t64_len[2] = {sizeof(int64_t), sizeof(int64_t)};
|
||||
|
@ -1024,11 +1064,22 @@ TEST(stmt2Case, stmt2_insert_non_statndard) {
|
|||
code = taos_stmt2_bind_param(stmt, &bindv, -1);
|
||||
checkError(stmt, code);
|
||||
|
||||
code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
|
||||
checkError(stmt, code);
|
||||
ASSERT_EQ(fieldNum, 2);
|
||||
ASSERT_STREQ(pFields[0].name, "tbname");
|
||||
ASSERT_STREQ(pFields[1].name, "ts");
|
||||
|
||||
int affected_rows;
|
||||
taos_stmt2_exec(stmt, &affected_rows);
|
||||
total_affect_rows += affected_rows;
|
||||
|
||||
checkError(stmt, code);
|
||||
|
||||
code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
|
||||
checkError(stmt, code);
|
||||
ASSERT_EQ(fieldNum, 2);
|
||||
ASSERT_STREQ(pFields[0].name, "tbname");
|
||||
ASSERT_STREQ(pFields[1].name, "ts");
|
||||
}
|
||||
|
||||
ASSERT_EQ(total_affect_rows, 12);
|
||||
|
@ -1959,27 +2010,27 @@ void stmt2_async_test(std::atomic<bool>& stop_task) {
|
|||
stop_task = true;
|
||||
}
|
||||
|
||||
TEST(stmt2Case, async_order) {
|
||||
std::atomic<bool> stop_task(false);
|
||||
std::thread t(stmt2_async_test, std::ref(stop_task));
|
||||
// TEST(stmt2Case, async_order) {
|
||||
// std::atomic<bool> stop_task(false);
|
||||
// std::thread t(stmt2_async_test, std::ref(stop_task));
|
||||
|
||||
// 等待 60 秒钟
|
||||
auto start_time = std::chrono::steady_clock::now();
|
||||
while (!stop_task) {
|
||||
auto elapsed_time = std::chrono::steady_clock::now() - start_time;
|
||||
if (std::chrono::duration_cast<std::chrono::seconds>(elapsed_time).count() > 100) {
|
||||
if (t.joinable()) {
|
||||
t.detach();
|
||||
}
|
||||
FAIL() << "Test[stmt2_async_test] timed out";
|
||||
break;
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1)); // 每 1s 检查一次
|
||||
}
|
||||
if (t.joinable()) {
|
||||
t.join();
|
||||
}
|
||||
}
|
||||
// // 等待 60 秒钟
|
||||
// auto start_time = std::chrono::steady_clock::now();
|
||||
// while (!stop_task) {
|
||||
// auto elapsed_time = std::chrono::steady_clock::now() - start_time;
|
||||
// if (std::chrono::duration_cast<std::chrono::seconds>(elapsed_time).count() > 100) {
|
||||
// if (t.joinable()) {
|
||||
// t.detach();
|
||||
// }
|
||||
// FAIL() << "Test[stmt2_async_test] timed out";
|
||||
// break;
|
||||
// }
|
||||
// std::this_thread::sleep_for(std::chrono::seconds(1)); // 每 1s 检查一次
|
||||
// }
|
||||
// if (t.joinable()) {
|
||||
// t.join();
|
||||
// }
|
||||
// }
|
||||
|
||||
TEST(stmt2Case, rowformat_bind) {
|
||||
TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
|
||||
|
|
|
@ -32,7 +32,7 @@ typedef struct SInsertParseContext {
|
|||
bool needTableTagVal;
|
||||
bool needRequest; // whether or not request server
|
||||
bool isStmtBind; // whether is stmt bind
|
||||
bool preCtbname;
|
||||
uint8_t stmtTbNameFlag;
|
||||
} SInsertParseContext;
|
||||
|
||||
typedef int32_t (*_row_append_fn_t)(SMsgBuf* pMsgBuf, const void* value, int32_t len, void* param);
|
||||
|
@ -993,6 +993,10 @@ static int32_t parseTagsClauseImpl(SInsertParseContext* pCxt, SVnodeModifyOpStmt
|
|||
code = buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", token.z);
|
||||
break;
|
||||
}
|
||||
if (pTagVals->size != 0) {
|
||||
code = buildSyntaxErrMsg(&pCxt->msg, "no mix usage for ? and tag values", token.z);
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
@ -1026,6 +1030,10 @@ static int32_t parseTagsClauseImpl(SInsertParseContext* pCxt, SVnodeModifyOpStmt
|
|||
pTag = NULL;
|
||||
}
|
||||
|
||||
if (code == TSDB_CODE_SUCCESS && !isParseBindParam) {
|
||||
pCxt->stmtTbNameFlag |= IS_FIXED_TAG;
|
||||
}
|
||||
|
||||
_exit:
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pTagVals); ++i) {
|
||||
STagVal* p = (STagVal*)TARRAY_GET_ELEM(pTagVals, i);
|
||||
|
@ -1416,6 +1424,7 @@ static int32_t parseUsingTableName(SInsertParseContext* pCxt, SVnodeModifyOpStmt
|
|||
return getTargetTableSchema(pCxt, pStmt);
|
||||
}
|
||||
pStmt->usingTableProcessing = true;
|
||||
pCxt->stmtTbNameFlag |= USING_CLAUSE;
|
||||
// pStmt->pSql -> stb_name [(tag1_name, ...)
|
||||
pStmt->pSql += index;
|
||||
int32_t code = parseDuplicateUsingClause(pCxt, pStmt, &pCxt->usingDuplicateTable);
|
||||
|
@ -1465,7 +1474,7 @@ static int32_t getTableDataCxt(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pS
|
|||
|
||||
char tbFName[TSDB_TABLE_FNAME_LEN];
|
||||
int32_t code = 0;
|
||||
if (pCxt->preCtbname) {
|
||||
if ((pCxt->stmtTbNameFlag & NO_DATA_USING_CLAUSE) == USING_CLAUSE) {
|
||||
tstrncpy(pStmt->targetTableName.tname, pStmt->usingTableName.tname, sizeof(pStmt->targetTableName.tname));
|
||||
tstrncpy(pStmt->targetTableName.dbname, pStmt->usingTableName.dbname, sizeof(pStmt->targetTableName.dbname));
|
||||
pStmt->targetTableName.type = TSDB_SUPER_TABLE;
|
||||
|
@ -2764,6 +2773,7 @@ static int32_t checkTableClauseFirstToken(SInsertParseContext* pCxt, SVnodeModif
|
|||
}
|
||||
|
||||
if (TK_NK_QUESTION == pTbName->type) {
|
||||
pCxt->stmtTbNameFlag &= ~IS_FIXED_VALUE;
|
||||
pCxt->isStmtBind = true;
|
||||
if (NULL == pCxt->pComCxt->pStmtCb) {
|
||||
return buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", pTbName->z);
|
||||
|
@ -2772,14 +2782,15 @@ static int32_t checkTableClauseFirstToken(SInsertParseContext* pCxt, SVnodeModif
|
|||
char* tbName = NULL;
|
||||
int32_t code = (*pCxt->pComCxt->pStmtCb->getTbNameFn)(pCxt->pComCxt->pStmtCb->pStmt, &tbName);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
pCxt->stmtTbNameFlag |= HAS_BIND_VALUE;
|
||||
pTbName->z = tbName;
|
||||
pTbName->n = strlen(tbName);
|
||||
} else if (code == TSDB_CODE_TSC_STMT_TBNAME_ERROR) {
|
||||
pCxt->preCtbname = true;
|
||||
code = TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
return code;
|
||||
}
|
||||
if (code == TSDB_CODE_TSC_STMT_TBNAME_ERROR) {
|
||||
pCxt->stmtTbNameFlag &= ~HAS_BIND_VALUE;
|
||||
code = TSDB_CODE_SUCCESS;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
if (TK_NK_ID != pTbName->type && TK_NK_STRING != pTbName->type && TK_NK_QUESTION != pTbName->type) {
|
||||
|
@ -2788,26 +2799,34 @@ static int32_t checkTableClauseFirstToken(SInsertParseContext* pCxt, SVnodeModif
|
|||
|
||||
// db.? situation,ensure that the only thing following the '.' mark is '?'
|
||||
char* tbNameAfterDbName = strnchr(pTbName->z, '.', pTbName->n, true);
|
||||
if ((tbNameAfterDbName != NULL) && (*(tbNameAfterDbName + 1) == '?')) {
|
||||
if (tbNameAfterDbName != NULL) {
|
||||
if (*(tbNameAfterDbName + 1) == '?') {
|
||||
pCxt->stmtTbNameFlag &= ~IS_FIXED_VALUE;
|
||||
char* tbName = NULL;
|
||||
if (NULL == pCxt->pComCxt->pStmtCb) {
|
||||
return buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", pTbName->z);
|
||||
}
|
||||
int32_t code = (*pCxt->pComCxt->pStmtCb->getTbNameFn)(pCxt->pComCxt->pStmtCb->pStmt, &tbName);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
pCxt->preCtbname = true;
|
||||
} else {
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
pCxt->stmtTbNameFlag |= HAS_BIND_VALUE;
|
||||
pTbName->z = tbName;
|
||||
pTbName->n = strlen(tbName);
|
||||
}
|
||||
if (code == TSDB_CODE_TSC_STMT_TBNAME_ERROR) {
|
||||
pCxt->stmtTbNameFlag &= ~HAS_BIND_VALUE;
|
||||
code = TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (pCxt->isStmtBind) {
|
||||
if (TK_NK_ID == pTbName->type || (tbNameAfterDbName != NULL && *(tbNameAfterDbName + 1) != '?')) {
|
||||
// In SQL statements, the table name has already been specified.
|
||||
} else {
|
||||
pCxt->stmtTbNameFlag |= IS_FIXED_VALUE;
|
||||
parserWarn("QID:0x%" PRIx64 ", table name is specified in sql, ignore the table name in bind param",
|
||||
pCxt->pComCxt->requestId);
|
||||
*pHasData = true;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (TK_NK_ID == pTbName->type) {
|
||||
pCxt->stmtTbNameFlag |= IS_FIXED_VALUE;
|
||||
}
|
||||
|
||||
*pHasData = true;
|
||||
|
@ -2824,7 +2843,7 @@ static int32_t setStmtInfo(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt)
|
|||
SStmtCallback* pStmtCb = pCxt->pComCxt->pStmtCb;
|
||||
int32_t code = (*pStmtCb->setInfoFn)(pStmtCb->pStmt, pStmt->pTableMeta, tags, &pStmt->targetTableName,
|
||||
pStmt->usingTableProcessing, pStmt->pVgroupsHashObj, pStmt->pTableBlockHashObj,
|
||||
pStmt->usingTableName.tname, pCxt->preCtbname);
|
||||
pStmt->usingTableName.tname, pCxt->stmtTbNameFlag);
|
||||
|
||||
memset(&pCxt->tags, 0, sizeof(pCxt->tags));
|
||||
pStmt->pVgroupsHashObj = NULL;
|
||||
|
@ -2880,9 +2899,6 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pS
|
|||
if (TSDB_CODE_SUCCESS == code && hasData) {
|
||||
code = parseInsertTableClause(pCxt, pStmt, &token);
|
||||
}
|
||||
if (TSDB_CODE_PAR_TABLE_NOT_EXIST == code && pCxt->preCtbname) {
|
||||
code = TSDB_CODE_TSC_STMT_TBNAME_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code && !pCxt->missCache) {
|
||||
|
|
|
@ -1070,10 +1070,11 @@ int32_t buildBoundFields(int32_t numOfBound, int16_t* boundColumns, SSchema* pSc
|
|||
}
|
||||
|
||||
int32_t buildStbBoundFields(SBoundColInfo boundColsInfo, SSchema* pSchema, int32_t* fieldNum, TAOS_FIELD_ALL** fields,
|
||||
STableMeta* pMeta, void* boundTags, bool preCtbname) {
|
||||
STableMeta* pMeta, void* boundTags, uint8_t tbNameFlag) {
|
||||
SBoundColInfo* tags = (SBoundColInfo*)boundTags;
|
||||
bool hastag = tags != NULL;
|
||||
int32_t numOfBound = boundColsInfo.numOfBound + (preCtbname ? 1 : 0);
|
||||
bool hastag = (tags != NULL) && !(tbNameFlag & IS_FIXED_TAG);
|
||||
int32_t numOfBound =
|
||||
boundColsInfo.numOfBound + ((tbNameFlag & IS_FIXED_VALUE) == 0 && (tbNameFlag & USING_CLAUSE) != 0 ? 1 : 0);
|
||||
if (hastag) {
|
||||
numOfBound += tags->mixTagsCols ? 0 : tags->numOfBound;
|
||||
}
|
||||
|
@ -1084,7 +1085,7 @@ int32_t buildStbBoundFields(SBoundColInfo boundColsInfo, SSchema* pSchema, int32
|
|||
return terrno;
|
||||
}
|
||||
|
||||
if (preCtbname && numOfBound != boundColsInfo.numOfBound) {
|
||||
if ((tbNameFlag & IS_FIXED_VALUE) == 0 && (tbNameFlag & USING_CLAUSE) != 0) {
|
||||
(*fields)[idx].field_type = TAOS_FIELD_TBNAME;
|
||||
tstrncpy((*fields)[idx].name, "tbname", sizeof((*fields)[idx].name));
|
||||
(*fields)[idx].type = TSDB_DATA_TYPE_BINARY;
|
||||
|
@ -1188,7 +1189,7 @@ int32_t qBuildStmtColFields(void* pBlock, int32_t* fieldNum, TAOS_FIELD_E** fiel
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qBuildStmtStbColFields(void* pBlock, void* boundTags, bool preCtbname, int32_t* fieldNum,
|
||||
int32_t qBuildStmtStbColFields(void* pBlock, void* boundTags, uint8_t tbNameFlag, int32_t* fieldNum,
|
||||
TAOS_FIELD_ALL** fields) {
|
||||
STableDataCxt* pDataBlock = (STableDataCxt*)pBlock;
|
||||
SSchema* pSchema = getTableColumnSchema(pDataBlock->pMeta);
|
||||
|
@ -1202,7 +1203,7 @@ int32_t qBuildStmtStbColFields(void* pBlock, void* boundTags, bool preCtbname, i
|
|||
}
|
||||
|
||||
CHECK_CODE(buildStbBoundFields(pDataBlock->boundColsInfo, pSchema, fieldNum, fields, pDataBlock->pMeta, boundTags,
|
||||
preCtbname));
|
||||
tbNameFlag));
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue