• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / TDengine / #4987

16 Mar 2026 12:26PM UTC coverage: 73.883% (+36.6%) from 37.305%
#4987

push

travis-ci

web-flow
feat: support secure delete option. (#34591)

209 of 391 new or added lines in 24 files covered. (53.45%)

3062 existing lines in 140 files now uncovered.

261133 of 353439 relevant lines covered (73.88%)

121262425.02 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.95
/source/client/test/stmt2Test.cpp
1
/*
2
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
3
 *
4
 * This program is free software: you can use, redistribute, and/or modify
5
 * it under the terms of the GNU Affero General Public License, version 3
6
 * or later ("AGPL"), as published by the Free Software Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
 * FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * You should have received a copy of the GNU Affero General Public License
13
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14
 */
15

16
#include <gtest/gtest.h>
17
#include <string.h>
18
#include <atomic>
19
#include <chrono>
20
#include <thread>
21
#include "clientInt.h"
22
#include "geosWrapper.h"
23
#include "osSemaphore.h"
24
#include "taoserror.h"
25
#include "tglobal.h"
26
#include "thash.h"
27

28
#pragma GCC diagnostic push
29
#pragma GCC diagnostic ignored "-Wwrite-strings"
30
#pragma GCC diagnostic ignored "-Wunused-function"
31
#pragma GCC diagnostic ignored "-Wunused-variable"
32
#pragma GCC diagnostic ignored "-Wsign-compare"
33

34
#include "../inc/clientStmt.h"
35
#include "../inc/clientStmt2.h"
36
#include "executor.h"
37
#include "taos.h"
38

39
const char* STMT_STATUS_NAMES[] = {
40
    "INVALID",   "STMT_INIT",     "STMT_PREPARE",   "STMT_SETTBNAME", "STMT_SETTAGS", "STMT_FETCH_FIELDS",
41
    "STMT_BIND", "STMT_BIND_COL", "STMT_ADD_BATCH", "STMT_EXECUTE",   "STMT_MAX",
42
};
43

44
namespace {
45
void checkError(TAOS_STMT2* stmt, int code, const char* file, int line) {
55,488✔
46
  if (code != TSDB_CODE_SUCCESS) {
55,488✔
UNCOV
47
    STscStmt2* pStmt = (STscStmt2*)stmt;
×
UNCOV
48
    if (pStmt == nullptr || pStmt->sql.sqlStr == nullptr) {
×
UNCOV
49
      printf("[STMT2 FAILED]\n  status : %s\n  errcode : %X\n  errstr : %s\n", STMT_STATUS_NAMES[pStmt->sql.status],
×
50
             code, taos_stmt2_error(stmt));
51
    } else {
52
      printf("[STMT2 FAILED]\n  sql : %s\n  stats : %s\n  errcode : %X\n  errstr : %s\n", pStmt->sql.sqlStr,
×
53
             STMT_STATUS_NAMES[pStmt->sql.status], code, taos_stmt2_error(stmt));
×
54
    }
UNCOV
55
    printf("  file : %s\n  line : %d\n", file, line);
×
UNCOV
56
    ASSERT_EQ(code, TSDB_CODE_SUCCESS);
×
57
  }
58
}
59

60
typedef struct AsyncArgs {
61
  int    async_affected_rows;
62
  tsem_t sem;
63
} AsyncArgs;
64

65
void stmtAsyncQueryCb(void* param, TAOS_RES* pRes, int code) {
1,440✔
66
  ((AsyncArgs*)param)->async_affected_rows = taos_affected_rows(pRes);
1,440✔
67
  ASSERT_EQ(tsem_post(&((AsyncArgs*)param)->sem), TSDB_CODE_SUCCESS);
1,440✔
68
  return;
1,440✔
69
}
70

71
void getFieldsSuccess(TAOS* taos, const char* sql, TAOS_FIELD_ALL* expectedFields, int expectedFieldNum) {
2,592✔
72
  TAOS_STMT2_OPTION option = {0};
2,592✔
73
  TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
2,592✔
74
  ASSERT_NE(stmt, nullptr);
2,592✔
75
  int code = taos_stmt2_prepare(stmt, sql, 0);
2,592✔
76
  checkError(stmt, code, __FILE__, __LINE__);
2,592✔
77

78
  int             fieldNum = 0;
2,592✔
79
  TAOS_FIELD_ALL* pFields = NULL;
2,592✔
80
  code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
2,592✔
81
  checkError(stmt, code, __FILE__, __LINE__);
2,592✔
82
  ASSERT_EQ(fieldNum, expectedFieldNum);
2,592✔
83

84
  for (int i = 0; i < fieldNum; i++) {
19,296✔
85
    ASSERT_STREQ(pFields[i].name, expectedFields[i].name);
16,704✔
86
    ASSERT_EQ(pFields[i].type, expectedFields[i].type);
16,704✔
87
    ASSERT_EQ(pFields[i].field_type, expectedFields[i].field_type);
16,704✔
88
    ASSERT_EQ(pFields[i].precision, expectedFields[i].precision);
16,704✔
89
    ASSERT_EQ(pFields[i].bytes, expectedFields[i].bytes);
16,704✔
90
    ASSERT_EQ(pFields[i].scale, expectedFields[i].scale);
16,704✔
91
  }
92
  taos_stmt2_free_fields(stmt, pFields);
2,592✔
93
  taos_stmt2_close(stmt);
2,592✔
94
}
95

96
void getFieldsError(TAOS* taos, const char* sql, int errorCode, const char* errorMsg) {
1,536✔
97
  TAOS_STMT2_OPTION option = {0};
1,536✔
98
  TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
1,536✔
99
  ASSERT_NE(stmt, nullptr);
1,536✔
100
  int code = taos_stmt2_prepare(stmt, sql, 0);
1,536✔
101
  checkError(stmt, code, __FILE__, __LINE__);
1,536✔
102

103
  int             fieldNum = 0;
1,536✔
104
  TAOS_FIELD_ALL* pFields = NULL;
1,536✔
105
  code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
1,536✔
106
  ASSERT_EQ(code, errorCode);
1,536✔
107
  ASSERT_STREQ(taos_stmt2_error(stmt), errorMsg);
1,536✔
108
  taos_stmt2_free_fields(stmt, pFields);
1,536✔
109
  taos_stmt2_close(stmt);
1,536✔
110
}
111

112
void getQueryFields(TAOS* taos, const char* sql, int expectedFieldNum) {
192✔
113
  TAOS_STMT2_OPTION option = {0};
192✔
114
  TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
192✔
115
  ASSERT_NE(stmt, nullptr);
192✔
116
  int code = taos_stmt2_prepare(stmt, sql, 0);
192✔
117
  checkError(stmt, code, __FILE__, __LINE__);
192✔
118

119
  int             fieldNum = 0;
192✔
120
  TAOS_FIELD_ALL* pFields = NULL;
192✔
121
  code = taos_stmt2_get_fields(stmt, &fieldNum, NULL);
192✔
122
  checkError(stmt, code, __FILE__, __LINE__);
192✔
123
  ASSERT_EQ(fieldNum, expectedFieldNum);
192✔
124
  taos_stmt2_free_fields(stmt, NULL);
192✔
125
  taos_stmt2_close(stmt);
192✔
126
}
127

128
void do_query(TAOS* taos, const char* sql) {
31,776✔
129
  TAOS_RES* result = taos_query(taos, sql);
31,776✔
130
  // printf("sql: %s\n", sql);
131
  int code = taos_errno(result);
31,776✔
132
  while (code == TSDB_CODE_MND_DB_IN_CREATING || code == TSDB_CODE_MND_DB_IN_DROPPING) {
31,776✔
133
    taosMsleep(2000);
×
134
    result = taos_query(taos, sql);
×
135
    code = taos_errno(result);
×
136
  }
137
  if (code != TSDB_CODE_SUCCESS) {
31,776✔
138
    printf("query failen  sql : %s\n  errstr : %s\n", sql, taos_errstr(result));
×
139
    ASSERT_EQ(taos_errno(result), TSDB_CODE_SUCCESS);
×
140
  }
141
  taos_free_result(result);
31,776✔
142
}
143

144
void do_error_query(TAOS* taos, const char* sql, int errorCode) {
96✔
145
  TAOS_RES* result = taos_query(taos, sql);
96✔
146
  // printf("sql: %s\n", sql);
147
  int code = taos_errno(result);
96✔
148
  while (code == TSDB_CODE_MND_DB_IN_CREATING || code == TSDB_CODE_MND_DB_IN_DROPPING) {
96✔
149
    taosMsleep(2000);
×
150
    result = taos_query(taos, sql);
×
151
    code = taos_errno(result);
×
152
  }
153
  ASSERT_EQ(code, errorCode);
96✔
154
  taos_free_result(result);
96✔
155
}
156

157
void do_stmt(const char* msg, TAOS* taos, TAOS_STMT2_OPTION* option, const char* sql, int CTB_NUMS, int ROW_NUMS,
1,440✔
158
             int CYC_NUMS, bool hastags, bool createTable) {
159
  printf("stmt2 [%s] : %s\n", msg, sql);
1,440✔
160
  do_query(taos, "drop database if exists stmt2_testdb_1");
1,440✔
161
  do_query(taos, "create database IF NOT EXISTS stmt2_testdb_1");
1,440✔
162
  do_query(taos, "create stable stmt2_testdb_1.stb (ts timestamp, b binary(10)) tags(t1 int, t2 binary(10))");
1,440✔
163

164
  TAOS_STMT2* stmt = taos_stmt2_init(taos, option);
1,440✔
165
  ASSERT_NE(stmt, nullptr);
1,440✔
166
  int code = taos_stmt2_prepare(stmt, sql, 0);
1,440✔
167
  checkError(stmt, code, __FILE__, __LINE__);
1,440✔
168
  int total_affected = 0;
1,440✔
169

170
  // tbname
171
  char** tbs = (char**)taosMemoryMalloc(CTB_NUMS * sizeof(char*));
1,440✔
172
  for (int i = 0; i < CTB_NUMS; i++) {
5,760✔
173
    tbs[i] = (char*)taosMemoryMalloc(sizeof(char) * 20);
4,320✔
174
    sprintf(tbs[i], "ctb_%d", i);
4,320✔
175
    if (createTable) {
4,320✔
176
      char tmp[100];
177
      sprintf(tmp, "create table stmt2_testdb_1.%s using stmt2_testdb_1.stb tags(0, 'after')", tbs[i]);
2,880✔
178
      do_query(taos, tmp);
2,880✔
179
    }
180
  }
181
  for (int r = 0; r < CYC_NUMS; r++) {
5,760✔
182
    // col params
183
    int64_t** ts = (int64_t**)taosMemoryMalloc(CTB_NUMS * sizeof(int64_t*));
4,320✔
184
    char**    b = (char**)taosMemoryMalloc(CTB_NUMS * sizeof(char*));
4,320✔
185
    int*      ts_len = (int*)taosMemoryMalloc(ROW_NUMS * sizeof(int));
4,320✔
186
    int*      b_len = (int*)taosMemoryMalloc(ROW_NUMS * sizeof(int));
4,320✔
187
    for (int i = 0; i < ROW_NUMS; i++) {
17,280✔
188
      ts_len[i] = sizeof(int64_t);
12,960✔
189
      b_len[i] = 1;
12,960✔
190
    }
191
    for (int i = 0; i < CTB_NUMS; i++) {
17,280✔
192
      ts[i] = (int64_t*)taosMemoryMalloc(ROW_NUMS * sizeof(int64_t));
12,960✔
193
      b[i] = (char*)taosMemoryMalloc(ROW_NUMS * sizeof(char));
12,960✔
194
      for (int j = 0; j < ROW_NUMS; j++) {
51,840✔
195
        ts[i][j] = 1591060628000 + r * 100000 + j;
38,880✔
196
        b[i][j] = 'a' + j;
38,880✔
197
      }
198
    }
199
    // tag params
200
    int t1 = 0;
4,320✔
201
    int t1len = sizeof(int);
4,320✔
202
    int t2len = 3;
4,320✔
203
    //   TAOS_STMT2_BIND* tagv[2] = {&tags[0][0], &tags[1][0]};
204

205
    // bind params
206
    TAOS_STMT2_BIND** paramv = (TAOS_STMT2_BIND**)taosMemoryMalloc(CTB_NUMS * sizeof(TAOS_STMT2_BIND*));
4,320✔
207
    TAOS_STMT2_BIND** tags = NULL;
4,320✔
208
    if (hastags) {
4,320✔
209
      tags = (TAOS_STMT2_BIND**)taosMemoryMalloc(CTB_NUMS * sizeof(TAOS_STMT2_BIND*));
2,592✔
210
      for (int i = 0; i < CTB_NUMS; i++) {
10,368✔
211
        // create tags
212
        tags[i] = (TAOS_STMT2_BIND*)taosMemoryMalloc(2 * sizeof(TAOS_STMT2_BIND));
7,776✔
213
        tags[i][0] = {TSDB_DATA_TYPE_INT, &t1, &t1len, NULL, 0};
7,776✔
214
        tags[i][1] = {TSDB_DATA_TYPE_BINARY, (void*)"after", &t2len, NULL, 0};
7,776✔
215
      }
216
    }
217

218
    for (int i = 0; i < CTB_NUMS; i++) {
17,280✔
219
      // create col params
220
      paramv[i] = (TAOS_STMT2_BIND*)taosMemoryMalloc(2 * sizeof(TAOS_STMT2_BIND));
12,960✔
221
      paramv[i][0] = {TSDB_DATA_TYPE_TIMESTAMP, &ts[i][0], &ts_len[0], NULL, ROW_NUMS};
12,960✔
222
      paramv[i][1] = {TSDB_DATA_TYPE_BINARY, &b[i][0], &b_len[0], NULL, ROW_NUMS};
12,960✔
223
    }
224
    // bind
225
    TAOS_STMT2_BINDV bindv = {CTB_NUMS, tbs, tags, paramv};
4,320✔
226
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
4,320✔
227
    checkError(stmt, code, __FILE__, __LINE__);
4,320✔
228

229
    // exec
230
    int affected = 0;
4,320✔
231
    code = taos_stmt2_exec(stmt, &affected);
4,320✔
232
    checkError(stmt, code, __FILE__, __LINE__);
4,320✔
233
    if (option->asyncExecFn == NULL) {
4,320✔
234
      total_affected += affected;
3,168✔
235
    } else {
236
      AsyncArgs* params = (AsyncArgs*)option->userdata;
1,152✔
237
      code = tsem_wait(&params->sem);
1,152✔
238
      ASSERT_EQ(code, TSDB_CODE_SUCCESS);
1,152✔
239
      total_affected += params->async_affected_rows;
1,152✔
240
    }
241

242
    for (int i = 0; i < CTB_NUMS; i++) {
17,280✔
243
      if (hastags) {
12,960✔
244
        taosMemoryFree(tags[i]);
7,776✔
245
      }
246
      taosMemoryFree(paramv[i]);
12,960✔
247
      taosMemoryFree(ts[i]);
12,960✔
248
      taosMemoryFree(b[i]);
12,960✔
249
    }
250
    taosMemoryFree(ts);
4,320✔
251
    taosMemoryFree(b);
4,320✔
252
    taosMemoryFree(ts_len);
4,320✔
253
    taosMemoryFree(b_len);
4,320✔
254
    taosMemoryFree(paramv);
4,320✔
255
    if (hastags) {
4,320✔
256
      taosMemoryFree(tags);
2,592✔
257
    }
258
  }
259
  ASSERT_EQ(total_affected, CYC_NUMS * ROW_NUMS * CTB_NUMS);
1,440✔
260
  for (int i = 0; i < CTB_NUMS; i++) {
5,760✔
261
    taosMemoryFree(tbs[i]);
4,320✔
262
  }
263
  taosMemoryFree(tbs);
1,440✔
264

265
  taos_stmt2_close(stmt);
1,440✔
266
}
267

268
TAOS* getConnWithTz(const char* tz) {
288✔
269
  TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
288✔
270
  ASSERT(pConn != nullptr);
288✔
271
  if (tz != NULL) {
288✔
272
    int code = taos_options_connection(pConn, TSDB_OPTION_CONNECTION_TIMEZONE, tz);
288✔
273
    ASSERT(code == 0);
288✔
274
  }
275
  return pConn;
288✔
276
}
277

278
}  // namespace
279

280
int main(int argc, char** argv) {
96✔
281
  testing::InitGoogleTest(&argc, argv);
96✔
282
  return RUN_ALL_TESTS();
96✔
283
}
284

285
TEST(stmt2Case, timezone) {
384✔
286
  const char* sql = "select * from stmt2_testdb_0.tt where ts = ?";
96✔
287
  // prepare data and check
288
  {
289
    TAOS* taos = getConnWithTz("UTC-8");  // Asia/Shanghai timezone
96✔
290
    do_query(taos, "drop database if exists stmt2_testdb_0");
96✔
291
    do_query(taos, "create database IF NOT EXISTS stmt2_testdb_0");
96✔
292
    do_query(taos, "create table stmt2_testdb_0.tt (ts timestamp, val int)");
96✔
293
    do_query(taos, "insert into stmt2_testdb_0.tt values('2025-08-08 08:08:08', 88)");
96✔
294
    do_query(taos, "use stmt2_testdb_0");
96✔
295

296
    TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
297
    TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
298
    ASSERT_NE(stmt, nullptr);
96✔
299
    int code = taos_stmt2_prepare(stmt, sql, 0);
96✔
300
    checkError(stmt, code, __FILE__, __LINE__);
96✔
301

302
    // stmt2 with timestamp
303
    int64_t          ts = 1754611688000;  // '2025-08-08 08:08:08' in Asia/Shanghai timezone
96✔
304
    int32_t          t64_len = sizeof(int64_t);
96✔
305
    TAOS_STMT2_BIND  params = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len, NULL, 1};
96✔
306
    TAOS_STMT2_BIND* paramv = &params;
96✔
307
    TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &paramv};
96✔
308
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
309
    checkError(stmt, code, __FILE__, __LINE__);
96✔
310
    code = taos_stmt2_exec(stmt, NULL);
96✔
311
    checkError(stmt, code, __FILE__, __LINE__);
96✔
312

313
    TAOS_RES* pRes = taos_stmt2_result(stmt);
96✔
314
    ASSERT_NE(pRes, nullptr);
96✔
315
    int getRecordCounts = 0;
96✔
316
    while ((taos_fetch_row(pRes))) {
192✔
317
      getRecordCounts++;
96✔
318
    }
319
    ASSERT_EQ(getRecordCounts, 1);
96✔
320
    taos_stmt2_close(stmt);
96✔
321
    taos_close(taos);
96✔
322
  }
323

324
  // stmt2 with time str in Asia/Shanghai timezone
325
  {
326
    TAOS* taos = getConnWithTz("UTC-8");
96✔
327
    do_query(taos, "use stmt2_testdb_0");
96✔
328

329
    TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
330
    TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
331
    ASSERT_NE(stmt, nullptr);
96✔
332
    int code = taos_stmt2_prepare(stmt, sql, 0);
96✔
333
    checkError(stmt, code, __FILE__, __LINE__);
96✔
334

335
    ASSERT_NE(stmt, nullptr);
96✔
336
    const char*      timeStrShanghai = "2025-08-08 08:08:08";
96✔
337
    int32_t          timeStrLen = strlen(timeStrShanghai);
96✔
338
    TAOS_STMT2_BIND  paramsCST = {TSDB_DATA_TYPE_BINARY, (void*)timeStrShanghai, &timeStrLen, NULL, 1};
96✔
339
    TAOS_STMT2_BIND* paramvCST = &paramsCST;
96✔
340
    TAOS_STMT2_BINDV bindvCST = {1, NULL, NULL, &paramvCST};
96✔
341
    code = taos_stmt2_bind_param(stmt, &bindvCST, -1);
96✔
342
    checkError(stmt, code, __FILE__, __LINE__);
96✔
343
    code = taos_stmt2_exec(stmt, NULL);
96✔
344
    checkError(stmt, code, __FILE__, __LINE__);
96✔
345

346
    TAOS_RES* pRes = taos_stmt2_result(stmt);
96✔
347
    ASSERT_NE(pRes, nullptr);
96✔
348
    int getRecordCounts = 0;
96✔
349
    while ((taos_fetch_row(pRes))) {
192✔
350
      getRecordCounts++;
96✔
351
    }
352
    ASSERT_EQ(getRecordCounts, 1);
96✔
353
  }
354

355
  // stmt2 wiht time str in UTC timezone
356
  {
357
    TAOS* taos = getConnWithTz("UTC+0");
96✔
358
    do_query(taos, "use stmt2_testdb_0");
96✔
359

360
    TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
361
    TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
362
    ASSERT_NE(stmt, nullptr);
96✔
363
    int code = taos_stmt2_prepare(stmt, sql, 0);
96✔
364
    checkError(stmt, code, __FILE__, __LINE__);
96✔
365

366
    const char*      timeStrUTC = "2025-08-08 00:08:08";  // '2025-08-08 08:08:08+8' in UTC timezone
96✔
367
    int32_t          timeStrUTCLen = strlen(timeStrUTC);
96✔
368
    TAOS_STMT2_BIND  paramsUTC = {TSDB_DATA_TYPE_BINARY, (void*)timeStrUTC, &timeStrUTCLen, NULL, 1};
96✔
369
    TAOS_STMT2_BIND* paramvUTC = &paramsUTC;
96✔
370
    TAOS_STMT2_BINDV bindvUTC = {1, NULL, NULL, &paramvUTC};
96✔
371
    code = taos_stmt2_bind_param(stmt, &bindvUTC, -1);
96✔
372
    checkError(stmt, code, __FILE__, __LINE__);
96✔
373
    code = taos_stmt2_exec(stmt, NULL);
96✔
374
    checkError(stmt, code, __FILE__, __LINE__);
96✔
375

376
    TAOS_RES* pRes = taos_stmt2_result(stmt);
96✔
377
    ASSERT_NE(pRes, nullptr);
96✔
378
    int getRecordCounts = 0;
96✔
379
    while ((taos_fetch_row(pRes))) {
192✔
380
      getRecordCounts++;
96✔
381
    }
382
    ASSERT_EQ(getRecordCounts, 1);
96✔
383

384
    taos_stmt2_close(stmt);
96✔
385
    do_query(taos, "drop database if exists stmt2_testdb_0");
96✔
386
    taos_close(taos);
96✔
387
  }
388
}
389

390
TEST(stmt2Case, stmt2_test_limit) {
384✔
391
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
392
  ASSERT_NE(taos, nullptr);
96✔
393
  do_query(taos, "drop database if exists stmt2_testdb_7");
96✔
394
  do_query(taos, "create database IF NOT EXISTS stmt2_testdb_7");
96✔
395
  do_query(taos, "create stable stmt2_testdb_7.stb (ts timestamp, b binary(10)) tags(t1 int, t2 binary(10))");
96✔
396
  do_query(taos,
96✔
397
           "insert into stmt2_testdb_7.tb2 using stmt2_testdb_7.stb tags(2,'xyz') values(1591060628000, "
398
           "'abc'),(1591060628001,'def'),(1591060628004, 'hij')");
399
  do_query(taos, "use stmt2_testdb_7");
96✔
400

401
  TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
402

403
  TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
404
  ASSERT_NE(stmt, nullptr);
96✔
405

406
  const char* sql = "select * from stmt2_testdb_7.tb2 where ts > ? and ts < ? limit ?";
96✔
407
  int         code = taos_stmt2_prepare(stmt, sql, 0);
96✔
408
  checkError(stmt, code, __FILE__, __LINE__);
96✔
409

410
  int             fieldNum = 0;
96✔
411
  TAOS_FIELD_ALL* pFields = NULL;
96✔
412
  code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
96✔
413
  checkError(stmt, code, __FILE__, __LINE__);
96✔
414
  ASSERT_EQ(fieldNum, 3);
96✔
415

416
  int              t64_len[1] = {sizeof(int64_t)};
96✔
417
  int              b_len[1] = {3};
96✔
418
  int              x = 2;
96✔
419
  int              x_len = sizeof(int);
96✔
420
  int64_t          ts[2] = {1591060627000, 1591060628005};
96✔
421
  TAOS_STMT2_BIND  params[3] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], t64_len, NULL, 1},
96✔
422
                                {TSDB_DATA_TYPE_TIMESTAMP, &ts[1], t64_len, NULL, 1},
423
                                {TSDB_DATA_TYPE_INT, &x, &x_len, NULL, 1}};
96✔
424
  TAOS_STMT2_BIND* paramv = &params[0];
96✔
425
  TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &paramv};
96✔
426
  code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
427
  checkError(stmt, code, __FILE__, __LINE__);
96✔
428

429
  taos_stmt2_exec(stmt, NULL);
96✔
430
  checkError(stmt, code, __FILE__, __LINE__);
96✔
431

432
  TAOS_RES* pRes = taos_stmt2_result(stmt);
96✔
433
  ASSERT_NE(pRes, nullptr);
96✔
434

435
  int getRecordCounts = 0;
96✔
436
  while ((taos_fetch_row(pRes))) {
288✔
437
    getRecordCounts++;
192✔
438
  }
439
  ASSERT_EQ(getRecordCounts, 2);
96✔
440
  taos_stmt2_close(stmt);
96✔
441
  do_query(taos, "drop database if exists stmt2_testdb_7");
96✔
442
  taos_close(taos);
96✔
443
}
444

