From 5ff1da7d4d6be1b743ee8b672a5b52ec4d8ed73f Mon Sep 17 00:00:00 2001 From: "pengrongkun94@qq.com" Date: Thu, 28 Aug 2025 20:24:07 +0800 Subject: [PATCH 1/3] enh : stmt2 checkout tables exist when insert into stb without tag --- source/client/src/clientStmt2.c | 80 ++++++++----- source/client/test/stmt2Test.cpp | 195 +++++++++++++++++++++++++++---- 2 files changed, 227 insertions(+), 48 deletions(-) diff --git a/source/client/src/clientStmt2.c b/source/client/src/clientStmt2.c index 9ab4537f6f2..9293fc404dc 100644 --- a/source/client/src/clientStmt2.c +++ b/source/client/src/clientStmt2.c @@ -238,6 +238,10 @@ static int32_t stmtUpdateBindInfo(TAOS_STMT2* stmt, STableMeta* pTableMeta, void return code; } + if ((tags != NULL && ((SBoundColInfo*)tags)->numOfCols == 0) || !autoCreateTbl) { + pStmt->sql.autoCreateTbl = false; + } + (void)memcpy(&pStmt->bInfo.sname, tbName, sizeof(*tbName)); tstrncpy(pStmt->bInfo.tbFName, tbFName, sizeof(pStmt->bInfo.tbFName)); pStmt->bInfo.tbFName[sizeof(pStmt->bInfo.tbFName) - 1] = 0; @@ -609,6 +613,41 @@ static int32_t stmtTryAddTableVgroupInfo(STscStmt2* pStmt, int32_t* vgId) { return TSDB_CODE_SUCCESS; } +int32_t stmtGetTableMetaAndValidate(STscStmt2* pStmt, uint64_t* uid, uint64_t* suid, int32_t* vgId, int8_t* tableType) { + STableMeta* pTableMeta = NULL; + SRequestConnInfo conn = {.pTrans = pStmt->taos->pAppInfo->pTransporter, + .requestId = pStmt->exec.pRequest->requestId, + .requestObjRefId = pStmt->exec.pRequest->self, + .mgmtEps = getEpSet_s(&pStmt->taos->pAppInfo->mgmtEp)}; + int32_t code = catalogGetTableMeta(pStmt->pCatalog, &conn, &pStmt->bInfo.sname, &pTableMeta); + + pStmt->stat.ctgGetTbMetaNum++; + + if (TSDB_CODE_PAR_TABLE_NOT_EXIST == code) { + STMT2_ELOG("tb %s not exist", pStmt->bInfo.tbFName); + (void)stmtCleanBindInfo(pStmt); + + if (!pStmt->sql.autoCreateTbl) { + STMT2_ELOG("table %s does not exist and autoCreateTbl is disabled", pStmt->bInfo.tbFName); + STMT_ERR_RET(TSDB_CODE_PAR_TABLE_NOT_EXIST); + } + + STMT_ERR_RET(code); + } + + STMT_ERR_RET(code); + + *uid = pTableMeta->uid; + *suid = pTableMeta->suid; + *tableType = pTableMeta->tableType; + pStmt->bInfo.tbVgId = pTableMeta->vgId; + *vgId = pTableMeta->vgId; + + taosMemoryFree(pTableMeta); + + return TSDB_CODE_SUCCESS; +} + static int32_t stmtRebuildDataBlock(STscStmt2* pStmt, STableDataCxt* pDataBlock, STableDataCxt** newBlock, uint64_t uid, uint64_t suid, int32_t vgId) { STMT_ERR_RET(stmtTryAddTableVgroupInfo(pStmt, &vgId)); @@ -655,6 +694,7 @@ static int32_t stmtGetFromCache(STscStmt2* pStmt) { } STMT2_DLOG("no stmt block cache for tb %s", pStmt->bInfo.tbFName); + return TSDB_CODE_SUCCESS; } @@ -686,31 +726,7 @@ static int32_t stmtGetFromCache(STscStmt2* pStmt) { int32_t vgId; int8_t tableType; - STableMeta* pTableMeta = NULL; - SRequestConnInfo conn = {.pTrans = pStmt->taos->pAppInfo->pTransporter, - .requestId = pStmt->exec.pRequest->requestId, - .requestObjRefId = pStmt->exec.pRequest->self, - .mgmtEps = getEpSet_s(&pStmt->taos->pAppInfo->mgmtEp)}; - int32_t code = catalogGetTableMeta(pStmt->pCatalog, &conn, &pStmt->bInfo.sname, &pTableMeta); - - pStmt->stat.ctgGetTbMetaNum++; - - if (TSDB_CODE_PAR_TABLE_NOT_EXIST == code) { - STMT2_DLOG("tb %s not exist", pStmt->bInfo.tbFName); - STMT_ERR_RET(stmtCleanBindInfo(pStmt)); - - STMT_ERR_RET(code); - } - - STMT_ERR_RET(code); - - uid = pTableMeta->uid; - suid = pTableMeta->suid; - tableType = pTableMeta->tableType; - pStmt->bInfo.tbVgId = pTableMeta->vgId; - vgId = pTableMeta->vgId; - - taosMemoryFree(pTableMeta); + STMT_ERR_RET(stmtGetTableMetaAndValidate(pStmt, &uid, &suid, &vgId, &tableType)); uint64_t cacheUid = (TSDB_CHILD_TABLE == tableType) ? suid : uid; @@ -805,11 +821,11 @@ static void stmtAsyncOutput(STscStmt2* pStmt, void* param) { int code = qAppendStmt2TableOutput(pStmt->sql.pQuery, pStmt->sql.pVgHash, &pParam->tblData, pStmt->exec.pCurrBlock, &pStmt->sql.siInfo, pParam->pCreateTbReq); // taosMemoryFree(pParam->pTbData); - (void)atomic_sub_fetch_64(&pStmt->sql.siInfo.tbRemainNum, 1); if (code != TSDB_CODE_SUCCESS) { STMT2_ELOG("async append stmt output failed, tbname:%s, err:%s", pParam->tblData.tbName, tstrerror(code)); pStmt->errCode = code; } + (void)atomic_sub_fetch_64(&pStmt->sql.siInfo.tbRemainNum, 1); } } @@ -1351,6 +1367,18 @@ int stmtSetTbName2(TAOS_STMT2* stmt, const char* tbName) { STMT_ERR_RET(stmtParseSql(pStmt)); } + + if (!pStmt->sql.autoCreateTbl) { + uint64_t uid, suid; + int32_t vgId; + int8_t tableType; + + int32_t code = stmtGetTableMetaAndValidate(pStmt, &uid, &suid, &vgId, &tableType); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + } + } else { tstrncpy(pStmt->bInfo.tbName, tbName, sizeof(pStmt->bInfo.tbName)); pStmt->bInfo.tbName[sizeof(pStmt->bInfo.tbName) - 1] = 0; diff --git a/source/client/test/stmt2Test.cpp b/source/client/test/stmt2Test.cpp index 4de22d408e7..bcae02966f4 100644 --- a/source/client/test/stmt2Test.cpp +++ b/source/client/test/stmt2Test.cpp @@ -264,10 +264,10 @@ void do_stmt(const char* msg, TAOS* taos, TAOS_STMT2_OPTION* option, const char* taos_stmt2_close(stmt); } -TAOS* getConnWithTz(const char *tz){ +TAOS* getConnWithTz(const char* tz) { TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0); ASSERT(pConn != nullptr); - if (tz != NULL){ + if (tz != NULL) { int code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_TIMEZONE, tz); ASSERT(code == 0); } @@ -293,14 +293,14 @@ TEST(stmt2Case, timezone) { do_query(taos, "use stmt2_testdb_0"); TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL}; - TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); ASSERT_NE(stmt, nullptr); int code = taos_stmt2_prepare(stmt, sql, 0); checkError(stmt, code, __FILE__, __LINE__); // stmt2 with timestamp - int64_t ts = 1754611688000; // '2025-08-08 08:08:08' in Asia/Shanghai timezone - int32_t t64_len = sizeof(int64_t); + int64_t ts = 1754611688000; // '2025-08-08 08:08:08' in Asia/Shanghai timezone + int32_t t64_len = sizeof(int64_t); TAOS_STMT2_BIND params = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len, NULL, 1}; TAOS_STMT2_BIND* paramv = ¶ms; TAOS_STMT2_BINDV bindv = {1, NULL, NULL, ¶mv}; @@ -326,14 +326,14 @@ TEST(stmt2Case, timezone) { do_query(taos, "use stmt2_testdb_0"); TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL}; - TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); ASSERT_NE(stmt, nullptr); int code = taos_stmt2_prepare(stmt, sql, 0); checkError(stmt, code, __FILE__, __LINE__); ASSERT_NE(stmt, nullptr); - char* timeStrShanghai = "2025-08-08 08:08:08"; - int32_t timeStrLen = strlen(timeStrShanghai); + char* timeStrShanghai = "2025-08-08 08:08:08"; + int32_t timeStrLen = strlen(timeStrShanghai); TAOS_STMT2_BIND paramsCST = {TSDB_DATA_TYPE_BINARY, timeStrShanghai, &timeStrLen, NULL, 1}; TAOS_STMT2_BIND* paramvCST = ¶msCST; TAOS_STMT2_BINDV bindvCST = {1, NULL, NULL, ¶mvCST}; @@ -357,13 +357,13 @@ TEST(stmt2Case, timezone) { do_query(taos, "use stmt2_testdb_0"); TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL}; - TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); ASSERT_NE(stmt, nullptr); int code = taos_stmt2_prepare(stmt, sql, 0); checkError(stmt, code, __FILE__, __LINE__); - char* timeStrUTC = "2025-08-08 00:08:08"; // '2025-08-08 08:08:08+8' in UTC timezone - int32_t timeStrUTCLen = strlen(timeStrUTC); + char* timeStrUTC = "2025-08-08 00:08:08"; // '2025-08-08 08:08:08+8' in UTC timezone + int32_t timeStrUTCLen = strlen(timeStrUTC); TAOS_STMT2_BIND paramsUTC = {TSDB_DATA_TYPE_BINARY, timeStrUTC, &timeStrUTCLen, NULL, 1}; TAOS_STMT2_BIND* paramvUTC = ¶msUTC; TAOS_STMT2_BINDV bindvUTC = {1, NULL, NULL, ¶mvUTC}; @@ -374,7 +374,7 @@ TEST(stmt2Case, timezone) { TAOS_RES* pRes = taos_stmt2_result(stmt); ASSERT_NE(pRes, nullptr); - int getRecordCounts = 0; + int getRecordCounts = 0; while ((taos_fetch_row(pRes))) { getRecordCounts++; } @@ -1134,13 +1134,19 @@ TEST(stmt2Case, stmt2_stb_insert) { do_stmt("no-interlcace & no-db", taos, &option, "insert into ? using stb (t1,t2)tags(?,?) (ts,b)values(?,?)", 3, 3, 3, true, true); } - { do_stmt("no-interlcace & no-db", taos, &option, "insert into ? values(?,?)", 3, 3, 3, false, true); } + { + do_stmt("no-interlcace & no-db", taos, &option, "insert into ? values(?,?)", 3, 3, 3, false, true); + } // interlace = 1 option = {0, true, true, stmtAsyncQueryCb, param}; - { do_stmt("interlcace & preCreateTB", taos, &option, "insert into ? values(?,?)", 3, 3, 3, false, true); } + { + do_stmt("interlcace & preCreateTB", taos, &option, "insert into ? values(?,?)", 3, 3, 3, false, true); + } option = {0, true, true, NULL, NULL}; - { do_stmt("interlcace & preCreateTB", taos, &option, "insert into ? values(?,?)", 3, 3, 3, false, true); } + { + do_stmt("interlcace & preCreateTB", taos, &option, "insert into ? values(?,?)", 3, 3, 3, false, true); + } // auto create table // interlace = 1 @@ -1802,7 +1808,7 @@ TEST(stmt2Case, stmt2_insert_duplicate) { ASSERT_EQ(getRecordCounts, 2); taos_free_result(pRes); - // do_query(taos, "drop database if exists stmt2_testdb_18"); + do_query(taos, "drop database if exists stmt2_testdb_18"); taos_close(taos); } @@ -2824,7 +2830,7 @@ TEST(stmt2Case, mixed_bind) { } geosFreeBuffer(outputGeom1); - // do_query(taos, "drop database if exists stmt2_testdb_19"); + do_query(taos, "drop database if exists stmt2_testdb_19"); taos_close(taos); } @@ -2897,7 +2903,7 @@ TEST(stmt2Case, usage_error) { TAOS_STMT2_OPTION option = {0}; // get fields error - TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); ASSERT_NE(stmt, nullptr); char* sql = "delete from ntb where ts=?"; int code = taos_stmt2_prepare(stmt, sql, 0); @@ -2924,7 +2930,7 @@ TEST(stmt2Case, usage_error) { ASSERT_STREQ(taos_stmt2_error(stmt), "stmt only support select or insert"); taos_stmt2_close(stmt); - do_query(taos, "DROP DATABASE IF EXISTS stmt2_testdb_14"); + do_query(taos, "DROP DATABASE IF EXISTS stmt2_testdb_17"); taos_close(taos); } @@ -3385,9 +3391,7 @@ TEST(stmt2Case, exec_retry) { do_query(taos, "drop database if exists stmt2_testdb_21"); } -void stmtAsyncQueryCb4(void* param, TAOS_RES* pRes, int code) { - ASSERT_EQ(code, TSDB_CODE_SUCCESS); -} +void stmtAsyncQueryCb4(void* param, TAOS_RES* pRes, int code) { ASSERT_EQ(code, TSDB_CODE_SUCCESS); } TEST(stmt2Case, core) { printf("stmt2Test: select COUNT(1) from (select LAST(operate_time) ...) with params\n"); @@ -3545,4 +3549,151 @@ TEST(stmt2Case, tbname) { } } +// TS-7074 +TEST(stmt2Case, no_tag) { + TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0); + ASSERT_NE(taos, nullptr); + + do_query(taos, "drop database if exists stmt2_testdb_23"); + do_query(taos, "create database IF NOT EXISTS stmt2_testdb_23"); + do_query(taos, "create stable stmt2_testdb_23.stb (ts timestamp, b binary(10)) tags(t1 int, t2 binary(10))"); + do_query( + taos, + "insert into stmt2_testdb_23.tb_exist using stmt2_testdb_23.stb tags(1, 'tag1') values(1591060628000, 'abc')"); + + const char* sql = "INSERT INTO stmt2_testdb_23.stb (tbname,ts,b) VALUES (?,?,?)"; + char* tbname[2] = {"tb_exist", "tb_not_exist"}; + int64_t ts = 1591060628000; + int t64_len = sizeof(int64_t); + char* b = "abc"; + int b_len = 3; + + TAOS_STMT2_BIND params[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len, NULL, 1}, + {TSDB_DATA_TYPE_BINARY, b, &b_len, NULL, 1}}; + // interlace=1 + { + TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL}; + + TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + ASSERT_NE(stmt, nullptr); + printf("case 1 : interlace=1] \n"); + int code = taos_stmt2_prepare(stmt, sql, 0); + checkError(stmt, code, __FILE__, __LINE__); + + TAOS_STMT2_BIND params[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len, NULL, 1}, + {TSDB_DATA_TYPE_BINARY, b, &b_len, NULL, 1}}; + + TAOS_STMT2_BIND* paramv = ¶ms[0]; + TAOS_STMT2_BINDV bindv = {1, &tbname[1], NULL, ¶mv}; + code = taos_stmt2_bind_param(stmt, &bindv, -1); + ASSERT_EQ(code, TSDB_CODE_PAR_TABLE_NOT_EXIST); + + taos_stmt2_close(stmt); + } + + // interlace=0 + { + TAOS_STMT2_OPTION option = {0, false, false, NULL, NULL}; + + TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + ASSERT_NE(stmt, nullptr); + printf("case 2 : interlace=0] \n"); + int code = taos_stmt2_prepare(stmt, sql, 0); + checkError(stmt, code, __FILE__, __LINE__); + + TAOS_STMT2_BIND params[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len, NULL, 1}, + {TSDB_DATA_TYPE_BINARY, b, &b_len, NULL, 1}}; + + TAOS_STMT2_BIND* paramv = ¶ms[0]; + TAOS_STMT2_BINDV bindv = {1, &tbname[1], NULL, ¶mv}; + code = taos_stmt2_bind_param(stmt, &bindv, -1); + ASSERT_EQ(code, TSDB_CODE_PAR_TABLE_NOT_EXIST); + + taos_stmt2_close(stmt); + } + + // interlace=0 && first table exist + { + TAOS_STMT2_OPTION option = {0, false, false, NULL, NULL}; + + TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + ASSERT_NE(stmt, nullptr); + printf("case 3 : interlace=0 && first table exist] \n"); + int code = taos_stmt2_prepare(stmt, sql, 0); + checkError(stmt, code, __FILE__, __LINE__); + + TAOS_STMT2_BIND* paramv[2] = {¶ms[0], ¶ms[0]}; + TAOS_STMT2_BINDV bindv = {2, &tbname[0], NULL, ¶mv[0]}; + code = taos_stmt2_bind_param(stmt, &bindv, -1); + ASSERT_EQ(code, TSDB_CODE_PAR_TABLE_NOT_EXIST); + + taos_stmt2_close(stmt); + } + // interlace=1 && first table exist + { + TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL}; + + TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + ASSERT_NE(stmt, nullptr); + printf("case 4 : interlace=1 && first table exist] \n"); + int code = taos_stmt2_prepare(stmt, sql, 0); + checkError(stmt, code, __FILE__, __LINE__); + + TAOS_STMT2_BIND* paramv[2] = {¶ms[0], ¶ms[0]}; + TAOS_STMT2_BINDV bindv = {2, &tbname[0], NULL, ¶mv[0]}; + code = taos_stmt2_bind_param(stmt, &bindv, -1); + checkError(stmt, code, __FILE__, __LINE__); + + code = taos_stmt2_exec(stmt, NULL); + ASSERT_EQ(code, TSDB_CODE_PAR_TABLE_NOT_EXIST); + + taos_stmt2_close(stmt); + } + + int t1 = 1; + char* t2 = "abc"; + int t1_len = sizeof(int); + int t2_len = 3; + TAOS_STMT2_BIND tag[2] = {{TSDB_DATA_TYPE_INT, &t1, &t1_len, NULL, 1}, {TSDB_DATA_TYPE_BINARY, t2, &t2_len, NULL, 1}}; + TAOS_STMT2_BIND* pTag = &tag[0]; + + // interlace=0 && with tag + { + TAOS_STMT2_OPTION option = {0, false, false, NULL, NULL}; + + TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + ASSERT_NE(stmt, nullptr); + printf("case 5 : interlace=0 && with tag] \n"); + int code = taos_stmt2_prepare(stmt, sql, 0); + checkError(stmt, code, __FILE__, __LINE__); + + TAOS_STMT2_BIND* paramv[2] = {¶ms[0], ¶ms[0]}; + TAOS_STMT2_BINDV bindv = {1, &tbname[1], &pTag, ¶mv[0]}; + code = taos_stmt2_bind_param(stmt, &bindv, -1); + ASSERT_EQ(code, TSDB_CODE_PAR_TABLE_NOT_EXIST); + + taos_stmt2_close(stmt); + } + + // interlace=1 && with tag + { + TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL}; + + TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + ASSERT_NE(stmt, nullptr); + printf("case 6 : interlace=1 && with tag] \n"); + int code = taos_stmt2_prepare(stmt, sql, 0); + checkError(stmt, code, __FILE__, __LINE__); + + TAOS_STMT2_BIND* paramv[2] = {¶ms[0], ¶ms[0]}; + TAOS_STMT2_BINDV bindv = {1, &tbname[1], &pTag, ¶mv[0]}; + code = taos_stmt2_bind_param(stmt, &bindv, -1); + ASSERT_EQ(code, TSDB_CODE_PAR_TABLE_NOT_EXIST); + + taos_stmt2_close(stmt); + } + do_query(taos, "drop database if exists stmt2_testdb_23"); + taos_close(taos); +} + #pragma GCC diagnostic pop From fedccc943679fb090d193384c3658f4aa7462a3d Mon Sep 17 00:00:00 2001 From: "pengrongkun94@qq.com" Date: Fri, 29 Aug 2025 14:02:06 +0800 Subject: [PATCH 2/3] fix CI --- .../uncatalog/army/tools/benchmark/basic/json/TD-32913-2.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cases/uncatalog/army/tools/benchmark/basic/json/TD-32913-2.json b/test/cases/uncatalog/army/tools/benchmark/basic/json/TD-32913-2.json index e7291466382..4cc92c3d2f8 100644 --- a/test/cases/uncatalog/army/tools/benchmark/basic/json/TD-32913-2.json +++ b/test/cases/uncatalog/army/tools/benchmark/basic/json/TD-32913-2.json @@ -32,7 +32,7 @@ "auto_create_table": "no", "batch_create_tbl_num": 500, "data_source": "rand", - "insert_mode": "stmt", + "insert_mode": "stmt2", "non_stop_mode": "no", "line_protocol": "line", "insert_rows": 1000, From 0849cad72c6b5b30abd9359b7cf26c4fca546ce3 Mon Sep 17 00:00:00 2001 From: "pengrongkun94@qq.com" Date: Fri, 29 Aug 2025 20:46:26 +0800 Subject: [PATCH 3/3] fix some performance --- source/client/src/clientStmt2.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/source/client/src/clientStmt2.c b/source/client/src/clientStmt2.c index 9293fc404dc..eaae2e3e2cb 100644 --- a/source/client/src/clientStmt2.c +++ b/source/client/src/clientStmt2.c @@ -1366,16 +1366,15 @@ int stmtSetTbName2(TAOS_STMT2* stmt, const char* tbName) { pStmt->bInfo.tbName[sizeof(pStmt->bInfo.tbName) - 1] = 0; STMT_ERR_RET(stmtParseSql(pStmt)); - } - - if (!pStmt->sql.autoCreateTbl) { - uint64_t uid, suid; - int32_t vgId; - int8_t tableType; - - int32_t code = stmtGetTableMetaAndValidate(pStmt, &uid, &suid, &vgId, &tableType); - if (code != TSDB_CODE_SUCCESS) { - return code; + if (!pStmt->sql.autoCreateTbl) { + uint64_t uid, suid; + int32_t vgId; + int8_t tableType; + + int32_t code = stmtGetTableMetaAndValidate(pStmt, &uid, &suid, &vgId, &tableType); + if (code != TSDB_CODE_SUCCESS) { + return code; + } } }