diff --git a/include/libs/parser/parser.h b/include/libs/parser/parser.h index 7ce4684f07..4fd6fef81a 100644 --- a/include/libs/parser/parser.h +++ b/include/libs/parser/parser.h @@ -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, diff --git a/source/client/inc/clientStmt.h b/source/client/inc/clientStmt.h index 74260c42e0..5d61e8b5d0 100644 --- a/source/client/inc/clientStmt.h +++ b/source/client/inc/clientStmt.h @@ -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]; diff --git a/source/client/src/clientStmt.c b/source/client/src/clientStmt.c index 2d9001d248..4cef20056b 100644 --- a/source/client/src/clientStmt.c +++ b/source/client/src/clientStmt.c @@ -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; diff --git a/source/client/src/clientStmt2.c b/source/client/src/clientStmt2.c index cfd302d895..c4f8702f43 100644 --- a/source/client/src/clientStmt2.c +++ b/source/client/src/clientStmt2.c @@ -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; diff --git a/source/client/test/stmt2Test.cpp b/source/client/test/stmt2Test.cpp index cc54cd55d3..5e50760648 100644 --- a/source/client/test/stmt2Test.cpp +++ b/source/client/test/stmt2Test.cpp @@ -534,7 +534,7 @@ TEST(stmt2Case, insert_ctb_using_get_fields_Test) { printf("support case \n"); // case 1 : test child table already exist { - const char* sql = "INSERT INTO stmt2_testdb_3.t0(ts,b)using stmt2_testdb_3.stb (t1,t2) TAGS(?,?) VALUES (?,?)"; + const char* sql = "INSERT INTO stmt2_testdb_3.t0(ts,b)using stmt2_testdb_3.stb (t1,t2) TAGS(?,?) VALUES(?,?)"; TAOS_FIELD_ALL expectedFields[4] = {{"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG}, {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG}, {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL}, @@ -612,7 +612,7 @@ TEST(stmt2Case, insert_ctb_using_get_fields_Test) { // case 8 : 'db' 'stb' { - const char* sql = "INSERT INTO 'stmt2_testdb_3'.? using 'stmt2_testdb_3'.'stb' (t1,t2) TAGS(?,?) (ts,b)VALUES(?,?)"; + const char* sql = "INSERT INTO 'stmt2_testdb_3'.? using 'stmt2_testdb_3'.'stb' (t1,t2) TAGS(?,?)(ts,b)VALUES(?,?)"; TAOS_FIELD_ALL expectedFields[5] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME}, {"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG}, {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG}, @@ -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& stop_task) { stop_task = true; } -TEST(stmt2Case, async_order) { - std::atomic stop_task(false); - std::thread t(stmt2_async_test, std::ref(stop_task)); +// TEST(stmt2Case, async_order) { +// std::atomic 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(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(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); diff --git a/source/libs/parser/src/parInsertSql.c b/source/libs/parser/src/parInsertSql.c index 81129a6f8f..25e8ccc1c6 100644 --- a/source/libs/parser/src/parInsertSql.c +++ b/source/libs/parser/src/parInsertSql.c @@ -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) == '?')) { - 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; + 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 (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; + } } else { - pTbName->z = tbName; - pTbName->n = strlen(tbName); - } - } - - if (pCxt->isStmtBind) { - if (TK_NK_ID == pTbName->type || (tbNameAfterDbName != NULL && *(tbNameAfterDbName + 1) != '?')) { - // In SQL statements, the table name has already been specified. + 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) { diff --git a/source/libs/parser/src/parInsertStmt.c b/source/libs/parser/src/parInsertStmt.c index 9bb98eb223..2dc9e96264 100644 --- a/source/libs/parser/src/parInsertStmt.c +++ b/source/libs/parser/src/parInsertStmt.c @@ -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; }