445
TEST(stmt2Case, insert_stb_get_fields_Test) {
384✔
446
  TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
96✔
447
  ASSERT_NE(taos, nullptr);
96✔
448

449
  do_query(taos, "drop database if exists stmt2_testdb_2");
96✔
450
  do_query(taos, "create database IF NOT EXISTS stmt2_testdb_2 PRECISION 'ns'");
96✔
451
  do_query(taos,
96✔
452
           "create stable stmt2_testdb_2.stb (ts timestamp, b binary(10)) tags(t1 "
453
           "int, t2 binary(10))");
454
  do_query(
96✔
455
      taos,
456
      "create stable if not exists stmt2_testdb_2.all_stb(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 "
457
      "bigint, "
458
      "v6 tinyint unsigned, v7 smallint unsigned, v8 int unsigned, v9 bigint unsigned, v10 float, v11 double, v12 "
459
      "binary(20), v13 varbinary(20), v14 geometry(100), v15 nchar(20))tags(tts timestamp, tv1 bool, tv2 tinyint, tv3 "
460
      "smallint, tv4 int, tv5 bigint, tv6 tinyint unsigned, tv7 smallint unsigned, tv8 int unsigned, tv9 bigint "
461
      "unsigned, tv10 float, tv11 double, tv12 binary(20), tv13 varbinary(20), tv14 geometry(100), tv15 nchar(20));");
462
  printf("support case \n");
96✔
463

464
  // case 1 : test super table
465
  {
466
    const char*    sql = "insert into stmt2_testdb_2.stb(t1,t2,ts,b,tbname) values(?,?,?,?,?)";
96✔
467
    TAOS_FIELD_ALL expectedFields[5] = {{"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG},
96✔
468
                                        {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG},
469
                                        {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL},
470
                                        {"b", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL},
471
                                        {"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME}};
472
    printf("case 1 : %s\n", sql);
96✔
473
    getFieldsSuccess(taos, sql, expectedFields, 5);
96✔
474
  }
475

476
  {
477
    // case 2 : no tag
478
    const char*    sql = "insert into stmt2_testdb_2.stb(ts,b,tbname) values(?,?,?)";
96✔
479
    TAOS_FIELD_ALL expectedFields[3] = {{"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL},
96✔
480
                                        {"b", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL},
481
                                        {"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME}};
482
    printf("case 2 : %s\n", sql);
96✔
483
    getFieldsSuccess(taos, sql, expectedFields, 3);
96✔
484
  }
485

486
  // case 3 : random order
487
  {
488
    const char*    sql = "insert into stmt2_testdb_2.stb(tbname,ts,t2,b,t1) values(?,?,?,?,?)";
96✔
489
    TAOS_FIELD_ALL expectedFields[5] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME},
96✔
490
                                        {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL},
491
                                        {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG},
492
                                        {"b", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL},
493
                                        {"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG}};
494
    printf("case 3 : %s\n", sql);
96✔
495
    getFieldsSuccess(taos, sql, expectedFields, 5);
96✔
496
  }
497

498
  // case 4 : random order 2
499
  {
500
    const char*    sql = "insert into stmt2_testdb_2.stb(ts,tbname,b,t2,t1) values(?,?,?,?,?)";
96✔
501
    TAOS_FIELD_ALL expectedFields[5] = {{"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL},
96✔
502
                                        {"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME},
503
                                        {"b", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL},
504
                                        {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG},
505
                                        {"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG}};
506
    printf("case 4 : %s\n", sql);
96✔
507
    getFieldsSuccess(taos, sql, expectedFields, 5);
96✔
508
  }
509

510
  // case 5 : 'db'.'stb'
511
  {
512
    const char*    sql = "insert into 'stmt2_testdb_2'.'stb'(t1,t2,ts,b,tbname) values(?,?,?,?,?)";
96✔
513
    TAOS_FIELD_ALL expectedFields[5] = {{"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG},
96✔
514
                                        {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG},
515
                                        {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL},
516
                                        {"b", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL},
517
                                        {"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME}};
518
    printf("case 5 : %s\n", sql);
96✔
519
    getFieldsSuccess(taos, sql, expectedFields, 5);
96✔
520
  }
521

522
  // case 6 : use db
523
  {
524
    do_query(taos, "use stmt2_testdb_2");
96✔
525
    const char*    sql = "insert into stb(t1,t2,ts,b,tbname) values(?,?,?,?,?)";
96✔
526
    TAOS_FIELD_ALL expectedFields[5] = {{"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG},
96✔
527
                                        {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG},
528
                                        {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL},
529
                                        {"b", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL},
530
                                        {"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME}};
531
    printf("case 6 : %s\n", sql);
96✔
532
    getFieldsSuccess(taos, sql, expectedFields, 5);
96✔
533
  }
534

535
  // case 7 : less param
536
  {
537
    const char*    sql = "insert into stmt2_testdb_2.stb(ts,tbname) values(?,?)";
96✔
538
    TAOS_FIELD_ALL expectedFields[2] = {{"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL},
96✔
539
                                        {"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME}};
540
    printf("case 7 : %s\n", sql);
96✔
541
    getFieldsSuccess(taos, sql, expectedFields, 2);
96✔
542
  }
543

544
  // case 8 : test all types
545
  {
546
    const char* sql =
96✔
547
        "insert into "
548
        "all_stb(tbname,tts,tv1,tv2,tv3,tv4,tv5,tv6,tv7,tv8,tv9,tv10,tv11,tv12,tv13,tv14,tv15,ts,v1,v2,v3,v4,v5,v6,v7,"
549
        "v8,v9,v10,"
550
        "v11,v12,v13,v14,v15) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
551
    TAOS_FIELD_ALL expectedFields[33] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME},
96✔
552
                                         {"tts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_TAG},
553
                                         {"tv1", TSDB_DATA_TYPE_BOOL, 0, 0, 1, TAOS_FIELD_TAG},
554
                                         {"tv2", TSDB_DATA_TYPE_TINYINT, 0, 0, 1, TAOS_FIELD_TAG},
555
                                         {"tv3", TSDB_DATA_TYPE_SMALLINT, 0, 0, 2, TAOS_FIELD_TAG},
556
                                         {"tv4", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG},
557
                                         {"tv5", TSDB_DATA_TYPE_BIGINT, 0, 0, 8, TAOS_FIELD_TAG},
558
                                         {"tv6", TSDB_DATA_TYPE_UTINYINT, 0, 0, 1, TAOS_FIELD_TAG},
559
                                         {"tv7", TSDB_DATA_TYPE_USMALLINT, 0, 0, 2, TAOS_FIELD_TAG},
560
                                         {"tv8", TSDB_DATA_TYPE_UINT, 0, 0, 4, TAOS_FIELD_TAG},
561
                                         {"tv9", TSDB_DATA_TYPE_UBIGINT, 0, 0, 8, TAOS_FIELD_TAG},
562
                                         {"tv10", TSDB_DATA_TYPE_FLOAT, 0, 0, 4, TAOS_FIELD_TAG},
563
                                         {"tv11", TSDB_DATA_TYPE_DOUBLE, 0, 0, 8, TAOS_FIELD_TAG},
564
                                         {"tv12", TSDB_DATA_TYPE_VARCHAR, 0, 0, 22, TAOS_FIELD_TAG},
565
                                         {"tv13", TSDB_DATA_TYPE_VARBINARY, 0, 0, 22, TAOS_FIELD_TAG},
566
                                         {"tv14", TSDB_DATA_TYPE_GEOMETRY, 0, 0, 102, TAOS_FIELD_TAG},
567
                                         {"tv15", TSDB_DATA_TYPE_NCHAR, 0, 0, 82, TAOS_FIELD_TAG},
568
                                         {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL},
569
                                         {"v1", TSDB_DATA_TYPE_BOOL, 0, 0, 1, TAOS_FIELD_COL},
570
                                         {"v2", TSDB_DATA_TYPE_TINYINT, 0, 0, 1, TAOS_FIELD_COL},
571
                                         {"v3", TSDB_DATA_TYPE_SMALLINT, 0, 0, 2, TAOS_FIELD_COL},
572
                                         {"v4", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_COL},
573
                                         {"v5", TSDB_DATA_TYPE_BIGINT, 0, 0, 8, TAOS_FIELD_COL},
574
                                         {"v6", TSDB_DATA_TYPE_UTINYINT, 0, 0, 1, TAOS_FIELD_COL},
575
                                         {"v7", TSDB_DATA_TYPE_USMALLINT, 0, 0, 2, TAOS_FIELD_COL},
576
                                         {"v8", TSDB_DATA_TYPE_UINT, 0, 0, 4, TAOS_FIELD_COL},
577
                                         {"v9", TSDB_DATA_TYPE_UBIGINT, 0, 0, 8, TAOS_FIELD_COL},
578
                                         {"v10", TSDB_DATA_TYPE_FLOAT, 0, 0, 4, TAOS_FIELD_COL},
579
                                         {"v11", TSDB_DATA_TYPE_DOUBLE, 0, 0, 8, TAOS_FIELD_COL},
580
                                         {"v12", TSDB_DATA_TYPE_VARCHAR, 0, 0, 22, TAOS_FIELD_COL},
581
                                         {"v13", TSDB_DATA_TYPE_VARBINARY, 0, 0, 22, TAOS_FIELD_COL},
582
                                         {"v14", TSDB_DATA_TYPE_GEOMETRY, 0, 0, 102, TAOS_FIELD_COL},
583
                                         {"v15", TSDB_DATA_TYPE_NCHAR, 0, 0, 82, TAOS_FIELD_COL}};
584
    printf("case 8 : %s\n", sql);
96✔
585
    getFieldsSuccess(taos, sql, expectedFields, 33);
96✔
586
  }
587

588
  // case 9 : fixed value
589
  {
590
    const char*    sql = "insert into stmt2_testdb_2.stb(t1,t2,ts,b,tbname) values(1,?,?,'abc',?)";
96✔
591
    TAOS_FIELD_ALL expectedFields[3] = {{"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG},
96✔
592
                                        {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL},
593
                                        {"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME}};
594
    printf("case 9 : %s\n", sql);
96✔
595
    getFieldsSuccess(taos, sql, expectedFields, 3);
96✔
596
  }
597

598
  // not support case
599
  printf("not support case \n");
96✔
600

601
  // case 2 : no pk
602
  {
603
    const char* sql = "insert into stmt2_testdb_2.stb(b,tbname) values(?,?)";
96✔
604
    printf("case 2 : %s\n", sql);
96✔
605
    getFieldsError(taos, sql, TSDB_CODE_TSC_INVALID_OPERATION, "Primary timestamp column should not be null");
96✔
606
  }
607

608
  // case 3 : no tbname and tag(not support bind)
609
  {
610
    const char* sql = "insert into stmt2_testdb_2.stb(ts,b) values(?,?)";
96✔
611
    printf("case 3 : %s\n", sql);
96✔
612
    getFieldsError(taos, sql, TSDB_CODE_TSC_INVALID_OPERATION, "tbname column should not be null");
96✔
613
  }
614

615
  // case 4 : no col and tag(not support bind)
616
  {
617
    const char* sql = "insert into stmt2_testdb_2.stb(tbname) values(?)";
96✔
618
    printf("case 4 : %s\n", sql);
96✔
619
    getFieldsError(taos, sql, TSDB_CODE_TSC_INVALID_OPERATION, "Primary timestamp column should not be null");
96✔
620
  }
621

622
  // case 5 : no field name
623
  {
624
    const char* sql = "insert into stmt2_testdb_2.stb values(?,?,?,?,?)";
96✔
625
    printf("case 5 : %s\n", sql);
96✔
626
    getFieldsError(taos, sql, TSDB_CODE_TSC_SQL_SYNTAX_ERROR,
96✔
627
                   "syntax error near ' values(?,?,?,?,?)' ((...tbname, ts...) bounded cols is expected for supertable "
628
                   "insertion)");
629
  }
630

631
  // case 6 :  test super table not exist
632
  {
633
    const char* sql = "insert into stmt2_testdb_2.nstb values(?,?,?,?,?)";
96✔
634
    printf("case 6 : %s\n", sql);
96✔
635
    getFieldsError(taos, sql, TSDB_CODE_TSC_STMT_TBNAME_ERROR, "Table does not exist");
96✔
636
  }
637

638
  // case 7 :  no col
639
  {
640
    const char* sql = "insert into stmt2_testdb_2.stb(t1,t2,tbname) values(?,?,?)";
96✔
641
    printf("case 7 : %s\n", sql);
96✔
642
    getFieldsError(taos, sql, TSDB_CODE_TSC_INVALID_OPERATION, "Primary timestamp column should not be null");
96✔
643
  }
644

645
  // case 8 :   wrong para nums
646
  {
647
    const char* sql = "insert into stmt2_testdb_2.stb(ts,b,tbname) values(?,?,?,?,?)";
96✔
648
    printf("case 8 : %s\n", sql);
96✔
649
    getFieldsError(taos, sql, TSDB_CODE_PAR_INVALID_COLUMNS_NUM, "Illegal number of columns");
96✔
650
  }
651

652
  // case 9 :   wrong simbol
653
  {
654
    const char* sql = "insert into stmt2_testdb_2.stb(t1,t2,ts,b,tbname) values(*,*,*,*,*)";
96✔
655
    printf("case 9 : %s\n", sql);
96✔
656
    getFieldsError(taos, sql, TSDB_CODE_PAR_INVALID_COLUMNS_NUM, "Illegal number of columns");
96✔
657
  }
658

659
  do_query(taos, "drop database if exists stmt2_testdb_2");
96✔
660
  taos_close(taos);
96✔
661
}
662

663
TEST(stmt2Case, insert_ctb_using_get_fields_Test) {
384✔
664
  TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
96✔
665
  ASSERT_NE(taos, nullptr);
96✔
666

667
  do_query(taos, "drop database if exists stmt2_testdb_3");
96✔
668
  do_query(taos, "create database IF NOT EXISTS stmt2_testdb_3 PRECISION 'ns'");
96✔
669
  do_query(taos,
96✔
670
           "create stable stmt2_testdb_3.stb (ts timestamp, b binary(10)) tags(t1 "
671
           "int, t2 binary(10))");
672
  do_query(
96✔
673
      taos,
674
      "create stable if not exists stmt2_testdb_3.all_stb(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 "
675
      "bigint, "
676
      "v6 tinyint unsigned, v7 smallint unsigned, v8 int unsigned, v9 bigint unsigned, v10 float, v11 double, v12 "
677
      "binary(20), v13 varbinary(20), v14 geometry(100), v15 nchar(20))tags(tts timestamp, tv1 bool, tv2 tinyint, tv3 "
678
      "smallint, tv4 int, tv5 bigint, tv6 tinyint unsigned, tv7 smallint unsigned, tv8 int unsigned, tv9 bigint "
679
      "unsigned, tv10 float, tv11 double, tv12 binary(20), tv13 varbinary(20), tv14 geometry(100), tv15 nchar(20));");
680
  do_query(taos, "CREATE TABLE stmt2_testdb_3.t0 USING stmt2_testdb_3.stb (t1,t2) TAGS (7,'Cali');");
96✔
681

682
  printf("support case \n");
96✔
683
  // case 1 : test child table already exist
684
  {
685
    const char*    sql = "INSERT INTO stmt2_testdb_3.t0(ts,b)using stmt2_testdb_3.stb (t1,t2) TAGS(?,?) VALUES(?,?)";
96✔
686
    TAOS_FIELD_ALL expectedFields[4] = {{"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG},
96✔
687
                                        {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG},
688
                                        {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL},
689
                                        {"b", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL}};
690
    printf("case 1 : %s\n", sql);
96✔
691
    getFieldsSuccess(taos, sql, expectedFields, 4);
96✔
692
  }
693

694
  // case 2 : insert clause
695
  {
696
    const char*    sql = "INSERT INTO stmt2_testdb_3.? using stmt2_testdb_3.stb (t1,t2) TAGS(?,?) (ts,b)VALUES(?,?)";
96✔
697
    TAOS_FIELD_ALL expectedFields[5] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME},
96✔
698
                                        {"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG},
699
                                        {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG},
700
                                        {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL},
701
                                        {"b", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL}};
702
    printf("case 2 : %s\n", sql);
96✔
703
    getFieldsSuccess(taos, sql, expectedFields, 5);
96✔
704
  }
705

706
  // case 3 : insert child table not exist
707
  {
708
    const char*    sql = "INSERT INTO stmt2_testdb_3.d1 using stmt2_testdb_3.stb (t1,t2)TAGS(?,?) (ts,b)VALUES(?,?)";
96✔
709
    TAOS_FIELD_ALL expectedFields[4] = {{"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG},
96✔
710
                                        {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG},
711
                                        {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL},
712
                                        {"b", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL}};
713
    printf("case 3 : %s\n", sql);
96✔
714
    getFieldsSuccess(taos, sql, expectedFields, 4);
96✔
715
  }
716

717
  // case 4 : random order
718
  {
719
    const char*    sql = "INSERT INTO stmt2_testdb_3.? using stmt2_testdb_3.stb (t2,t1)TAGS(?,?) (b,ts)VALUES(?,?)";
96✔
720
    TAOS_FIELD_ALL expectedFields[5] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME},
96✔
721
                                        {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG},
722
                                        {"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG},
723
                                        {"b", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL},
724
                                        {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL}};
725
    printf("case 4 : %s\n", sql);
96✔
726
    getFieldsSuccess(taos, sql, expectedFields, 5);
96✔
727
  }
728

729
  // case 5 : less para
730
  {
731
    const char*    sql = "insert into stmt2_testdb_3.? using stmt2_testdb_3.stb (t2)tags(?) (ts)values(?)";
96✔
732
    TAOS_FIELD_ALL expectedFields[3] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME},
96✔
733
                                        {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG},
734
                                        {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL}};
735
    printf("case 5 : %s\n", sql);
96✔
736
    getFieldsSuccess(taos, sql, expectedFields, 3);
96✔
737
  }
738

739
  // case 6 : insert into db.? using db.stb tags(?, ?) values(?,?)
740
  // no field name
741
  {
742
    const char*    sql = "insert into stmt2_testdb_3.? using stmt2_testdb_3.stb tags(?, ?) values(?,?)";
96✔
743
    TAOS_FIELD_ALL expectedFields[5] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME},
96✔
744
                                        {"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG},
745
                                        {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG},
746
                                        {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL},
747
                                        {"b", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL}};
748
    printf("case 6 : %s\n", sql);
96✔
749
    getFieldsSuccess(taos, sql, expectedFields, 5);
96✔
750
  }
751

752
  // case 7 : insert into db.d0 (ts)values(?)
753
  //  less para
754
  {
755
    const char*    sql = "insert into stmt2_testdb_3.t0 (ts)values(?)";
96✔
756
    TAOS_FIELD_ALL expectedFields[1] = {{"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL}};
96✔
757
    printf("case 7 : %s\n", sql);
96✔
758
    getFieldsSuccess(taos, sql, expectedFields, 1);
96✔
759
  }
760

761
  // case 8 : 'db' 'stb'
762
  {
763
    const char* sql = "INSERT INTO 'stmt2_testdb_3'.? using 'stmt2_testdb_3'.'stb' (t1,t2) TAGS(?,?)(ts,b)VALUES(?,?)";
96✔
764
    TAOS_FIELD_ALL expectedFields[5] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME},
96✔
765
                                        {"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG},
766
                                        {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG},
767
                                        {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL},
768
                                        {"b", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL}};
769
    printf("case 8 : %s\n", sql);
96✔
770
    getFieldsSuccess(taos, sql, expectedFields, 5);
96✔
771
  }
772

773
  // case 9 : use db
774
  {
775
    do_query(taos, "use stmt2_testdb_3");
96✔
776
    const char*    sql = "INSERT INTO ? using stb (t1,t2) TAGS(?,?) (ts,b)VALUES(?,?)";
96✔
777
    TAOS_FIELD_ALL expectedFields[5] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME},
96✔
778
                                        {"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG},
779
                                        {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG},
780
                                        {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL},
781
                                        {"b", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL}};
782
    printf("case 9 : %s\n", sql);
96✔
783
    getFieldsSuccess(taos, sql, expectedFields, 5);
96✔
784
  }
785
  // case 11: TD-34097
786
  {
787
    do_query(taos, "use stmt2_testdb_3");
96✔
788
    const char*    sql = "INSERT INTO ? using stb (t1,t2) TAGS(1,'abc') (ts,b)VALUES(?,?)";
96✔
789
    TAOS_FIELD_ALL expectedFields[3] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME},
96✔
790
                                        {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL},
791
                                        {"b", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL}};
792
    printf("case 11 : %s\n", sql);
96✔
793
    getFieldsSuccess(taos, sql, expectedFields, 3);
96✔
794
  }
795

796
  // case 10 : test all types
797
  {
798
    do_query(taos, "use stmt2_testdb_3");
96✔
799
    const char* sql =
96✔
800
        "insert into ? using all_stb tags(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
801
    TAOS_FIELD_ALL expectedFields[33] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME},
96✔
802
                                         {"tts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_TAG},
803
                                         {"tv1", TSDB_DATA_TYPE_BOOL, 0, 0, 1, TAOS_FIELD_TAG},
804
                                         {"tv2", TSDB_DATA_TYPE_TINYINT, 0, 0, 1, TAOS_FIELD_TAG},
805
                                         {"tv3", TSDB_DATA_TYPE_SMALLINT, 0, 0, 2, TAOS_FIELD_TAG},
806
                                         {"tv4", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG},
807
                                         {"tv5", TSDB_DATA_TYPE_BIGINT, 0, 0, 8, TAOS_FIELD_TAG},
808
                                         {"tv6", TSDB_DATA_TYPE_UTINYINT, 0, 0, 1, TAOS_FIELD_TAG},
809
                                         {"tv7", TSDB_DATA_TYPE_USMALLINT, 0, 0, 2, TAOS_FIELD_TAG},
810
                                         {"tv8", TSDB_DATA_TYPE_UINT, 0, 0, 4, TAOS_FIELD_TAG},
811
                                         {"tv9", TSDB_DATA_TYPE_UBIGINT, 0, 0, 8, TAOS_FIELD_TAG},
812
                                         {"tv10", TSDB_DATA_TYPE_FLOAT, 0, 0, 4, TAOS_FIELD_TAG},
813
                                         {"tv11", TSDB_DATA_TYPE_DOUBLE, 0, 0, 8, TAOS_FIELD_TAG},
814
                                         {"tv12", TSDB_DATA_TYPE_VARCHAR, 0, 0, 22, TAOS_FIELD_TAG},
815
                                         {"tv13", TSDB_DATA_TYPE_VARBINARY, 0, 0, 22, TAOS_FIELD_TAG},
816
                                         {"tv14", TSDB_DATA_TYPE_GEOMETRY, 0, 0, 102, TAOS_FIELD_TAG},
817
                                         {"tv15", TSDB_DATA_TYPE_NCHAR, 0, 0, 82, TAOS_FIELD_TAG},
818
                                         {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL},
819
                                         {"v1", TSDB_DATA_TYPE_BOOL, 0, 0, 1, TAOS_FIELD_COL},
820
                                         {"v2", TSDB_DATA_TYPE_TINYINT, 0, 0, 1, TAOS_FIELD_COL},
821
                                         {"v3", TSDB_DATA_TYPE_SMALLINT, 0, 0, 2, TAOS_FIELD_COL},
822
                                         {"v4", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_COL},
823
                                         {"v5", TSDB_DATA_TYPE_BIGINT, 0, 0, 8, TAOS_FIELD_COL},
824
                                         {"v6", TSDB_DATA_TYPE_UTINYINT, 0, 0, 1, TAOS_FIELD_COL},
825
                                         {"v7", TSDB_DATA_TYPE_USMALLINT, 0, 0, 2, TAOS_FIELD_COL},
826
                                         {"v8", TSDB_DATA_TYPE_UINT, 0, 0, 4, TAOS_FIELD_COL},
827
                                         {"v9", TSDB_DATA_TYPE_UBIGINT, 0, 0, 8, TAOS_FIELD_COL},
828
                                         {"v10", TSDB_DATA_TYPE_FLOAT, 0, 0, 4, TAOS_FIELD_COL},
829
                                         {"v11", TSDB_DATA_TYPE_DOUBLE, 0, 0, 8, TAOS_FIELD_COL},
830
                                         {"v12", TSDB_DATA_TYPE_VARCHAR, 0, 0, 22, TAOS_FIELD_COL},
831
                                         {"v13", TSDB_DATA_TYPE_VARBINARY, 0, 0, 22, TAOS_FIELD_COL},
832
                                         {"v14", TSDB_DATA_TYPE_GEOMETRY, 0, 0, 102, TAOS_FIELD_COL},
833
                                         {"v15", TSDB_DATA_TYPE_NCHAR, 0, 0, 82, TAOS_FIELD_COL}};
834
    printf("case 10 : %s\n", sql);
96✔
835
    getFieldsSuccess(taos, sql, expectedFields, 33);
96✔
836
  }
837

838
  // case 12 : fixed value
839
  {
840
    do_query(taos, "use stmt2_testdb_3");
96✔
841
    const char*    sql = "INSERT INTO ? using stb (t1,t2) TAGS(1,?) (ts,b)VALUES(?,'abc')";
96✔
842
    TAOS_FIELD_ALL expectedFields[3] = {
96✔
843
        {"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME},
844
        {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG},
845
        {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL},
846
    };
847
    printf("case 12 : %s\n", sql);
96✔
848
    getFieldsSuccess(taos, sql, expectedFields, 3);
96✔
849
  }
850
  // case 13 : mix value and ?
851
  {
852
    do_query(taos, "use stmt2_testdb_3");
96✔
853
    const char*    sql = "INSERT INTO ? using stb (t1,t2) TAGS(?,?) (ts,b)VALUES(15910606280001,?)";
96✔
854
    TAOS_FIELD_ALL expectedFields[4] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME},
96✔
855
                                        {"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG},
856
                                        {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG},
857
                                        {"b", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL}};
858
    printf("case 13 : %s\n", sql);
96✔
859
    getFieldsSuccess(taos, sql, expectedFields, 4);
96✔
860
  }
861
  // case 14 : mix value and ?
862
  {
863
    do_query(taos, "use stmt2_testdb_3");
96✔
864
    const char*    sql = "INSERT INTO ? using stb (t1,t2) TAGS(?,?) (ts,b)VALUES(15910606280001,'abc')";
96✔
865
    TAOS_FIELD_ALL expectedFields[3] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME},
96✔
866
                                        {"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG},
867
                                        {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG}};
868
    printf("case 13 : %s\n", sql);
96✔
869
    getFieldsSuccess(taos, sql, expectedFields, 3);
96✔
870
  }
871

872
  printf("not support case \n");
96✔
873

874
  // case 1 : test super table not exist
875
  {
876
    const char* sql = "INSERT INTO stmt2_testdb_3.? using stmt2_testdb_3.nstb (t1,t2) TAGS(?,?) (ts,b)VALUES (?,?)";
96✔
877
    printf("case 1 : %s\n", sql);
96✔
878
    getFieldsError(taos, sql, TSDB_CODE_TSC_STMT_TBNAME_ERROR, "Table does not exist");
96✔
879
  }
880

881
  // case 2 : no pk
882
  {
883
    const char* sql = "INSERT INTO stmt2_testdb_3.? using stmt2_testdb_3.stb (t1,t2) TAGS(?,?) (b)VALUES (?)";
96✔
884
    printf("case 2 : %s\n", sql);
96✔
885
    getFieldsError(taos, sql, TSDB_CODE_TSC_INVALID_OPERATION, "Primary timestamp column should not be null");
96✔
886
  }
887

888
  // case 3 : less param and no filed name
889
  {
890
    const char* sql = "INSERT INTO stmt2_testdb_3.? using stmt2_testdb_3.stb TAGS(?)VALUES (?,?)";
96✔
891
    printf("case 3 : %s\n", sql);
96✔
892
    getFieldsError(taos, sql, TSDB_CODE_TSC_SQL_SYNTAX_ERROR,
96✔
893
                   "syntax error near ')values (?,?)' (invalid data or symbol)");
894
  }
895

896
  // case 4 :  no tags for ctbname
897
  {
898
    const char* sql = "INSERT INTO stmt2_testdb_3.d0 using stmt2_testdb_3.stb values(?,?)";
96✔
899
    printf("case 4 : %s\n", sql);
96✔
900
    getFieldsError(taos, sql, TSDB_CODE_TSC_SQL_SYNTAX_ERROR, "syntax error near 'values(?,?)' (TAGS is expected)");
96✔
901
  }
902

903
  // case 5 :  wrong placeholder
904
  {
905
    const char* sql = "insert into ! using stmt2_testdb_3.stb tags(?, ?) values(?,?)";
96✔
906
    printf("case 5 : %s\n", sql);
96✔
907
    getFieldsError(taos, sql, TSDB_CODE_TSC_SQL_SYNTAX_ERROR,
96✔
908
                   "syntax error near '! using stmt2_testdb_3.stb tags(?, ?) values(?,?)' (table_name is expected)");
909
  }
910
  do_query(taos, "drop database if exists stmt2_testdb_3");
96✔
911
  taos_close(taos);
96✔
912
}
913

914
TEST(stmt2Case, insert_ntb_get_fields_Test) {
384✔
915
  TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
96✔
916
  ASSERT_NE(taos, nullptr);
96✔
917

918
  do_query(taos, "drop database if exists stmt2_testdb_4");
96✔
919
  do_query(taos, "create database IF NOT EXISTS stmt2_testdb_4 PRECISION 'ms'");
96✔
920
  do_query(taos, "CREATE TABLE stmt2_testdb_4.ntb(nts timestamp, nb binary(10),nvc varchar(16),ni int);");
96✔
921
  do_query(
96✔
922
      taos,
923
      "create table if not exists stmt2_testdb_4.all_ntb(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 "
924
      "bigint, v6 tinyint unsigned, v7 smallint unsigned, v8 int unsigned, v9 bigint unsigned, v10 float, v11 "
925
      "double, v12 binary(20), v13 varbinary(20), v14 geometry(100), v15 nchar(20));");
926

927
  printf("support case \n");
96✔
928

929
  // case 1 : test normal table no field name
930
  {
931
    const char*    sql = "INSERT INTO stmt2_testdb_4.ntb VALUES(?,?,?,?)";
96✔
932
    TAOS_FIELD_ALL expectedFields[4] = {{"nts", TSDB_DATA_TYPE_TIMESTAMP, 0, 0, 8, TAOS_FIELD_COL},
96✔
933
                                        {"nb", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL},
934
                                        {"nvc", TSDB_DATA_TYPE_BINARY, 0, 0, 18, TAOS_FIELD_COL},
935
                                        {"ni", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_COL}};
936
    printf("case 1 : %s\n", sql);
96✔
937
    getFieldsSuccess(taos, sql, expectedFields, 4);
96✔
938
  }
939

940
  // case 2 : test random order
941
  {
942
    const char*    sql = "INSERT INTO stmt2_testdb_4.ntb (ni,nb,nvc,nts)VALUES(?,?,?,?)";
96✔
943
    TAOS_FIELD_ALL expectedFields[4] = {{"ni", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_COL},
96✔
944
                                        {"nb", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL},
945
                                        {"nvc", TSDB_DATA_TYPE_BINARY, 0, 0, 18, TAOS_FIELD_COL},
946
                                        {"nts", TSDB_DATA_TYPE_TIMESTAMP, 0, 0, 8, TAOS_FIELD_COL}};
947
    printf("case 2 : %s\n", sql);
96✔
948
    getFieldsSuccess(taos, sql, expectedFields, 4);
96✔
949
  }
950

951
  // case 3 : less param
952
  {
953
    const char*    sql = "INSERT INTO stmt2_testdb_4.ntb (nts)VALUES(?)";
96✔
954
    TAOS_FIELD_ALL expectedFields[1] = {{"nts", TSDB_DATA_TYPE_TIMESTAMP, 0, 0, 8, TAOS_FIELD_COL}};
96✔
955
    printf("case 3 : %s\n", sql);
96✔
956
    getFieldsSuccess(taos, sql, expectedFields, 1);
96✔
957
  }
958

959
  // case 4 : test all types
960
  {
961
    const char*    sql = "insert into stmt2_testdb_4.all_ntb values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
96✔
962
    TAOS_FIELD_ALL expectedFields[16] = {{"ts", TSDB_DATA_TYPE_TIMESTAMP, 0, 0, 8, TAOS_FIELD_COL},
96✔
963
                                         {"v1", TSDB_DATA_TYPE_BOOL, 0, 0, 1, TAOS_FIELD_COL},
964
                                         {"v2", TSDB_DATA_TYPE_TINYINT, 0, 0, 1, TAOS_FIELD_COL},
965
                                         {"v3", TSDB_DATA_TYPE_SMALLINT, 0, 0, 2, TAOS_FIELD_COL},
966
                                         {"v4", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_COL},
967
                                         {"v5", TSDB_DATA_TYPE_BIGINT, 0, 0, 8, TAOS_FIELD_COL},
968
                                         {"v6", TSDB_DATA_TYPE_UTINYINT, 0, 0, 1, TAOS_FIELD_COL},
969
                                         {"v7", TSDB_DATA_TYPE_USMALLINT, 0, 0, 2, TAOS_FIELD_COL},
970
                                         {"v8", TSDB_DATA_TYPE_UINT, 0, 0, 4, TAOS_FIELD_COL},
971
                                         {"v9", TSDB_DATA_TYPE_UBIGINT, 0, 0, 8, TAOS_FIELD_COL},
972
                                         {"v10", TSDB_DATA_TYPE_FLOAT, 0, 0, 4, TAOS_FIELD_COL},
973
                                         {"v11", TSDB_DATA_TYPE_DOUBLE, 0, 0, 8, TAOS_FIELD_COL},
974
                                         {"v12", TSDB_DATA_TYPE_VARCHAR, 0, 0, 22, TAOS_FIELD_COL},
975
                                         {"v13", TSDB_DATA_TYPE_VARBINARY, 0, 0, 22, TAOS_FIELD_COL},
976
                                         {"v14", TSDB_DATA_TYPE_GEOMETRY, 0, 0, 102, TAOS_FIELD_COL},
977
                                         {"v15", TSDB_DATA_TYPE_NCHAR, 0, 0, 82, TAOS_FIELD_COL}};
978
    printf("case 4 : %s\n", sql);
96✔
979
    getFieldsSuccess(taos, sql, expectedFields, 16);
96✔
980
  }
981

982
  printf("not support case \n");
96✔
983

984
  // case 1 :  wrong db
985
  {
986
    const char* sql = "insert into ntb values(?,?,?,?)";
96✔
987
    printf("case 1 : %s\n", sql);
96✔
988
    getFieldsError(taos, sql, TSDB_CODE_PAR_DB_NOT_SPECIFIED, "Database not specified");
96✔
989
  }
990

991
  // case 2 :  normal table must have tbnam
992
  {
993
    const char* sql = "insert into stmt2_testdb_4.? values(?,?)";
96✔
994
    printf("case 2 : %s\n", sql);
96✔
995
    getFieldsError(taos, sql, TSDB_CODE_TSC_STMT_TBNAME_ERROR, "Table does not exist");
96✔
996
  }
997

998
  // case 3 :  wrong para nums
999
  {
1000
    const char* sql = "insert into stmt2_testdb_4.ntb(nts,ni) values(?,?,?,?,?)";
96✔
1001
    printf("case 3 : %s\n", sql);
96✔
1002
    getFieldsError(taos, sql, TSDB_CODE_PAR_INVALID_COLUMNS_NUM, "Illegal number of columns");
96✔
1003
  }
1004

1005
  do_query(taos, "drop database if exists stmt2_testdb_4");
96✔
1006
  taos_close(taos);
96✔
1007
}
1008

1009
TEST(stmt2Case, select_get_fields_Test) {
384✔
1010
  TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
96✔
1011
  ASSERT_NE(taos, nullptr);
96✔
1012
  do_query(taos, "drop database if exists stmt2_testdb_5");
96✔
1013
  do_query(taos, "create database IF NOT EXISTS stmt2_testdb_5 PRECISION 'ns'");
96✔
1014
  do_query(taos, "use stmt2_testdb_5");
96✔
1015
  do_query(taos, "CREATE TABLE stmt2_testdb_5.ntb(nts timestamp, nb binary(10),nvc varchar(16),ni int);");
96✔
1016
  {
1017
    // case 1 :
1018
    const char* sql = "select * from ntb where ts = ?";
96✔
1019
    printf("case 1 : %s\n", sql);
96✔
1020
    getQueryFields(taos, sql, 1);
96✔
1021
  }
1022

1023
  {
1024
    // case 2 :
1025
    const char* sql = "select * from ntb where ts = ? and b = ?";
96✔
1026
    printf("case 2 : %s\n", sql);
96✔
1027
    getQueryFields(taos, sql, 2);
96✔
1028
  }
1029

1030
  do_query(taos, "drop database if exists stmt2_testdb_5");
96✔
1031
  taos_close(taos);
96✔
1032
}
1033

1034
TEST(stmt2Case, get_fields_error_Test) {
384✔
1035
  // case 1 :
1036
  {
1037
    printf("case 1 : NULL param \n");
96✔
1038
    int code = taos_stmt2_get_fields(NULL, NULL, NULL);
96✔
1039
    ASSERT_EQ(code, TSDB_CODE_INVALID_PARA);
96✔
1040
  }
1041
}
1042

1043
TEST(stmt2Case, stmt2_init_prepare_Test) {
384✔
1044
  TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
96✔
1045
  ASSERT_NE(taos, nullptr);
96✔
1046
  {
1047
    (void)taos_stmt2_init(NULL, NULL);
96✔
1048
    ASSERT_EQ(terrno, TSDB_CODE_INVALID_PARA);
96✔
1049
    terrno = 0;
96✔
1050
  }
1051

1052
  {
1053
    (void)taos_stmt2_prepare(NULL, NULL, 0);
96✔
1054
    ASSERT_EQ(terrno, TSDB_CODE_INVALID_PARA);
96✔
1055
    terrno = 0;
96✔
1056
  }
1057

1058
  {
1059
    TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
1060
    TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
1061
    ASSERT_NE(stmt, nullptr);
96✔
1062
    int code = taos_stmt2_prepare(stmt, "wrong sql", 0);
96✔
1063
    ASSERT_NE(stmt, nullptr);
96✔
1064
    ASSERT_EQ(((STscStmt2*)stmt)->db, nullptr);
96✔
1065
    taos_stmt2_close(stmt);
96✔
1066
  }
1067

1068
  {
1069
    TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
1070
    TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
1071
    ASSERT_NE(stmt, nullptr);
96✔
1072
    int code = taos_stmt2_prepare(stmt, "insert into 'stmt2_testdb_5'.stb(t1,t2,ts,b,tbname) values(?,?,?,?,?)", 0);
96✔
1073
    ASSERT_NE(stmt, nullptr);
96✔
1074
    ASSERT_STREQ(((STscStmt2*)stmt)->db, "stmt2_testdb_5");  // add in main TD-33332
96✔
1075
    taos_stmt2_close(stmt);
96✔
1076
  }
1077

1078
  {
1079
    TAOS_STMT2_OPTION option = {0, true, false, NULL, NULL};
96✔
1080
    TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
1081
    ASSERT_NE(stmt, nullptr);
96✔
1082
    taos_stmt2_close(stmt);
96✔
1083
  }
1084

1085
  {
1086
    TAOS_STMT2_OPTION option = {0, true, true, stmtAsyncQueryCb, NULL};
96✔
1087
    TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
1088
    ASSERT_NE(stmt, nullptr);
96✔
1089
    taos_stmt2_close(stmt);
96✔
1090
  }
1091
  taos_close(taos);
96✔
1092
}
1093

1094
TEST(stmt2Case, stmt2_stb_insert) {
384✔
1095
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
1096
  ASSERT_NE(taos, nullptr);
96✔
1097
  // normal
1098
  TAOS_STMT2_OPTION option = {0, false, true, NULL, NULL};
96✔
1099
  {
1100
    do_stmt("no-interlcace", taos, &option, "insert into `stmt2_testdb_1`.`stb` (tbname,ts,b,t1,t2) values(?,?,?,?,?)",
96✔
1101
            3, 3, 3, true, true);
1102
  }
1103
  {
1104
    do_stmt("no-interlcace", taos, &option,
96✔
1105
            "insert into `stmt2_testdb_1`.? using `stmt2_testdb_1`.`stb` tags(?,?) values(?,?)", 3, 3, 3, true, true);
1106
  }
1107

1108
  // async
1109
  AsyncArgs* aa = (AsyncArgs*)taosMemoryMalloc(sizeof(AsyncArgs));
96✔
1110
  aa->async_affected_rows = 0;
96✔
1111
  ASSERT_EQ(tsem_init(&aa->sem, 0, 0), TSDB_CODE_SUCCESS);
96✔
1112
  void* param = aa;
96✔
1113
  option = {0, false, true, stmtAsyncQueryCb, param};
96✔
1114
  {
1115
    do_stmt("no-interlcace & aync exec", taos, &option,
96✔
1116
            "insert into stmt2_testdb_1.stb (ts,b,tbname,t1,t2) values(?,?,?,?,?)", 3, 3, 3, true, true);
1117
  }
1118
  {
1119
    do_stmt("no-interlcace & aync exec", taos, &option,
96✔
1120
            "insert into stmt2_testdb_1.? using stmt2_testdb_1.stb (t1,t2)tags(?,?) (ts,b)values(?,?)", 3, 3, 3, true,
1121
            true);
1122
  }
1123
  // TD-34123 : interlace=0 with fixed tags
1124
  {
1125
    do_stmt("no-interlcace & aync exec", taos, &option,
96✔
1126
            "insert into `stmt2_testdb_1`.`stb` (tbname,ts,b,t1,t2) values(?,?,?,?,?)", 3, 3, 3, false, true);
1127
  }
1128

1129
  // interlace = 0 & use db]
1130
  do_query(taos, "use stmt2_testdb_1");
96✔
1131
  option = {0, false, false, NULL, NULL};
96✔
1132
  {
1133
    do_stmt("no-interlcace & no-db", taos, &option, "insert into stb (tbname,ts,b) values(?,?,?)", 3, 3, 3, false,
96✔
1134
            true);
1135
  }
1136
  {
1137
    do_stmt("no-interlcace & no-db", taos, &option, "insert into ? using stb (t1,t2)tags(?,?) (ts,b)values(?,?)", 3, 3,
96✔
1138
            3, true, true);
1139
  }
1140
  { do_stmt("no-interlcace & no-db", taos, &option, "insert into ? values(?,?)", 3, 3, 3, false, true); }
96✔
1141

1142
  // interlace = 1
1143
  option = {0, true, true, stmtAsyncQueryCb, param};
96✔
1144
  { do_stmt("interlcace & preCreateTB", taos, &option, "insert into ? values(?,?)", 3, 3, 3, false, true); }
96✔
1145
  option = {0, true, true, NULL, NULL};
96✔
1146
  { do_stmt("interlcace & preCreateTB", taos, &option, "insert into ? values(?,?)", 3, 3, 3, false, true); }
96✔
1147

1148
  //  auto create table
1149
  // interlace = 1
1150
  option = {0, true, true, NULL, NULL};
96✔
1151
  {
1152
    do_stmt("interlcace & no-preCreateTB", taos, &option, "insert into ? using stb (t1,t2)tags(?,?) (ts,b)values(?,?)",
96✔
1153
            3, 3, 3, true, false);
1154
  }
1155
  {
1156
    do_stmt("interlcace & no-preCreateTB", taos, &option,
96✔
1157
            "insert into stmt2_testdb_1.? using stb (t1,t2)tags(1,'abc') (ts,b)values(?,?)", 3, 3, 3, false, false);
1158
  }
1159
  {
1160
    do_stmt("interlcace & no-preCreateTB", taos, &option,
96✔
1161
            "insert into stmt2_testdb_1.stb (ts,b,tbname,t1,t2) values(?,?,?,?,?)", 3, 3, 3, true, false);
1162
  }
1163
  // interlace = 0
1164
  option = {0, false, false, NULL, NULL};
96✔
1165
  {
1166
    do_stmt("no-interlcace & no-preCreateTB", taos, &option,
96✔
1167
            "insert into ? using stb (t1,t2)tags(?,?) (ts,b)values(?,?)", 3, 3, 3, true, false);
1168
  }
1169
  {
1170
    do_stmt("no-interlcace & no-preCreateTB", taos, &option,
96✔
1171
            "insert into stmt2_testdb_1.stb (ts,b,tbname,t1,t2) values(?,?,?,?,?)", 3, 3, 3, true, false);
1172
  }
1173

1174
  do_query(taos, "drop database if exists stmt2_testdb_1");
96✔
1175
  (void)tsem_destroy(&aa->sem);
96✔
1176
  taosMemoryFree(aa);
96✔
1177
  taos_close(taos);
96✔
1178
}
1179

1180
// TD-33417
1181
// TS-6515
1182
// TD-35141
1183
// TS-6798
1184
TEST(stmt2Case, stmt2_insert_non_statndard) {
384✔
1185
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
1186
  ASSERT_NE(taos, nullptr);
96✔
1187
  do_query(taos, "drop database if exists stmt2_testdb_6");
96✔
1188
  do_query(taos, "create database IF NOT EXISTS stmt2_testdb_6");
96✔
1189
  do_query(taos,
96✔
1190
           "create stable stmt2_testdb_6.stb1  (ts timestamp, int_col int,long_col bigint,double_col "
1191
           "double,bool_col bool,binary_col binary(1),nchar_col nchar(20),varbinary_col varbinary(20),geometry_col "
1192
           "geometry(200)) tags(int_tag int,long_tag bigint,double_tag double,bool_tag bool,binary_tag "
1193
           "binary(20),nchar_tag nchar(20),varbinary_tag varbinary(20),geometry_tag geometry(200));");
1194
  do_query(taos, "use stmt2_testdb_6");
96✔
1195
  do_error_query(taos, "INSERT INTO stmt2_testdb_6.stb1 (tbname,ts)VALUES (?,?)", TSDB_CODE_TSC_INVALID_OPERATION);
96✔
1196

1197
  TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
1198

1199
  // less cols and tags using stb
1200
  {
1201
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
1202
    ASSERT_NE(stmt, nullptr);
96✔
1203
    const char* sql = "INSERT INTO stmt2_testdb_6.? using stmt2_testdb_6.stb1 (int_tag)tags(1) (ts)  VALUES (?)";
96✔
1204
    printf("stmt2 [%s] : %s\n", "less params", sql);
96✔
1205
    int code = taos_stmt2_prepare(stmt, sql, 0);
96✔
1206
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1207
    // test get fields
1208
    int             fieldNum = 0;
96✔
1209
    TAOS_FIELD_ALL* pFields = NULL;
96✔
1210
    code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
96✔
1211
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1212
    ASSERT_EQ(fieldNum, 2);
96✔
1213
    ASSERT_STREQ(pFields[0].name, "tbname");
96✔
1214
    ASSERT_STREQ(pFields[1].name, "ts");
96✔
1215
    taos_stmt2_free_fields(stmt, pFields);
96✔
1216

1217
    int total_affect_rows = 0;
96✔
1218

1219
    int     t64_len[2] = {sizeof(int64_t), sizeof(int64_t)};
96✔
1220
    int     tag_i = 0;
96✔
1221
    int     tag_l = sizeof(int);
96✔
1222
    int64_t ts[2] = {1591060628000, 1591060628100};
96✔
1223
    for (int i = 0; i < 3; i++) {
384✔
1224
      ts[0] += 1000;
288✔
1225
      ts[1] += 1000;
288✔
1226

1227
      TAOS_STMT2_BIND tags1 = {TSDB_DATA_TYPE_INT, &tag_i, &tag_l, NULL, 1};
288✔
1228
      TAOS_STMT2_BIND tags2 = {TSDB_DATA_TYPE_INT, &tag_i, &tag_l, NULL, 1};
288✔
1229
      TAOS_STMT2_BIND params1 = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len[0], NULL, 2};
288✔
1230
      TAOS_STMT2_BIND params2 = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len[0], NULL, 2};
288✔
1231

1232
      TAOS_STMT2_BIND* tagv[2] = {&tags1, &tags2};
288✔
1233
      TAOS_STMT2_BIND* paramv[2] = {&params1, &params2};
288✔
1234
      char*            tbname[2] = {"tb1", "tb2"};
288✔
1235
      TAOS_STMT2_BINDV bindv = {2, &tbname[0], tagv, &paramv[0]};
288✔
1236
      code = taos_stmt2_bind_param(stmt, &bindv, -1);
288✔
1237
      checkError(stmt, code, __FILE__, __LINE__);
288✔
1238

1239
      code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
288✔
1240
      checkError(stmt, code, __FILE__, __LINE__);
288✔
1241
      ASSERT_EQ(fieldNum, 2);
288✔
1242
      ASSERT_STREQ(pFields[0].name, "tbname");
288✔
1243
      ASSERT_STREQ(pFields[1].name, "ts");
288✔
1244
      taos_stmt2_free_fields(stmt, pFields);
288✔
1245

1246
      int affected_rows;
1247
      taos_stmt2_exec(stmt, &affected_rows);
288✔
1248
      total_affect_rows += affected_rows;
288✔
1249
      checkError(stmt, code, __FILE__, __LINE__);
288✔
1250

1251
      code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
288✔
1252
      checkError(stmt, code, __FILE__, __LINE__);
288✔
1253
      ASSERT_EQ(fieldNum, 2);
288✔
1254
      ASSERT_STREQ(pFields[0].name, "tbname");
288✔
1255
      ASSERT_STREQ(pFields[1].name, "ts");
288✔
1256
      taos_stmt2_free_fields(stmt, pFields);
288✔
1257
    }
1258

1259
    ASSERT_EQ(total_affect_rows, 12);
96✔
1260
    taos_stmt2_close(stmt);
96✔
1261
  }
1262

1263
  // less cols and tags
1264
  {
1265
    TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
1266
    TAOS_STMT2_OPTION option = {0, false, false, NULL, NULL};
96✔
1267
    ASSERT_NE(stmt, nullptr);
96✔
1268
    const char* sql = "INSERT INTO stmt2_testdb_6.stb1 (ts,int_tag,tbname)  VALUES (?,?,?)";
96✔
1269
    printf("stmt2 [%s] : %s\n", "less params", sql);
96✔
1270
    int code = taos_stmt2_prepare(stmt, sql, 0);
96✔
1271
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1272
    int total_affect_rows = 0;
96✔
1273

1274
    int     t64_len[2] = {sizeof(int64_t), sizeof(int64_t)};
96✔
1275
    int     tag_i = 0;
96✔
1276
    int     tag_l = sizeof(int);
96✔
1277
    int64_t ts[2] = {1591060628000, 1591060628100};
96✔
1278
    for (int i = 0; i < 3; i++) {
384✔
1279
      ts[0] += 1000;
288✔
1280
      ts[1] += 1000;
288✔
1281

1282
      TAOS_STMT2_BIND tags1 = {TSDB_DATA_TYPE_INT, &tag_i, &tag_l, NULL, 1};
288✔
1283
      TAOS_STMT2_BIND tags2 = {TSDB_DATA_TYPE_INT, &tag_i, &tag_l, NULL, 1};
288✔
1284
      TAOS_STMT2_BIND params1 = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len[0], NULL, 2};
288✔
1285
      TAOS_STMT2_BIND params2 = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len[0], NULL, 2};
288✔
1286

1287
      TAOS_STMT2_BIND* tagv[2] = {&tags1, &tags2};
288✔
1288
      TAOS_STMT2_BIND* paramv[2] = {&params1, &params2};
288✔
1289
      char*            tbname[2] = {"tb1", "tb2"};
288✔
1290
      TAOS_STMT2_BINDV bindv = {2, &tbname[0], &tagv[0], &paramv[0]};
288✔
1291
      code = taos_stmt2_bind_param(stmt, &bindv, -1);
288✔
1292
      checkError(stmt, code, __FILE__, __LINE__);
288✔
1293

1294
      int affected_rows;
1295
      taos_stmt2_exec(stmt, &affected_rows);
288✔
1296
      total_affect_rows += affected_rows;
288✔
1297

1298
      checkError(stmt, code, __FILE__, __LINE__);
288✔
1299
    }
1300

1301
    ASSERT_EQ(total_affect_rows, 12);
96✔
1302
    taos_stmt2_close(stmt);
96✔
1303
  }
1304

1305
  // disorder cols and tags
1306
  {
1307
    TAOS_STMT2_OPTION option = {0, false, false, NULL, NULL};
96✔
1308
    TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
1309
    ASSERT_NE(stmt, nullptr);
96✔
1310
    do_query(taos,
96✔
1311
             "INSERT INTO stmt2_testdb_6.stb1 (ts, int_tag, tbname)  VALUES (1591060627000, 5, 'tb5')(1591060627000, "
1312
             "6,'tb6') ");
1313
    const char* sql = "INSERT INTO stmt2_testdb_6.stb1 (binary_tag,int_col,tbname,ts,int_tag)  VALUES (?,?,?,?,?)";
96✔
1314
    printf("stmt2 [%s] : %s\n", "disorder params", sql);
96✔
1315
    int code = taos_stmt2_prepare(stmt, sql, 0);
96✔
1316
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1317

1318
    int     tag_i = 0;
96✔
1319
    int     tag_l = sizeof(int);
96✔
1320
    int     tag_bl = 3;
96✔
1321
    int64_t ts[2] = {1591060628000, 1591060628100};
96✔
1322
    int64_t ts_2[2] = {1591060628800, 1591060628900};
96✔
1323
    int     t64_len[2] = {sizeof(int64_t), sizeof(int64_t)};
96✔
1324
    int     coli[2] = {1, 2};
96✔
1325
    int     coli_2[2] = {3, 4};
96✔
1326
    int     ilen[2] = {sizeof(int), sizeof(int)};
96✔
1327
    int     total_affect_rows = 0;
96✔
1328
    for (int i = 0; i < 3; i++) {
384✔
1329
      ts[0] += 1000;
288✔
1330
      ts[1] += 1000;
288✔
1331
      ts_2[0] += 1000;
288✔
1332
      ts_2[1] += 1000;
288✔
1333

1334
      TAOS_STMT2_BIND tags[2][2] = {
288✔
1335
          {{TSDB_DATA_TYPE_BINARY, (void*)"abc", &tag_bl, NULL, 1}, {TSDB_DATA_TYPE_INT, &tag_i, &tag_l, NULL, 1}},
1336
          {{TSDB_DATA_TYPE_BINARY, (void*)"def", &tag_bl, NULL, 1}, {TSDB_DATA_TYPE_INT, &tag_i, &tag_l, NULL, 1}}};
288✔
1337
      TAOS_STMT2_BIND params[2][2] = {
288✔
1338
          {{TSDB_DATA_TYPE_INT, &coli[0], &ilen[0], NULL, 2}, {TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &t64_len[0], NULL, 2}},
1339
          {{TSDB_DATA_TYPE_INT, &coli_2[0], &ilen[0], NULL, 2},
1340
           {TSDB_DATA_TYPE_TIMESTAMP, &ts_2[0], &t64_len[0], NULL, 2}}};
288✔
1341

1342
      TAOS_STMT2_BIND* tagv[2] = {&tags[0][0], &tags[1][0]};
288✔
1343
      TAOS_STMT2_BIND* paramv[2] = {&params[0][0], &params[1][0]};
288✔
1344
      char*            tbname[2] = {"tb5", "tb6"};
288✔
1345
      TAOS_STMT2_BINDV bindv = {2, &tbname[0], &tagv[0], &paramv[0]};
288✔
1346
      code = taos_stmt2_bind_param(stmt, &bindv, -1);
288✔
1347
      checkError(stmt, code, __FILE__, __LINE__);
288✔
1348

1349
      int affected_rows;
1350
      taos_stmt2_exec(stmt, &affected_rows);
288✔
1351
      total_affect_rows += affected_rows;
288✔
1352
      checkError(stmt, code, __FILE__, __LINE__);
288✔
1353
    }
1354
    ASSERT_EQ(total_affect_rows, 12);
96✔
1355
    taos_stmt2_close(stmt);
96✔
1356
  }
1357

1358
  // pk error
1359
  {
1360
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
1361
    ASSERT_NE(stmt, nullptr);
96✔
1362
    const char* sql =
96✔
1363
        "INSERT INTO stmt2_testdb_6.? using  stmt2_testdb_6.stb1 (int_tag)tags(1) (int_col,ts)VALUES (?,?)";
1364
    printf("stmt2 [%s] : %s\n", "PK error", sql);
96✔
1365
    int code = taos_stmt2_prepare(stmt, sql, 0);
96✔
1366
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1367

1368
    int     tag_i = 0;
96✔
1369
    int     tag_l = sizeof(int);
96✔
1370
    int     tag_bl = 3;
96✔
1371
    int64_t ts[2] = {1591060628000, NULL};
96✔
1372
    int     t64_len[2] = {sizeof(int64_t), sizeof(int64_t)};
96✔
1373
    int     coli[2] = {1, 2};
96✔
1374
    int     ilen[2] = {sizeof(int), sizeof(int)};
96✔
1375
    int     total_affect_rows = 0;
96✔
1376
    char    is_null[2] = {1, 1};
96✔
1377

1378
    TAOS_STMT2_BIND params1[2] = {{TSDB_DATA_TYPE_INT, &coli, &ilen[0], is_null, 2},
96✔
1379
                                  {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len[0], is_null, 2}};
96✔
1380

1381
    TAOS_STMT2_BIND* paramv = &params1[0];
96✔
1382
    char*            tbname = "tb3";
96✔
1383
    TAOS_STMT2_BINDV bindv = {1, &tbname, NULL, &paramv};
96✔
1384
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
1385
    ASSERT_EQ(code, TSDB_CODE_PAR_PRIMARY_KEY_IS_NULL);
96✔
1386

1387
    taos_stmt2_close(stmt);
96✔
1388
  }
1389
  // TD-34123 disorder pk ts
1390
  {
1391
    do_query(taos, "create stable stmt2_testdb_6.stb2  (ts timestamp, int_col int PRIMARY KEY) tags(int_tag int);");
96✔
1392
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
1393
    ASSERT_NE(stmt, nullptr);
96✔
1394
    const char* sql =
96✔
1395
        "INSERT INTO stmt2_testdb_6.? using  stmt2_testdb_6.stb2 (int_tag)tags(1) (ts,int_col)VALUES (?,?)";
1396
    printf("stmt2 [%s] : %s\n", "disorder pk ts", sql);
96✔
1397
    int code = taos_stmt2_prepare(stmt, sql, 0);
96✔
1398
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1399

1400
    int     tag_i = 0;
96✔
1401
    int     tag_l = sizeof(int);
96✔
1402
    int     tag_bl = 3;
96✔
1403
    int64_t ts[5] = {1591060628003, 1591060628002, 1591060628002, 1591060628002, 1591060628001};
96✔
1404
    int     t64_len[5] = {sizeof(int64_t), sizeof(int64_t), sizeof(int64_t), sizeof(int64_t), sizeof(int64_t)};
96✔
1405
    int     coli[5] = {1, 4, 4, 3, 2};
96✔
1406
    int     ilen[5] = {sizeof(int), sizeof(int), sizeof(int), sizeof(int), sizeof(int)};
96✔
1407
    char    is_null[2] = {1, 1};
96✔
1408

1409
    TAOS_STMT2_BIND params1[2] = {
96✔
1410
        {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len[0], NULL, 5},
1411
        {TSDB_DATA_TYPE_INT, &coli, &ilen[0], NULL, 5},
1412
    };
96✔
1413

1414
    TAOS_STMT2_BIND* paramv = &params1[0];
96✔
1415
    char*            tbname = "tb3";
96✔
1416
    TAOS_STMT2_BINDV bindv = {1, &tbname, NULL, &paramv};
96✔
1417
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
1418
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1419

1420
    int affected_rows;
1421
    taos_stmt2_exec(stmt, &affected_rows);
96✔
1422
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1423
    ASSERT_EQ(affected_rows, 4);
96✔
1424

1425
    int64_t         ts2[2] = {1591060628003, 1591060628002};
96✔
1426
    int             t64_len2[2] = {sizeof(int64_t), sizeof(int64_t)};
96✔
1427
    int             coli2[2] = {1, 2};
96✔
1428
    int             ilen2[2] = {sizeof(int), sizeof(int)};
96✔
1429
    TAOS_STMT2_BIND params2[2] = {
96✔
1430
        {TSDB_DATA_TYPE_TIMESTAMP, &ts2, &t64_len2[0], NULL, 2},
1431
        {TSDB_DATA_TYPE_INT, &coli2, &ilen2[0], NULL, 2},
1432
    };
96✔
1433
    TAOS_STMT2_BIND* paramv2 = &params2[0];
96✔
1434
    TAOS_STMT2_BINDV bindv2 = {1, &tbname, NULL, &paramv2};
96✔
1435
    code = taos_stmt2_bind_param(stmt, &bindv2, -1);
96✔
1436
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1437

1438
    int affected_rows2;
1439
    taos_stmt2_exec(stmt, &affected_rows2);
96✔
1440
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1441
    ASSERT_EQ(affected_rows2, 2);
96✔
1442

1443
    taos_stmt2_close(stmt);
96✔
1444
  }
1445

1446
  // get fields insert into ? valuse
1447
  {
1448
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
1449
    ASSERT_NE(stmt, nullptr);
96✔
1450
    do_query(taos, "create table stmt2_testdb_6.ntb(ts timestamp, b binary(10))");
96✔
1451
    do_query(taos, "use stmt2_testdb_6");
96✔
1452
    const char* sql = "INSERT INTO ? VALUES (?,?)";
96✔
1453
    printf("stmt2 [%s] : %s\n", "get fields", sql);
96✔
1454
    int code = taos_stmt2_prepare(stmt, sql, 0);
96✔
1455
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1456

1457
    char*            tbname = "ntb";
96✔
1458
    TAOS_STMT2_BINDV bindv = {1, &tbname, NULL, NULL};
96✔
1459
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
1460
    ASSERT_EQ(code, 0);
96✔
1461

1462
    int             fieldNum = 0;
96✔
1463
    TAOS_FIELD_ALL* pFields = NULL;
96✔
1464
    code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
96✔
1465
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1466
    ASSERT_EQ(fieldNum, 3);
96✔
1467
    ASSERT_STREQ(pFields[0].name, "tbname");
96✔
1468
    ASSERT_STREQ(pFields[1].name, "ts");
96✔
1469
    ASSERT_STREQ(pFields[2].name, "b");
96✔
1470
    taos_stmt2_free_fields(stmt, pFields);
96✔
1471

1472
    taos_stmt2_close(stmt);
96✔
1473
  }
1474

1475
  // null sql
1476
  {
1477
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
1478
    ASSERT_NE(stmt, nullptr);
96✔
1479
    const char* sql = "";
96✔
1480
    printf("stmt2 [%s] : %s\n", "null sql", sql);
96✔
1481
    int code = taos_stmt2_prepare(stmt, sql, 0);
96✔
1482
    ASSERT_EQ(code, TSDB_CODE_PAR_SYNTAX_ERROR);
96✔
1483
    ASSERT_STREQ(taos_stmt2_error(stmt), "stmt only support 'SELECT' or 'INSERT'");
96✔
1484

1485
    taos_stmt2_close(stmt);
96✔
1486
  }
1487

1488
  // TS-6798 alter schema
1489
  {
1490
    do_query(taos, "alter stable stmt2_testdb_6.stb1 DROP COLUMN int_col");
96✔
1491
    do_query(taos, "alter stable stmt2_testdb_6.stb1 ADD COLUMN int_col_new int");
96✔
1492
    do_query(taos, "alter stable stmt2_testdb_6.stb1 MODIFY COLUMN binary_col binary(10)");
96✔
1493

1494
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
1495
    ASSERT_NE(stmt, nullptr);
96✔
1496
    const char* sql =
96✔
1497
        "INSERT INTO stmt2_testdb_6.? using stmt2_testdb_6.stb1 "
1498
        "(int_tag,binary_tag)tags(?,?) "
1499
        "(ts,varbinary_col,binary_col,int_col_new)VALUES (?,?,?,?)";
1500
    printf("stmt2 [%s] : %s\n", "alter schema", sql);
96✔
1501
    int code = taos_stmt2_prepare(stmt, sql, 0);
96✔
1502
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1503

1504
    int             fieldNum = 0;
96✔
1505
    TAOS_FIELD_ALL* pFields = NULL;
96✔
1506
    code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
96✔
1507
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1508
    ASSERT_EQ(fieldNum, 7);
96✔
1509
    taos_stmt2_free_fields(stmt, pFields);
96✔
1510

1511
    int total_affect_rows = 0;
96✔
1512

1513
    int     t64_len[2] = {sizeof(int64_t), sizeof(int64_t)};
96✔
1514
    int     tag_i = 0;
96✔
1515
    int     tag_l = sizeof(int);
96✔
1516
    int64_t ts[2] = {1591060628000, 1591060628100};
96✔
1517
    for (int i = 0; i < 3; i++) {
384✔
1518
      ts[0] += 1000;
288✔
1519
      ts[1] += 1000;
288✔
1520

1521
      int  tag_i = 1 + i;
288✔
1522
      int  tag_l = sizeof(int);
288✔
1523
      int  tag_bl = 3;
288✔
1524
      char tag_binary[2][4] = {"abc", "def"};
288✔
1525

1526
      int   coli[2] = {100 + i, 200 + i};
288✔
1527
      int   ilen[2] = {sizeof(int), sizeof(int)};
288✔
1528
      bool  bool_val[2] = {true, false};
288✔
1529
      int   bool_len[2] = {sizeof(bool), sizeof(bool)};
288✔
1530
      char* varbinary_val = "xyzuvw";
288✔
1531
      int   varbinary_len[2] = {3, 3};
288✔
1532

1533
      TAOS_STMT2_BIND tags[2][2] = {
288✔
1534
          {{TSDB_DATA_TYPE_INT, &tag_i, &tag_l, NULL, 1}, {TSDB_DATA_TYPE_BINARY, tag_binary[0], &tag_bl, NULL, 1}},
1535
          {{TSDB_DATA_TYPE_INT, &tag_i, &tag_l, NULL, 1}, {TSDB_DATA_TYPE_BINARY, tag_binary[1], &tag_bl, NULL, 1}}};
288✔
1536

1537
      TAOS_STMT2_BIND params[2][4] = {{{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &t64_len[0], NULL, 2},
288✔
1538
                                       {TSDB_DATA_TYPE_VARBINARY, &varbinary_val[0], &varbinary_len[0], NULL, 2},
1539
                                       {TSDB_DATA_TYPE_BINARY, &varbinary_val[0], &varbinary_len[0], NULL, 2},
1540
                                       {TSDB_DATA_TYPE_INT, &coli[0], &ilen[0], NULL, 2}},
1541
                                      {{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &t64_len[0], NULL, 2},
1542
                                       {TSDB_DATA_TYPE_VARBINARY, &varbinary_val[0], &varbinary_len[0], NULL, 2},
1543
                                       {TSDB_DATA_TYPE_BINARY, &varbinary_val[0], &varbinary_len[0], NULL, 2},
1544
                                       {TSDB_DATA_TYPE_INT, &coli[0], &ilen[0], NULL, 2}}};
288✔
1545

1546
      TAOS_STMT2_BIND* tagv[2] = {&tags[0][0], &tags[1][0]};
288✔
1547
      TAOS_STMT2_BIND* paramv[2] = {&params[0][0], &params[1][0]};
288✔
1548
      char*            tbname[2] = {"tb1", "tb2"};
288✔
1549

1550
      TAOS_STMT2_BINDV bindv = {2, &tbname[0], &tagv[0], &paramv[0]};
288✔
1551
      code = taos_stmt2_bind_param(stmt, &bindv, -1);
288✔
1552
      checkError(stmt, code, __FILE__, __LINE__);
288✔
1553

1554
      int affected_rows;
1555
      code = taos_stmt2_exec(stmt, &affected_rows);
288✔
1556
      checkError(stmt, code, __FILE__, __LINE__);
288✔
1557
      total_affect_rows += affected_rows;
288✔
1558
    }
1559

1560
    ASSERT_EQ(total_affect_rows, 12);
96✔
1561
    taos_stmt2_close(stmt);
96✔
1562
  }
1563

1564
  do_query(taos, "drop database if exists stmt2_testdb_6");
96✔
1565
  taos_close(taos);
96✔
1566
}
1567

1568
void asyncInsertDB(void* param, TAOS_RES* pRes, int code) {
288✔
1569
  ASSERT_EQ(code, TSDB_CODE_SUCCESS);
288✔
1570
  return;
288✔
1571
}
1572

1573
// TD-33419
1574
// TD-34075
1575
// TD-34504
1576
TEST(stmt2Case, stmt2_insert_db) {
384✔
1577
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
1578
  ASSERT_NE(taos, nullptr);
96✔
1579
  do_query(taos, "drop database if exists stmt2_testdb_12");
96✔
1580
  do_query(taos, "create database IF NOT EXISTS stmt2_testdb_12");
96✔
1581
  do_query(taos, "create stable `stmt2_testdb_12`.`stb1`(ts timestamp, int_col int) tags(int_tag int)");
96✔
1582
  do_query(taos,
96✔
1583
           "INSERT INTO `stmt2_testdb_12`.`stb1` (ts,int_tag,tbname)  VALUES "
1584
           "(1591060627000,1,'tb1')(1591060627000,2,'tb2')");
1585

1586
  TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
1587

1588
  // test 1
1589
  TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
1590
  ASSERT_NE(stmt, nullptr);
96✔
1591
  const char* sql = "INSERT INTO `stmt2_testdb_12`.`stb1` (ts,int_tag,tbname)  VALUES (?,?,?)";
96✔
1592

1593
  int     t64_len[2] = {sizeof(int64_t), sizeof(int64_t)};
96✔
1594
  int     tag_i = 0;
96✔
1595
  int     tag_l = sizeof(int);
96✔
1596
  int64_t ts[2] = {1591060628000, 1591060628100};
96✔
1597
  int     total_affect_rows = 0;
96✔
1598

1599
  TAOS_STMT2_BIND tags1 = {TSDB_DATA_TYPE_INT, &tag_i, &tag_l, NULL, 1};
96✔
1600
  TAOS_STMT2_BIND tags2 = {TSDB_DATA_TYPE_INT, &tag_i, &tag_l, NULL, 1};
96✔
1601
  TAOS_STMT2_BIND params1 = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len[0], NULL, 2};
96✔
1602
  TAOS_STMT2_BIND params2 = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len[0], NULL, 2};
96✔
1603

1604
  TAOS_STMT2_BIND* tagv[2] = {&tags1, &tags2};
96✔
1605
  TAOS_STMT2_BIND* paramv[2] = {&params1, &params2};
96✔
1606
  char*            tbname[2] = {"tb1", "tb2"};
96✔
1607
  TAOS_STMT2_BINDV bindv = {2, &tbname[0], &tagv[0], &paramv[0]};
96✔
1608

1609
  for (int i = 0; i < 3; i++) {
384✔
1610
    int code = taos_stmt2_prepare(stmt, sql, 0);
288✔
1611
    checkError(stmt, code, __FILE__, __LINE__);
288✔
1612

1613
    ts[0] += 1000;
288✔
1614
    ts[1] += 1000;
288✔
1615

1616
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
288✔
1617
    checkError(stmt, code, __FILE__, __LINE__);
288✔
1618

1619
    int affected_rows;
1620
    code = taos_stmt2_exec(stmt, &affected_rows);
288✔
1621
    total_affect_rows += affected_rows;
288✔
1622
    checkError(stmt, code, __FILE__, __LINE__);
288✔
1623
  }
1624

1625
  ASSERT_EQ(total_affect_rows, 12);
96✔
1626
  taos_stmt2_close(stmt);
96✔
1627

1628
  // test 2
1629
  total_affect_rows = 0;
96✔
1630
  option = {0, false, false, NULL, NULL};
96✔
1631
  do_query(taos, "use stmt2_testdb_12");
96✔
1632
  stmt = taos_stmt2_init(taos, &option);
96✔
1633
  ASSERT_NE(stmt, nullptr);
96✔
1634
  sql = "INSERT INTO stb1 (ts,int_tag,tbname)  VALUES (?,?,?)";
96✔
1635

1636
  for (int i = 0; i < 3; i++) {
384✔
1637
    int code = taos_stmt2_prepare(stmt, sql, 0);
288✔
1638
    checkError(stmt, code, __FILE__, __LINE__);
288✔
1639

1640
    ts[0] += 1000;
288✔
1641
    ts[1] += 1000;
288✔
1642

1643
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
288✔
1644
    checkError(stmt, code, __FILE__, __LINE__);
288✔
1645

1646
    int affected_rows;
1647
    taos_stmt2_exec(stmt, &affected_rows);
288✔
1648
    total_affect_rows += affected_rows;
288✔
1649
    checkError(stmt, code, __FILE__, __LINE__);
288✔
1650
  }
1651

1652
  ASSERT_EQ(total_affect_rows, 12);
96✔
1653
  taos_stmt2_close(stmt);
96✔
1654

1655
  // test 3
1656
  option = {0, true, true, asyncInsertDB, NULL};
96✔
1657
  do_query(taos, "use stmt2_testdb_12");
96✔
1658
  stmt = taos_stmt2_init(taos, &option);
96✔
1659
  ASSERT_NE(stmt, nullptr);
96✔
1660
  sql = "INSERT INTO stb1 (ts,int_tag,tbname)  VALUES (?,?,?)";
96✔
1661

1662
  for (int i = 0; i < 3; i++) {
384✔
1663
    int code = taos_stmt2_prepare(stmt, sql, 0);
288✔
1664
    checkError(stmt, code, __FILE__, __LINE__);
288✔
1665

1666
    ts[0] += 1000;
288✔
1667
    ts[1] += 1000;
288✔
1668

1669
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
288✔
1670
    checkError(stmt, code, __FILE__, __LINE__);
288✔
1671

1672
    code = taos_stmt2_exec(stmt, NULL);
288✔
1673
    checkError(stmt, code, __FILE__, __LINE__);
288✔
1674
  }
1675

1676
  taos_stmt2_close(stmt);
96✔
1677

1678
  do_query(taos, "drop database if exists stmt2_testdb_12");
96✔
1679
  taos_close(taos);
96✔
1680
}
1681

1682
TEST(stmt2Case, stmt2_insert_duplicate) {
384✔
1683
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
1684
  ASSERT_NE(taos, nullptr);
96✔
1685
  do_query(taos, "drop database if exists stmt2_testdb_18");
96✔
1686
  do_query(taos, "create database IF NOT EXISTS stmt2_testdb_18");
96✔
1687
  do_query(taos, "create stable `stmt2_testdb_18`.`stb1`(ts timestamp, int_col int) tags(int_tag int)");
96✔
1688
  do_query(taos, "create stable `stmt2_testdb_18`.`stb2`(ts timestamp, int_col int) tags(int_tag int)");
96✔
1689
  do_query(taos, "create table `stmt2_testdb_18`.`tb1` using `stmt2_testdb_18`.`stb1` (int_tag)tags(1)");
96✔
1690
  TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
1691

1692
  // test 1
1693
  TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
1694
  ASSERT_NE(stmt, nullptr);
96✔
1695
  const char* sql = "INSERT INTO `stmt2_testdb_18`.`stb1` (ts,int_col,int_tag,tbname)  VALUES (?,?,?,?)";
96✔
1696
  int         code = taos_stmt2_prepare(stmt, sql, 0);
96✔
1697
  checkError(stmt, code, __FILE__, __LINE__);
96✔
1698

1699
  int     t64_len[2] = {sizeof(int64_t), sizeof(int64_t)};
96✔
1700
  int     tag_i[2] = {1, 2};
96✔
1701
  int     tag_l[2] = {sizeof(int), sizeof(int)};
96✔
1702
  int64_t ts[2] = {1591060628000, 1591060629000};
96✔
1703
  int     total_affect_rows = 0;
96✔
1704

1705
  TAOS_STMT2_BIND params1[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &t64_len[0], NULL, 2},
96✔
1706
                                {TSDB_DATA_TYPE_INT, &tag_i[0], &tag_l[0], NULL, 2}};
96✔
1707

1708
  TAOS_STMT2_BIND* paramv = &params1[0];
96✔
1709
  char*            tbname[2] = {"tb1"};
96✔
1710

1711
  TAOS_STMT2_BINDV bindv = {1, &tbname[0], NULL, &paramv};
96✔
1712

1713
  for (int i = 0; i < 3; i++) {
384✔
1714
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
288✔
1715
    checkError(stmt, code, __FILE__, __LINE__);
288✔
1716
  }
1717
  int affected_rows;
1718
  code = taos_stmt2_exec(stmt, &affected_rows);
96✔
1719
  ASSERT_EQ(affected_rows, 2);
96✔
1720
  checkError(stmt, code, __FILE__, __LINE__);  // ASSERT_STREQ(taos_stmt2_error(stmt), "Table name duplicated");
96✔
1721

1722
  char*           tbname2[2] = {"tb2", "tb3"};
96✔
1723
  TAOS_STMT2_BIND paramv2[2][2]{
96✔
1724
      {{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &t64_len[0], NULL, 2}, {TSDB_DATA_TYPE_INT, &tag_i[0], &tag_l[0], NULL, 2}},
1725
      {{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &t64_len[0], NULL, 2}, {TSDB_DATA_TYPE_INT, &tag_i[0], &tag_l[0], NULL, 2}}};
96✔
1726
  TAOS_STMT2_BIND* paramvs2[2] = {&paramv2[0][0], &paramv2[1][0]};
96✔
1727
  TAOS_STMT2_BINDV bindv2 = {2, &tbname2[0], NULL, &paramvs2[0]};
96✔
1728
  for (int i = 0; i < 3; i++) {
384✔
1729
    code = taos_stmt2_bind_param(stmt, &bindv2, -1);
288✔
1730
    checkError(stmt, code, __FILE__, __LINE__);
288✔
1731
  }
1732

1733
  code = taos_stmt2_exec(stmt, &affected_rows);
96✔
1734
  ASSERT_EQ(affected_rows, 4);
96✔
1735
  checkError(stmt, code, __FILE__, __LINE__);
96✔
1736

1737
  taos_stmt2_close(stmt);
96✔
1738

1739
  TAOS_RES* pRes = taos_query(taos, "select * from `stmt2_testdb_18`.`tb1`");
96✔
1740
  ASSERT_NE(pRes, nullptr);
96✔
1741

1742
  int getRecordCounts = 0;
96✔
1743
  while ((taos_fetch_row(pRes))) {
288✔
1744
    getRecordCounts++;
192✔
1745
  }
1746
  ASSERT_EQ(getRecordCounts, 2);
96✔
1747
  taos_free_result(pRes);
96✔
1748

1749
  pRes = taos_query(taos, "select * from `stmt2_testdb_18`.`tb2`");
96✔
1750
  ASSERT_NE(pRes, nullptr);
96✔
1751

1752
  getRecordCounts = 0;
96✔
1753
  while ((taos_fetch_row(pRes))) {
288✔
1754
    getRecordCounts++;
192✔
1755
  }
1756
  ASSERT_EQ(getRecordCounts, 2);
96✔
1757
  taos_free_result(pRes);
96✔
1758

1759
  pRes = taos_query(taos, "select * from `stmt2_testdb_18`.`tb3`");
96✔
1760
  ASSERT_NE(pRes, nullptr);
96✔
1761

1762
  getRecordCounts = 0;
96✔
1763
  while ((taos_fetch_row(pRes))) {
288✔
1764
    getRecordCounts++;
192✔
1765
  }
1766
  ASSERT_EQ(getRecordCounts, 2);
96✔
1767
  taos_free_result(pRes);
96✔
1768

1769
  // no interlace mode
1770
  option = {0, false, false, NULL, NULL};
96✔
1771
  stmt = taos_stmt2_init(taos, &option);
96✔
1772
  code = taos_stmt2_prepare(stmt, sql, 0);
96✔
1773
  checkError(stmt, code, __FILE__, __LINE__);
96✔
1774

1775
  for (int i = 0; i < 3; i++) {
384✔
1776
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
288✔
1777
    checkError(stmt, code, __FILE__, __LINE__);
288✔
1778
  }
1779
  code = taos_stmt2_exec(stmt, &affected_rows);
96✔
1780
  ASSERT_EQ(affected_rows, 2);
96✔
1781
  checkError(stmt, code, __FILE__, __LINE__);  // ASSERT_STREQ(taos_stmt2_error(stmt), "Table name duplicated");
96✔
1782
  taos_stmt2_close(stmt);
96✔
1783

1784
  pRes = taos_query(taos, "select * from `stmt2_testdb_18`.`tb1`");
96✔
1785
  ASSERT_NE(pRes, nullptr);
96✔
1786

1787
  getRecordCounts = 0;
96✔
1788
  while ((taos_fetch_row(pRes))) {
288✔
1789
    getRecordCounts++;
192✔
1790
  }
1791
  ASSERT_EQ(getRecordCounts, 2);
96✔
1792
  taos_free_result(pRes);
96✔
1793

1794
  // insert same tbname from different stb
1795
  option = {0, false, false, NULL, NULL};
96✔
1796
  stmt = taos_stmt2_init(taos, &option);
96✔
1797
  code =
96✔
1798
      taos_stmt2_prepare(stmt, "INSERT INTO `stmt2_testdb_18`.`stb2` (ts,int_col,int_tag,tbname)  VALUES (?,?,?,?)", 0);
96✔
1799
  checkError(stmt, code, __FILE__, __LINE__);
96✔
1800
  char*            tbname3[2] = {"tb1", "tb10"};
96✔
1801
  TAOS_STMT2_BIND  tag = {TSDB_DATA_TYPE_INT, &tag_i[0], &tag_l[0], NULL, 1};
96✔
1802
  TAOS_STMT2_BIND* pTag[2] = {&tag, &tag};
96✔
1803
  TAOS_STMT2_BINDV bindv3 = {2, &tbname3[0], &pTag[0], &paramvs2[0]};
96✔
1804

1805
  code = taos_stmt2_bind_param(stmt, &bindv3, -1);
96✔
1806
  checkError(stmt, code, __FILE__, __LINE__);
96✔
1807
  code = taos_stmt2_exec(stmt, &affected_rows);
96✔
1808
  ASSERT_EQ(code, TSDB_CODE_TDB_TABLE_IN_OTHER_STABLE);
96✔
1809

1810
  stmt = taos_stmt2_init(taos, &option);
96✔
1811
  taos_stmt2_prepare(stmt, "INSERT INTO `stmt2_testdb_18`.`stb2` (ts,int_col,tbname)  VALUES (?,?,?)", 0);
96✔
1812
  bindv3 = {1, &tbname3[0], NULL, &paramvs2[0]};
96✔
1813
  code = taos_stmt2_bind_param(stmt, &bindv3, -1);
96✔
1814
  checkError(stmt, code, __FILE__, __LINE__);
96✔
1815
  code = taos_stmt2_exec(stmt, &affected_rows);
96✔
1816
  ASSERT_EQ(code, TSDB_CODE_TDB_TABLE_IN_OTHER_STABLE);
96✔
1817

1818
  taos_stmt2_close(stmt);
96✔
1819

1820
  do_query(taos, "drop database if exists stmt2_testdb_18");
96✔
1821
  taos_close(taos);
96✔
1822
}
1823

1824
void taos_retrieve_call_back(void* param, TAOS_RES* tres, int numOfRows) {
576✔
1825
  if (numOfRows > 0) {
576✔
1826
    // synchronous API to retrieve a row from batch of records
1827
    TAOS_ROW row = taos_fetch_row(tres);
288✔
1828
    ASSERT_NE(row, nullptr);
288✔
1829
    ASSERT_EQ(strncmp((char*)row[0], "tb1", 3), 0);
288✔
1830
    ASSERT_EQ(strncmp((char*)row[1], "abc", 3), 0);
288✔
1831
    ASSERT_EQ(strncmp((char*)row[2], "abc", 3), 0);
288✔
1832

1833
    row = taos_fetch_row(tres);
288✔
1834
    ASSERT_NE(row, nullptr);
288✔
1835
    ASSERT_EQ(strncmp((char*)row[0], "tb2", 3), 0);
288✔
1836
    ASSERT_EQ(strncmp((char*)row[1], "xyz", 3), 0);
288✔
1837
    ASSERT_EQ(strncmp((char*)row[2], "abc", 3), 0);
288✔
1838
    taos_fetch_rows_a(tres, taos_retrieve_call_back, param);
288✔
1839

1840
  } else {
1841
    ASSERT_EQ(tsem_post(&((AsyncArgs*)param)->sem), TSDB_CODE_SUCCESS);
288✔
1842
  }
1843
}
1844

1845
void asyncExec(void* param, TAOS_RES* res, int code) {
288✔
1846
  ASSERT_EQ(code, TSDB_CODE_SUCCESS);
288✔
1847
  taos_fetch_rows_a(res, taos_retrieve_call_back, param);
288✔
1848
  return;
288✔
1849
}
1850

1851
TEST(stmt2Case, query) {
384✔
1852
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
1853
  ASSERT_NE(taos, nullptr);
96✔
1854
  do_query(taos, "drop database if exists stmt2_testdb_7");
96✔
1855
  do_query(taos, "create database IF NOT EXISTS stmt2_testdb_7");
96✔
1856
  do_query(taos, "create stable stmt2_testdb_7.stb (ts timestamp, b binary(10)) tags(t1 int, t2 binary(10))");
96✔
1857
  do_query(taos,
96✔
1858
           "insert into stmt2_testdb_7.tb1 using stmt2_testdb_7.stb tags(1,'abc') values(1591060628000, "
1859
           "'abc'),(1591060628001,'def'),(1591060628002, 'hij')");
1860
  do_query(taos,
96✔
1861
           "insert into stmt2_testdb_7.tb2 using stmt2_testdb_7.stb tags(2,'xyz') values(1591060628000, "
1862
           "'abc'),(1591060628001,'def'),(1591060628004, 'hij')");
1863
  do_query(taos, "use stmt2_testdb_7");
96✔
1864

1865
  // sync query
1866
  {
1867
    TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
1868

1869
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
1870
    ASSERT_NE(stmt, nullptr);
96✔
1871

1872
    const char* sql = "select tbname,t2,b from stmt2_testdb_7.stb where ts = ? order by tbname";
96✔
1873
    int         code = taos_stmt2_prepare(stmt, sql, 0);
96✔
1874
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1875

1876
    int             fieldNum = 0;
96✔
1877
    TAOS_FIELD_ALL* pFields = NULL;
96✔
1878
    code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
96✔
1879
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1880
    ASSERT_EQ(fieldNum, 1);
96✔
1881

1882
    int              t64_len = sizeof(int64_t);
96✔
1883
    int64_t          ts = 1591060628000;
96✔
1884
    TAOS_STMT2_BIND  params = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len, NULL, 1};
96✔
1885
    TAOS_STMT2_BIND* paramv = &params;
96✔
1886
    TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &paramv};
96✔
1887
    for (int i = 0; i < 3; i++) {
384✔
1888
      code = taos_stmt2_bind_param(stmt, &bindv, -1);
288✔
1889
      checkError(stmt, code, __FILE__, __LINE__);
288✔
1890

1891
      taos_stmt2_exec(stmt, NULL);
288✔
1892
      checkError(stmt, code, __FILE__, __LINE__);
288✔
1893

1894
      TAOS_RES* pRes = taos_stmt2_result(stmt);
288✔
1895
      ASSERT_NE(pRes, nullptr);
288✔
1896
      TAOS_ROW row = taos_fetch_row(pRes);
288✔
1897
      ASSERT_NE(row, nullptr);
288✔
1898
      ASSERT_EQ(strncmp((char*)row[0], "tb1", 3), 0);
288✔
1899
      ASSERT_EQ(strncmp((char*)row[1], "abc", 3), 0);
288✔
1900
      ASSERT_EQ(strncmp((char*)row[2], "abc", 3), 0);
288✔
1901
      row = taos_fetch_row(pRes);
288✔
1902
      ASSERT_NE(row, nullptr);
288✔
1903
      ASSERT_EQ(strncmp((char*)row[0], "tb2", 3), 0);
288✔
1904
      ASSERT_EQ(strncmp((char*)row[1], "xyz", 3), 0);
288✔
1905
      ASSERT_EQ(strncmp((char*)row[2], "abc", 3), 0);
288✔
1906
    }
1907

1908
    taos_stmt2_close(stmt);
96✔
1909
  }
1910

1911
  // async query with async fetch
1912
  {
1913
    AsyncArgs* aa = (AsyncArgs*)taosMemoryMalloc(sizeof(AsyncArgs));
96✔
1914
    aa->async_affected_rows = 0;
96✔
1915
    ASSERT_EQ(tsem_init(&aa->sem, 0, 0), TSDB_CODE_SUCCESS);
96✔
1916

1917
    TAOS_STMT2_OPTION option = {0, true, true, asyncExec, (void*)aa};
96✔
1918

1919
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
1920
    ASSERT_NE(stmt, nullptr);
96✔
1921

1922
    const char* sql = "select tbname,t2,b from stmt2_testdb_7.stb where ts = ? order by tbname";
96✔
1923
    int         code = taos_stmt2_prepare(stmt, sql, 0);
96✔
1924
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1925

1926
    int             fieldNum = 0;
96✔
1927
    TAOS_FIELD_ALL* pFields = NULL;
96✔
1928
    code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
96✔
1929
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1930
    ASSERT_EQ(fieldNum, 1);
96✔
1931

1932
    int              t64_len = sizeof(int64_t);
96✔
1933
    int64_t          ts = 1591060628000;
96✔
1934
    TAOS_STMT2_BIND  params = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len, NULL, 1};
96✔
1935
    TAOS_STMT2_BIND* paramv = &params;
96✔
1936
    TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &paramv};
96✔
1937

1938
    for (int i = 0; i < 3; i++) {
384✔
1939
      code = taos_stmt2_bind_param(stmt, &bindv, -1);
288✔
1940
      checkError(stmt, code, __FILE__, __LINE__);
288✔
1941

1942
      taos_stmt2_exec(stmt, NULL);
288✔
1943
      checkError(stmt, code, __FILE__, __LINE__);
288✔
1944

1945
      tsem_wait(&aa->sem);
288✔
1946
    }
1947

1948
    tsem_destroy(&aa->sem);
96✔
1949
    taosMemoryFree(aa);
96✔
1950
    taos_stmt2_close(stmt);
96✔
1951
  }
1952

1953
  {
1954
    TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
1955

1956
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
1957
    ASSERT_NE(stmt, nullptr);
96✔
1958

1959
    const char* sql =
96✔
1960
        "select table_name, db_name, stable_name from information_schema.ins_tables where 1 = 1 and table_name = ? and "
1961
        "db_name = ?";
1962
    int code = taos_stmt2_prepare(stmt, sql, 0);
96✔
1963
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1964

1965
    int             fieldNum = 0;
96✔
1966
    TAOS_FIELD_ALL* pFields = NULL;
96✔
1967
    code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
96✔
1968
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1969
    ASSERT_EQ(fieldNum, 2);
96✔
1970

1971
    int              b_len = 3;
96✔
1972
    int              b_len2 = 14;
96✔
1973
    TAOS_STMT2_BIND  params[2] = {{TSDB_DATA_TYPE_BINARY, (void*)"tb1", &b_len, NULL, 1},
96✔
1974
                                  {TSDB_DATA_TYPE_BINARY, (void*)"stmt2_testdb_7", &b_len2, NULL, 1}};
96✔
1975
    TAOS_STMT2_BIND* paramv = &params[0];
96✔
1976
    TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &paramv};
96✔
1977
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
1978
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1979

1980
    taos_stmt2_exec(stmt, NULL);
96✔
1981
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1982

1983
    TAOS_RES* pRes = taos_stmt2_result(stmt);
96✔
1984
    ASSERT_NE(pRes, nullptr);
96✔
1985
    TAOS_ROW row = taos_fetch_row(pRes);
96✔
1986
    ASSERT_NE(row, nullptr);
96✔
1987
    ASSERT_EQ(strncmp((char*)row[0], "tb1", 3), 0);
96✔
1988
    ASSERT_EQ(strncmp((char*)row[1], "stmt2_testdb_7", 14), 0);
96✔
1989
    ASSERT_EQ(strncmp((char*)row[2], "stb", 3), 0);
96✔
1990
    taos_stmt2_close(stmt);
96✔
1991
  }
1992
  {
1993
    TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
1994
    TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
1995
    ASSERT_NE(stmt, nullptr);
96✔
1996

1997
    int code = taos_stmt2_prepare(stmt, "select tbname,t2,b from stmt2_testdb_7.stb where ts = ? and tbname = ?", 0);
96✔
1998
    checkError(stmt, code, __FILE__, __LINE__);
96✔
1999

2000
    int32_t b_len = 3;
96✔
2001
    int32_t t64_len = sizeof(int64_t);
96✔
2002
    int64_t ts = 1591060628000;
96✔
2003

2004
    TAOS_STMT2_BIND  params2[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len, NULL, 1},
96✔
2005
                                   {TSDB_DATA_TYPE_BINARY, (void*)"tb1", &b_len, NULL, 1}};
96✔
2006
    TAOS_STMT2_BIND* paramv2[2] = {&params2[0], &params2[1]};
96✔
2007
    TAOS_STMT2_BINDV bindv2 = {1, NULL, NULL, &paramv2[0]};
96✔
2008

2009
    code = taos_stmt2_bind_param(stmt, &bindv2, -1);
96✔
2010
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2011

2012
    taos_stmt2_exec(stmt, NULL);
96✔
2013
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2014

2015
    TAOS_RES* pRes = taos_stmt2_result(stmt);
96✔
2016
    ASSERT_NE(pRes, nullptr);
96✔
2017

2018
    TAOS_ROW row = taos_fetch_row(pRes);
96✔
2019
    ASSERT_NE(row, nullptr);
96✔
2020
    ASSERT_EQ(strncmp((char*)row[0], "tb1", 3), 0);
96✔
2021
    ASSERT_EQ(strncmp((char*)row[1], "abc", 3), 0);
96✔
2022
    ASSERT_EQ(strncmp((char*)row[2], "abc", 3), 0);
96✔
2023

2024
    code = taos_stmt2_prepare(stmt, "select tbname,t2,b from stmt2_testdb_7.stb where ts = ? and tbname = 'tb2'", 0);
96✔
2025
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2026

2027
    TAOS_STMT2_BIND  params3 = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len, NULL, 1};
96✔
2028
    TAOS_STMT2_BIND* paramv3 = &params3;
96✔
2029
    TAOS_STMT2_BINDV bindv3 = {1, NULL, NULL, &paramv3};
96✔
2030
    code = taos_stmt2_bind_param(stmt, &bindv3, -1);
96✔
2031
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2032

2033
    taos_stmt2_exec(stmt, NULL);
96✔
2034
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2035
    pRes = taos_stmt2_result(stmt);
96✔
2036
    ASSERT_NE(pRes, nullptr);
96✔
2037
    row = taos_fetch_row(pRes);
96✔
2038
    ASSERT_NE(row, nullptr);
96✔
2039
    ASSERT_EQ(strncmp((char*)row[0], "tb2", 3), 0);
96✔
2040
    ASSERT_EQ(strncmp((char*)row[1], "xyz", 3), 0);
96✔
2041
    ASSERT_EQ(strncmp((char*)row[2], "abc", 3), 0);
96✔
2042
  }
2043

2044
  do_query(taos, "drop database if exists stmt2_testdb_7");
96✔
2045
  taos_close(taos);
96✔
2046
}
2047

