-
Notifications
You must be signed in to change notification settings - Fork 5k
feat:stmt2 query free result by adapter #34155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -1878,11 +1878,26 @@ TEST(stmt2Case, query) { | |||||||||||||||||||||||||||
| 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}; | ||||||||||||||||||||||||||||
| code = taos_stmt2_bind_param(stmt, &bindv, -1); | ||||||||||||||||||||||||||||
| checkError(stmt, code); | ||||||||||||||||||||||||||||
| for (int i = 0; i < 3; i++) { | ||||||||||||||||||||||||||||
| code = taos_stmt2_bind_param(stmt, &bindv, -1); | ||||||||||||||||||||||||||||
| checkError(stmt, code); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| taos_stmt2_exec(stmt, NULL); | ||||||||||||||||||||||||||||
| checkError(stmt, code); | ||||||||||||||||||||||||||||
| taos_stmt2_exec(stmt, NULL); | ||||||||||||||||||||||||||||
| checkError(stmt, code); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| TAOS_RES* pRes = taos_stmt2_result(stmt); | ||||||||||||||||||||||||||||
| ASSERT_NE(pRes, nullptr); | ||||||||||||||||||||||||||||
| TAOS_ROW row = taos_fetch_row(pRes); | ||||||||||||||||||||||||||||
| ASSERT_NE(row, nullptr); | ||||||||||||||||||||||||||||
| ASSERT_EQ(strncmp((char*)row[0], "tb1", 3), 0); | ||||||||||||||||||||||||||||
| ASSERT_EQ(strncmp((char*)row[1], "abc", 3), 0); | ||||||||||||||||||||||||||||
| ASSERT_EQ(strncmp((char*)row[2], "abc", 3), 0); | ||||||||||||||||||||||||||||
| row = taos_fetch_row(pRes); | ||||||||||||||||||||||||||||
| ASSERT_NE(row, nullptr); | ||||||||||||||||||||||||||||
| ASSERT_EQ(strncmp((char*)row[0], "tb2", 3), 0); | ||||||||||||||||||||||||||||
| ASSERT_EQ(strncmp((char*)row[1], "xyz", 3), 0); | ||||||||||||||||||||||||||||
| ASSERT_EQ(strncmp((char*)row[2], "abc", 3), 0); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| taos_stmt2_close(stmt); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
@@ -1913,16 +1928,19 @@ TEST(stmt2Case, query) { | |||||||||||||||||||||||||||
| 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}; | ||||||||||||||||||||||||||||
| code = taos_stmt2_bind_param(stmt, &bindv, -1); | ||||||||||||||||||||||||||||
| checkError(stmt, code); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| taos_stmt2_exec(stmt, NULL); | ||||||||||||||||||||||||||||
| checkError(stmt, code); | ||||||||||||||||||||||||||||
| for (int i = 0; i < 3; i++) { | ||||||||||||||||||||||||||||
| code = taos_stmt2_bind_param(stmt, &bindv, -1); | ||||||||||||||||||||||||||||
| checkError(stmt, code); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| taos_stmt2_exec(stmt, NULL); | ||||||||||||||||||||||||||||
| checkError(stmt, code); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| tsem_wait(&aa->sem); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| tsem_wait(&aa->sem); | ||||||||||||||||||||||||||||
| tsem_destroy(&aa->sem); | ||||||||||||||||||||||||||||
| taosMemoryFree(aa); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| taos_stmt2_close(stmt); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
@@ -2018,6 +2036,124 @@ TEST(stmt2Case, query) { | |||||||||||||||||||||||||||
| taos_close(taos); | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| TEST(stmt2Case, query_use_adapter) { | ||||||||||||||||||||||||||||
| TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0); | ||||||||||||||||||||||||||||
| ASSERT_NE(taos, nullptr); | ||||||||||||||||||||||||||||
| int32_t code = taos_options(TSDB_OPTION_USE_ADAPTER, "true"); | ||||||||||||||||||||||||||||
| ASSERT_EQ(code, TSDB_CODE_SUCCESS); | ||||||||||||||||||||||||||||
| do_query(taos, "drop database if exists stmt2_testdb_37"); | ||||||||||||||||||||||||||||
| do_query(taos, "create database IF NOT EXISTS stmt2_testdb_37"); | ||||||||||||||||||||||||||||
| do_query(taos, "create stable stmt2_testdb_37.stb (ts timestamp, b binary(10)) tags(t1 int, t2 binary(10))"); | ||||||||||||||||||||||||||||
| do_query(taos, | ||||||||||||||||||||||||||||
| "insert into stmt2_testdb_37.tb1 using stmt2_testdb_37.stb tags(1,'abc') values(1591060628000, " | ||||||||||||||||||||||||||||
| "'abc'),(1591060628001,'def'),(1591060628002, 'hij')"); | ||||||||||||||||||||||||||||
| do_query(taos, | ||||||||||||||||||||||||||||
| "insert into stmt2_testdb_37.tb2 using stmt2_testdb_37.stb tags(2,'xyz') values(1591060628000, " | ||||||||||||||||||||||||||||
| "'abc'),(1591060628001,'def'),(1591060628004, 'hij')"); | ||||||||||||||||||||||||||||
| do_query(taos, "use stmt2_testdb_37"); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| // sync query | ||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||
| TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL}; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); | ||||||||||||||||||||||||||||
| ASSERT_NE(stmt, nullptr); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const char* sql = "select tbname,t2,b from stmt2_testdb_37.stb where ts = ? order by tbname"; | ||||||||||||||||||||||||||||
| int code = taos_stmt2_prepare(stmt, sql, 0); | ||||||||||||||||||||||||||||
| checkError(stmt, code); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| for (int i = 0; i < 3; i++) { | ||||||||||||||||||||||||||||
| int fieldNum = 0; | ||||||||||||||||||||||||||||
| TAOS_FIELD_ALL* pFields = NULL; | ||||||||||||||||||||||||||||
| code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields); | ||||||||||||||||||||||||||||
| checkError(stmt, code); | ||||||||||||||||||||||||||||
| ASSERT_EQ(fieldNum, 1); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
Comment on lines
+2066
to
+2072
|
||||||||||||||||||||||||||||
| for (int i = 0; i < 3; i++) { | |
| int fieldNum = 0; | |
| TAOS_FIELD_ALL* pFields = NULL; | |
| code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields); | |
| checkError(stmt, code); | |
| ASSERT_EQ(fieldNum, 1); | |
| int fieldNum = 0; | |
| TAOS_FIELD_ALL* pFields = NULL; | |
| code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields); | |
| checkError(stmt, code); | |
| ASSERT_EQ(fieldNum, 1); | |
| for (int i = 0; i < 3; i++) { |
Copilot
AI
Jan 4, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The taos_stmt2_get_fields call should be moved outside the loop. The field metadata doesn't change between iterations of the same prepared statement, so calling it on every iteration is inefficient and inconsistent with the pattern used in the non-adapter test (lines 1920-1924) where it's called once before the loop.
| for (int i = 0; i < 3; i++) { | |
| int fieldNum = 0; | |
| TAOS_FIELD_ALL* pFields = NULL; | |
| code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields); | |
| checkError(stmt, code); | |
| ASSERT_EQ(fieldNum, 1); | |
| int fieldNum = 0; | |
| TAOS_FIELD_ALL* pFields = NULL; | |
| code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields); | |
| checkError(stmt, code); | |
| ASSERT_EQ(fieldNum, 1); | |
| for (int i = 0; i < 3; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The assertions for the content of the second fetched row are missing here. The corresponding synchronous test case includes these assertions. To ensure the async query logic is fully tested, please add assertions for the second row's data, similar to the sync test case.
row = taos_fetch_row(pRes);
ASSERT_NE(row, nullptr);
ASSERT_EQ(strncmp((char*)row[0], "tb2", 3), 0);
ASSERT_EQ(strncmp((char*)row[1], "xyz", 3), 0);
ASSERT_EQ(strncmp((char*)row[2], "abc", 3), 0);
Copilot
AI
Jan 4, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The result from taos_stmt2_result should be freed using taos_free_result to prevent a memory leak. Each iteration returns a result object that needs to be explicitly freed. Only the last iteration frees its result, leaving the first two iterations' results leaked.
Copilot
AI
Jan 4, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incomplete result validation: only one row is fetched and validated, but the sync test validates two rows (tb1 and tb2). The second row should also be validated with assertions to ensure consistent test coverage between sync and async modes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The result from taos_stmt2_result should be freed using taos_free_result to prevent a memory leak. In the loop, each iteration calls taos_stmt2_result which returns a new result object, but only the last one gets implicitly freed when the statement is closed. The previous iterations' result objects are leaked.