2048
TEST(stmt2Case, query_use_adapter) {
384✔
2049
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
2050
  ASSERT_NE(taos, nullptr);
96✔
2051
  int32_t code = taos_options(TSDB_OPTION_USE_ADAPTER, "true");
96✔
2052
  ASSERT_EQ(code, TSDB_CODE_SUCCESS);
96✔
2053
  do_query(taos, "drop database if exists stmt2_testdb_37");
96✔
2054
  do_query(taos, "create database IF NOT EXISTS stmt2_testdb_37");
96✔
2055
  do_query(taos, "create stable stmt2_testdb_37.stb (ts timestamp, b binary(10)) tags(t1 int, t2 binary(10))");
96✔
2056
  do_query(taos,
96✔
2057
           "insert into stmt2_testdb_37.tb1 using stmt2_testdb_37.stb tags(1,'abc') values(1591060628000, "
2058
           "'abc'),(1591060628001,'def'),(1591060628002, 'hij')");
2059
  do_query(taos,
96✔
2060
           "insert into stmt2_testdb_37.tb2 using stmt2_testdb_37.stb tags(2,'xyz') values(1591060628000, "
2061
           "'abc'),(1591060628001,'def'),(1591060628004, 'hij')");
2062
  do_query(taos, "use stmt2_testdb_37");
96✔
2063

2064
  // sync query
2065
  {
2066
    TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
2067

2068
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
2069
    ASSERT_NE(stmt, nullptr);
96✔
2070

2071
    const char* sql = "select tbname,t2,b from stmt2_testdb_37.stb where ts = ? order by tbname";
96✔
2072
    int         code = taos_stmt2_prepare(stmt, sql, 0);
96✔
2073
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2074

2075
    for (int i = 0; i < 3; i++) {
384✔
2076
      int             fieldNum = 0;
288✔
2077
      TAOS_FIELD_ALL* pFields = NULL;
288✔
2078
      code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
288✔
2079
      checkError(stmt, code, __FILE__, __LINE__);
288✔
2080
      ASSERT_EQ(fieldNum, 1);
288✔
2081

2082
      int              t64_len = sizeof(int64_t);
288✔
2083
      int64_t          ts = 1591060628000;
288✔
2084
      TAOS_STMT2_BIND  params = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len, NULL, 1};
288✔
2085
      TAOS_STMT2_BIND* paramv = &params;
288✔
2086
      TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &paramv};
288✔
2087
      code = taos_stmt2_bind_param(stmt, &bindv, -1);
288✔
2088
      checkError(stmt, code, __FILE__, __LINE__);
288✔
2089

2090
      taos_stmt2_exec(stmt, NULL);
288✔
2091
      checkError(stmt, code, __FILE__, __LINE__);
288✔
2092

2093
      TAOS_RES* pRes = taos_stmt2_result(stmt);
288✔
2094
      ASSERT_NE(pRes, nullptr);
288✔
2095
      TAOS_ROW row = taos_fetch_row(pRes);
288✔
2096
      ASSERT_NE(row, nullptr);
288✔
2097
      ASSERT_EQ(strncmp((char*)row[0], "tb1", 3), 0);
288✔
2098
      ASSERT_EQ(strncmp((char*)row[1], "abc", 3), 0);
288✔
2099
      ASSERT_EQ(strncmp((char*)row[2], "abc", 3), 0);
288✔
2100
      row = taos_fetch_row(pRes);
288✔
2101
      ASSERT_NE(row, nullptr);
288✔
2102
      ASSERT_EQ(strncmp((char*)row[0], "tb2", 3), 0);
288✔
2103
      ASSERT_EQ(strncmp((char*)row[1], "xyz", 3), 0);
288✔
2104
      ASSERT_EQ(strncmp((char*)row[2], "abc", 3), 0);
288✔
2105
      taos_free_result(pRes);
288✔
2106
    }
2107

2108
    taos_stmt2_close(stmt);
96✔
2109
  }
2110

2111
  // async query with async fetch
2112
  {
2113
    AsyncArgs* aa = (AsyncArgs*)taosMemoryMalloc(sizeof(AsyncArgs));
96✔
2114
    aa->async_affected_rows = 0;
96✔
2115
    ASSERT_EQ(tsem_init(&aa->sem, 0, 0), TSDB_CODE_SUCCESS);
96✔
2116

2117
    TAOS_STMT2_OPTION option = {0, true, true, stmtAsyncQueryCb, (void*)aa};
96✔
2118

2119
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
2120
    ASSERT_NE(stmt, nullptr);
96✔
2121

2122
    const char* sql = "select tbname,t2,b from stmt2_testdb_37.stb where ts = ? order by tbname";
96✔
2123
    int         code = taos_stmt2_prepare(stmt, sql, 0);
96✔
2124
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2125

2126
    for (int i = 0; i < 3; i++) {
384✔
2127
      int             fieldNum = 0;
288✔
2128
      TAOS_FIELD_ALL* pFields = NULL;
288✔
2129
      code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
288✔
2130
      checkError(stmt, code, __FILE__, __LINE__);
288✔
2131
      ASSERT_EQ(fieldNum, 1);
288✔
2132

2133
      int              t64_len = sizeof(int64_t);
288✔
2134
      int64_t          ts = 1591060628000;
288✔
2135
      TAOS_STMT2_BIND  params = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len, NULL, 1};
288✔
2136
      TAOS_STMT2_BIND* paramv = &params;
288✔
2137
      TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &paramv};
288✔
2138
      code = taos_stmt2_bind_param(stmt, &bindv, -1);
288✔
2139
      checkError(stmt, code, __FILE__, __LINE__);
288✔
2140

2141
      taos_stmt2_exec(stmt, NULL);
288✔
2142
      checkError(stmt, code, __FILE__, __LINE__);
288✔
2143

2144
      tsem_wait(&aa->sem);
288✔
2145

2146
      TAOS_RES* pRes = taos_stmt2_result(stmt);
288✔
2147
      ASSERT_NE(pRes, nullptr);
288✔
2148
      TAOS_ROW row = taos_fetch_row(pRes);
288✔
2149
      ASSERT_NE(row, nullptr);
288✔
2150
      ASSERT_EQ(strncmp((char*)row[0], "tb1", 3), 0);
288✔
2151
      ASSERT_EQ(strncmp((char*)row[1], "abc", 3), 0);
288✔
2152
      ASSERT_EQ(strncmp((char*)row[2], "abc", 3), 0);
288✔
2153
      row = taos_fetch_row(pRes);
288✔
2154
      ASSERT_NE(row, nullptr);
288✔
2155
      taos_free_result(pRes);
288✔
2156
    }
2157

2158
    tsem_destroy(&aa->sem);
96✔
2159
    taosMemoryFree(aa);
96✔
2160
    taos_stmt2_close(stmt);
96✔
2161
  }
2162
  do_query(taos, "drop database if exists stmt2_testdb_37");
96✔
2163
  taos_close(taos);
96✔
2164
}
2165

2166
void asyncSelectError(void* param, TAOS_RES* pRes, int code) {
96✔
2167
  taosMsleep(500);
96✔
2168
  // wrong usage 3 : sync fetch in callback
2169
  taos_fetch_row(pRes);
96✔
2170
  ASSERT_EQ(terrno, TSDB_CODE_TSC_INVALID_OPERATION);
96✔
2171

2172
  ((AsyncArgs*)param)->async_affected_rows = taos_affected_rows(pRes);
96✔
2173
  ASSERT_EQ(tsem_post(&((AsyncArgs*)param)->sem), TSDB_CODE_SUCCESS);
96✔
2174
}
2175

2176
TEST(stmt2Case, query_error) {
384✔
2177
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
2178
  ASSERT_NE(taos, nullptr);
96✔
2179
  do_query(taos, "drop database if exists stmt2_testdb_27");
96✔
2180
  do_query(taos, "create database IF NOT EXISTS stmt2_testdb_27");
96✔
2181
  do_query(taos, "create stable stmt2_testdb_27.stb (ts timestamp, b binary(10)) tags(t1 int, t2 binary(10))");
96✔
2182
  do_query(taos,
96✔
2183
           "insert into stmt2_testdb_27.tb1 using stmt2_testdb_27.stb tags(1,'abc') values(1591060628000, "
2184
           "'abc'),(1591060628001,'def'),(1591060628002, 'hij')");
2185
  do_query(taos,
96✔
2186
           "insert into stmt2_testdb_27.tb2 using stmt2_testdb_27.stb tags(2,'xyz') values(1591060628000, "
2187
           "'abc'),(1591060628001,'def'),(1591060628004, 'hij')");
2188
  do_query(taos, "use stmt2_testdb_27");
96✔
2189

2190
  TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
2191

2192
  // no tbname
2193
  {
2194
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
2195
    ASSERT_NE(stmt, nullptr);
96✔
2196

2197
    int code = taos_stmt2_prepare(stmt, "select * from ? where ts = ?", 0);
96✔
2198
    ASSERT_EQ(code, TSDB_CODE_PAR_SYNTAX_ERROR);
96✔
2199
    ASSERT_STREQ(taos_stmt2_error(stmt), "syntax error near \"? where ts = ?\"");
96✔
2200
    taos_stmt2_close(stmt);
96✔
2201
  }
2202

2203
  // tbname not exist
2204
  {
2205
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
2206
    ASSERT_NE(stmt, nullptr);
96✔
2207

2208
    int code = taos_stmt2_prepare(stmt, "select * from stmt2_testdb_27.tb_not_exist where ts = ?", 0);
96✔
2209
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2210

2211
    int fieldNum = 0;
96✔
2212
    code = taos_stmt2_get_fields(stmt, &fieldNum, NULL);
96✔
2213
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2214
    ASSERT_EQ(fieldNum, 1);
96✔
2215

2216
    int              t64_len = sizeof(int64_t);
96✔
2217
    int64_t          ts = 1591060628000;
96✔
2218
    TAOS_STMT2_BIND  params = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len, NULL, 1};
96✔
2219
    TAOS_STMT2_BIND* paramv = &params;
96✔
2220
    TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &paramv};
96✔
2221
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
2222
    ASSERT_EQ(code, TSDB_CODE_PAR_TABLE_NOT_EXIST);
96✔
2223
    ASSERT_STREQ(taos_stmt2_error(stmt), "Table does not exist");
96✔
2224
    taos_stmt2_close(stmt);
96✔
2225
  }
2226

2227
  {
2228
    AsyncArgs* aa = (AsyncArgs*)taosMemoryMalloc(sizeof(AsyncArgs));
96✔
2229
    aa->async_affected_rows = 0;
96✔
2230
    ASSERT_EQ(tsem_init(&aa->sem, 0, 0), TSDB_CODE_SUCCESS);
96✔
2231

2232
    TAOS_STMT2_OPTION option = {0, true, true, asyncSelectError, (void*)aa};
96✔
2233
    TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
2234
    ASSERT_NE(stmt, nullptr);
96✔
2235

2236
    int code =
2237
        taos_stmt2_prepare(stmt, "select tbname,b,t1,t2 from stmt2_testdb_27.stb where ts = ? order by tbname", 0);
96✔
2238
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2239

2240
    int fieldNum = 0;
96✔
2241
    code = taos_stmt2_get_fields(stmt, &fieldNum, NULL);
96✔
2242
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2243
    ASSERT_EQ(fieldNum, 1);
96✔
2244

2245
    int              t64_len = sizeof(int64_t);
96✔
2246
    int64_t          ts = 1591060628000;
96✔
2247
    TAOS_STMT2_BIND  params = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len, NULL, 1};
96✔
2248
    TAOS_STMT2_BIND* paramv = &params;
96✔
2249
    TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &paramv};
96✔
2250
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
2251
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2252

2253
    code = taos_stmt2_exec(stmt, NULL);
96✔
2254
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2255

2256
    // wrong usage 1 : before call back
2257
    TAOS_RES* pRes = taos_stmt2_result(stmt);
96✔
2258
    ASSERT_EQ(pRes, nullptr);
96✔
2259

2260
    tsem_wait(&aa->sem);
96✔
2261
    tsem_destroy(&aa->sem);
96✔
2262
    taosMemoryFree(aa);
96✔
2263
    // correct usage 2 : sync fetch in async query
2264
    pRes = taos_stmt2_result(stmt);
96✔
2265
    ASSERT_NE(pRes, nullptr);
96✔
2266
    TAOS_ROW row = taos_fetch_row(pRes);
96✔
2267
    ASSERT_NE(row, nullptr);
96✔
2268
    ASSERT_EQ(strncmp((char*)row[0], "tb1", 3), 0);
96✔
2269
    ASSERT_EQ(strncmp((char*)row[1], "abc", 3), 0);
96✔
2270
    ASSERT_EQ(*(int*)row[2], 1);
96✔
2271
    ASSERT_EQ(strncmp((char*)row[3], "abc", 3), 0);
96✔
2272

2273
    row = taos_fetch_row(pRes);
96✔
2274
    ASSERT_NE(row, nullptr);
96✔
2275
    ASSERT_EQ(strncmp((char*)row[0], "tb2", 3), 0);
96✔
2276
    ASSERT_EQ(strncmp((char*)row[1], "abc", 3), 0);
96✔
2277
    ASSERT_EQ(*(int*)row[2], 2);
96✔
2278
    ASSERT_EQ(strncmp((char*)row[3], "xyz", 3), 0);
96✔
2279

2280
    do_query(taos, "drop database if exists stmt2_testdb_7");
96✔
2281
    taos_stmt2_close(stmt);
96✔
2282
  }
2283
  do_query(taos, "drop database if exists stmt2_testdb_27");
96✔
2284
  taos_close(taos);
96✔
2285
}
2286

2287
TEST(stmt2Case, stmt2_ntb_insert) {
384✔
2288
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
2289
  ASSERT_NE(taos, nullptr);
96✔
2290
  TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
2291
  do_query(taos, "drop database if exists stmt2_testdb_8");
96✔
2292
  do_query(taos, "create database IF NOT EXISTS stmt2_testdb_8");
96✔
2293
  do_query(taos, "create table stmt2_testdb_8.ntb(ts timestamp, b binary(10))");
96✔
2294
  do_query(taos, "use stmt2_testdb_8");
96✔
2295
  TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
2296
  ASSERT_NE(stmt, nullptr);
96✔
2297

2298
  // test fixed tbname and bind per col
2299
  {
2300
    int         total_affected_rows = 0;
96✔
2301
    const char* sql = "insert into stmt2_testdb_8.ntb values(?,?)";
96✔
2302
    int         code = taos_stmt2_prepare(stmt, sql, 0);
96✔
2303
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2304
    for (int i = 0; i < 3; i++) {
384✔
2305
      int64_t ts[3] = {1591060628000 + i * 3, 1591060628001 + i * 3, 1591060628002 + i * 3};
288✔
2306
      int     t64_len[3] = {sizeof(int64_t), sizeof(int64_t), sizeof(int64_t)};
288✔
2307
      int     b_len[3] = {5, 5, 5};
288✔
2308

2309
      TAOS_STMT2_BIND  params1 = {TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &t64_len[0], NULL, 3};
288✔
2310
      TAOS_STMT2_BIND  params2 = {TSDB_DATA_TYPE_BINARY, (void*)"abcdefghijklmnopqrstuvwxyz", &b_len[0], NULL, 3};
288✔
2311
      TAOS_STMT2_BIND* paramv1 = &params1;
288✔
2312
      TAOS_STMT2_BIND* paramv2 = &params2;
288✔
2313

2314
      TAOS_STMT2_BINDV bindv1 = {1, NULL, NULL, &paramv1};
288✔
2315
      TAOS_STMT2_BINDV bindv2 = {1, NULL, NULL, &paramv2};
288✔
2316

2317
      code = taos_stmt2_bind_param(stmt, &bindv1, 0);
288✔
2318
      code = taos_stmt2_bind_param(stmt, &bindv2, 1);
288✔
2319
      checkError(stmt, code, __FILE__, __LINE__);
288✔
2320

2321
      int affected_rows;
2322
      code = taos_stmt2_exec(stmt, &affected_rows);
288✔
2323
      total_affected_rows += affected_rows;
288✔
2324
      checkError(stmt, code, __FILE__, __LINE__);
288✔
2325
    }
2326
    ASSERT_EQ(total_affected_rows, 9);
96✔
2327
  }
2328

2329
  taos_stmt2_close(stmt);
96✔
2330
  do_query(taos, "drop database if exists stmt2_testdb_8");
96✔
2331
  taos_close(taos);
96✔
2332
}
2333

2334
TEST(stmt2Case, stmt2_status_Test) {
384✔
2335
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
2336
  ASSERT_NE(taos, nullptr);
96✔
2337
  TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
2338
  TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
2339

2340
  int64_t ts[3] = {1591060628000, 1591060628001, 1591060628002};
96✔
2341
  int     t64_len[3] = {sizeof(int64_t), sizeof(int64_t), sizeof(int64_t)};
96✔
2342

2343
  TAOS_STMT2_BIND  params = {TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &t64_len[0], NULL, 3};
96✔
2344
  TAOS_STMT2_BIND* paramv = &params;
96✔
2345
  TAOS_STMT2_BINDV bindv1 = {1, NULL, NULL, &paramv};
96✔
2346

2347
  int code = taos_stmt2_bind_param(stmt, &bindv1, 0);
96✔
2348
  ASSERT_EQ(code, TSDB_CODE_TSC_STMT_API_ERROR);
96✔
2349
  ASSERT_STREQ(taos_stmt2_error(stmt), "Stmt API usage error");
96✔
2350

2351
  code = taos_stmt2_exec(stmt, NULL);
96✔
2352
  ASSERT_EQ(code, TSDB_CODE_TSC_STMT_API_ERROR);
96✔
2353
  ASSERT_STREQ(taos_stmt2_error(stmt), "Stmt API usage error");
96✔
2354

2355
  const char* sql = "insert into stmt2_testdb_9.ntb values(?,?)";
96✔
2356
  code = taos_stmt2_prepare(stmt, sql, 0);
96✔
2357
  ASSERT_EQ(code, TSDB_CODE_TSC_STMT_API_ERROR);
96✔
2358
  ASSERT_STREQ(taos_stmt2_error(stmt), "Stmt API usage error");
96✔
2359

2360
  taos_stmt2_close(stmt);
96✔
2361
  taos_close(taos);
96✔
2362
}
2363

2364
TEST(stmt2Case, stmt2_nchar) {
384✔
2365
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
2366
  do_query(taos, "drop database if exists stmt2_testdb_10;");
96✔
2367
  do_query(taos, "create database IF NOT EXISTS stmt2_testdb_10;");
96✔
2368
  do_query(taos, "use stmt2_testdb_10;");
96✔
2369
  do_query(taos,
96✔
2370
           "create table m1 (ts timestamp, nchar1 nchar(10), nchar2 nchar(10),nchar3 nchar(10),nchar4 nchar(10),nchar5 "
2371
           "nchar(10),nchar6 nchar(10));");
2372

2373
  // insert 10 records
2374
  struct {
2375
    int64_t ts[10];
2376
    char    blob[10][1];
2377
    char    blob2[10][1];
2378
    char    blob3[10][1];
2379
    char    blob4[10][1];
2380
    char    blob5[10][1];
2381
  } v;
2382

2383
  int32_t* t64_len = (int32_t*)taosMemoryMalloc(sizeof(int32_t) * 10);
96✔
2384
  int32_t* blob_len = (int32_t*)taosMemoryMalloc(sizeof(int32_t) * 10);
96✔
2385
  int32_t* blob_len2 = (int32_t*)taosMemoryMalloc(sizeof(int32_t) * 10);
96✔
2386
  int32_t* blob_len3 = (int32_t*)taosMemoryMalloc(sizeof(int32_t) * 10);
96✔
2387
  int32_t* blob_len4 = (int32_t*)taosMemoryMalloc(sizeof(int32_t) * 10);
96✔
2388
  int32_t* blob_len5 = (int32_t*)taosMemoryMalloc(sizeof(int32_t) * 10);
96✔
2389
  {
2390
    TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
2391

2392
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
2393
    ASSERT_NE(stmt, nullptr);
96✔
2394
    TAOS_STMT2_BIND params[10];
2395
    char            is_null[10] = {0};
96✔
2396

2397
    params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
96✔
2398
    // params[0].buffer_length = sizeof(v.ts[0]);
2399
    params[0].buffer = v.ts;
96✔
2400
    params[0].length = t64_len;
96✔
2401
    params[0].is_null = is_null;
96✔
2402
    params[0].num = 10;
96✔
2403

2404
    params[1].buffer_type = TSDB_DATA_TYPE_NCHAR;
96✔
2405
    // params[8].buffer_length = sizeof(v.blob2[0]);
2406
    params[1].buffer = v.blob2;
96✔
2407
    params[1].length = blob_len2;
96✔
2408
    params[1].is_null = is_null;
96✔
2409
    params[1].num = 10;
96✔
2410

2411
    params[2].buffer_type = TSDB_DATA_TYPE_NCHAR;
96✔
2412
    // params[9].buffer_length = sizeof(v.blob[0]);
2413
    params[2].buffer = v.blob3;
96✔
2414
    params[2].length = blob_len;
96✔
2415
    params[2].is_null = is_null;
96✔
2416
    params[2].num = 10;
96✔
2417

2418
    params[3].buffer_type = TSDB_DATA_TYPE_NCHAR;
96✔
2419
    // params[9].buffer_length = sizeof(v.blob[0]);
2420
    params[3].buffer = v.blob4;
96✔
2421
    params[3].length = blob_len;
96✔
2422
    params[3].is_null = is_null;
96✔
2423
    params[3].num = 10;
96✔
2424

2425
    params[4].buffer_type = TSDB_DATA_TYPE_NCHAR;
96✔
2426
    // params[9].buffer_length = sizeof(v.blob[0]);
2427
    params[4].buffer = v.blob;
96✔
2428
    params[4].length = blob_len;
96✔
2429
    params[4].is_null = is_null;
96✔
2430
    params[4].num = 10;
96✔
2431

2432
    params[5].buffer_type = TSDB_DATA_TYPE_NCHAR;
96✔
2433
    // params[9].buffer_length = sizeof(v.blob[0]);
2434
    params[5].buffer = v.blob5;
96✔
2435
    params[5].length = blob_len;
96✔
2436
    params[5].is_null = is_null;
96✔
2437
    params[5].num = 10;
96✔
2438

2439
    int len[10] = {0};
96✔
2440
    params[6].buffer_type = TSDB_DATA_TYPE_NCHAR;
96✔
2441
    // params[9].buffer_length = sizeof(v.blob[0]);
2442
    params[6].buffer = NULL;
96✔
2443
    params[6].length = &len[0];
96✔
2444
    params[6].is_null = is_null;
96✔
2445
    params[6].num = 10;
96✔
2446

2447
    int code = taos_stmt2_prepare(
96✔
2448
        stmt, "insert into ? (ts, nchar1, nchar2, nchar3, nchar4, nchar5, nchar6) values(?,?,?,?,?,?,?)", 0);
2449
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2450
    int64_t ts = 1591060628000;
96✔
2451
    for (int i = 0; i < 10; ++i) {
1,056✔
2452
      is_null[i] = 0;
960✔
2453

2454
      v.ts[i] = ts++;
960✔
2455

2456
      v.blob[i][0] = 'a' + i;
960✔
2457
      v.blob2[i][0] = 'f' + i;
960✔
2458
      v.blob3[i][0] = 't' + i;
960✔
2459
      v.blob4[i][0] = 'A' + i;
960✔
2460
      v.blob5[i][0] = 'G' + i;
960✔
2461

2462
      blob_len[i] = sizeof(char);
960✔
2463
      blob_len2[i] = sizeof(char);
960✔
2464
      blob_len3[i] = sizeof(char);
960✔
2465
      blob_len4[i] = sizeof(char);
960✔
2466
      blob_len5[i] = sizeof(char);
960✔
2467
    }
2468

2469
    char*            tbname = "m1";
96✔
2470
    TAOS_STMT2_BIND* bind_cols[1] = {&params[0]};
96✔
2471
    TAOS_STMT2_BINDV bindv = {1, &tbname, NULL, &bind_cols[0]};
96✔
2472
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
2473
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2474

2475
    int affected_rows;
2476
    code = taos_stmt2_exec(stmt, &affected_rows);
96✔
2477
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2478
    ASSERT_EQ(affected_rows, 10);
96✔
2479

2480
    taos_stmt2_close(stmt);
96✔
2481
  }
2482
  taosMemoryFree(blob_len);
96✔
2483
  taosMemoryFree(blob_len2);
96✔
2484
  taosMemoryFree(blob_len5);
96✔
2485
  taosMemoryFree(blob_len3);
96✔
2486
  taosMemoryFree(blob_len4);
96✔
2487

2488
  // test null value
2489
  do_query(taos, "create stable stmt2_testdb_10.stb (ts timestamp, b nchar(10)) tags(t1 nchar(10))");
96✔
2490
  TAOS_STMT2_OPTION options[2] = {{0, true, true, NULL, NULL}, {0, false, false, NULL, NULL}};
96✔
2491
  for (int i = 0; i < 2; i++) {
288✔
2492
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &options[i]);
192✔
2493
    ASSERT_NE(stmt, nullptr);
192✔
2494

2495
    int code =
2496
        taos_stmt2_prepare(stmt, "INSERT INTO stmt2_testdb_10.? using stmt2_testdb_10.stb tags(?) values(?,?)", 0);
192✔
2497
    checkError(stmt, code, __FILE__, __LINE__);
192✔
2498

2499
    char*            tbname[2] = {"tb1", "tb2"};
192✔
2500
    int64_t          ts[2] = {1591060628000, 1591060628001};
192✔
2501
    int              t64_len[2] = {sizeof(int64_t), sizeof(int64_t)};
192✔
2502
    char             isNull[2] = {1, 0};
192✔
2503
    int              nchar_len[2] = {0, 0};
192✔
2504
    TAOS_STMT2_BIND  tags = {TSDB_DATA_TYPE_NCHAR, NULL, &nchar_len[1], NULL, 1};
192✔
2505
    TAOS_STMT2_BIND* tagv[2] = {&tags, &tags};
192✔
2506
    TAOS_STMT2_BIND  params[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &t64_len[0], NULL, 2},
192✔
2507
                                  {TSDB_DATA_TYPE_NCHAR, NULL, &nchar_len[0], &isNull[0], 2}};
192✔
2508
    TAOS_STMT2_BIND* paramv[2] = {&params[0], &params[0]};
192✔
2509
    TAOS_STMT2_BINDV bindv1 = {1, &tbname[i], &tagv[0], &paramv[0]};
192✔
2510

2511
    code = taos_stmt2_bind_param(stmt, &bindv1, -1);
192✔
2512
    checkError(stmt, code, __FILE__, __LINE__);
192✔
2513

2514
    int affected_rows;
2515
    code = taos_stmt2_exec(stmt, &affected_rows);
192✔
2516
    checkError(stmt, code, __FILE__, __LINE__);
192✔
2517
    ASSERT_EQ(affected_rows, 2);
192✔
2518

2519
    taos_stmt2_close(stmt);
192✔
2520
  }
2521

2522
  do_query(taos, "drop database if exists stmt2_testdb_10;");
96✔
2523
  taos_close(taos);
96✔
2524
}
2525

2526
// TEST(stmt2Case, stmt2_blob) {
2527
//   TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
2528
//   do_query(taos, "drop database if exists stmt2_testdb_10;");
2529
//   do_query(taos, "create database IF NOT EXISTS stmt2_testdb_10;");
2530
//   do_query(taos, "use stmt2_testdb_10;");
2531
//   do_query(
2532
//       taos,
2533
//       "create table m1 (ts timestamp, blob1 blob, blob2 nchar(10),blob3 nchar(10),blob4 nchar(10),blob5 nchar(12))");
2534

2535
//   // insert 10 records
2536
//   struct {
2537
//     int64_t ts[10];
2538
//     char    blob[10][1];
2539
//     char    blob2[10][1];
2540
//     char    blob3[10][1];
2541
//     char    blob4[10][1];
2542
//     char    blob5[10][1];
2543

2544
//   } v;
2545

2546
//   int32_t* t64_len = (int32_t*)taosMemMalloc(sizeof(int32_t) * 10);
2547
//   int32_t* nchar_len1 = (int32_t*)taosMemMalloc(sizeof(int32_t) * 10);
2548
//   int32_t* nchar_len2 = (int32_t*)taosMemMalloc(sizeof(int32_t) * 10);
2549
//   int32_t* nchar_len3 = (int32_t*)taosMemMalloc(sizeof(int32_t) * 10);
2550
//   int32_t* nchar_len4 = (int32_t*)taosMemMalloc(sizeof(int32_t) * 10);
2551
//   int32_t* nchar_len5 = (int32_t*)taosMemMalloc(sizeof(int32_t) * 10);
2552

2553
//   TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
2554

2555
//   TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
2556
//   ASSERT_NE(stmt, nullptr);
2557
//   TAOS_STMT2_BIND params[10];
2558
//   char            is_null[10] = {0};
2559

2560
//   params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
2561
//   // params[0].buffer_length = sizeof(v.ts[0]);
2562
//   params[0].buffer = v.ts;
2563
//   params[0].length = t64_len;
2564
//   params[0].is_null = is_null;
2565
//   params[0].num = 10;
2566

2567
//   params[1].buffer_type = TSDB_DATA_TYPE_NCHAR;
2568
//   // params[8].buffer_length = sizeof(v.nchar2[0]);
2569
//   params[1].buffer = v.nchar1;
2570
//   params[1].length = nchar_len1;
2571
//   params[1].is_null = is_null;
2572
//   params[1].num = 10;
2573

2574
//   params[2].buffer_type = TSDB_DATA_TYPE_NCHAR;
2575
//   // params[9].buffer_length = sizeof(v.nchar[0]);
2576
//   params[2].buffer = v.nchar2;
2577
//   params[2].length = nchar_len2;
2578
//   params[2].is_null = is_null;
2579
//   params[2].num = 10;
2580

2581
//   params[3].buffer_type = TSDB_DATA_TYPE_NCHAR;
2582
//   // params[9].buffer_length = sizeof(v.nchar[0]);
2583
//   params[3].buffer = v.nchar3;
2584
//   params[3].length = nchar_len3;
2585
//   params[3].is_null = is_null;
2586
//   params[3].num = 10;
2587

2588
//   params[4].buffer_type = TSDB_DATA_TYPE_NCHAR;
2589
//   // params[9].buffer_length = sizeof(v.nchar[0]);
2590
//   params[4].buffer = v.nchar4;
2591
//   params[4].length = nchar_len4;
2592
//   params[4].is_null = is_null;
2593
//   params[4].num = 10;
2594

2595
//   params[5].buffer_type = TSDB_DATA_TYPE_NCHAR;
2596
//   // params[9].buffer_length = sizeof(v.nchar[0]);
2597
//   params[5].buffer = v.nchar5;
2598
//   params[5].length = nchar_len5;
2599
//   params[5].is_null = is_null;
2600
//   params[5].num = 10;
2601

2602
//   int code = taos_stmt2_prepare(stmt, "insert into ? (ts, blob1, blob2 blob3, blob4, blob5) values(?,?,?,?,?,?)", 0);
2603
//   checkError(stmt, code, __FILE__, __LINE__);
2604

2605
//   int64_t ts = 1591060628000;
2606
//   for (int i = 0; i < 10; ++i) {
2607
//     is_null[i] = 0;
2608

2609
//     v.ts[i] = ts++;
2610

2611
//     v.nchar1[i][0] = 'a' + i;
2612
//     v.nchar2[i][0] = 'f' + i;
2613
//     v.nchar3[i][0] = 't' + i;
2614
//     v.nchar4[i][0] = 'A' + i;
2615
//     v.nchar5[i][0] = 'G' + i;
2616

2617
//     nchar_len1[i] = sizeof(char);
2618
//     nchar_len2[i] = sizeof(char);
2619
//     nchar_len3[i] = sizeof(char);
2620
//     nchar_len4[i] = sizeof(char);
2621
//     nchar_len5[i] = sizeof(char);
2622
//   }
2623

2624
//   char*            tbname = "m1";
2625
//   TAOS_STMT2_BIND* bind_cols[1] = {&params[0]};
2626
//   TAOS_STMT2_BINDV bindv = {1, &tbname, NULL, &bind_cols[0]};
2627
//   code = taos_stmt2_bind_param(stmt, &bindv, -1);
2628
//   checkError(stmt, code, __FILE__, __LINE__);
2629

2630
//   int affected_rows;
2631
//   code = taos_stmt2_exec(stmt, &affected_rows);
2632
//   checkError(stmt, code, __FILE__, __LINE__);
2633
//   ASSERT_EQ(affected_rows, 10);
2634

2635
//   taos_stmt2_close(stmt);
2636
//   do_query(taos, "drop database if exists stmt2_testdb_10;");
2637
//   taos_close(taos);
2638
//   taosMemoryFree(nchar_len1);
2639
//   taosMemoryFree(nchar_len2);
2640
//   taosMemoryFree(nchar_len5);
2641
//   taosMemoryFree(nchar_len3);
2642
//   taosMemoryFree(nchar_len4);
2643
// }
2644

2645
TEST(stmt2Case, all_type) {
384✔
2646
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
2647
  ASSERT_NE(taos, nullptr);
96✔
2648

2649
  do_query(taos, "drop database if exists stmt2_testdb_11");
96✔
2650
  do_query(taos, "create database IF NOT EXISTS stmt2_testdb_11");
96✔
2651
  do_query(taos,
96✔
2652
           "create stable stmt2_testdb_11.stb(ts timestamp, c1 int, c2 bigint, c3 float, c4 double, c5 binary(128), c6 "
2653
           "smallint, c7 "
2654
           "tinyint, c8 bool, c9 nchar(128), c10 geometry(256))TAGS(tts timestamp, t1 int, t2 bigint, t3 float, t4 "
2655
           "double, t5 "
2656
           "binary(128), t6 smallint, t7 tinyint, t8 bool, t9 nchar(128), t10 geometry(256))");
2657

2658
  TAOS_STMT2_OPTION option = {0};
96✔
2659
  TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
2660
  ASSERT_NE(stmt, nullptr);
96✔
2661
  int       code = 0;
96✔
2662
  uintptr_t c10len = 0;
96✔
2663
  struct {
2664
    int64_t       c1;
2665
    int32_t       c2;
2666
    int64_t       c3;
2667
    float         c4;
2668
    double        c5;
2669
    unsigned char c6[8];
2670
    int16_t       c7;
2671
    int8_t        c8;
2672
    int8_t        c9;
2673
    char          c10[32];
2674
  } v = {1591060628000, 1, 2, 3.0, 4.0, "abcdef", 5, 6, 7, "ijnop"};
96✔
2675

2676
  struct {
2677
    int32_t c1;
2678
    int32_t c2;
2679
    int32_t c3;
2680
    int32_t c4;
2681
    int32_t c5;
2682
    int32_t c6;
2683
    int32_t c7;
2684
    int32_t c8;
2685
    int32_t c9;
2686
    int32_t c10;
2687
  } v_len = {sizeof(int64_t), sizeof(int32_t),
96✔
2688
             sizeof(int64_t), sizeof(float),
2689
             sizeof(double),  8,
2690
             sizeof(int16_t), sizeof(int8_t),
2691
             sizeof(int8_t),  8};
2692
  TAOS_STMT2_BIND params[11];
2693
  params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
96✔
2694
  params[0].length = (int32_t*)&v_len.c1;
96✔
2695
  params[0].buffer = &v.c1;
96✔
2696
  params[0].is_null = NULL;
96✔
2697
  params[0].num = 1;
96✔
2698

2699
  params[1].buffer_type = TSDB_DATA_TYPE_INT;
96✔
2700
  params[1].buffer = &v.c2;
96✔
2701
  params[1].length = (int32_t*)&v_len.c2;
96✔
2702
  params[1].is_null = NULL;
96✔
2703
  params[1].num = 1;
96✔
2704

2705
  params[2].buffer_type = TSDB_DATA_TYPE_BIGINT;
96✔
2706
  params[2].buffer = &v.c3;
96✔
2707
  params[2].length = (int32_t*)&v_len.c3;
96✔
2708
  params[2].is_null = NULL;
96✔
2709
  params[2].num = 1;
96✔
2710

2711
  params[3].buffer_type = TSDB_DATA_TYPE_FLOAT;
96✔
2712
  params[3].buffer = &v.c4;
96✔
2713
  params[3].length = (int32_t*)&v_len.c4;
96✔
2714
  params[3].is_null = NULL;
96✔
2715
  params[3].num = 1;
96✔
2716

2717
  params[4].buffer_type = TSDB_DATA_TYPE_DOUBLE;
96✔
2718
  params[4].buffer = &v.c5;
96✔
2719
  params[4].length = (int32_t*)&v_len.c5;
96✔
2720
  params[4].is_null = NULL;
96✔
2721
  params[4].num = 1;
96✔
2722

2723
  params[5].buffer_type = TSDB_DATA_TYPE_BINARY;
96✔
2724
  params[5].buffer = &v.c6;
96✔
2725
  params[5].length = (int32_t*)&v_len.c6;
96✔
2726
  params[5].is_null = NULL;
96✔
2727
  params[5].num = 1;
96✔
2728

2729
  params[6].buffer_type = TSDB_DATA_TYPE_SMALLINT;
96✔
2730
  params[6].buffer = &v.c7;
96✔
2731
  params[6].length = (int32_t*)&v_len.c7;
96✔
2732
  params[6].is_null = NULL;
96✔
2733
  params[6].num = 1;
96✔
2734

2735
  params[7].buffer_type = TSDB_DATA_TYPE_TINYINT;
96✔
2736
  params[7].buffer = &v.c8;
96✔
2737
  params[7].length = (int32_t*)&v_len.c8;
96✔
2738
  params[7].is_null = NULL;
96✔
2739
  params[7].num = 1;
96✔
2740

2741
  params[8].buffer_type = TSDB_DATA_TYPE_BOOL;
96✔
2742
  params[8].buffer = &v.c9;
96✔
2743
  params[8].length = (int32_t*)&v_len.c9;
96✔
2744
  params[8].is_null = NULL;
96✔
2745
  params[8].num = 1;
96✔
2746

2747
  params[9].buffer_type = TSDB_DATA_TYPE_NCHAR;
96✔
2748
  params[9].buffer = &v.c10;
96✔
2749
  params[9].length = (int32_t*)&v_len.c10;
96✔
2750
  params[9].is_null = NULL;
96✔
2751
  params[9].num = 1;
96✔
2752

2753
  unsigned char* outputGeom1;
2754
  size_t         size1;
2755
  initCtxMakePoint();
96✔
2756
  code = doMakePoint(1.000, 2.000, &outputGeom1, &size1);
96✔
2757
  checkError(stmt, code, __FILE__, __LINE__);
96✔
2758
  params[10].buffer_type = TSDB_DATA_TYPE_GEOMETRY;
96✔
2759
  params[10].buffer = outputGeom1;
96✔
2760
  params[10].length = (int32_t*)&size1;
96✔
2761
  params[10].is_null = NULL;
96✔
2762
  params[10].num = 1;
96✔
2763

2764
  char* stmt_sql = "insert into stmt2_testdb_11.? using stb tags(?,?,?,?,?,?,?,?,?,?,?)values (?,?,?,?,?,?,?,?,?,?,?)";
96✔
2765
  code = taos_stmt2_prepare(stmt, stmt_sql, 0);
96✔
2766
  checkError(stmt, code, __FILE__, __LINE__);
96✔
2767

2768
  char*            tbname[1] = {"tb1"};
96✔
2769
  TAOS_STMT2_BIND* tags = &params[0];
96✔
2770
  TAOS_STMT2_BIND* cols = &params[0];
96✔
2771
  TAOS_STMT2_BINDV bindv = {1, &tbname[0], &tags, &cols};
96✔
2772
  code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
2773
  checkError(stmt, code, __FILE__, __LINE__);
96✔
2774

2775
  int affected_rows;
2776
  code = taos_stmt2_exec(stmt, &affected_rows);
96✔
2777
  checkError(stmt, code, __FILE__, __LINE__);
96✔
2778
  ASSERT_EQ(affected_rows, 1);
96✔
2779
  taos_stmt2_close(stmt);
96✔
2780

2781
  option = {0, true, true, NULL, NULL};
96✔
2782
  stmt = taos_stmt2_init(taos, &option);
96✔
2783
  stmt_sql = "insert into stmt2_testdb_11.stb(tbname,ts,c5,c9,t5,t9)values(?,?,?,?,?,?)";
96✔
2784
  code = taos_stmt2_prepare(stmt, stmt_sql, 0);
96✔
2785
  checkError(stmt, code, __FILE__, __LINE__);
96✔
2786
  int     tag_l[2] = {128, 128};
96✔
2787
  int64_t ts[2]{1591060628001, 1591060628002};
96✔
2788
  int32_t t64_len[2] = {sizeof(int64_t), sizeof(int64_t)};
96✔
2789
  char    c[2][128] = {
96✔
2790
      "abcdefjhijklmnopqrstuvwxyzabcdefjhijklmnopqrstuvwxyzabcdefjhijklmnopqrstuvwxyzabcdefjhijklmnopqrstuvwxyz",
2791
      "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"};
2792
  for (int i = 0; i < 3; i++) {
384✔
2793
    TAOS_STMT2_BIND tags1[2] = {{TSDB_DATA_TYPE_BINARY, &c[0], &tag_l[0], NULL, 1},
288✔
2794
                                {TSDB_DATA_TYPE_NCHAR, &c[1], &tag_l[0], NULL, 1}};
288✔
2795
    TAOS_STMT2_BIND params1[3] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &t64_len[0], NULL, 2},
288✔
2796
                                  {TSDB_DATA_TYPE_BINARY, &c[0], &tag_l[0], NULL, 2},
2797
                                  {TSDB_DATA_TYPE_NCHAR, &c[0], &tag_l[0], NULL, 2}};
288✔
2798

2799
    TAOS_STMT2_BIND* tagv[2] = {&tags1[0], &tags1[0]};
288✔
2800
    TAOS_STMT2_BIND* paramv[2] = {&params1[0], &params1[0]};
288✔
2801
    char*            tbname[2] = {"tb2", "tb3"};
288✔
2802
    TAOS_STMT2_BINDV bindv = {2, &tbname[0], &tagv[0], &paramv[0]};
288✔
2803
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
288✔
2804
    checkError(stmt, code, __FILE__, __LINE__);
288✔
2805

2806
    int affected_rows;
2807
    code = taos_stmt2_exec(stmt, &affected_rows);
288✔
2808
    checkError(stmt, code, __FILE__, __LINE__);
288✔
2809
    ASSERT_EQ(affected_rows, 4);
288✔
2810

2811
    stmt_sql = "insert into stmt2_testdb_11.? using stmt2_testdb_11.stb(t5,t9)tags(?,?) (ts,c5,c9)values(?,?,?)";
288✔
2812
    code = taos_stmt2_prepare(stmt, stmt_sql, 0);
288✔
2813
    checkError(stmt, code, __FILE__, __LINE__);
288✔
2814

2815
    char* tbname2[2] = {"tb4", "tb5"};
288✔
2816
    bindv = {2, &tbname2[0], &tagv[0], &paramv[0]};
288✔
2817
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
288✔
2818
    checkError(stmt, code, __FILE__, __LINE__);
288✔
2819
    code = taos_stmt2_exec(stmt, &affected_rows);
288✔
2820
    checkError(stmt, code, __FILE__, __LINE__);
288✔
2821
    ASSERT_EQ(affected_rows, 4);
288✔
2822
  }
2823

2824
  geosFreeBuffer(outputGeom1);
96✔
2825
  taos_stmt2_close(stmt);
96✔
2826
  do_query(taos, "drop database if exists stmt2_testdb_11");
96✔
2827
  taos_close(taos);
96✔
2828
}
2829

2830
TEST(stmt2Case, geometry) {
384✔
2831
  TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
96✔
2832
  ASSERT_NE(taos, nullptr);
96✔
2833

2834
  do_query(taos, "DROP DATABASE IF EXISTS stmt2_testdb_13");
96✔
2835
  do_query(taos, "CREATE DATABASE IF NOT EXISTS stmt2_testdb_13");
96✔
2836
  do_query(taos,
96✔
2837
           "CREATE STABLE stmt2_testdb_13.stb (ts timestamp, c1 geometry(256)) tags(t1 timestamp,t2 geometry(256))");
2838
  do_query(taos, "CREATE TABLE stmt2_testdb_13.tb1(ts timestamp,c1 geometry(256))");
96✔
2839

2840
  //  wrong wkb input
2841
  unsigned char wkb1[] = {
96✔
2842
      // 1
2843
      0x01,                                            // 字节顺序:小端字节序
2844
      0x01, 0x00, 0x00, 0x00,                          // 几何类型:Point (1)
2845
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F,  // p1
2846
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,  // p2
2847
                                                       // 2
2848
      0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2849
      0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
2850
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00,
2851
      0x00, 0x00, 0xf0, 0x3f,
2852
      // 3
2853
      0x01, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00,
2854
      0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
2855
      0x00, 0x00, 0x40};
2856
  //  wrong wkb input
2857
  unsigned char wkb2[3][61] = {
96✔
2858
      {
2859
          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2860
          0xF0, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
2861
      },
2862
      {0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2863
       0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00,
2864
       0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
2865
       0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f},
2866
      {0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2867
       0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00,
2868
       0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40}};
2869

2870
  // unsigned char* wkb_all[3]{&wkb1[0], &wkb2[0], &wkb3[0]};
2871
  int32_t wkb_len[4] = {21, 61, 41, 0};
96✔
2872

2873
  int64_t         ts[4] = {1591060628000, 1591060628001, 1591060628002, 1591060628003};
96✔
2874
  int32_t         t64_len[4] = {sizeof(int64_t), sizeof(int64_t), sizeof(int64_t), sizeof(int64_t)};
96✔
2875
  char            is_null[4] = {0, 0, 0, 1};
96✔
2876
  TAOS_STMT2_BIND params[2];
2877
  params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
96✔
2878
  params[0].buffer = &ts[0];
96✔
2879
  params[0].length = &t64_len[0];
96✔
2880
  params[0].is_null = NULL;
96✔
2881
  params[0].num = 4;
96✔
2882

2883
  params[1].buffer_type = TSDB_DATA_TYPE_GEOMETRY;
96✔
2884
  params[1].buffer = &wkb1[0];
96✔
2885
  params[1].length = &wkb_len[0];
96✔
2886
  params[1].is_null = is_null;
96✔
2887
  params[1].num = 4;
96✔
2888

2889
  // case 1 : ntb
2890
  {
2891
    printf("  case 1 : ntb\n");
96✔
2892
    TAOS_STMT2_OPTION option = {0};
96✔
2893
    TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
2894
    ASSERT_NE(stmt, nullptr);
96✔
2895

2896
    char* stmt_sql = "insert into stmt2_testdb_13.tb1 (ts,c1)values(?,?)";
96✔
2897
    int   code = taos_stmt2_prepare(stmt, stmt_sql, 0);
96✔
2898
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2899

2900
    TAOS_STMT2_BIND* cols = &params[0];
96✔
2901
    TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &cols};
96✔
2902
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
2903
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2904

2905
    int affected_rows;
2906
    code = taos_stmt2_exec(stmt, &affected_rows);
96✔
2907
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2908
    ASSERT_EQ(affected_rows, 4);
96✔
2909
  }
2910
  // case 2 : interlace = 1
2911
  {
2912
    printf("  case 2 : interlace = 1\n");
96✔
2913
    TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
2914
    TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
2915
    ASSERT_NE(stmt, nullptr);
96✔
2916

2917
    char* stmt_sql = "insert into stmt2_testdb_13.? using stmt2_testdb_13.stb tags(?,?)values(?,?)";
96✔
2918
    int   code = taos_stmt2_prepare(stmt, stmt_sql, 0);
96✔
2919
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2920

2921
    char*            ctbname[1] = {"ctb1"};
96✔
2922
    TAOS_STMT2_BIND* cols = &params[0];
96✔
2923
    TAOS_STMT2_BINDV bindv = {1, ctbname, &cols, &cols};
96✔
2924
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
2925
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2926

2927
    int affected_rows;
2928
    code = taos_stmt2_exec(stmt, &affected_rows);
96✔
2929
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2930
    ASSERT_EQ(affected_rows, 4);
96✔
2931
    taos_stmt2_close(stmt);
96✔
2932
  }
2933
  // case 3 : interlace = 0
2934
  {
2935
    printf("  case 3 : interlace = 0\n");
96✔
2936
    TAOS_STMT2_OPTION option = {0, false, false, NULL, NULL};
96✔
2937
    TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
2938
    ASSERT_NE(stmt, nullptr);
96✔
2939

2940
    char* stmt_sql = "insert into stmt2_testdb_13.? using stmt2_testdb_13.stb tags(?,?)values(?,?)";
96✔
2941
    int   code = taos_stmt2_prepare(stmt, stmt_sql, 0);
96✔
2942
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2943

2944
    char*            ctbname[1] = {"ctb2"};
96✔
2945
    TAOS_STMT2_BIND* cols = &params[0];
96✔
2946
    TAOS_STMT2_BINDV bindv = {1, ctbname, &cols, &cols};
96✔
2947
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
2948
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2949

2950
    int affected_rows;
2951
    code = taos_stmt2_exec(stmt, &affected_rows);
96✔
2952
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2953
    ASSERT_EQ(affected_rows, 4);
96✔
2954
    taos_stmt2_close(stmt);
96✔
2955
  }
2956
  // case 4 : error case
2957
  params[1].buffer = &wkb2[0];
96✔
2958
  {
2959
    printf("  case 4 : error format\n");
96✔
2960
    TAOS_STMT2_OPTION option = {0, false, false, NULL, NULL};
96✔
2961
    TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
2962
    ASSERT_NE(stmt, nullptr);
96✔
2963

2964
    char* stmt_sql = "insert into stmt2_testdb_13.? using stmt2_testdb_13.stb tags(?,?)values(?,?)";
96✔
2965
    int   code = taos_stmt2_prepare(stmt, stmt_sql, 0);
96✔
2966
    checkError(stmt, code, __FILE__, __LINE__);
96✔
2967

2968
    char*            ctbname[1] = {"ctb3"};
96✔
2969
    TAOS_STMT2_BIND* cols = &params[0];
96✔
2970
    TAOS_STMT2_BINDV bindv = {1, ctbname, &cols, &cols};
96✔
2971
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
2972
    ASSERT_EQ(code, TSDB_CODE_FUNC_FUNTION_PARA_VALUE);
96✔
2973
    taos_stmt2_close(stmt);
96✔
2974
  }
2975

2976
  do_query(taos, "DROP DATABASE IF EXISTS stmt2_testdb_13");
96✔
2977
  taos_close(taos);
96✔
2978
}
2979

2980
TEST(stmt2Case, decimal) {
384✔
2981
  TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
96✔
2982
  ASSERT_NE(taos, nullptr);
96✔
2983

2984
  do_query(taos, "DROP DATABASE IF EXISTS stmt2_testdb_20");
96✔
2985
  do_query(taos, "CREATE DATABASE IF NOT EXISTS stmt2_testdb_20");
96✔
2986
  do_query(taos, "CREATE STABLE `stmt2_testdb_20`.stb (ts TIMESTAMP, b1 DECIMAL(4,2), b2 DECIMAL(20,10)) TAGS (t INT)");
96✔
2987
  do_query(taos, "CREATE TABLE `stmt2_testdb_20`.ntb (ts TIMESTAMP, b1 DECIMAL(4,2), b2 DECIMAL(20,10))");
96✔
2988

2989
  TAOS_STMT2_OPTION option[2] = {{0, true, true, NULL, NULL}, {0, false, false, NULL, NULL}};
96✔
2990

2991
  int64_t ts[3] = {1591060628000, 1591060629000, 1591060630000};
96✔
2992

2993
  char b1_data[64] =
96✔
2994
      "99.9876"
2995
      "1.0234";
2996
  char b2_data[128] =
96✔
2997
      "1234567890.1234567890123"
2998
      "1.23e+5";
2999
  int t64_len[2] = {sizeof(int64_t), sizeof(int64_t)};
96✔
3000
  int b1_len[2] = {7, 6};
96✔
3001
  int b2_len[2] = {24, 7};
96✔
3002

3003
  int   tag_data = 1;
96✔
3004
  int   tag_len = sizeof(int64_t);
96✔
3005
  char* tbnames[2] = {"tb1", "tb2"};
96✔
3006
  int   affected_rows;
3007

3008
  // insert stb with interlace and no interlace
3009
  for (int i = 0; i < 2; i++) {
288✔
3010
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option[i]);
192✔
3011
    ASSERT_NE(stmt, nullptr);
192✔
3012
    char* sql = "insert into `stmt2_testdb_20`.? using `stmt2_testdb_20`.stb tags(?) values(?,?,?)";
192✔
3013
    int   code = taos_stmt2_prepare(stmt, sql, 0);
192✔
3014
    checkError(stmt, code, __FILE__, __LINE__);
192✔
3015

3016
    int             fieldNum = 0;
192✔
3017
    TAOS_FIELD_ALL* pFields = NULL;
192✔
3018
    code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
192✔
3019
    checkError(stmt, code, __FILE__, __LINE__);
192✔
3020
    ASSERT_EQ(fieldNum, 5);
192✔
3021
    ASSERT_STREQ(pFields[3].name, "b1");
192✔
3022
    ASSERT_EQ(pFields[3].type, TSDB_DATA_TYPE_DECIMAL64);
192✔
3023
    ASSERT_EQ(pFields[3].precision, 4);
192✔
3024
    ASSERT_EQ(pFields[3].scale, 2);
192✔
3025

3026
    ASSERT_STREQ(pFields[4].name, "b2");
192✔
3027
    ASSERT_EQ(pFields[4].type, TSDB_DATA_TYPE_DECIMAL);
192✔
3028
    ASSERT_EQ(pFields[4].precision, 20);
192✔
3029
    ASSERT_EQ(pFields[4].scale, 10);
192✔
3030

3031
    taos_stmt2_free_fields(stmt, pFields);
192✔
3032

3033
    TAOS_STMT2_BIND  tag = {TSDB_DATA_TYPE_INT, &tag_data, &tag_len, NULL, 1};
192✔
3034
    TAOS_STMT2_BIND* pTags[2] = {&tag, &tag};
192✔
3035

3036
    TAOS_STMT2_BIND  col[3] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &t64_len[0], NULL, 2},
192✔
3037
                               {TSDB_DATA_TYPE_DECIMAL64, &b1_data[0], &b1_len[0], NULL, 2},
3038
                               {TSDB_DATA_TYPE_DECIMAL, &b2_data[0], &b2_len[0], NULL, 2}};
192✔
3039
    TAOS_STMT2_BIND* cols[2] = {&col[0], &col[0]};
192✔
3040
    TAOS_STMT2_BINDV bindv = {2, &tbnames[0], &pTags[0], &cols[0]};
192✔
3041
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
192✔
3042
    checkError(stmt, code, __FILE__, __LINE__);
192✔
3043

3044
    code = taos_stmt2_exec(stmt, &affected_rows);
192✔
3045
    checkError(stmt, code, __FILE__, __LINE__);
192✔
3046
    ASSERT_EQ(affected_rows, 4);
192✔
3047

3048
    TAOS_RES* result = taos_query(taos, "select b1,b2,tbname from stmt2_testdb_20.stb order by tbname");
192✔
3049
    ASSERT_NE(result, nullptr);
192✔
3050
    ASSERT_EQ(taos_errno(result), 0);
192✔
3051

3052
    TAOS_ROW row = taos_fetch_row(result);
192✔
3053
    ASSERT_NE(row, nullptr);
192✔
3054
    ASSERT_STREQ((char*)row[0], "99.99");
192✔
3055
    ASSERT_STREQ((char*)row[1], "1234567890.1234567890");
192✔
3056
    ASSERT_EQ(strncmp((char*)row[2], "tb1", 3), 0);
192✔
3057

3058
    row = taos_fetch_row(result);
192✔
3059
    ASSERT_NE(row, nullptr);
192✔
3060
    ASSERT_STREQ((char*)row[0], "1.02");
192✔
3061
    ASSERT_STREQ((char*)row[1], "123000.0000000000");
192✔
3062
    ASSERT_EQ(strncmp((char*)row[2], "tb1", 3), 0);
192✔
3063

3064
    row = taos_fetch_row(result);
192✔
3065
    ASSERT_NE(row, nullptr);
192✔
3066
    ASSERT_STREQ((char*)row[0], "99.99");
192✔
3067
    ASSERT_STREQ((char*)row[1], "1234567890.1234567890");
192✔
3068
    ASSERT_EQ(strncmp((char*)row[2], "tb2", 3), 0);
192✔
3069

3070
    row = taos_fetch_row(result);
192✔
3071
    ASSERT_NE(row, nullptr);
192✔
3072
    ASSERT_STREQ((char*)row[0], "1.02");
192✔
3073
    ASSERT_STREQ((char*)row[1], "123000.0000000000");
192✔
3074
    ASSERT_EQ(strncmp((char*)row[2], "tb2", 3), 0);
192✔
3075

3076
    taos_free_result(result);
192✔
3077

3078
    // check null decimal
3079
    char             is_null1 = '1';
192✔
3080
    TAOS_STMT2_BIND  col1[3] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts[2], &t64_len[0], NULL, 1},
192✔
3081
                                {TSDB_DATA_TYPE_DECIMAL64, NULL, NULL, &is_null1, 1},
3082
                                {TSDB_DATA_TYPE_DECIMAL, NULL, NULL, &is_null1, 1}};
192✔
3083
    TAOS_STMT2_BIND* cols1 = &col1[0];
192✔
3084
    bindv = TAOS_STMT2_BINDV{1, &tbnames[0], &pTags[0], &cols1};
192✔
3085
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
192✔
3086
    checkError(stmt, code, __FILE__, __LINE__);
192✔
3087

3088
    code = taos_stmt2_exec(stmt, &affected_rows);
192✔
3089
    checkError(stmt, code, __FILE__, __LINE__);
192✔
3090
    ASSERT_EQ(affected_rows, 1);
192✔
3091

3092
    result = taos_query(taos, "select b1,b2,tbname from stmt2_testdb_20.tb1 where ts = 1591060630000 order by tbname");
192✔
3093
    ASSERT_NE(result, nullptr);
192✔
3094
    ASSERT_EQ(taos_errno(result), 0);
192✔
3095

3096
    row = taos_fetch_row(result);
192✔
3097
    ASSERT_NE(row, nullptr);
192✔
3098
    ASSERT_STREQ((char*)row[0], NULL);
192✔
3099
    ASSERT_STREQ((char*)row[1], NULL);
192✔
3100
    ASSERT_EQ(strncmp((char*)row[2], "tb1", 3), 0);
192✔
3101
    taos_free_result(result);
192✔
3102

3103
    do_query(taos, "delete from stmt2_testdb_20.tb1");
192✔
3104
    do_query(taos, "delete from stmt2_testdb_20.tb2");
192✔
3105
    taos_stmt2_close(stmt);
192✔
3106
  }
3107

3108
  // check decimal overflow
3109
  {
3110
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option[0]);
96✔
3111
    ASSERT_NE(stmt, nullptr);
96✔
3112
    char* sql = "insert into `stmt2_testdb_20`.? using `stmt2_testdb_20`.stb tags(1) values(?,?,?)";
96✔
3113
    int   code = taos_stmt2_prepare(stmt, sql, 0);
96✔
3114
    checkError(stmt, code, __FILE__, __LINE__);
96✔
3115

3116
    char*            b1_data2 = "99.99999";
96✔
3117
    char*            b2_data2 = "1.23e+5";
96✔
3118
    int32_t          b1_len2 = 8;
96✔
3119
    int32_t          b2_len2 = 7;
96✔
3120
    TAOS_STMT2_BIND  col2[3] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &t64_len[0], NULL, 1},
96✔
3121
                                {TSDB_DATA_TYPE_DECIMAL64, b1_data2, &b1_len2, NULL, 1},
3122
                                {TSDB_DATA_TYPE_DECIMAL, b2_data2, &b2_len2, NULL, 1}};
96✔
3123
    TAOS_STMT2_BIND* cols2 = &col2[0];
96✔
3124
    TAOS_STMT2_BINDV bindv = TAOS_STMT2_BINDV{1, &tbnames[0], NULL, &cols2};
96✔
3125

3126
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
3127
    ASSERT_EQ(code, TSDB_CODE_DECIMAL_OVERFLOW);
96✔
3128

3129
    taos_stmt2_close(stmt);
96✔
3130
  }
3131

3132
  // normal table
3133
  {
3134
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option[0]);
96✔
3135
    ASSERT_NE(stmt, nullptr);
96✔
3136
    char* sql = "insert into stmt2_testdb_20.ntb values(?,?,?)";
96✔
3137
    int   code = taos_stmt2_prepare(stmt, sql, 0);
96✔
3138
    checkError(stmt, code, __FILE__, __LINE__);
96✔
3139

3140
    int             fieldNum = 0;
96✔
3141
    TAOS_FIELD_ALL* pFields = NULL;
96✔
3142
    code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
96✔
3143
    checkError(stmt, code, __FILE__, __LINE__);
96✔
3144
    ASSERT_EQ(fieldNum, 3);
96✔
3145
    ASSERT_STREQ(pFields[1].name, "b1");
96✔
3146
    ASSERT_EQ(pFields[1].type, TSDB_DATA_TYPE_DECIMAL64);
96✔
3147
    ASSERT_EQ(pFields[1].precision, 4);
96✔
3148
    ASSERT_EQ(pFields[1].scale, 2);
96✔
3149

3150
    ASSERT_STREQ(pFields[2].name, "b2");
96✔
3151
    ASSERT_EQ(pFields[2].type, TSDB_DATA_TYPE_DECIMAL);
96✔
3152
    ASSERT_EQ(pFields[2].precision, 20);
96✔
3153
    ASSERT_EQ(pFields[2].scale, 10);
96✔
3154

3155
    taos_stmt2_free_fields(stmt, pFields);
96✔
3156

3157
    TAOS_STMT2_BIND  col[3] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &t64_len[0], NULL, 2},
96✔
3158
                               {TSDB_DATA_TYPE_DECIMAL64, &b1_data[0], &b1_len[0], NULL, 2},
3159
                               {TSDB_DATA_TYPE_DECIMAL, &b2_data[0], &b2_len[0], NULL, 2}};
96✔
3160
    TAOS_STMT2_BIND* cols[2] = {&col[0]};
96✔
3161
    TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &cols[0]};
96✔
3162
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
3163
    checkError(stmt, code, __FILE__, __LINE__);
96✔
3164

3165
    code = taos_stmt2_exec(stmt, &affected_rows);
96✔
3166
    checkError(stmt, code, __FILE__, __LINE__);
96✔
3167
    ASSERT_EQ(affected_rows, 2);
96✔
3168

3169
    TAOS_RES* result = taos_query(taos, "select b1,b2 from stmt2_testdb_20.ntb");
96✔
3170
    ASSERT_NE(result, nullptr);
96✔
3171
    ASSERT_EQ(taos_errno(result), 0);
96✔
3172

3173
    TAOS_ROW row = taos_fetch_row(result);
96✔
3174
    ASSERT_NE(row, nullptr);
96✔
3175
    ASSERT_STREQ((char*)row[0], "99.99");
96✔
3176
    ASSERT_STREQ((char*)row[1], "1234567890.1234567890");
96✔
3177

3178
    row = taos_fetch_row(result);
96✔
3179
    ASSERT_NE(row, nullptr);
96✔
3180
    ASSERT_STREQ((char*)row[0], "1.02");
96✔
3181
    ASSERT_STREQ((char*)row[1], "123000.0000000000");
96✔
3182
    taos_free_result(result);
96✔
3183
    taos_stmt2_close(stmt);
96✔
3184
  }
3185

3186
  // query decimal
3187
  {
3188
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option[0]);
96✔
3189
    ASSERT_NE(stmt, nullptr);
96✔
3190
    char* sql = "select b1,b2 from stmt2_testdb_20.ntb where b1 < ? and b2 < ?";
96✔
3191
    int   code = taos_stmt2_prepare(stmt, sql, 0);
96✔
3192
    checkError(stmt, code, __FILE__, __LINE__);
96✔
3193

3194
    TAOS_STMT2_BIND  col[2] = {{TSDB_DATA_TYPE_DECIMAL64, &b1_data[0], &b1_len[0], NULL, 1},
96✔
3195
                               {TSDB_DATA_TYPE_DECIMAL, &b2_data[0], &b2_len[0], NULL, 1}};
96✔
3196
    TAOS_STMT2_BIND* cols = &col[0];
96✔
3197
    TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &cols};
96✔
3198
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
3199
    checkError(stmt, code, __FILE__, __LINE__);
96✔
3200

3201
    code = taos_stmt2_exec(stmt, NULL);
96✔
3202
    checkError(stmt, code, __FILE__, __LINE__);
96✔
3203

3204
    TAOS_RES* result = taos_stmt2_result(stmt);
96✔
3205
    ASSERT_NE(result, nullptr);
96✔
3206
    ASSERT_EQ(taos_errno(result), 0);
96✔
3207

3208
    TAOS_ROW row = taos_fetch_row(result);
96✔
3209
    ASSERT_NE(row, nullptr);
96✔
3210
    ASSERT_STREQ((char*)row[0], "1.02");
96✔
3211
    ASSERT_STREQ((char*)row[1], "123000.0000000000");
96✔
3212
    taos_stmt2_close(stmt);
96✔
3213
  }
3214

3215
  do_query(taos, "DROP DATABASE IF EXISTS stmt2_testdb_20");
96✔
3216
  taos_close(taos);
96✔
3217
}
3218

3219
void testMultiPrepare(TAOS* taos, TAOS_STMT2_OPTION* option) {
192✔
3220
  TAOS_STMT2* stmt = taos_stmt2_init(taos, option);
192✔
3221
  ASSERT_NE(stmt, nullptr);
192✔
3222
  // 1 insert stb
3223
  char* sql = "insert into ? using stb tags(?,?) values(?,?)";
192✔
3224
  int   code = taos_stmt2_prepare(stmt, sql, 0);
192✔
3225
  checkError(stmt, code, __FILE__, __LINE__);
192✔
3226
  int total_affected = 0;
192✔
3227

3228
  char*            tbname = "t1";
192✔
3229
  int64_t          tt = 1591060628000;
192✔
3230
  int32_t          tb = 100;
192✔
3231
  int              tag_len[2] = {sizeof(int64_t), sizeof(int32_t)};
192✔
3232
  TAOS_STMT2_BIND  tags[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &tt, &tag_len[0], NULL, 1},
192✔
3233
                              {TSDB_DATA_TYPE_INT, &tb, &tag_len[1], NULL, 1}};
192✔
3234
  TAOS_STMT2_BIND* tagv = &tags[0];
192✔
3235

3236
  int64_t          ts[2] = {1591060628000, 1591060629000};
192✔
3237
  int32_t          values[2] = {100, 200};
192✔
3238
  int              t64_len[2] = {sizeof(int64_t), sizeof(int64_t)};
192✔
3239
  int              val_len[2] = {sizeof(int32_t), sizeof(int32_t)};
192✔
3240
  TAOS_STMT2_BIND  col[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &t64_len[0], NULL, 2},
192✔
3241
                             {TSDB_DATA_TYPE_INT, &values[0], &val_len[0], NULL, 2}};
192✔
3242
  TAOS_STMT2_BIND* cols = &col[0];
192✔
3243
  TAOS_STMT2_BINDV bindv = {1, &tbname, &tagv, &cols};
192✔
3244
  code = taos_stmt2_bind_param(stmt, &bindv, -1);
192✔
3245
  checkError(stmt, code, __FILE__, __LINE__);
192✔
3246

3247
  int affected_rows;
3248
  code = taos_stmt2_exec(stmt, &affected_rows);
192✔
3249
  checkError(stmt, code, __FILE__, __LINE__);
192✔
3250
  ASSERT_EQ(affected_rows, 2);
192✔
3251

3252
  // 2 insert ntb
3253
  sql = "INSERT INTO t VALUES (?, ?)";
192✔
3254
  code = taos_stmt2_prepare(stmt, sql, 0);
192✔
3255
  checkError(stmt, code, __FILE__, __LINE__);
192✔
3256

3257
  TAOS_STMT2_BIND params[2];
3258
  params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
192✔
3259
  params[0].buffer = &ts[0];
192✔
3260
  params[0].length = &t64_len[0];
192✔
3261
  params[0].is_null = NULL;
192✔
3262
  params[0].num = 2;
192✔
3263

3264
  params[1].buffer_type = TSDB_DATA_TYPE_INT;
192✔
3265
  params[1].buffer = &values[0];
192✔
3266
  params[1].length = &val_len[0];
192✔
3267
  params[1].is_null = NULL;
192✔
3268
  params[1].num = 2;
192✔
3269
  TAOS_STMT2_BIND* paramv[2] = {&params[0], &params[1]};
192✔
3270

3271
  bindv = {1, NULL, NULL, &paramv[0]};
192✔
3272
  code = taos_stmt2_bind_param(stmt, &bindv, -1);
192✔
3273
  checkError(stmt, code, __FILE__, __LINE__);
192✔
3274

3275
  affected_rows = 0;
192✔
3276
  code = taos_stmt2_exec(stmt, &affected_rows);
192✔
3277
  checkError(stmt, code, __FILE__, __LINE__);
192✔
3278
  ASSERT_EQ(affected_rows, 2);
192✔
3279

3280
  // 3 select data
3281
  const char* query_sql = "SELECT * FROM t WHERE ts >= ? AND ts <= ?";
192✔
3282
  code = taos_stmt2_prepare(stmt, query_sql, 0);
192✔
3283
  checkError(stmt, code, __FILE__, __LINE__);
192✔
3284

3285
  int             fieldNum = 0;
192✔
3286
  TAOS_FIELD_ALL* pFields = NULL;
192✔
3287
  code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
192✔
3288
  checkError(stmt, code, __FILE__, __LINE__);
192✔
3289
  ASSERT_EQ(fieldNum, 2);
192✔
3290

3291
  int64_t start_ts[2] = {1591060627000, 1591060630000};
192✔
3292
  int     t64_len_query[2] = {sizeof(int64_t), sizeof(int64_t)};
192✔
3293

3294
  TAOS_STMT2_BIND  param3[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &start_ts[0], &t64_len_query[0], NULL, 1},
192✔
3295
                                {TSDB_DATA_TYPE_TIMESTAMP, &start_ts[1], &t64_len_query[1], NULL, 1}};
192✔
3296
  TAOS_STMT2_BIND* paramv2 = &param3[0];
192✔
3297
  TAOS_STMT2_BINDV bindv2 = {1, NULL, NULL, &paramv2};
192✔
3298
  code = taos_stmt2_bind_param(stmt, &bindv2, -1);
192✔
3299
  checkError(stmt, code, __FILE__, __LINE__);
192✔
3300

3301
  code = taos_stmt2_exec(stmt, NULL);
192✔
3302
  checkError(stmt, code, __FILE__, __LINE__);
192✔
3303

3304
  TAOS_RES* res = taos_stmt2_result(stmt);
192✔
3305
  ASSERT_NE(res, nullptr);
192✔
3306

3307
  TAOS_ROW row;
3308
  int      rows = 0;
192✔
3309
  while ((row = taos_fetch_row(res))) {
576✔
3310
    rows++;
384✔
3311
  }
3312
  ASSERT_EQ(rows, 2);  // 应该返回2条记录
192✔
3313

3314
  taos_stmt2_close(stmt);
192✔
3315
}
3316

3317
TEST(stmt2Case, prepare) {
384✔
3318
  TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
96✔
3319
  ASSERT_NE(taos, nullptr);
96✔
3320

3321
  do_query(taos, "DROP DATABASE IF EXISTS stmt2_testdb_prepare");
96✔
3322
  do_query(taos, "CREATE DATABASE IF NOT EXISTS stmt2_testdb_prepare");
96✔
3323
  do_query(taos, "USE stmt2_testdb_prepare");
96✔
3324
  do_query(taos, "CREATE TABLE t (ts TIMESTAMP, b INT)");
96✔
3325
  do_query(taos, "CREATE STABLE stb (ts TIMESTAMP, b INT) TAGS (tt TIMESTAMP, tb INT)");
96✔
3326

3327
  TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
3328
  testMultiPrepare(taos, &option);
96✔
3329

3330
  option = {0, false, false, NULL, NULL};
96✔
3331
  testMultiPrepare(taos, &option);
96✔
3332

3333
  do_query(taos, "DROP DATABASE IF EXISTS stmt2_testdb_prepare");
96✔
3334
  taos_close(taos);
96✔
3335
}
3336

3337
// TD-34593
3338
TEST(stmt2Case, prepare_fixedtags) {
384✔
3339
  TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
96✔
3340
  ASSERT_NE(taos, nullptr);
96✔
3341

3342
  do_query(taos, "DROP DATABASE IF EXISTS stmt2_testdb_prepare2");
96✔
3343
  do_query(taos, "CREATE DATABASE IF NOT EXISTS stmt2_testdb_prepare2");
96✔
3344
  do_query(taos, "CREATE STABLE `stmt2_testdb_prepare2`.stb (ts TIMESTAMP, b INT) TAGS (tt TIMESTAMP, tb INT)");
96✔
3345

3346
  TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
3347
  TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
3348
  ASSERT_NE(stmt, nullptr);
96✔
3349
  for (int i = 0; i < 10; i++) {
1,056✔
3350
    // 1 insert stb
3351
    char* sql = "insert into `stmt2_testdb_prepare2`.? using `stmt2_testdb_prepare2`.stb tags(now,1) values(?,?)";
960✔
3352
    int   code = taos_stmt2_prepare(stmt, sql, 0);
960✔
3353
    checkError(stmt, code, __FILE__, __LINE__);
960✔
3354
    int total_affected = 0;
960✔
3355

3356
    int             fieldNum = 0;
960✔
3357
    TAOS_FIELD_ALL* pFields = NULL;
960✔
3358
    code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
960✔
3359
    checkError(stmt, code, __FILE__, __LINE__);
960✔
3360
    ASSERT_EQ(fieldNum, 3);
960✔
3361

3362
    int64_t          tt = 1591060628000;
960✔
3363
    int32_t          tb = 100;
960✔
3364
    int              tag_len[2] = {sizeof(int64_t), sizeof(int32_t)};
960✔
3365
    TAOS_STMT2_BIND  tags[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &tt, &tag_len[0], NULL, 1},
960✔
3366
                                {TSDB_DATA_TYPE_INT, &tb, &tag_len[1], NULL, 1}};
960✔
3367
    TAOS_STMT2_BIND* tagv = &tags[0];
960✔
3368
    char             tbname[10];
3369
    sprintf(tbname, "t%d", i);
960✔
3370
    char*            tbnames = &tbname[0];
960✔
3371
    int64_t          ts[2] = {1591060628000, 1591060629000};
960✔
3372
    int32_t          values[2] = {100, 200};
960✔
3373
    int              t64_len[2] = {sizeof(int64_t), sizeof(int64_t)};
960✔
3374
    int              val_len[2] = {sizeof(int32_t), sizeof(int32_t)};
960✔
3375
    TAOS_STMT2_BIND  col[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &t64_len[0], NULL, 2},
960✔
3376
                               {TSDB_DATA_TYPE_INT, &values[0], &val_len[0], NULL, 2}};
960✔
3377
    TAOS_STMT2_BIND* cols = &col[0];
960✔
3378
    TAOS_STMT2_BINDV bindv = {1, &tbnames, NULL, &cols};
960✔
3379
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
960✔
3380
    checkError(stmt, code, __FILE__, __LINE__);
960✔
3381

3382
    int affected_rows;
3383
    code = taos_stmt2_exec(stmt, &affected_rows);
960✔
3384
    checkError(stmt, code, __FILE__, __LINE__);
960✔
3385
    ASSERT_EQ(affected_rows, 2);
960✔
3386

3387
    taos_stmt2_free_fields(stmt, pFields);
960✔
3388
  }
3389

3390
  do_query(taos, "DROP DATABASE IF EXISTS stmt2_testdb_prepare2");
96✔
3391
  taos_stmt2_close(stmt);
96✔
3392
  taos_close(taos);
96✔
3393
}
3394

3395
// TD-33921
3396
TEST(stmt2Case, mixed_bind) {
384✔
3397
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
3398
  ASSERT_NE(taos, nullptr);
96✔
3399

3400
  do_query(taos, "drop database if exists stmt2_testdb_19");
96✔
3401
  do_query(taos, "create database IF NOT EXISTS stmt2_testdb_19");
96✔
3402
  do_query(taos,
96✔
3403
           "create stable stmt2_testdb_19.stb(ts timestamp, c1 int, c2 bigint, c3 float, c4 double, c5 binary(128), c6 "
3404
           "smallint, c7 "
3405
           "tinyint, c8 bool, c9 nchar(128), c10 geometry(256))TAGS(tts timestamp, t1 int, t2 bigint, t3 float, t4 "
3406
           "double, t5 "
3407
           "binary(128), t6 smallint, t7 tinyint, t8 bool, t9 nchar(128), t10 geometry(256))");
3408
  do_query(taos, "use stmt2_testdb_19");
96✔
3409

3410
  int code = 0;
96✔
3411
  struct {
3412
    int64_t       c1;
3413
    int32_t       c2;
3414
    int64_t       c3;
3415
    float         c4;
3416
    double        c5;
3417
    unsigned char c6[8];
3418
    int16_t       c7;
3419
    int8_t        c8;
3420
    int8_t        c9;
3421
    char          c10[32];
3422
  } v = {1591060628000, 1, 2, 3.0, 4.0, "abcdef", 5, 6, 7, "ijnop"};
96✔
3423

3424
  struct {
3425
    int32_t c1;
3426
    int32_t c2;
3427
    int32_t c3;
3428
    int32_t c4;
3429
    int32_t c5;
3430
    int32_t c6;
3431
    int32_t c7;
3432
    int32_t c8;
3433
    int32_t c9;
3434
    int32_t c10;
3435
  } v_len = {sizeof(int64_t), sizeof(int32_t),
96✔
3436
             sizeof(int64_t), sizeof(float),
3437
             sizeof(double),  8,
3438
             sizeof(int16_t), sizeof(int8_t),
3439
             sizeof(int8_t),  8};
3440
  unsigned char* outputGeom1;
3441
  size_t         size1;
3442
  initCtxMakePoint();
96✔
3443
  code = doMakePoint(1.000, 2.000, &outputGeom1, &size1);
96✔
3444
  char* tbname[8] = {"tb1", "tb2", "tb3", "tb4", "tb5", "tb6", "tb7", "tb8"};
96✔
3445

3446
  TAOS_STMT2_BIND params_tags[9] = {{TSDB_DATA_TYPE_INT, &v.c2, (int32_t*)&v_len.c2, NULL, 1},
96✔
3447
                                    {TSDB_DATA_TYPE_BIGINT, &v.c3, (int32_t*)&v_len.c3, NULL, 1},
3448
                                    {TSDB_DATA_TYPE_FLOAT, &v.c4, (int32_t*)&v_len.c4, NULL, 1},
3449
                                    {TSDB_DATA_TYPE_BINARY, &v.c6, (int32_t*)&v_len.c6, NULL, 1},
3450
                                    {TSDB_DATA_TYPE_SMALLINT, &v.c7, (int32_t*)&v_len.c7, NULL, 1},
3451
                                    {TSDB_DATA_TYPE_TINYINT, &v.c8, (int32_t*)&v_len.c8, NULL, 1},
3452
                                    {TSDB_DATA_TYPE_BOOL, &v.c9, (int32_t*)&v_len.c9, NULL, 1},
3453
                                    {TSDB_DATA_TYPE_NCHAR, &v.c10, (int32_t*)&v_len.c10, NULL, 1},
3454
                                    {TSDB_DATA_TYPE_GEOMETRY, outputGeom1, (int32_t*)&size1, NULL, 1}};
96✔
3455

3456
  TAOS_STMT2_BIND params_cols[9] = {{TSDB_DATA_TYPE_TIMESTAMP, &v.c1, (int32_t*)&v_len.c1, NULL, 1},
96✔
3457
                                    {TSDB_DATA_TYPE_BIGINT, &v.c3, (int32_t*)&v_len.c3, NULL, 1},
3458
                                    {TSDB_DATA_TYPE_FLOAT, &v.c4, (int32_t*)&v_len.c4, NULL, 1},
3459
                                    {TSDB_DATA_TYPE_DOUBLE, &v.c5, (int32_t*)&v_len.c5, NULL, 1},
3460
                                    {TSDB_DATA_TYPE_BINARY, &v.c6, (int32_t*)&v_len.c6, NULL, 1},
3461
                                    {TSDB_DATA_TYPE_SMALLINT, &v.c7, (int32_t*)&v_len.c7, NULL, 1},
3462
                                    {TSDB_DATA_TYPE_TINYINT, &v.c8, (int32_t*)&v_len.c8, NULL, 1},
3463
                                    {TSDB_DATA_TYPE_NCHAR, &v.c10, (int32_t*)&v_len.c10, NULL, 1},
3464
                                    {TSDB_DATA_TYPE_GEOMETRY, outputGeom1, (int32_t*)&size1, NULL, 1}};
96✔
3465

3466
  TAOS_STMT2_OPTION option[2] = {{0, false, false, NULL, NULL}, {0, true, true, NULL, NULL}};
96✔
3467
  for (int k = 0; k < 2; k++) {
288✔
3468
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option[k]);
192✔
3469
    ASSERT_NE(stmt, nullptr);
192✔
3470
    char* stmt_sql =
192✔
3471
        "insert into stmt2_testdb_19.? using stb tags(1591060628000,?,?,?,4.0,?,?,?,?,?,?)values "
3472
        "(?,2,?,?,?,?,?,?,1,?,?)";
3473
    code = taos_stmt2_prepare(stmt, stmt_sql, 0);
192✔
3474
    checkError(stmt, code, __FILE__, __LINE__);
192✔
3475

3476
    TAOS_STMT2_BIND* tags[2] = {&params_tags[0], &params_tags[0]};
192✔
3477
    TAOS_STMT2_BIND* cols[2] = {&params_cols[0], &params_cols[0]};
192✔
3478
    TAOS_STMT2_BINDV bindv = {2, &tbname[0 + k * 4], &tags[0], &cols[0]};
192✔
3479
    for (int i = 0; i < 3; i++) {
768✔
3480
      v.c1 += i * 10000;
576✔
3481
      code = taos_stmt2_bind_param(stmt, &bindv, -1);
576✔
3482
    }
3483
    checkError(stmt, code, __FILE__, __LINE__);
192✔
3484

3485
    int affected_rows;
3486
    code = taos_stmt2_exec(stmt, &affected_rows);
192✔
3487
    checkError(stmt, code, __FILE__, __LINE__);
192✔
3488
    ASSERT_EQ(affected_rows, 6);
192✔
3489

3490
    stmt_sql =
192✔
3491
        "insert into stb (tbname, tts, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, ts, c1, c2, c3, c4, c5, c6, c7, c8, "
3492
        "c9, c10) values(?,1591060628000,?,?,?,4.0,?,?,?,?,?,?,?,2,?,?,?,?,?,?,1,?,?)";
3493
    code = taos_stmt2_prepare(stmt, stmt_sql, 0);
192✔
3494
    checkError(stmt, code, __FILE__, __LINE__);
192✔
3495

3496
    bindv = {2, &tbname[2 + k * 4], &tags[0], &cols[0]};
192✔
3497
    for (int i = 0; i < 3; i++) {
768✔
3498
      v.c1 += i * 10000;
576✔
3499
      code = taos_stmt2_bind_param(stmt, &bindv, -1);
576✔
3500
    }
3501
    checkError(stmt, code, __FILE__, __LINE__);
192✔
3502

3503
    code = taos_stmt2_exec(stmt, &affected_rows);
192✔
3504
    checkError(stmt, code, __FILE__, __LINE__);
192✔
3505
    ASSERT_EQ(affected_rows, 6);
192✔
3506
    taos_stmt2_close(stmt);
192✔
3507
  }
3508

3509
  geosFreeBuffer(outputGeom1);
96✔
3510

3511
  // TD-6581610626
3512
  taos_query(taos, "drop table if exists stmt2_testdb_19.ntb");
96✔
3513
  taos_query(taos, "create table stmt2_testdb_19.ntb (ts timestamp, name nchar(10), i32 int)");
96✔
3514
  for (int i = 0; i < 2; i++) {
288✔
3515
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option[i]);
192✔
3516
    ASSERT_NE(stmt, nullptr);
192✔
3517

3518
    const char* sql = "insert into ntb (ts, name, i32) values (?, 'world', ?)";
192✔
3519
    int         code = taos_stmt2_prepare(stmt, sql, 0);
192✔
3520
    checkError(stmt, code, __FILE__, __LINE__);
192✔
3521

3522
    int64_t ts[2] = {1591060628000, 1591060629000};
192✔
3523
    int32_t t64_len[2] = {sizeof(int64_t), sizeof(int64_t)};
192✔
3524

3525
    int32_t         i32[2] = {70, 80};
192✔
3526
    int32_t         i32_len[2] = {sizeof(int32_t), sizeof(int32_t)};
192✔
3527
    TAOS_STMT2_BIND param[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &t64_len[0], NULL, 2},
192✔
3528
                                {TSDB_DATA_TYPE_INT, &i32[0], &i32_len[0], NULL, 2}};
192✔
3529

3530
    TAOS_STMT2_BIND* params[2] = {&param[0], &param[1]};
192✔
3531
    TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &params[0]};
192✔
3532

3533
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
192✔
3534
    checkError(stmt, code, __FILE__, __LINE__);
192✔
3535

3536
    code = taos_stmt2_exec(stmt, NULL);
192✔
3537
    checkError(stmt, code, __FILE__, __LINE__);
192✔
3538

3539
    taos_stmt2_close(stmt);
192✔
3540
  }
3541
  do_query(taos, "drop database if exists stmt2_testdb_19");
96✔
3542
  taos_close(taos);
96✔
3543
}
3544

3545
// TD-33582
3546
TEST(stmt2Case, errcode) {
384✔
3547
  TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
96✔
3548
  ASSERT_NE(taos, nullptr);
96✔
3549
  do_query(taos, "DROP DATABASE IF EXISTS stmt2_testdb_14");
96✔
3550
  do_query(taos, "CREATE DATABASE IF NOT EXISTS stmt2_testdb_14");
96✔
3551
  do_query(taos, "use stmt2_testdb_14");
96✔
3552
  do_query(taos, "create table stmt2_testdb_14.tb (ts timestamp, b binary(10))");
96✔
3553
  do_query(taos, "CREATE STABLE `stmt2_testdb_14`.stb (ts TIMESTAMP, b INT) TAGS (tt TIMESTAMP, tb INT)");
96✔
3554

3555
  {
3556
    TAOS_STMT2_OPTION option = {0};
96✔
3557
    TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
3558
    ASSERT_NE(stmt, nullptr);
96✔
3559
    char* sql = "insert into ? values(?,?)";
96✔
3560
    int   code = taos_stmt2_prepare(stmt, sql, 0);
96✔
3561
    checkError(stmt, code, __FILE__, __LINE__);
96✔
3562

3563
    int             fieldNum = 0;
96✔
3564
    TAOS_FIELD_ALL* pFields = NULL;
96✔
3565
    code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
96✔
3566
    ASSERT_EQ(code, TSDB_CODE_TSC_STMT_TBNAME_ERROR);
96✔
3567

3568
    // get fail dont influence the next stmt prepare
3569
    sql = "insert into ? (ts, name) values (?, ?)";
96✔
3570
    code = taos_stmt2_prepare(stmt, sql, 0);
96✔
3571
    checkError(stmt, code, __FILE__, __LINE__);
96✔
3572
    taos_stmt2_close(stmt);
96✔
3573
  }
3574
  // TD-38218, skip bind data before execute
3575
  {
3576
    TAOS_STMT2_OPTION option = {0};
96✔
3577
    TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
3578
    ASSERT_NE(stmt, nullptr);
96✔
3579
    char* sql = "insert into tb values(?,?)";
96✔
3580
    int   code = taos_stmt2_prepare(stmt, sql, 0);
96✔
3581
    checkError(stmt, code, __FILE__, __LINE__);
96✔
3582

3583
    int             fieldNum = 0;
96✔
3584
    TAOS_FIELD_ALL* pFields = NULL;
96✔
3585
    code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
96✔
3586
    checkError(stmt, code, __FILE__, __LINE__);
96✔
3587

3588
    code = taos_stmt2_exec(stmt, NULL);
96✔
3589
    ASSERT_EQ(code, TSDB_CODE_TSC_STMT_API_ERROR);
96✔
3590

3591
    taos_stmt2_close(stmt);
96✔
3592
  }
3593

3594
  // already support in TS-7067
3595
  // {
3596
  //   TAOS_STMT2_OPTION option = {0, false, true, NULL, NULL};
3597
  //   TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
3598
  //   ASSERT_NE(stmt, nullptr);
3599
  //   char* sql = "insert into stmt2_testdb_14.? using stmt2_testdb_14.stb tags(now, 1) values(?, ?)";
3600
  //   int   code = taos_stmt2_prepare(stmt, sql, 0);
3601
  //   checkError(stmt, code, __FILE__, __LINE__);
3602
  //   char* wrong_tbname[2] = {"tb-1", "tb-2"};
3603

3604
  //   int64_t          ts[2] = {1591060628000, 1591060629000};
3605
  //   int32_t          values[2] = {100, 200};
3606
  //   int              t64_len[2] = {sizeof(int64_t), sizeof(int64_t)};
3607
  //   int              val_len[2] = {sizeof(int32_t), sizeof(int32_t)};
3608
  //   TAOS_STMT2_BIND  col[4] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &t64_len[0], NULL, 2},
3609
  //                              {TSDB_DATA_TYPE_INT, &values[0], &val_len[0], NULL, 2},
3610
  //                              {TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &t64_len[0], NULL, 2},
3611
  //                              {TSDB_DATA_TYPE_INT, &values[0], &val_len[0], NULL, 2}};
3612
  //   TAOS_STMT2_BIND* cols[2] = {&col[0], &col[2]};
3613
  //   TAOS_STMT2_BINDV bindv = {2, &wrong_tbname[0], NULL, &cols[0]};
3614
  //   code = taos_stmt2_bind_param(stmt, &bindv, -1);
3615
  //   ASSERT_EQ(code, TSDB_CODE_TSC_STMT_TBNAME_ERROR);
3616

3617
  //   taos_stmt2_close(stmt);
3618
  // }
3619
  // TS-7502
3620
  {
3621
    TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
3622
    TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
3623
    ASSERT_NE(stmt, nullptr);
96✔
3624
    char* sql = "insert into ? using stb tags(now(),1) values(now(),?)";
96✔
3625
    int   code = taos_stmt2_prepare(stmt, sql, 0);
96✔
3626
    checkError(stmt, code, __FILE__, __LINE__);
96✔
3627

3628
    // int             fieldNum = 0;
3629
    // TAOS_FIELD_ALL* pFields = NULL;
3630
    // code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
3631
    // checkError(stmt, code, __FILE__, __LINE__);
3632

3633
    int   values[2] = {100, 200};
96✔
3634
    int   val_len[2] = {sizeof(int32_t), sizeof(int32_t)};
96✔
3635
    char* tbname[2] = {"tb3", "tb4"};
96✔
3636

3637
    TAOS_STMT2_BIND  param = {TSDB_DATA_TYPE_INT, &values[0], &val_len[0], NULL, 2};
96✔
3638
    TAOS_STMT2_BIND* params[2] = {&param, &param};
96✔
3639
    for (int i = 0; i < 3; i++) {
384✔
3640
      TAOS_STMT2_BINDV bindv = {2, &tbname[0], NULL, &params[0]};
288✔
3641
      code = taos_stmt2_bind_param(stmt, &bindv, -1);
288✔
3642
      checkError(stmt, code, __FILE__, __LINE__);
288✔
3643

3644
      code = taos_stmt2_exec(stmt, NULL);
288✔
3645
      checkError(stmt, code, __FILE__, __LINE__);
288✔
3646
    }
3647
    taos_stmt2_close(stmt);
96✔
3648
  }
3649

3650
  do_query(taos, "DROP DATABASE IF EXISTS stmt2_testdb_14");
96✔
3651
  taos_close(taos);
96✔
3652
}
3653

3654
TEST(stmt2Case, usage_error) {
384✔
3655
  TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
96✔
3656
  ASSERT_NE(taos, nullptr);
96✔
3657
  do_query(taos, "DROP DATABASE IF EXISTS stmt2_testdb_17");
96✔
3658
  do_query(taos, "CREATE DATABASE IF NOT EXISTS stmt2_testdb_17");
96✔
3659
  do_query(taos, "use stmt2_testdb_17");
96✔
3660
  do_query(taos, "CREATE TABLE stmt2_testdb_17.ntb(nts timestamp, nb binary(10),nvc varchar(16),ni int);");
96✔
3661

3662
  TAOS_STMT2_OPTION option = {0};
96✔
3663
  // get fields error
3664
  TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
3665
  ASSERT_NE(stmt, nullptr);
96✔
3666
  char* sql = "delete from ntb where ts=?";
96✔
3667
  int   code = taos_stmt2_prepare(stmt, sql, 0);
96✔
3668
  ASSERT_EQ(code, TSDB_CODE_PAR_SYNTAX_ERROR);
96✔
3669
  ASSERT_STREQ(taos_stmt2_error(stmt), "stmt only support 'SELECT' or 'INSERT'");
96✔
3670
  int             fieldNum = 0;
96✔
3671
  TAOS_FIELD_ALL* pFields = NULL;
96✔
3672
  code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
96✔
3673
  ASSERT_EQ(code, TSDB_CODE_PAR_SYNTAX_ERROR);
96✔
3674
  ASSERT_STREQ(taos_stmt2_error(stmt), "stmt only support 'SELECT' or 'INSERT'");
96✔
3675
  // bind error
3676

3677
  int              t64_len[1] = {sizeof(int64_t)};
96✔
3678
  int64_t          ts = 1591060628000;
96✔
3679
  TAOS_STMT2_BIND  params = {TSDB_DATA_TYPE_TIMESTAMP, &ts, t64_len, NULL, 1};
96✔
3680
  TAOS_STMT2_BIND* params1 = &params;
96✔
3681

3682
  TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &params1};
96✔
3683
  code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
3684
  ASSERT_EQ(code, TSDB_CODE_PAR_SYNTAX_ERROR);
96✔
3685
  ASSERT_STREQ(taos_stmt2_error(stmt), "stmt only support 'SELECT' or 'INSERT'");
96✔
3686

3687
  taos_stmt2_close(stmt);
96✔
3688
  do_query(taos, "DROP DATABASE IF EXISTS stmt2_testdb_17");
96✔
3689
  taos_close(taos);
96✔
3690
}
3691

3692
void stmtAsyncBindCb(void* param, TAOS_RES* pRes, int code) {
×
3693
  bool* finish = (bool*)param;
×
3694
  ASSERT_EQ(code, TSDB_CODE_SUCCESS);
×
3695
  taosMsleep(500);
×
3696
  *finish = true;
×
3697
  return;
×
3698
}
3699

3700
void stmtAsyncQueryCb2(void* param, TAOS_RES* pRes, int code) {
×
3701
  ASSERT_EQ(code, TSDB_CODE_SUCCESS);
×
3702
  taosMsleep(500);
×
3703
  return;
×
3704
}
3705

3706
void stmtAsyncBindCb2(void* param, TAOS_RES* pRes, int code) {
×
3707
  bool* finish = (bool*)param;
×
3708
  taosMsleep(500);
×
3709
  *finish = true;
×
3710
  return;
×
3711
}
3712

3713
void stmt2_async_test(std::atomic<bool>& stop_task) {
×
3714
  int CTB_NUMS = 2;
×
3715
  int ROW_NUMS = 2;
×
3716
  int CYC_NUMS = 2;
×
3717

3718
  TAOS*             taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
×
3719
  TAOS_STMT2_OPTION option = {0, true, true, stmtAsyncQueryCb2, NULL};
×
3720
  char*             sql = "insert into ? values(?,?)";
×
3721

3722
  do_query(taos, "drop database if exists stmt2_testdb_15");
×
3723
  do_query(taos, "create database IF NOT EXISTS stmt2_testdb_15");
×
3724
  do_query(taos, "create stable stmt2_testdb_15.stb (ts timestamp, b binary(10)) tags(t1 int, t2 binary(10))");
×
3725
  do_query(taos, "use stmt2_testdb_15");
×
3726

3727
  TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
×
3728
  ASSERT_NE(stmt, nullptr);
×
3729
  int code = taos_stmt2_prepare(stmt, sql, 0);
×
3730
  checkError(stmt, code, __FILE__, __LINE__);
×
3731
  int total_affected = 0;
×
3732

3733
  // tbname
3734
  char** tbs = (char**)taosMemoryMalloc(CTB_NUMS * sizeof(char*));
×
3735
  for (int i = 0; i < CTB_NUMS; i++) {
×
3736
    tbs[i] = (char*)taosMemoryMalloc(sizeof(char) * 20);
×
3737
    sprintf(tbs[i], "ctb_%d", i);
×
3738
    char* tmp = (char*)taosMemoryMalloc(sizeof(char) * 100);
×
3739
    sprintf(tmp, "create table stmt2_testdb_15.%s using stmt2_testdb_15.stb tags(0, 'after')", tbs[i]);
×
3740
    do_query(taos, tmp);
×
3741
  }
3742
  // params
3743
  TAOS_STMT2_BIND** paramv = (TAOS_STMT2_BIND**)taosMemoryMalloc(CTB_NUMS * sizeof(TAOS_STMT2_BIND*));
×
3744
  // col params
3745
  int64_t** ts = (int64_t**)taosMemoryMalloc(CTB_NUMS * sizeof(int64_t*));
×
3746
  char**    b = (char**)taosMemoryMalloc(CTB_NUMS * sizeof(char*));
×
3747
  int*      ts_len = (int*)taosMemoryMalloc(ROW_NUMS * sizeof(int));
×
3748
  int*      b_len = (int*)taosMemoryMalloc(ROW_NUMS * sizeof(int));
×
3749
  for (int i = 0; i < ROW_NUMS; i++) {
×
3750
    ts_len[i] = sizeof(int64_t);
×
3751
    b_len[i] = 1;
×
3752
  }
3753
  for (int i = 0; i < CTB_NUMS; i++) {
×
3754
    ts[i] = (int64_t*)taosMemoryMalloc(ROW_NUMS * sizeof(int64_t));
×
3755
    b[i] = (char*)taosMemoryMalloc(ROW_NUMS * sizeof(char));
×
3756
    for (int j = 0; j < ROW_NUMS; j++) {
×
3757
      ts[i][j] = 1591060628000 + 100000 + j;
×
3758
      b[i][j] = 'a' + j;
×
3759
    }
3760
  }
3761
  // bind params
3762
  for (int i = 0; i < CTB_NUMS; i++) {
×
3763
    // create col params
3764
    paramv[i] = (TAOS_STMT2_BIND*)taosMemoryMalloc(2 * sizeof(TAOS_STMT2_BIND));
×
3765
    paramv[i][0] = {TSDB_DATA_TYPE_TIMESTAMP, &ts[i][0], &ts_len[0], NULL, ROW_NUMS};
×
3766
    paramv[i][1] = {TSDB_DATA_TYPE_BINARY, &b[i][0], &b_len[0], NULL, ROW_NUMS};
×
3767
  }
3768

3769
  // case 1 : bind_a->exec_a->bind_a->exec_a->...
3770
  {
3771
    printf("case 1 : bind_a->exec_a->bind_a->exec_a->...\n");
×
3772
    for (int r = 0; r < CYC_NUMS; r++) {
×
3773
      // bind
3774
      TAOS_STMT2_BINDV bindv = {CTB_NUMS, tbs, NULL, paramv};
×
3775
      bool             finish = false;
×
3776
      code = taos_stmt2_bind_param_a(stmt, &bindv, -1, stmtAsyncBindCb, (void*)&finish);
×
3777

3778
      checkError(stmt, code, __FILE__, __LINE__);
×
3779

3780
      // exec
3781
      code = taos_stmt2_exec(stmt, NULL);
×
3782
      checkError(stmt, code, __FILE__, __LINE__);
×
3783
    }
3784
  }
3785

3786
  // case 2 : bind_a->bind_a->bind_a->exec_a->...
3787
  {
3788
    printf("case 2 : bind_a->bind_a->bind_a->exec_a->...\n");
×
3789
    for (int r = 0; r < CYC_NUMS; r++) {
×
3790
      // bind params
3791
      TAOS_STMT2_BIND** paramv = (TAOS_STMT2_BIND**)taosMemoryMalloc(CTB_NUMS * sizeof(TAOS_STMT2_BIND*));
×
3792
      for (int i = 0; i < CTB_NUMS; i++) {
×
3793
        // create col params
3794
        paramv[i] = (TAOS_STMT2_BIND*)taosMemoryMalloc(2 * sizeof(TAOS_STMT2_BIND));
×
3795
        paramv[i][0] = {TSDB_DATA_TYPE_TIMESTAMP, &ts[i][0], &ts_len[0], NULL, ROW_NUMS};
×
3796
        paramv[i][1] = {TSDB_DATA_TYPE_BINARY, &b[i][0], &b_len[0], NULL, ROW_NUMS};
×
3797
      }
3798
      // bind
3799
      TAOS_STMT2_BINDV bindv = {CTB_NUMS, tbs, NULL, paramv};
×
3800
      bool             finish = false;
×
3801
      code = taos_stmt2_bind_param_a(stmt, &bindv, -1, stmtAsyncBindCb, (void*)&finish);
×
3802
      while (!finish) {
×
3803
        taosMsleep(100);
×
3804
      }
3805
      checkError(stmt, code, __FILE__, __LINE__);
×
3806
    }
3807
    // exec
3808
    code = taos_stmt2_exec(stmt, NULL);
×
3809
    checkError(stmt, code, __FILE__, __LINE__);
×
3810
  }
3811

3812
  // case 3 : bind->exec_a->bind->exec_a->...
3813
  {
3814
    printf("case 3 : bind->exec_a->bind->exec_a->...\n");
×
3815
    for (int r = 0; r < CYC_NUMS; r++) {
×
3816
      // bind
3817
      TAOS_STMT2_BINDV bindv = {CTB_NUMS, tbs, NULL, paramv};
×
3818
      bool             finish = false;
×
3819
      code = taos_stmt2_bind_param(stmt, &bindv, -1);
×
3820

3821
      checkError(stmt, code, __FILE__, __LINE__);
×
3822

3823
      // exec
3824
      code = taos_stmt2_exec(stmt, NULL);
×
3825
      checkError(stmt, code, __FILE__, __LINE__);
×
3826
    }
3827
  }
3828

3829
  // case 4 : bind_a->close
3830
  {
3831
    printf("case 4 : bind_a->close\n");
×
3832
    // bind
3833
    TAOS_STMT2_BINDV bindv = {CTB_NUMS, tbs, NULL, paramv};
×
3834
    bool             finish = false;
×
3835
    code = taos_stmt2_bind_param_a(stmt, &bindv, -1, stmtAsyncBindCb, (void*)&finish);
×
3836
    checkError(stmt, code, __FILE__, __LINE__);
×
3837
    taos_stmt2_close(stmt);
×
3838
    checkError(stmt, code, __FILE__, __LINE__);
×
3839
  }
3840

3841
  // case 5 : bind_a->exec_a->close
3842
  {
3843
    printf("case 5 : bind_a->exec_a->close\n");
×
3844
    // init
3845
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
×
3846
    ASSERT_NE(stmt, nullptr);
×
3847
    int code = taos_stmt2_prepare(stmt, sql, 0);
×
3848
    checkError(stmt, code, __FILE__, __LINE__);
×
3849
    // bind
3850
    TAOS_STMT2_BINDV bindv = {CTB_NUMS, tbs, NULL, paramv};
×
3851
    bool             finish = false;
×
3852
    code = taos_stmt2_bind_param_a(stmt, &bindv, -1, stmtAsyncBindCb, (void*)&finish);
×
3853
    checkError(stmt, code, __FILE__, __LINE__);
×
3854
    // exec
3855
    code = taos_stmt2_exec(stmt, NULL);
×
3856
    checkError(stmt, code, __FILE__, __LINE__);
×
3857
    // close
3858
    taos_stmt2_close(stmt);
×
3859
    checkError(stmt, code, __FILE__, __LINE__);
×
3860
  }
3861

3862
  option = {0, false, false, NULL, NULL};
×
3863
  stmt = taos_stmt2_init(taos, &option);
×
3864
  ASSERT_NE(stmt, nullptr);
×
3865
  code = taos_stmt2_prepare(stmt, sql, 0);
×
3866
  checkError(stmt, code, __FILE__, __LINE__);
×
3867

3868
  // case 6 : bind_a->exec->bind_a->exec->...
3869
  {
3870
    printf("case 6 : bind_a->exec->bind_a->exec->...\n");
×
3871
    // init
3872

3873
    checkError(stmt, code, __FILE__, __LINE__);
×
3874
    for (int r = 0; r < CYC_NUMS; r++) {
×
3875
      // bind
3876
      TAOS_STMT2_BINDV bindv = {CTB_NUMS, tbs, NULL, paramv};
×
3877
      bool             finish = false;
×
3878
      code = taos_stmt2_bind_param_a(stmt, &bindv, -1, stmtAsyncBindCb, (void*)&finish);
×
3879
      checkError(stmt, code, __FILE__, __LINE__);
×
3880
      // exec
3881
      code = taos_stmt2_exec(stmt, NULL);
×
3882
      checkError(stmt, code, __FILE__, __LINE__);
×
3883
    }
3884
  }
3885

3886
  // case 7 (error:no wait error) : bind_a->bind_a
3887
  {
3888
    printf("case 7 (error:no wait error) : bind_a->bind_a\n");
×
3889
    // bind
3890
    TAOS_STMT2_BINDV bindv = {CTB_NUMS, tbs, NULL, paramv};
×
3891
    bool             finish = false;
×
3892
    code = taos_stmt2_bind_param_a(stmt, &bindv, -1, stmtAsyncBindCb2, (void*)&finish);
×
3893
    checkError(stmt, code, __FILE__, __LINE__);
×
3894
    taosMsleep(200);
×
3895
    code = taos_stmt2_bind_param_a(stmt, &bindv, -1, stmtAsyncBindCb2, (void*)&finish);
×
3896
    ASSERT_EQ(code, TSDB_CODE_TSC_STMT_API_ERROR);
×
3897
    while (!finish) {
×
3898
      taosMsleep(100);
×
3899
    }
3900
  }
3901
  // close
3902
  taos_stmt2_close(stmt);
×
3903

3904
  // free memory
3905
  for (int i = 0; i < CTB_NUMS; i++) {
×
3906
    taosMemoryFree(paramv[i]);
×
3907
    taosMemoryFree(ts[i]);
×
3908
    taosMemoryFree(b[i]);
×
3909
  }
3910
  taosMemoryFree(ts);
×
3911
  taosMemoryFree(b);
×
3912
  taosMemoryFree(ts_len);
×
3913
  taosMemoryFree(b_len);
×
3914
  taosMemoryFree(paramv);
×
3915
  for (int i = 0; i < CTB_NUMS; i++) {
×
3916
    taosMemoryFree(tbs[i]);
×
3917
  }
3918
  taosMemoryFree(tbs);
×
3919
  stop_task = true;
×
3920
}
3921

3922
// TEST(stmt2Case, async_order) {
3923
//   std::atomic<bool> stop_task(false);
3924
//   std::thread       t(stmt2_async_test, std::ref(stop_task));
3925

3926
//   // 等待 60 秒钟
3927
//   auto start_time = std::chrono::steady_clock::now();
3928
//   while (!stop_task) {
3929
//     auto elapsed_time = std::chrono::steady_clock::now() - start_time;
3930
//     if (std::chrono::duration_cast<std::chrono::seconds>(elapsed_time).count() > 100) {
3931
//       if (t.joinable()) {
3932
//         t.detach();
3933
//       }
3934
//       FAIL() << "Test[stmt2_async_test] timed out";
3935
//       break;
3936
//     }
3937
//     std::this_thread::sleep_for(std::chrono::seconds(1));  // 每 1s 检查一次
3938
//   }
3939
//   if (t.joinable()) {
3940
//     t.join();
3941
//   }
3942
// }
3943

3944
TEST(stmt2Case, rowformat_bind) {
384✔
3945
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
3946
  ASSERT_NE(taos, nullptr);
96✔
3947

3948
  do_query(taos, "drop database if exists stmt2_testdb_16");
96✔
3949
  do_query(taos, "create database IF NOT EXISTS stmt2_testdb_16");
96✔
3950
  do_query(
96✔
3951
      taos,
3952
      "create stable stmt2_testdb_16.stb(ts timestamp, c1 int, c2 bigint, c3 float, c4 double, c5 binary(8), c6 "
3953
      "smallint, c7 "
3954
      "tinyint, c8 bool, c9 nchar(8), c10 geometry(256))TAGS(tts timestamp, t1 int, t2 bigint, t3 float, t4 double, t5 "
3955
      "binary(8), t6 smallint, t7 tinyint, t8 bool, t9 nchar(8), t10 geometry(256))");
3956

3957
  TAOS_STMT2_OPTION option = {0};
96✔
3958
  TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
3959
  ASSERT_NE(stmt, nullptr);
96✔
3960
  int       code = 0;
96✔
3961
  uintptr_t c10len = 0;
96✔
3962
  struct {
3963
    int64_t       c1;
3964
    int32_t       c2;
3965
    int64_t       c3;
3966
    float         c4;
3967
    double        c5;
3968
    unsigned char c6[8];
3969
    int16_t       c7;
3970
    int8_t        c8;
3971
    int8_t        c9;
3972
    char          c10[32];
3973
  } v = {1591060628000, 1, 2, 3.0, 4.0, "abcdef", 5, 6, 7, "ijnop"};
96✔
3974

3975
  struct {
3976
    int32_t c1;
3977
    int32_t c2;
3978
    int32_t c3;
3979
    int32_t c4;
3980
    int32_t c5;
3981
    int32_t c6;
3982
    int32_t c7;
3983
    int32_t c8;
3984
    int32_t c9;
3985
    int32_t c10;
3986
  } v_len = {sizeof(int64_t), sizeof(int32_t),
96✔
3987
             sizeof(int64_t), sizeof(float),
3988
             sizeof(double),  8,
3989
             sizeof(int16_t), sizeof(int8_t),
3990
             sizeof(int8_t),  8};
3991
  TAOS_STMT2_BIND params[11];
3992
  params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
96✔
3993
  params[0].length = (int32_t*)&v_len.c1;
96✔
3994
  params[0].buffer = &v.c1;
96✔
3995
  params[0].is_null = NULL;
96✔
3996
  params[0].num = 1;
96✔
3997

3998
  params[1].buffer_type = TSDB_DATA_TYPE_INT;
96✔
3999
  params[1].buffer = &v.c2;
96✔
4000
  params[1].length = (int32_t*)&v_len.c2;
96✔
4001
  params[1].is_null = NULL;
96✔
4002
  params[1].num = 1;
96✔
4003

4004
  params[2].buffer_type = TSDB_DATA_TYPE_BIGINT;
96✔
4005
  params[2].buffer = &v.c3;
96✔
4006
  params[2].length = (int32_t*)&v_len.c3;
96✔
4007
  params[2].is_null = NULL;
96✔
4008
  params[2].num = 1;
96✔
4009

4010
  params[3].buffer_type = TSDB_DATA_TYPE_FLOAT;
96✔
4011
  params[3].buffer = &v.c4;
96✔
4012
  params[3].length = (int32_t*)&v_len.c4;
96✔
4013
  params[3].is_null = NULL;
96✔
4014
  params[3].num = 1;
96✔
4015

4016
  params[4].buffer_type = TSDB_DATA_TYPE_DOUBLE;
96✔
4017
  params[4].buffer = &v.c5;
96✔
4018
  params[4].length = (int32_t*)&v_len.c5;
96✔
4019
  params[4].is_null = NULL;
96✔
4020
  params[4].num = 1;
96✔
4021

4022
  params[5].buffer_type = TSDB_DATA_TYPE_BINARY;
96✔
4023
  params[5].buffer = &v.c6;
96✔
4024
  params[5].length = (int32_t*)&v_len.c6;
96✔
4025
  params[5].is_null = NULL;
96✔
4026
  params[5].num = 1;
96✔
4027

4028
  params[6].buffer_type = TSDB_DATA_TYPE_SMALLINT;
96✔
4029
  params[6].buffer = &v.c7;
96✔
4030
  params[6].length = (int32_t*)&v_len.c7;
96✔
4031
  params[6].is_null = NULL;
96✔
4032
  params[6].num = 1;
96✔
4033

4034
  params[7].buffer_type = TSDB_DATA_TYPE_TINYINT;
96✔
4035
  params[7].buffer = &v.c8;
96✔
4036
  params[7].length = (int32_t*)&v_len.c8;
96✔
4037
  params[7].is_null = NULL;
96✔
4038
  params[7].num = 1;
96✔
4039

4040
  params[8].buffer_type = TSDB_DATA_TYPE_BOOL;
96✔
4041
  params[8].buffer = &v.c9;
96✔
4042
  params[8].length = (int32_t*)&v_len.c9;
96✔
4043
  params[8].is_null = NULL;
96✔
4044
  params[8].num = 1;
96✔
4045

4046
  params[9].buffer_type = TSDB_DATA_TYPE_NCHAR;
96✔
4047
  params[9].buffer = &v.c10;
96✔
4048
  params[9].length = (int32_t*)&v_len.c10;
96✔
4049
  params[9].is_null = NULL;
96✔
4050
  params[9].num = 1;
96✔
4051

4052
  unsigned char* outputGeom1;
4053
  size_t         size1;
4054
  initCtxMakePoint();
96✔
4055
  code = doMakePoint(1.000, 2.000, &outputGeom1, &size1);
96✔
4056
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4057
  params[10].buffer_type = TSDB_DATA_TYPE_GEOMETRY;
96✔
4058
  params[10].buffer = outputGeom1;
96✔
4059
  params[10].length = (int32_t*)&size1;
96✔
4060
  params[10].is_null = NULL;
96✔
4061
  params[10].num = 1;
96✔
4062

4063
  char* stmt_sql = "insert into stmt2_testdb_16.? using stb tags(?,?,?,?,?,?,?,?,?,?,?)values (?,?,?,?,?,?,?,?,?,?,?)";
96✔
4064
  code = taos_stmt2_prepare(stmt, stmt_sql, 0);
96✔
4065
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4066

4067
  char*            tbname[1] = {"tb1"};
96✔
4068
  TAOS_STMT2_BIND* tags = &params[0];
96✔
4069
  TAOS_STMT2_BIND* cols = &params[0];
96✔
4070
  TAOS_STMT2_BINDV bindv = {1, &tbname[0], &tags, &cols};
96✔
4071
  code = taos_stmt2_bind_param(stmt, &bindv, -2);
96✔
4072
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4073

4074
  int affected_rows;
4075
  code = taos_stmt2_exec(stmt, &affected_rows);
96✔
4076
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4077
  ASSERT_EQ(affected_rows, 1);
96✔
4078

4079
  int64_t ts2 = 1591060628000;
96✔
4080
  params[0].buffer = &ts2;
96✔
4081
  code = taos_stmt2_bind_param(stmt, &bindv, -2);
96✔
4082
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4083

4084
  code = taos_stmt2_exec(stmt, &affected_rows);
96✔
4085
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4086
  ASSERT_EQ(affected_rows, 1);
96✔
4087

4088
  params[0].buffer = &ts2;
96✔
4089
  code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
4090
  ASSERT_EQ(code, TSDB_CODE_TSC_STMT_API_ERROR);
96✔
4091

4092
  geosFreeBuffer(outputGeom1);
96✔
4093
  taos_stmt2_close(stmt);
96✔
4094
  do_query(taos, "drop database if exists stmt2_testdb_16");
96✔
4095
  taos_close(taos);
96✔
4096
}
4097

4098
// TS-7047
4099
void stmtAsyncQueryCb3(void* param, TAOS_RES* pRes, int code) {
96✔
4100
  ASSERT_EQ(code, TSDB_CODE_TDB_TABLE_NOT_EXIST);
96✔
4101
  return;
96✔
4102
}
4103

4104
TEST(stmt2Case, exec_retry) {
384✔
4105
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
4106
  ASSERT_NE(taos, nullptr);
96✔
4107
  TAOS_STMT2_OPTION option = {0, true, true, stmtAsyncQueryCb3, NULL};
96✔
4108
  do_query(taos, "drop database if exists stmt2_testdb_21");
96✔
4109
  do_query(taos, "create database stmt2_testdb_21");
96✔
4110
  do_query(taos, "create stable stmt2_testdb_21.stb (ts timestamp, b binary(10)) tags(t1 int, t2 binary(10))");
96✔
4111
  // do_query(taos, "create stable stmt2_testdb_21.stb2 (ts timestamp, b binary(10)) tags(t1 int, t2 binary(10))");
4112
  do_query(taos,
96✔
4113
           "insert into stmt2_testdb_21.tb1 using stmt2_testdb_21.stb tags(1, 'after') "
4114
           "values(1591060628000, 'abcde')");
4115
  // do_query(taos, "create table stmt2_testdb_8.ntb(ts timestamp, b binary(10))");
4116
  do_query(taos, "use stmt2_testdb_21");
96✔
4117
  TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
4118
  ASSERT_NE(stmt, nullptr);
96✔
4119

4120
  // test fixed tbname and bind per col
4121
  {
4122
    int         total_affected_rows = 0;
96✔
4123
    const char* sql = "insert into stmt2_testdb_21.stb (tbname,ts,b)values(?,?,?)";
96✔
4124
    int         code = taos_stmt2_prepare(stmt, sql, 0);
96✔
4125
    checkError(stmt, code, __FILE__, __LINE__);
96✔
4126
    int64_t          ts[3] = {1591060628000, 1591060628001, 1591060628002};
96✔
4127
    int              t64_len[3] = {sizeof(int64_t), sizeof(int64_t), sizeof(int64_t)};
96✔
4128
    int              b_len[3] = {5, 5, 5};
96✔
4129
    char*            tbname = "tb1";
96✔
4130
    TAOS_STMT2_BIND  params1[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &t64_len[0], NULL, 3},
96✔
4131
                                   {TSDB_DATA_TYPE_BINARY, (void*)"abcdefghijklmnopqrstuvwxyz", &b_len[0], NULL, 3}};
96✔
4132
    TAOS_STMT2_BIND* paramv1 = &params1[0];
96✔
4133

4134
    TAOS_STMT2_BINDV bindv1 = {1, &tbname, NULL, &paramv1};
96✔
4135

4136
    code = taos_stmt2_bind_param(stmt, &bindv1, -1);
96✔
4137
    checkError(stmt, code, __FILE__, __LINE__);
96✔
4138

4139
    // wait async bind finish
4140
    taosMsleep(2000);
96✔
4141
    do_query(taos, "drop table if exists stmt2_testdb_21.tb1");
96✔
4142

4143
    code = taos_stmt2_exec(stmt, NULL);
96✔
4144
    checkError(stmt, code, __FILE__, __LINE__);
96✔
4145
  }
4146

4147
  taos_stmt2_close(stmt);
96✔
4148
  do_query(taos, "drop database if exists stmt2_testdb_21");
96✔
4149
}
4150

4151
void stmtAsyncQueryCb4(void* param, TAOS_RES* pRes, int code) { ASSERT_EQ(code, TSDB_CODE_SUCCESS); }
192✔
4152

4153
TEST(stmt2Case, core) {
384✔
4154
  printf("stmt2Test: select COUNT(1) from (select LAST(operate_time) ...) with params\n");
96✔
4155

4156
  TAOS* taos = taos_connect("127.0.0.1", "root", "taosdata", NULL, 0);
96✔
4157
  ASSERT_NE(taos, nullptr);
96✔
4158

4159
  do_query(taos, "drop database if exists ivs");
96✔
4160
  do_query(taos, "create database ivs");
96✔
4161
  do_query(taos, "use ivs");
96✔
4162
  do_query(taos,
96✔
4163
           "create table alarm_operate_info ("
4164
           "operate_time timestamp, "
4165
           "alarm_id int, "
4166
           "operator_id int, "
4167
           "operator_name binary(32), "
4168
           "operator_info binary(64), "
4169
           "operator_status int, "
4170
           "device_id int)");
4171

4172
  do_query(taos,
96✔
4173
           "insert into alarm_operate_info values"
4174
           "(1591060628000, 1, 100, '张三', 'info1', 0, 10),"
4175
           "(1591060629000, 1, 101, '李四', 'info2', 1, 10),"
4176
           "(1591060630000, 2, 102, '王五', 'info3', 0, 11)");
4177

4178
  TAOS_STMT2_OPTION option = {0, true, true, stmtAsyncQueryCb4, NULL};
96✔
4179
  TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
4180
  ASSERT_NE(stmt, nullptr);
96✔
4181

4182
  const char* sql =
96✔
4183
      "select COUNT(1) from ("
4184
      " select LAST(operate_time) as operate_time, alarm_id, operator_id, operator_name, operator_info, "
4185
      "operator_status, device_id"
4186
      " from ivs.alarm_operate_info"
4187
      " WHERE operate_time >= ? and operate_time <= ?"
4188
      " PARTITION BY alarm_id"
4189
      " ORDER BY operate_time desc"
4190
      ")";
4191

4192
  int code = taos_stmt2_prepare(stmt, sql, 0);
96✔
4193
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4194

4195
  int             fieldNum = 0;
96✔
4196
  TAOS_FIELD_ALL* pFields = NULL;
96✔
4197
  code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
96✔
4198
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4199
  ASSERT_EQ(fieldNum, 2);
96✔
4200

4201
  int64_t ts_begin[1] = {1591060628000};
96✔
4202
  int64_t ts_end[1] = {1591060630000};
96✔
4203
  int32_t len[1] = {sizeof(int64_t)};
96✔
4204

4205
  TAOS_STMT2_BIND params[2] = {0};
96✔
4206
  params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
96✔
4207
  params[0].buffer = &ts_begin[0];
96✔
4208
  params[0].length = &len[0];
96✔
4209
  params[0].is_null = NULL;
96✔
4210
  params[0].num = 1;
96✔
4211

4212
  params[1].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
96✔
4213
  params[1].buffer = &ts_end[0];
96✔
4214
  params[1].length = &len[0];
96✔
4215
  params[1].is_null = NULL;
96✔
4216
  params[1].num = 1;
96✔
4217

4218
  TAOS_STMT2_BIND* c = &params[0];
96✔
4219

4220
  TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &c};
96✔
4221
  code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
4222
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4223

4224
  code = taos_stmt2_exec(stmt, NULL);
96✔
4225
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4226

4227
  code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
4228
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4229

4230
  code = taos_stmt2_exec(stmt, NULL);
96✔
4231
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4232

4233
  taos_stmt2_close(stmt);
96✔
4234

4235
  do_query(taos, "drop database if exists ivs");
96✔
4236
  taos_close(taos);
96✔
4237
}
4238

4239
// TS-7067
4240
TEST(stmt2Case, tbname) {
384✔
4241
  TAOS* taos = taos_connect("127.0.0.1", "root", "taosdata", NULL, 0);
96✔
4242
  ASSERT_NE(taos, nullptr);
96✔
4243

4244
  do_query(taos, "drop database if exists stmt2_testdb_22");
96✔
4245
  do_query(taos, "create database stmt2_testdb_22");
96✔
4246
  do_query(taos, "use stmt2_testdb_22");
96✔
4247
  do_query(taos, "create table stmt2_testdb_22.stb (ts timestamp, b binary(10)) tags(t1 int, t2 binary(10))");
96✔
4248

4249
  TAOS_STMT2_OPTION option[2] = {{0, false, false, NULL, NULL}, {0, true, true, NULL, NULL}};
96✔
4250
  for (int i = 0; i < 2; i++) {
288✔
4251
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option[i]);
192✔
4252
    ASSERT_NE(stmt, nullptr);
192✔
4253

4254
    const char* sql = "insert into stmt2_testdb_22.stb (tbname,ts,b,t1,t2)values(?,?,?,?,?)";
192✔
4255
    int         code = taos_stmt2_prepare(stmt, sql, 0);
192✔
4256
    checkError(stmt, code, __FILE__, __LINE__);
192✔
4257

4258
    int             fieldNum = 0;
192✔
4259
    TAOS_FIELD_ALL* pFields = NULL;
192✔
4260
    code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
192✔
4261
    checkError(stmt, code, __FILE__, __LINE__);
192✔
4262
    ASSERT_EQ(fieldNum, 5);
192✔
4263

4264
    int     t1 = 1;
192✔
4265
    char*   t2 = "abc";
192✔
4266
    int32_t t2_len = 3;
192✔
4267
    int32_t t1_len = sizeof(int);
192✔
4268

4269
    int64_t ts[2] = {1591060628000, 1591060628001};
192✔
4270
    int32_t len[2] = {sizeof(int64_t), sizeof(int64_t)};
192✔
4271

4272
    char* tbname[2] = {"CTb-1", "中文表名"};
192✔
4273

4274
    TAOS_STMT2_BIND tag[2] = {{TSDB_DATA_TYPE_INT, &t1, &t1_len, NULL, 1},
192✔
4275
                              {TSDB_DATA_TYPE_BINARY, &t2, &t2_len, NULL, 1}};
192✔
4276

4277
    TAOS_STMT2_BIND col[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &len[0], NULL, 2},
192✔
4278
                              {TSDB_DATA_TYPE_BINARY, &tbname[0], &len[0], NULL, 2}};
192✔
4279

4280
    TAOS_STMT2_BIND* pTag[2] = {&tag[0], &tag[0]};
192✔
4281
    TAOS_STMT2_BIND* pCol[2] = {&col[0], &col[0]};
192✔
4282

4283
    TAOS_STMT2_BINDV bindv = {2, &tbname[0], &pTag[0], &pCol[0]};
192✔
4284

4285
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
192✔
4286
    checkError(stmt, code, __FILE__, __LINE__);
192✔
4287

4288
    int affected_rows = 0;
192✔
4289
    code = taos_stmt2_exec(stmt, &affected_rows);
192✔
4290
    checkError(stmt, code, __FILE__, __LINE__);
192✔
4291
    ASSERT_EQ(affected_rows, 4);
192✔
4292

4293
    TAOS_RES* result = taos_query(taos, "select tbname from stmt2_testdb_22.stb group by tbname order by tbname");
192✔
4294
    ASSERT_NE(result, nullptr);
192✔
4295

4296
    TAOS_ROW row = taos_fetch_row(result);
192✔
4297
    ASSERT_EQ(strncmp((char*)row[0], "CTb-1", 5), 0);
192✔
4298

4299
    row = taos_fetch_row(result);
192✔
4300
    ASSERT_EQ(strncmp((char*)row[0], "中文表名", 4), 0);
192✔
4301

4302
    taos_free_result(result);
192✔
4303
    taos_stmt2_close(stmt);
192✔
4304
  }
4305

4306
  for (int i = 0; i < 2; i++) {
288✔
4307
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option[i]);
192✔
4308
    ASSERT_NE(stmt, nullptr);
192✔
4309

4310
    const char* sql = "insert into stmt2_testdb_22.stb (tbname,ts,b,t1,t2)values(?,?,?,?,?)";
192✔
4311
    int         code = taos_stmt2_prepare(stmt, sql, 0);
192✔
4312
    checkError(stmt, code, __FILE__, __LINE__);
192✔
4313

4314
    int             fieldNum = 0;
192✔
4315
    TAOS_FIELD_ALL* pFields = NULL;
192✔
4316
    code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
192✔
4317
    checkError(stmt, code, __FILE__, __LINE__);
192✔
4318
    ASSERT_EQ(fieldNum, 5);
192✔
4319

4320
    int     t1 = 1;
192✔
4321
    char*   t2 = "abc";
192✔
4322
    int32_t t2_len = 3;
192✔
4323
    int32_t t1_len = sizeof(int);
192✔
4324

4325
    int64_t ts[2] = {1591060628000, 1591060628001};
192✔
4326
    int32_t len[2] = {sizeof(int64_t), sizeof(int64_t)};
192✔
4327

4328
    char tbname192[192 + 2 + 1];
4329
    char tbname193[193 + 2 + 1];
4330
    tbname192[0] = '`';
192✔
4331
    tbname193[0] = '`';
192✔
4332
    for (int i = 1; i < 193; ++i) {
37,056✔
4333
      tbname192[i] = 'a';
36,864✔
4334
      tbname193[i] = 'b';
36,864✔
4335
    }
4336
    tbname192[193] = '`';
192✔
4337
    tbname192[194] = '\0';
192✔
4338

4339
    tbname193[193] = 'b';
192✔
4340
    tbname193[194] = '`';
192✔
4341
    tbname193[195] = '\0';
192✔
4342

4343
    char* tbname[2] = {&tbname192[0], &tbname193[0]};
192✔
4344

4345
    TAOS_STMT2_BIND tag[2] = {{TSDB_DATA_TYPE_INT, &t1, &t1_len, NULL, 1},
192✔
4346
                              {TSDB_DATA_TYPE_BINARY, &t2, &t2_len, NULL, 1}};
192✔
4347

4348
    TAOS_STMT2_BIND col[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &len[0], NULL, 2},
192✔
4349
                              {TSDB_DATA_TYPE_BINARY, &tbname[0], &len[0], NULL, 2}};
192✔
4350

4351
    TAOS_STMT2_BIND* pTag[2] = {&tag[0], &tag[0]};
192✔
4352
    TAOS_STMT2_BIND* pCol[2] = {&col[0], &col[0]};
192✔
4353

4354
    TAOS_STMT2_BINDV bindv = {1, &tbname[0], &pTag[0], &pCol[0]};
192✔
4355

4356
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
192✔
4357
    checkError(stmt, code, __FILE__, __LINE__);
192✔
4358

4359
    bindv = {1, &tbname[1], &pTag[0], &pCol[0]};
192✔
4360
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
192✔
4361
    ASSERT_EQ(code, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME);
192✔
4362
    ASSERT_STREQ(taos_stmt2_error(stmt), "Invalid identifier name: table name is too long");
192✔
4363

4364
    code = taos_stmt2_prepare(stmt, sql, 0);
192✔
4365
    checkError(stmt, code, __FILE__, __LINE__);
192✔
4366
    bindv = {2, &tbname[0], &pTag[0], &pCol[0]};
192✔
4367
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
192✔
4368
    ASSERT_EQ(code, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME);
192✔
4369
    ASSERT_STREQ(taos_stmt2_error(stmt), "Invalid identifier name: table name is too long");
192✔
4370

4371
    code = taos_stmt2_prepare(stmt, "insert into ? using stmt2_testdb_22.stb tags(?,?)values(?,?)", 0);
192✔
4372
    checkError(stmt, code, __FILE__, __LINE__);
192✔
4373
    char full_tbname[256];
4374
    sprintf(full_tbname, "`stmt2_testdb_22`.%s", tbname[0]);
192✔
4375

4376
    char* tbname_ptr = &full_tbname[0];
192✔
4377
    bindv = {1, &tbname_ptr, &pTag[0], &pCol[0]};
192✔
4378
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
192✔
4379
    checkError(stmt, code, __FILE__, __LINE__);
192✔
4380

4381
    sprintf(full_tbname, "`stmt2_testdb_22`.`%s`", tbname[1]);
192✔
4382
    bindv = {1, &tbname_ptr, &pTag[0], &pCol[0]};
192✔
4383
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
192✔
4384
    ASSERT_EQ(code, TSDB_CODE_PAR_INVALID_IDENTIFIER_NAME);
192✔
4385
    ASSERT_STREQ(taos_stmt2_error(stmt), "Invalid identifier name: table name is too long");
192✔
4386

4387
    taos_stmt2_close(stmt);
192✔
4388
  }
4389

4390
  do_query(taos, "drop database if exists stmt2_testdb_22");
96✔
4391
}
4392

4393
// TS-7074
4394
TEST(stmt2Case, no_tag) {
384✔
4395
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
4396
  ASSERT_NE(taos, nullptr);
96✔
4397

4398
  do_query(taos, "drop database if exists stmt2_testdb_23");
96✔
4399
  do_query(taos, "create database IF NOT EXISTS stmt2_testdb_23");
96✔
4400
  do_query(taos, "create stable stmt2_testdb_23.stb (ts timestamp, b binary(10)) tags(t1 int, t2 binary(10))");
96✔
4401
  do_query(
96✔
4402
      taos,
4403
      "insert into stmt2_testdb_23.tb_exist using stmt2_testdb_23.stb tags(1, 'tag1') values(1591060628000, 'abc')");
4404

4405
  const char* sql = "INSERT INTO stmt2_testdb_23.stb (tbname,ts,b) VALUES (?,?,?)";
96✔
4406
  char*       tbname[2] = {"tb_exist", "tb_not_exist"};
96✔
4407
  int64_t     ts = 1591060628000;
96✔
4408
  int         t64_len = sizeof(int64_t);
96✔
4409
  char*       b = "abc";
96✔
4410
  int         b_len = 3;
96✔
4411

4412
  TAOS_STMT2_BIND params[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len, NULL, 1},
96✔
4413
                               {TSDB_DATA_TYPE_BINARY, b, &b_len, NULL, 1}};
96✔
4414
  // interlace=1
4415
  {
4416
    TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
4417

4418
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
4419
    ASSERT_NE(stmt, nullptr);
96✔
4420
    printf("case 1 : interlace=1] \n");
96✔
4421
    int code = taos_stmt2_prepare(stmt, sql, 0);
96✔
4422
    checkError(stmt, code, __FILE__, __LINE__);
96✔
4423

4424
    TAOS_STMT2_BIND params[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len, NULL, 1},
96✔
4425
                                 {TSDB_DATA_TYPE_BINARY, b, &b_len, NULL, 1}};
96✔
4426

4427
    TAOS_STMT2_BIND* paramv = &params[0];
96✔
4428
    TAOS_STMT2_BINDV bindv = {1, &tbname[1], NULL, &paramv};
96✔
4429
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
4430
    ASSERT_EQ(code, TSDB_CODE_PAR_TABLE_NOT_EXIST);
96✔
4431

4432
    taos_stmt2_close(stmt);
96✔
4433
  }
4434

4435
  // interlace=0
4436
  {
4437
    TAOS_STMT2_OPTION option = {0, false, false, NULL, NULL};
96✔
4438

4439
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
4440
    ASSERT_NE(stmt, nullptr);
96✔
4441
    printf("case 2 : interlace=0] \n");
96✔
4442
    int code = taos_stmt2_prepare(stmt, sql, 0);
96✔
4443
    checkError(stmt, code, __FILE__, __LINE__);
96✔
4444

4445
    TAOS_STMT2_BIND params[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len, NULL, 1},
96✔
4446
                                 {TSDB_DATA_TYPE_BINARY, b, &b_len, NULL, 1}};
96✔
4447

4448
    TAOS_STMT2_BIND* paramv = &params[0];
96✔
4449
    TAOS_STMT2_BINDV bindv = {1, &tbname[1], NULL, &paramv};
96✔
4450
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
4451
    ASSERT_EQ(code, TSDB_CODE_PAR_TABLE_NOT_EXIST);
96✔
4452

4453
    taos_stmt2_close(stmt);
96✔
4454
  }
4455

4456
  // interlace=0 && first table exist
4457
  {
4458
    TAOS_STMT2_OPTION option = {0, false, false, NULL, NULL};
96✔
4459

4460
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
4461
    ASSERT_NE(stmt, nullptr);
96✔
4462
    printf("case 3 : interlace=0 && first table exist] \n");
96✔
4463
    int code = taos_stmt2_prepare(stmt, sql, 0);
96✔
4464
    checkError(stmt, code, __FILE__, __LINE__);
96✔
4465

4466
    TAOS_STMT2_BIND* paramv[2] = {&params[0], &params[0]};
96✔
4467
    TAOS_STMT2_BINDV bindv = {2, &tbname[0], NULL, &paramv[0]};
96✔
4468
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
4469
    ASSERT_EQ(code, TSDB_CODE_PAR_TABLE_NOT_EXIST);
96✔
4470

4471
    taos_stmt2_close(stmt);
96✔
4472
  }
4473
  // interlace=1 && first table exist
4474
  {
4475
    TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
4476

4477
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
4478
    ASSERT_NE(stmt, nullptr);
96✔
4479
    printf("case 4 : interlace=1 && first table exist] \n");
96✔
4480
    int code = taos_stmt2_prepare(stmt, sql, 0);
96✔
4481
    checkError(stmt, code, __FILE__, __LINE__);
96✔
4482

4483
    TAOS_STMT2_BIND* paramv[2] = {&params[0], &params[0]};
96✔
4484
    TAOS_STMT2_BINDV bindv = {2, &tbname[0], NULL, &paramv[0]};
96✔
4485
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
4486
    checkError(stmt, code, __FILE__, __LINE__);
96✔
4487

4488
    code = taos_stmt2_exec(stmt, NULL);
96✔
4489
    ASSERT_EQ(code, TSDB_CODE_PAR_TABLE_NOT_EXIST);
96✔
4490

4491
    taos_stmt2_close(stmt);
96✔
4492
  }
4493

4494
  int             t1 = 1;
96✔
4495
  char*           t2 = "abc";
96✔
4496
  int             t1_len = sizeof(int);
96✔
4497
  int             t2_len = 3;
96✔
4498
  TAOS_STMT2_BIND tag[2] = {{TSDB_DATA_TYPE_INT, &t1, &t1_len, NULL, 1}, {TSDB_DATA_TYPE_BINARY, t2, &t2_len, NULL, 1}};
96✔
4499
  TAOS_STMT2_BIND* pTag = &tag[0];
96✔
4500

4501
  // interlace=0 && with tag
4502
  {
4503
    TAOS_STMT2_OPTION option = {0, false, false, NULL, NULL};
96✔
4504

4505
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
4506
    ASSERT_NE(stmt, nullptr);
96✔
4507
    printf("case 5 : interlace=0 && with tag] \n");
96✔
4508
    int code = taos_stmt2_prepare(stmt, sql, 0);
96✔
4509
    checkError(stmt, code, __FILE__, __LINE__);
96✔
4510

4511
    TAOS_STMT2_BIND* paramv[2] = {&params[0], &params[0]};
96✔
4512
    TAOS_STMT2_BINDV bindv = {1, &tbname[1], &pTag, &paramv[0]};
96✔
4513
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
4514
    ASSERT_EQ(code, TSDB_CODE_PAR_TABLE_NOT_EXIST);
96✔
4515

4516
    taos_stmt2_close(stmt);
96✔
4517
  }
4518

4519
  // interlace=1 && with tag
4520
  {
4521
    TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
4522

4523
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
4524
    ASSERT_NE(stmt, nullptr);
96✔
4525
    printf("case 6 : interlace=1 && with tag] \n");
96✔
4526
    int code = taos_stmt2_prepare(stmt, sql, 0);
96✔
4527
    checkError(stmt, code, __FILE__, __LINE__);
96✔
4528

4529
    TAOS_STMT2_BIND* paramv[2] = {&params[0], &params[0]};
96✔
4530
    TAOS_STMT2_BINDV bindv = {1, &tbname[1], &pTag, &paramv[0]};
96✔
4531
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
4532
    ASSERT_EQ(code, TSDB_CODE_PAR_TABLE_NOT_EXIST);
96✔
4533

4534
    taos_stmt2_close(stmt);
96✔
4535
  }
4536
  do_query(taos, "drop database if exists stmt2_testdb_23");
96✔
4537
  taos_close(taos);
96✔
4538
}
4539

4540
TEST(stmt2Case, vtable) {
384✔
4541
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
4542
  ASSERT_NE(taos, nullptr);
96✔
4543

4544
  // Drop database if exists
4545
  do_query(taos, "drop database if exists stmt2_testdb_29");
96✔
4546

4547
  // Create database
4548
  do_query(taos, "create database stmt2_testdb_29");
96✔
4549
  do_query(taos, "use stmt2_testdb_29");
96✔
4550

4551
  // Create normal table
4552
  do_query(taos, "create table ntb_0(ts timestamp, c1 int, c2 int, c3 int)");
96✔
4553

4554
  // Create super table and child table
4555
  do_query(taos, "create stable stb (ts timestamp, c1 int, c2 int, c3 int) tags (t1 int)");
96✔
4556
  do_query(taos, "create table ctb_0 using stb tags (1)");
96✔
4557

4558
  // Insert data
4559
  do_query(taos, "insert into ntb_0 values(1591060628000, 1, 1, 1)");
96✔
4560
  do_query(taos, "insert into ntb_0 values(1591060628100, 2, 2, 2)");
96✔
4561
  do_query(taos, "insert into ntb_0 values(1591060628200, 3, 3, 3)");
96✔
4562

4563
  do_query(taos, "insert into ctb_0 values(1591060628000, 1, 1, 1)");
96✔
4564
  do_query(taos, "insert into ctb_0 values(1591060628100, 2, 2, 2)");
96✔
4565
  do_query(taos, "insert into ctb_0 values(1591060628200, 3, 3, 3)");
96✔
4566

4567
  // Create virtual tables
4568
  do_query(taos, "create stable vstb (ts timestamp, c1 int, c2 int, c3 int) tags (t1 int) virtual 1");
96✔
4569
  do_query(taos, "create vtable vtb_0 (c1 from ntb_0.c1, c2 from ntb_0.c2, c3 from ntb_0.c3) using vstb tags (1)");
96✔
4570
  do_query(taos, "create vtable vtb_1 (c1 from ctb_0.c1, c2 from ctb_0.c2, c3 from ctb_0.c3) using vstb tags (2)");
96✔
4571

4572
  // 0. Query vstable before alter origin table
4573
  TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
4574

4575
  TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
4576
  ASSERT_NE(stmt, nullptr);
96✔
4577

4578
  // query virtual super table
4579
  const char* sql = "select tbname,c1 from vstb where ts = ? order by tbname";
96✔
4580
  int         code = taos_stmt2_prepare(stmt, sql, 0);
96✔
4581
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4582

4583
  int             fieldNum = 0;
96✔
4584
  TAOS_FIELD_ALL* pFields = NULL;
96✔
4585
  code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
96✔
4586
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4587
  ASSERT_EQ(fieldNum, 1);
96✔
4588

4589
  int              t64_len = sizeof(int64_t);
96✔
4590
  int64_t          ts = 1591060628000;
96✔
4591
  TAOS_STMT2_BIND  params = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len, NULL, 1};
96✔
4592
  TAOS_STMT2_BIND* paramv = &params;
96✔
4593
  TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &paramv};
96✔
4594
  code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
4595
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4596

4597
  taos_stmt2_exec(stmt, NULL);
96✔
4598
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4599

4600
  TAOS_RES* pRes = taos_stmt2_result(stmt);
96✔
4601
  ASSERT_NE(pRes, nullptr);
96✔
4602
  TAOS_ROW row = taos_fetch_row(pRes);
96✔
4603
  ASSERT_NE(row, nullptr);
96✔
4604
  ASSERT_EQ(strncmp((char*)row[0], "vtb_0", 5), 0);
96✔
4605
  ASSERT_EQ(*(int*)row[1], 1);
96✔
4606
  row = taos_fetch_row(pRes);
96✔
4607
  ASSERT_NE(row, nullptr);
96✔
4608
  ASSERT_EQ(strncmp((char*)row[0], "vtb_1", 5), 0);
96✔
4609
  ASSERT_EQ(*(int*)row[1], 1);
96✔
4610

4611
  // query virtual child table
4612
  code = taos_stmt2_prepare(stmt, "select c1 from vtb_0 where ts = ? order by c1", 0);
96✔
4613
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4614
  int t2_len = 5;
96✔
4615
  code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
4616
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4617
  code = taos_stmt2_exec(stmt, NULL);
96✔
4618
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4619
  pRes = taos_stmt2_result(stmt);
96✔
4620
  ASSERT_NE(pRes, nullptr);
96✔
4621
  row = taos_fetch_row(pRes);
96✔
4622
  ASSERT_NE(row, nullptr);
96✔
4623
  ASSERT_EQ(*(int*)row[0], 1);
96✔
4624

4625
  // composite condition
4626
  code = taos_stmt2_prepare(stmt, "select c1,c2,c3 from vstb where c1 > ? and c3 < ? order by c1", 0);
96✔
4627
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4628
  fieldNum = 0;
96✔
4629
  pFields = NULL;
96✔
4630
  code = taos_stmt2_get_fields(stmt, &fieldNum, &pFields);
96✔
4631
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4632
  ASSERT_EQ(fieldNum, 2);
96✔
4633

4634
  int              c1 = 1;
96✔
4635
  int              c3 = 3;
96✔
4636
  int              c3_len = sizeof(int);
96✔
4637
  TAOS_STMT2_BIND  params2[2] = {{TSDB_DATA_TYPE_INT, &c1, &c3_len, NULL, 1},
96✔
4638
                                 {TSDB_DATA_TYPE_INT, &c3, &c3_len, NULL, 1}};
96✔
4639
  TAOS_STMT2_BIND* paramv2 = &params2[0];
96✔
4640
  TAOS_STMT2_BINDV bindv2 = {1, NULL, NULL, &paramv2};
96✔
4641
  code = taos_stmt2_bind_param(stmt, &bindv2, -1);
96✔
4642
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4643
  code = taos_stmt2_exec(stmt, NULL);
96✔
4644
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4645
  pRes = taos_stmt2_result(stmt);
96✔
4646
  ASSERT_NE(pRes, nullptr);
96✔
4647
  row = taos_fetch_row(pRes);
96✔
4648
  ASSERT_NE(row, nullptr);
96✔
4649
  ASSERT_EQ(*(int*)row[0], 2);
96✔
4650
  ASSERT_EQ(*(int*)row[1], 2);
96✔
4651
  ASSERT_EQ(*(int*)row[2], 2);
96✔
4652
  row = taos_fetch_row(pRes);
96✔
4653
  ASSERT_NE(row, nullptr);
96✔
4654
  row = taos_fetch_row(pRes);
96✔
4655
  ASSERT_EQ(row, nullptr);
96✔
4656

4657
  // Cleanup
4658
  taos_stmt2_close(stmt);
96✔
4659
  do_query(taos, "drop database if exists stmt2_testdb_29");
96✔
4660
  taos_close(taos);
96✔
4661
}
4662

4663
TEST(stmt2Case, bool_bind) {
384✔
4664
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
4665
  ASSERT_NE(taos, nullptr);
96✔
4666

4667
  do_query(taos, "drop database if exists stmt2_testdb_30");
96✔
4668
  do_query(taos, "create database stmt2_testdb_30");
96✔
4669
  do_query(taos, "use stmt2_testdb_30");
96✔
4670
  do_query(taos, "create stable stb(ts timestamp, c1 bool) tags(t1 bool,t2 bool,t3 bool,t4 bool)");
96✔
4671

4672
  TAOS_STMT2_OPTION option = {0, false, false, NULL, NULL};
96✔
4673
  TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
4674
  ASSERT_NE(stmt, nullptr);
96✔
4675

4676
  int code = taos_stmt2_prepare(stmt, "insert into tb1 using stb tags(?,?,?,?) values(?, ?)", 0);
96✔
4677
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4678

4679
  int64_t ts[4] = {1591060628000, 1591060628100, 1591060628200, 1591060628300};
96✔
4680
  int8_t  c1[4] = {-7, 1, 0, -1};
96✔
4681
  // int             c1_len = sizeof(int);
4682
  TAOS_STMT2_BIND  tag[4] = {{TSDB_DATA_TYPE_BOOL, &c1[0], NULL, NULL, 1},
96✔
4683
                             {TSDB_DATA_TYPE_BOOL, &c1[1], NULL, NULL, 1},
4684
                             {TSDB_DATA_TYPE_BOOL, &c1[2], NULL, NULL, 1},
4685
                             {TSDB_DATA_TYPE_BOOL, &c1[3], NULL, NULL, 1}};
96✔
4686
  TAOS_STMT2_BIND  params[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], NULL, NULL, 4},
96✔
4687
                                {TSDB_DATA_TYPE_BOOL, &c1[0], NULL, NULL, 4}};
96✔
4688
  TAOS_STMT2_BIND* tagv = &tag[0];
96✔
4689
  TAOS_STMT2_BIND* paramv = &params[0];
96✔
4690
  TAOS_STMT2_BINDV bindv = {1, NULL, &tagv, &paramv};
96✔
4691
  code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
4692
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4693
  code = taos_stmt2_exec(stmt, NULL);
96✔
4694
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4695

4696
  do_query(taos, "flush database stmt2_testdb_30");
96✔
4697

4698
  option = {0, true, true, NULL, NULL};
96✔
4699
  stmt = taos_stmt2_init(taos, &option);
96✔
4700
  ASSERT_NE(stmt, nullptr);
96✔
4701

4702
  code = taos_stmt2_prepare(stmt, "insert into tb2 using stb tags(?,?,?,?) values(?, ?)", 0);
96✔
4703
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4704

4705
  code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
4706
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4707
  code = taos_stmt2_exec(stmt, NULL);
96✔
4708
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4709
  taos_stmt2_close(stmt);
96✔
4710

4711
  do_query(taos, "flush database stmt2_testdb_30");
96✔
4712
  do_query(taos, "drop database if exists stmt2_testdb_30");
96✔
4713
  taos_close(taos);
96✔
4714
}
4715

4716
TEST(stmt2Case, mixed_literal) {
384✔
4717
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
4718
  ASSERT_NE(taos, nullptr);
96✔
4719

4720
  // Drop database if exists
4721
  do_query(taos, "drop database if exists stmt2_testdb_30");
96✔
4722

4723
  // Create database
4724
  do_query(taos, "create database stmt2_testdb_30");
96✔
4725
  do_query(taos, "use stmt2_testdb_30");
96✔
4726

4727
  // Create normal table
4728
  do_query(taos, "create table ntb(ts timestamp, name varchar(20), i32 int)");
96✔
4729

4730
#define TABLES 1
4731
#define ROWS   1
4732
  if (0) {
4733
    TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
4734

4735
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
4736
    ASSERT_NE(stmt, nullptr);
4737

4738
    const char* sql = "insert into ntb (ts, name, i32) values (?, ?, ?)";
4739
    int         code = taos_stmt2_prepare(stmt, sql, 0);
4740
    checkError(stmt, code, __FILE__, __LINE__);
4741

4742
    time_t tm;
4743
    taosTime(&tm);
4744

4745
    int64_t         ts = ((int64_t)tm) * 1000;
4746
    int32_t         t64_len = (int32_t)sizeof(ts);
4747
    TAOS_STMT2_BIND ts_param = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len, NULL, ROWS};
4748

4749
    char            name[] = "hello";
4750
    int32_t         name_len = (int32_t)sizeof(name);
4751
    TAOS_STMT2_BIND name_param = {TSDB_DATA_TYPE_VARCHAR, &name[0], &name_len, NULL, ROWS};
4752

4753
    int32_t         i32 = 70;
4754
    int32_t         i32_len = sizeof(i32);
4755
    TAOS_STMT2_BIND i32_param = {TSDB_DATA_TYPE_INT, &i32, &i32_len, NULL, ROWS};
4756

4757
    TAOS_STMT2_BIND params_for_this_table[] = {
4758
        ts_param,
4759
        name_param,
4760
        i32_param,
4761
    };
4762

4763
    TAOS_STMT2_BIND* binds_for_all_tables[TABLES] = {
4764
        params_for_this_table,
4765
    };
4766

4767
    TAOS_STMT2_BINDV bindv = {TABLES, NULL, NULL, binds_for_all_tables};
4768
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
4769
    checkError(stmt, code, __FILE__, __LINE__);
4770

4771
    code = taos_stmt2_exec(stmt, NULL);
4772
    checkError(stmt, code, __FILE__, __LINE__);
4773

4774
    taos_stmt2_close(stmt);
4775
  } else {
4776
    TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
4777

4778
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
4779
    ASSERT_NE(stmt, nullptr);
96✔
4780

4781
    const char* sql = "insert into ntb (ts, name, i32) values (?, 'world', ?)";
96✔
4782
    int         code = taos_stmt2_prepare(stmt, sql, 0);
96✔
4783
    checkError(stmt, code, __FILE__, __LINE__);
96✔
4784

4785
    time_t tm;
4786
    taosTime(&tm);
96✔
4787

4788
    int64_t         ts = ((int64_t)tm) * 1000;
96✔
4789
    int32_t         t64_len = (int32_t)sizeof(ts);
96✔
4790
    TAOS_STMT2_BIND ts_param = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len, NULL, ROWS};
96✔
4791

4792
    int32_t         i32 = 70;
96✔
4793
    int32_t         i32_len = sizeof(i32);
96✔
4794
    TAOS_STMT2_BIND i32_param = {TSDB_DATA_TYPE_INT, &i32, &i32_len, NULL, ROWS};
96✔
4795

4796
    TAOS_STMT2_BIND params_for_this_table[] = {
4797
        ts_param,
4798
        i32_param,
4799
    };
96✔
4800

4801
    TAOS_STMT2_BIND* binds_for_all_tables[TABLES] = {
4802
        params_for_this_table,
4803
    };
96✔
4804

4805
    TAOS_STMT2_BINDV bindv = {TABLES, NULL, NULL, binds_for_all_tables};
96✔
4806
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
4807
    checkError(stmt, code, __FILE__, __LINE__);
96✔
4808

4809
    code = taos_stmt2_exec(stmt, NULL);
96✔
4810
    checkError(stmt, code, __FILE__, __LINE__);
96✔
4811

4812
    taos_stmt2_close(stmt);
96✔
4813
  }
4814
  taos_close(taos);
96✔
4815
}
4816

4817
TEST(stmt2Case, query_interval) {
384✔
4818
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
4819
  ASSERT_NE(taos, nullptr);
96✔
4820

4821
  do_query(taos, "drop database if exists stmt2_testdb_31");
96✔
4822
  do_query(taos, "create database stmt2_testdb_31");
96✔
4823
  do_query(taos, "use stmt2_testdb_31");
96✔
4824

4825
  do_query(taos,
96✔
4826
           "CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId "
4827
           "INT, location BINARY(24))");
4828
  do_query(taos,
96✔
4829
           "insert into d1001 using meters tags(2, 'California.SanFrancisco') values"
4830
           "(1591060628000, 10.0, 218, 0.32)"
4831
           "(1591060629000, 10.1, 219, 0.32)"
4832
           "(1591060630000, 10.2, 220, 0.32)"
4833
           "(1591060631000, 10.3, 221, 0.32)"
4834
           "(1591060632000, 10.4, 222, 0.32)"
4835
           "(1591060633000, 10.5, 223, 0.32)"
4836
           "(1591060634000, 10.6, 224, 0.32)"
4837
           "(1591060635000, 10.7, 225, 0.32)"
4838
           "(1591060636000, 10.8, 226, 0.32)"
4839
           "(1591060637000, 10.9, 227, 0.32)"
4840
           "(1591060638000, 11.0, 228, 0.32)");
4841

4842
  TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
4843
  TAOS_STMT2*       stmt = taos_stmt2_init(taos, &option);
96✔
4844
  ASSERT_NE(stmt, nullptr);
96✔
4845

4846
  int code = taos_stmt2_prepare(
96✔
4847
      stmt, "select tbname,avg(voltage) from meters WHERE ts >= ? and ts <= ? partition by tbname interval(?)", 0);
4848
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4849

4850
  int              char_len[] = {5, 2};
96✔
4851
  int64_t          ts[] = {1591060629000, 1591060636000};
96✔
4852
  TAOS_STMT2_BIND  params[10] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts[0], NULL, NULL, 1},
96✔
4853
                                 {TSDB_DATA_TYPE_TIMESTAMP, &ts[1], NULL, NULL, 1},
4854
                                 {TSDB_DATA_TYPE_BINARY, (void*)"9s", &char_len[1], NULL, 1}};
96✔
4855
  TAOS_STMT2_BIND* paramv = &params[0];
96✔
4856
  TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &paramv};
96✔
4857

4858
  code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
4859
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4860
  code = taos_stmt2_exec(stmt, NULL);
96✔
4861
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4862

4863
  TAOS_RES* res = taos_stmt2_result(stmt);
96✔
4864
  ASSERT_NE(res, nullptr);
96✔
4865

4866
  TAOS_ROW row = taos_fetch_row(res);
96✔
4867
  ASSERT_NE(row, nullptr);
96✔
4868
  ASSERT_EQ(strncmp((char*)row[0], "d1001", 5), 0);
96✔
4869
  ASSERT_EQ(*(double*)row[1], 221.5);
96✔
4870

4871
  row = taos_fetch_row(res);
96✔
4872
  ASSERT_NE(row, nullptr);
96✔
4873
  ASSERT_EQ(strncmp((char*)row[0], "d1001", 5), 0);
96✔
4874
  ASSERT_EQ(*(double*)row[1], 225.5);
96✔
4875

4876
  int32_t interval = 9000;
96✔
4877
  params[2] = {TSDB_DATA_TYPE_INT, &interval, NULL, NULL, 1};
96✔
4878
  code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
4879
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4880
  code = taos_stmt2_exec(stmt, NULL);
96✔
4881
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4882

4883
  res = taos_stmt2_result(stmt);
96✔
4884
  ASSERT_NE(res, nullptr);
96✔
4885
  row = taos_fetch_row(res);
96✔
4886
  ASSERT_NE(row, nullptr);
96✔
4887
  ASSERT_EQ(strncmp((char*)row[0], "d1001", 5), 0);
96✔
4888
  ASSERT_EQ(*(double*)row[1], 221.5);
96✔
4889

4890
  row = taos_fetch_row(res);
96✔
4891
  ASSERT_NE(row, nullptr);
96✔
4892
  ASSERT_EQ(strncmp((char*)row[0], "d1001", 5), 0);
96✔
4893
  ASSERT_EQ(*(double*)row[1], 225.5);
96✔
4894

4895
  code = taos_stmt2_prepare(
96✔
4896
      stmt, "select tbname,avg(voltage) from meters WHERE ts >= ? and ts <= ? partition by tbname interval(?,?)", 0);
4897
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4898
  int32_t offset = 1000;
96✔
4899
  params[3] = {TSDB_DATA_TYPE_INT, &offset, NULL, NULL, 1};
96✔
4900
  code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
4901
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4902
  code = taos_stmt2_exec(stmt, NULL);
96✔
4903
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4904
  res = taos_stmt2_result(stmt);
96✔
4905
  ASSERT_NE(res, nullptr);
96✔
4906
  row = taos_fetch_row(res);
96✔
4907
  ASSERT_NE(row, nullptr);
96✔
4908
  ASSERT_EQ(strncmp((char*)row[0], "d1001", 5), 0);
96✔
4909
  ASSERT_EQ(*(double*)row[1], 222);
96✔
4910
  row = taos_fetch_row(res);
96✔
4911
  ASSERT_NE(row, nullptr);
96✔
4912
  ASSERT_EQ(strncmp((char*)row[0], "d1001", 5), 0);
96✔
4913
  ASSERT_EQ(*(double*)row[1], 226);
96✔
4914

4915
  params[2] = {TSDB_DATA_TYPE_BINARY, (void*)"9s", &char_len[1], NULL, 1};
96✔
4916
  params[3] = {TSDB_DATA_TYPE_BINARY, (void*)"1s", &char_len[1], NULL, 1};
96✔
4917
  code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
4918
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4919
  code = taos_stmt2_exec(stmt, NULL);
96✔
4920
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4921
  res = taos_stmt2_result(stmt);
96✔
4922
  ASSERT_NE(res, nullptr);
96✔
4923
  row = taos_fetch_row(res);
96✔
4924
  ASSERT_NE(row, nullptr);
96✔
4925
  ASSERT_EQ(strncmp((char*)row[0], "d1001", 5), 0);
96✔
4926
  ASSERT_EQ(*(double*)row[1], 222);
96✔
4927
  row = taos_fetch_row(res);
96✔
4928
  ASSERT_NE(row, nullptr);
96✔
4929
  ASSERT_EQ(strncmp((char*)row[0], "d1001", 5), 0);
96✔
4930
  ASSERT_EQ(*(double*)row[1], 226);
96✔
4931

4932
  code = taos_stmt2_prepare(
96✔
4933
      stmt,
4934
      "select tbname,avg(voltage) from meters WHERE ts >= ? and ts <= ? partition by tbname interval(?,?) sliding(?)",
4935
      0);
4936
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4937
  params[4] = {TSDB_DATA_TYPE_BINARY, (void*)"8s", &char_len[1], NULL, 1};
96✔
4938
  code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
4939
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4940
  code = taos_stmt2_exec(stmt, NULL);
96✔
4941
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4942
  res = taos_stmt2_result(stmt);
96✔
4943
  ASSERT_NE(res, nullptr);
96✔
4944
  row = taos_fetch_row(res);
96✔
4945
  ASSERT_NE(row, nullptr);
96✔
4946
  ASSERT_EQ(strncmp((char*)row[0], "d1001", 5), 0);
96✔
4947
  ASSERT_EQ(*(double*)row[1], 221);
96✔
4948
  row = taos_fetch_row(res);
96✔
4949
  ASSERT_NE(row, nullptr);
96✔
4950
  ASSERT_EQ(strncmp((char*)row[0], "d1001", 5), 0);
96✔
4951
  ASSERT_EQ(*(double*)row[1], 224.5);
96✔
4952

4953
  int32_t sliding = 8000;
96✔
4954
  params[2] = {TSDB_DATA_TYPE_INT, &interval, NULL, NULL, 1};
96✔
4955
  params[3] = {TSDB_DATA_TYPE_INT, &offset, NULL, NULL, 1};
96✔
4956
  params[4] = {TSDB_DATA_TYPE_INT, &sliding, NULL, NULL, 1};
96✔
4957
  code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
4958
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4959
  code = taos_stmt2_exec(stmt, NULL);
96✔
4960
  checkError(stmt, code, __FILE__, __LINE__);
96✔
4961
  res = taos_stmt2_result(stmt);
96✔
4962
  ASSERT_NE(res, nullptr);
96✔
4963
  row = taos_fetch_row(res);
96✔
4964
  ASSERT_NE(row, nullptr);
96✔
4965
  ASSERT_EQ(strncmp((char*)row[0], "d1001", 5), 0);
96✔
4966
  ASSERT_EQ(*(double*)row[1], 221);
96✔
4967
  row = taos_fetch_row(res);
96✔
4968
  ASSERT_NE(row, nullptr);
96✔
4969
  ASSERT_EQ(strncmp((char*)row[0], "d1001", 5), 0);
96✔
4970
  ASSERT_EQ(*(double*)row[1], 224.5);
96✔
4971

4972
  taos_stmt2_close(stmt);
96✔
4973
  do_query(taos, "drop database if exists stmt2_testdb_31");
96✔
4974
  taos_close(taos);
96✔
4975
}
4976

4977
TEST(stmt2Case, stmt2_insert_fixed_tag_value) {
384✔
4978
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
4979
  ASSERT_NE(taos, nullptr);
96✔
4980
  do_query(taos, "drop database if exists stmt2_testdb_6");
96✔
4981
  do_query(taos, "create database IF NOT EXISTS stmt2_testdb_6");
96✔
4982

4983
  TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
4984

4985
  // TD-34123 disorder pk ts
4986
  {
4987
    do_query(taos, "create stable stmt2_testdb_6.stb2  (ts timestamp, int_col int PRIMARY KEY) tags(int_tag int);");
96✔
4988
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
4989
    ASSERT_NE(stmt, nullptr);
96✔
4990
    const char* sql =
96✔
4991
        "INSERT INTO stmt2_testdb_6.? using  stmt2_testdb_6.stb2 (int_tag)tags(1) (ts,int_col)VALUES (?,?)";
4992
    printf("stmt2 [%s] : %s\n", "disorder pk ts", sql);
96✔
4993
    int code = taos_stmt2_prepare(stmt, sql, 0);
96✔
4994
    checkError(stmt, code, __FILE__, __LINE__);
96✔
4995

4996
    int             tag_i = 0;
96✔
4997
    int             tag_l = sizeof(int);
96✔
4998
    int             tag_bl = 3;
96✔
4999
    int64_t         ts[5] = {1591060628003, 1591060628002, 1591060628002, 1591060628002, 1591060628001};
96✔
5000
    int             t64_len[5] = {sizeof(int64_t), sizeof(int64_t), sizeof(int64_t), sizeof(int64_t), sizeof(int64_t)};
96✔
5001
    int             coli[5] = {1, 4, 4, 3, 2};
96✔
5002
    int             ilen[5] = {sizeof(int), sizeof(int), sizeof(int), sizeof(int), sizeof(int)};
96✔
5003
    char            is_null[2] = {1, 1};
96✔
5004
    TAOS_STMT2_BIND params1[2] = {
96✔
5005
        {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len[0], NULL, 5},
5006
        {TSDB_DATA_TYPE_INT, &coli, &ilen[0], NULL, 5},
5007
    };
96✔
5008

5009
    TAOS_STMT2_BIND* paramv = &params1[0];
96✔
5010
    char*            tbname = "tb3";
96✔
5011
    TAOS_STMT2_BINDV bindv = {1, &tbname, NULL, &paramv};
96✔
5012
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
5013
    checkError(stmt, code, __FILE__, __LINE__);
96✔
5014

5015
    int affected_rows;
5016
    taos_stmt2_exec(stmt, &affected_rows);
96✔
5017
    checkError(stmt, code, __FILE__, __LINE__);
96✔
5018
    ASSERT_EQ(affected_rows, 4);
96✔
5019

5020
    taos_stmt2_close(stmt);
96✔
5021
  }
5022

5023
  do_query(taos, "drop database if exists stmt2_testdb_6");
96✔
5024
  taos_close(taos);
96✔
5025
}
5026
// 6788971938
5027
TEST(stmt2Case, query_vtable_core) {
384✔
5028
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
5029
  ASSERT_NE(taos, nullptr);
96✔
5030

5031
  do_query(taos, "drop database if exists stmt2_testdb_32");
96✔
5032
  do_query(taos, "create database stmt2_testdb_32");
96✔
5033
  do_query(taos, "use stmt2_testdb_32");
96✔
5034
  do_query(taos, "create table tb1(ts timestamp, bool_v bool)");
96✔
5035
  do_query(taos, "create table tb2(ts timestamp, bool_v bool)");
96✔
5036

5037
  do_query(taos,
96✔
5038
           "create stable ts_kv_data(ts timestamp, bool_v bool,float_v float) tags(dataname binary(20)) virtual 1");
5039
  do_query(taos, "create vtable tbv1 (bool_v from tb1.bool_v) using ts_kv_data tags('abc')");
96✔
5040
  do_query(taos, "create vtable tbv2 (bool_v from tb2.bool_v) using ts_kv_data tags('def')");
96✔
5041

5042
  do_query(taos, "insert into tb1 values(1591060629000, true)");
96✔
5043
  do_query(taos, "insert into tb1 values(1591060630000, false)");
96✔
5044
  do_query(taos, "insert into tb2 values(1591060629000, true)");
96✔
5045
  do_query(taos, "insert into tb2 values(1591060630000, false)");
96✔
5046

5047
  TAOS_RES* res1 = taos_query(
96✔
5048
      taos,
5049
      "select last(ts,bool_v,float_v) from stmt2_testdb_32.ts_kv_data where dataname in ('abc','def') partition "
5050
      "by tbname");
96✔
5051
  ASSERT_NE(res1, nullptr);
96✔
5052
  TAOS_ROW row1 = taos_fetch_row(res1);
96✔
5053
  ASSERT_NE(row1, nullptr);
96✔
5054
  ASSERT_EQ(*(int64_t*)row1[0], 1591060630000);
96✔
5055
  row1 = taos_fetch_row(res1);
96✔
5056
  ASSERT_NE(row1, nullptr);
96✔
5057
  ASSERT_EQ(*(int64_t*)row1[0], 1591060630000);
96✔
5058
  row1 = taos_fetch_row(res1);
96✔
5059
  ASSERT_EQ(row1, nullptr);
96✔
5060
  taos_free_result(res1);
96✔
5061

5062
  AsyncArgs args = {0, 0};
96✔
5063
  ASSERT_EQ(tsem_init(&args.sem, 0, 0), TSDB_CODE_SUCCESS);
96✔
5064
  TAOS_STMT2_OPTION option[2] = {{0, true, true, stmtAsyncQueryCb, &args}, {0, true, true, NULL, NULL}};
96✔
5065

5066
  int32_t dataname_len = 3;
96✔
5067
  char*   dataname = "abc";
96✔
5068
  char*   dataname2 = "def";
96✔
5069

5070
  for (int i = 1; i < 2; i++) {
192✔
5071
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option[i]);
96✔
5072
    ASSERT_NE(stmt, nullptr);
96✔
5073

5074
    int code = taos_stmt2_prepare(
96✔
5075
        stmt,
5076
        "select last(ts,bool_v,float_v) from stmt2_testdb_32.ts_kv_data where dataname in (?,?) partition by tbname",
5077
        0);
5078
    checkError(stmt, code, __FILE__, __LINE__);
96✔
5079
    TAOS_STMT2_BIND params[2] = {
96✔
5080
        {TSDB_DATA_TYPE_BINARY, dataname, &dataname_len, NULL, 1},
5081
        {TSDB_DATA_TYPE_BINARY, dataname2, &dataname_len, NULL, 1},
5082
    };
96✔
5083
    TAOS_STMT2_BIND* paramv = &params[0];
96✔
5084
    TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &paramv};
96✔
5085
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
5086
    checkError(stmt, code, __FILE__, __LINE__);
96✔
5087
    code = taos_stmt2_exec(stmt, NULL);
96✔
5088
    checkError(stmt, code, __FILE__, __LINE__);
96✔
5089

5090
    if (i == 0) {
96✔
5091
      tsem_wait(&args.sem);
×
5092
    }
5093

5094
    TAOS_RES* res2 = taos_stmt2_result(stmt);
96✔
5095
    ASSERT_NE(res2, nullptr);
96✔
5096
    TAOS_ROW row2 = taos_fetch_row(res2);
96✔
5097
    ASSERT_NE(row2, nullptr);
96✔
5098
    ASSERT_EQ(*(int64_t*)row2[0], 1591060630000);
96✔
5099
    row2 = taos_fetch_row(res2);
96✔
5100
    ASSERT_NE(row2, nullptr);
96✔
5101
    ASSERT_EQ(*(int64_t*)row2[0], 1591060630000);
96✔
5102
    row2 = taos_fetch_row(res2);
96✔
5103
    ASSERT_EQ(row2, nullptr);
96✔
5104

5105
    taos_stmt2_close(stmt);
96✔
5106
  }
5107

5108
  tsem_destroy(&args.sem);
96✔
5109

5110
  // different database
5111
  do_query(taos, "drop database if exists stmt2_testdb_32_1");
96✔
5112
  do_query(taos, "drop database if exists stmt2_testdb_32_2");
96✔
5113
  do_query(taos, "create database stmt2_testdb_32_1");
96✔
5114
  do_query(taos, "create database stmt2_testdb_32_2");
96✔
5115

5116
  do_query(taos, "create table stmt2_testdb_32_1.tb1(ts timestamp, bool_v bool)");
96✔
5117
  do_query(taos, "create table stmt2_testdb_32_2.tb2(ts timestamp, float_v float)");
96✔
5118

5119
  do_query(taos, "insert into stmt2_testdb_32_1.tb1 values(1591060629000, true)");
96✔
5120
  do_query(taos, "insert into stmt2_testdb_32_1.tb1 values(1591060630000, false)");
96✔
5121
  do_query(taos, "insert into stmt2_testdb_32_2.tb2 values(1591060629000, 10.1)");
96✔
5122
  do_query(taos, "insert into stmt2_testdb_32_2.tb2 values(1591060630000, 10.2)");
96✔
5123

5124
  do_query(taos, "use stmt2_testdb_32");
96✔
5125
  do_query(taos,
96✔
5126
           "create vtable tbv3 (bool_v from stmt2_testdb_32_1.tb1.bool_v, float_v from stmt2_testdb_32_2.tb2.float_v) "
5127
           "using ts_kv_data tags('abc')");
5128

5129
  TAOS_STMT2* stmt = taos_stmt2_init(taos, &option[1]);
96✔
5130
  ASSERT_NE(stmt, nullptr);
96✔
5131
  int code = taos_stmt2_prepare(
96✔
5132
      stmt, "select last(ts,bool_v,float_v) from ts_kv_data where dataname in(?) partition by tbname", 0);
5133
  checkError(stmt, code, __FILE__, __LINE__);
96✔
5134
  TAOS_STMT2_BIND params[1] = {
96✔
5135
      {TSDB_DATA_TYPE_BINARY, (void*)"abc", &dataname_len, NULL, 1},
5136
  };
96✔
5137
  TAOS_STMT2_BIND* paramv = &params[0];
96✔
5138
  TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &paramv};
96✔
5139
  code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
5140
  checkError(stmt, code, __FILE__, __LINE__);
96✔
5141
  code = taos_stmt2_exec(stmt, NULL);
96✔
5142
  checkError(stmt, code, __FILE__, __LINE__);
96✔
5143
  TAOS_RES* res = taos_stmt2_result(stmt);
96✔
5144
  ASSERT_NE(res, nullptr);
96✔
5145
  TAOS_ROW row = taos_fetch_row(res);
96✔
5146
  ASSERT_NE(row, nullptr);
96✔
5147
  ASSERT_EQ(*(int64_t*)row[0], 1591060630000);
96✔
5148
  ASSERT_EQ(*(bool*)row[1], false);
96✔
5149
  ASSERT_FLOAT_EQ(*(float*)row[2], 10.2f);
96✔
5150
  row = taos_fetch_row(res);
96✔
5151
  ASSERT_NE(row, nullptr);
96✔
5152
  ASSERT_EQ(*(int64_t*)row[0], 1591060630000);
96✔
5153
  ASSERT_EQ(*(bool*)row[1], false);
96✔
5154
  ASSERT_EQ(row[2], nullptr);
96✔
5155

5156
  taos_stmt2_close(stmt);
96✔
5157
  do_query(taos, "drop database if exists stmt2_testdb_32_1");
96✔
5158
  do_query(taos, "drop database if exists stmt2_testdb_32_2");
96✔
5159
  do_query(taos, "drop database if exists stmt2_testdb_32");
96✔
5160
  taos_close(taos);
96✔
5161
}
5162

5163
TEST(stmt2Case, query_last_core) {
384✔
5164
  TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0);
96✔
5165
  ASSERT_NE(taos, nullptr);
96✔
5166

5167
  do_query(taos, "drop database if exists stmt2_testdb_32");
96✔
5168
  do_query(taos, "create database stmt2_testdb_32");
96✔
5169
  do_query(taos, "use stmt2_testdb_32");
96✔
5170
  do_query(taos, "create table tb1(ts timestamp, bool_v bool)");
96✔
5171
  do_query(taos, "create table tb2(ts timestamp, bool_v bool)");
96✔
5172
  do_query(taos, "create table tb3(ts timestamp, float_v float)");
96✔
5173

5174
  do_query(taos,
96✔
5175
           "create stable ts_kv_data(ts timestamp, bool_v bool,float_v float) tags(dataname binary(20)) virtual 1");
5176
  do_query(taos, "create vtable tbv1 (bool_v from tb1.bool_v) using ts_kv_data tags('abc')");
96✔
5177
  do_query(taos, "create vtable tbv2 (bool_v from tb2.bool_v) using ts_kv_data tags('def')");
96✔
5178

5179
  do_query(taos, "insert into tb1 values(1591060629000, true)");
96✔
5180
  do_query(taos, "insert into tb1 values(1591060630000, false)");
96✔
5181
  do_query(taos, "insert into tb2 values(1591060629000, true)");
96✔
5182
  do_query(taos, "insert into tb2 values(1591060630000, false)");
96✔
5183
  do_query(taos, "insert into tb3 values(1591060629000, 10.1)");
96✔
5184
  do_query(taos, "insert into tb3 values(1591060630000, 10.2)");
96✔
5185

5186
  do_query(taos,
96✔
5187
           "CREATE STABLE `ts_kv_data2` (`ts` TIMESTAMP, `bool_v` BOOL, `str_v` NCHAR(256), `long_v` BIGINT, `db1_v` "
5188
           "DOUBLE, `json_v` VARCHAR(10000), `float_v` FLOAT) TAGS (`dataname` VARCHAR(100), `groupname` "
5189
           "VARCHAR(100)) VIRTUAL 1");
5190
  do_query(taos,
96✔
5191
           "CREATE VTABLE `vtb_bool_0` (`bool_v` FROM `stmt2_testdb_32`.`tb1`.`bool_v`) USING `ts_kv_data2` "
5192
           "(`dataname`, `groupname`) TAGS ('VTB_BOOL_0', 'VTB_BOOL_1')");
5193
  do_query(taos,
96✔
5194
           "CREATE VTABLE `vtb_float_1` (`float_v` FROM `stmt2_testdb_32`.`tb3`.`float_v`) USING `ts_kv_data2` "
5195
           "(`dataname`, `groupname`) TAGS ('VTB_FLOAT_1', '')");
5196

5197
  TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL};
96✔
5198
  int32_t           dataname_len = 3;
96✔
5199
  char*             dataname = "abc";
96✔
5200
  char*             dataname2 = "def";
96✔
5201

5202
  {
5203
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
5204
    ASSERT_NE(stmt, nullptr);
96✔
5205

5206
    int code = taos_stmt2_prepare(stmt,
96✔
5207
                                  "select last(ts,bool_v,float_v) from stmt2_testdb_32.ts_kv_data where "
5208
                                  "dataname in (?,?) partition by tbname",
5209
                                  0);
5210
    checkError(stmt, code, __FILE__, __LINE__);
96✔
5211
    TAOS_STMT2_BIND params[2] = {
96✔
5212
        {TSDB_DATA_TYPE_BINARY, dataname, &dataname_len, NULL, 1},
5213
        {TSDB_DATA_TYPE_BINARY, dataname2, &dataname_len, NULL, 1},
5214
    };
96✔
5215
    TAOS_STMT2_BIND* paramv[2] = {&params[0], &params[1]};
96✔
5216
    TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &paramv[0]};
96✔
5217
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
5218
    checkError(stmt, code, __FILE__, __LINE__);
96✔
5219
    code = taos_stmt2_exec(stmt, NULL);
96✔
5220
    checkError(stmt, code, __FILE__, __LINE__);
96✔
5221

5222
    TAOS_RES* res2 = taos_stmt2_result(stmt);
96✔
5223
    ASSERT_NE(res2, nullptr);
96✔
5224
    TAOS_ROW row2 = taos_fetch_row(res2);
96✔
5225
    ASSERT_NE(row2, nullptr);
96✔
5226
    ASSERT_EQ(*(int64_t*)row2[0], 1591060630000);
96✔
5227
    row2 = taos_fetch_row(res2);
96✔
5228
    ASSERT_NE(row2, nullptr);
96✔
5229
    ASSERT_EQ(*(int64_t*)row2[0], 1591060630000);
96✔
5230
    row2 = taos_fetch_row(res2);
96✔
5231
    ASSERT_EQ(row2, nullptr);
96✔
5232

5233
    taos_stmt2_close(stmt);
96✔
5234
  }
5235

5236
  {
5237
    TAOS_STMT2* stmt = taos_stmt2_init(taos, &option);
96✔
5238
    ASSERT_NE(stmt, nullptr);
96✔
5239
    int code = taos_stmt2_prepare(stmt,
96✔
5240
                                  "select last(ts,bool_v,str_v,long_v,db1_v,json_v,groupname,dataname,float_v) from "
5241
                                  "ts_kv_data2 WHERE dataname in (?,?) partition by tbname",
5242
                                  0);
5243

5244
    int32_t         location_len1 = 10;
96✔
5245
    int32_t         location_len2 = 11;
96✔
5246
    char*           location1 = "VTB_BOOL_0";
96✔
5247
    char*           location2 = "VTB_FLOAT_1";
96✔
5248
    TAOS_STMT2_BIND params[2] = {
96✔
5249
        {TSDB_DATA_TYPE_BINARY, location1, &location_len1, NULL, 1},
5250
        {TSDB_DATA_TYPE_BINARY, location2, &location_len2, NULL, 1},
5251
    };
96✔
5252
    TAOS_STMT2_BIND* paramv[2] = {&params[0], &params[1]};
96✔
5253
    TAOS_STMT2_BINDV bindv = {1, NULL, NULL, &paramv[0]};
96✔
5254
    code = taos_stmt2_bind_param(stmt, &bindv, -1);
96✔
5255
    checkError(stmt, code, __FILE__, __LINE__);
96✔
5256
    code = taos_stmt2_exec(stmt, NULL);
96✔
5257
    checkError(stmt, code, __FILE__, __LINE__);
96✔
5258
    TAOS_RES* res = taos_stmt2_result(stmt);
96✔
5259
    ASSERT_NE(res, nullptr);
96✔
5260
    TAOS_ROW row = taos_fetch_row(res);
96✔
5261
    ASSERT_NE(row, nullptr);
96✔
5262
    ASSERT_EQ(*(int64_t*)row[0], 1591060630000);
96✔
5263
    row = taos_fetch_row(res);
96✔
5264
    ASSERT_NE(row, nullptr);
96✔
5265
    ASSERT_EQ(*(int64_t*)row[0], 1591060630000);
96✔
5266
    taos_stmt2_close(stmt);
96✔
5267
  }
5268

5269
  do_query(taos, "drop database if exists stmt2_testdb_32");
96✔
5270
  taos_close(taos);
96✔
5271
}
5272

5273
#pragma GCC diagnostic pop
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc