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

taosdata / TDengine / #4271

10 Jun 2025 09:45AM UTC coverage: 62.985% (+0.002%) from 62.983%
#4271

push

travis-ci

web-flow
Merge pull request #31337 from taosdata/newtest_3.0

fix TD-35057 and TD-35346

158179 of 319671 branches covered (49.48%)

Branch coverage included in aggregate %.

243860 of 318637 relevant lines covered (76.53%)

18624660.26 hits per line

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

52.89
/source/client/src/clientMain.c
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 "catalog.h"
17
#include "clientInt.h"
18
#include "clientLog.h"
19
#include "clientMonitor.h"
20
#include "clientStmt.h"
21
#include "clientStmt2.h"
22
#include "functionMgt.h"
23
#include "os.h"
24
#include "query.h"
25
#include "scheduler.h"
26
#include "tcompare.h"
27
#include "tconv.h"
28
#include "tdatablock.h"
29
#include "tglobal.h"
30
#include "tmsg.h"
31
#include "tref.h"
32
#include "trpc.h"
33
#include "version.h"
34

35
#define TSC_VAR_NOT_RELEASE 1
36
#define TSC_VAR_RELEASED    0
37

38
#ifdef TAOSD_INTEGRATED
39
extern void shellStopDaemon();
40
#endif
41

42
static int32_t sentinel = TSC_VAR_NOT_RELEASE;
43
static int32_t createParseContext(const SRequestObj *pRequest, SParseContext **pCxt, SSqlCallbackWrapper *pWrapper);
44

45
int taos_options(TSDB_OPTION option, const void *arg, ...) {
3,375✔
46
  if (arg == NULL) {
3,375!
47
    return TSDB_CODE_INVALID_PARA;
×
48
  }
49
  static int32_t lock = 0;
50

51
  for (int i = 1; atomic_val_compare_exchange_32(&lock, 0, 1) != 0; ++i) {
4,695✔
52
    if (i % 1000 == 0) {
1,339✔
53
      (void)sched_yield();
1✔
54
    }
55
  }
56

57
  int ret = taos_options_imp(option, (const char *)arg);
3,352✔
58
  atomic_store_32(&lock, 0);
3,376✔
59
  return ret;
3,376✔
60
}
61

62
#if !defined(WINDOWS) && !defined(TD_ASTRA)
63
static void freeTz(void *p) {
10✔
64
  timezone_t tz = *(timezone_t *)p;
10✔
65
  tzfree(tz);
10✔
66
}
10✔
67

68
int32_t tzInit() {
18,508✔
69
  pTimezoneMap = taosHashInit(0, MurmurHash3_32, false, HASH_ENTRY_LOCK);
18,508✔
70
  if (pTimezoneMap == NULL) {
18,508!
71
    return terrno;
×
72
  }
73
  taosHashSetFreeFp(pTimezoneMap, freeTz);
18,508✔
74

75
  pTimezoneNameMap = taosHashInit(0, taosIntHash_64, false, HASH_ENTRY_LOCK);
18,508✔
76
  if (pTimezoneNameMap == NULL) {
18,508!
77
    return terrno;
×
78
  }
79
  return 0;
18,508✔
80
}
81

82
void tzCleanup() {
18,509✔
83
  taosHashCleanup(pTimezoneMap);
18,509✔
84
  taosHashCleanup(pTimezoneNameMap);
18,509✔
85
}
18,509✔
86

87
static timezone_t setConnnectionTz(const char *val) {
17✔
88
  timezone_t  tz = NULL;
17✔
89
  timezone_t *tmp = taosHashGet(pTimezoneMap, val, strlen(val));
17✔
90
  if (tmp != NULL && *tmp != NULL) {
17!
91
    tz = *tmp;
7✔
92
    goto END;
7✔
93
  }
94

95
  tscDebug("set timezone to %s", val);
10!
96
  tz = tzalloc(val);
10✔
97
  if (tz == NULL) {
10✔
98
    tscWarn("%s unknown timezone %s change to UTC", __func__, val);
1!
99
    tz = tzalloc("UTC");
1✔
100
    if (tz == NULL) {
1!
101
      tscError("%s set timezone UTC error", __func__);
×
102
      terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
103
      goto END;
×
104
    }
105
  }
106
  int32_t code = taosHashPut(pTimezoneMap, val, strlen(val), &tz, sizeof(timezone_t));
10✔
107
  if (code != 0) {
10!
108
    tscError("%s put timezone to tz map error:%d", __func__, code);
×
109
    tzfree(tz);
×
110
    tz = NULL;
×
111
    goto END;
×
112
  }
113

114
  time_t tx1 = taosGetTimestampSec();
10✔
115
  char   output[TD_TIMEZONE_LEN] = {0};
10✔
116
  code = taosFormatTimezoneStr(tx1, val, tz, output);
10✔
117
  if (code == 0) {
10!
118
    code = taosHashPut(pTimezoneNameMap, &tz, sizeof(timezone_t), output, strlen(output) + 1);
10✔
119
  }
120
  if (code != 0) {
10!
121
    tscError("failed to put timezone %s to map", val);
×
122
  }
123

124
END:
10✔
125
  return tz;
17✔
126
}
127
#endif
128

129
static int32_t setConnectionOption(TAOS *taos, TSDB_OPTION_CONNECTION option, const char *val) {
38✔
130
  if (taos == NULL) {
38✔
131
    return terrno = TSDB_CODE_INVALID_PARA;
1✔
132
  }
133

134
#ifdef WINDOWS
135
  if (option == TSDB_OPTION_CONNECTION_TIMEZONE) {
136
    return terrno = TSDB_CODE_NOT_SUPPORTTED_IN_WINDOWS;
137
  }
138
#endif
139

140
  if (option < TSDB_OPTION_CONNECTION_CLEAR || option >= TSDB_MAX_OPTIONS_CONNECTION) {
37!
141
    return terrno = TSDB_CODE_INVALID_PARA;
1✔
142
  }
143

144
  int32_t code = taos_init();
36✔
145
  // initialize global config
146
  if (code != 0) {
36!
147
    return terrno = code;
×
148
  }
149

150
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
36✔
151
  if (NULL == pObj) {
36!
152
    tscError("invalid parameter for %s", __func__);
×
153
    return terrno;
×
154
  }
155

156
  if (option == TSDB_OPTION_CONNECTION_CLEAR) {
36✔
157
    val = NULL;
1✔
158
  }
159

160
#ifndef DISALLOW_NCHAR_WITHOUT_ICONV
161
  if (option == TSDB_OPTION_CONNECTION_CHARSET || option == TSDB_OPTION_CONNECTION_CLEAR) {
36✔
162
    if (val != NULL) {
8✔
163
      if (!taosValidateEncodec(val)) {
5✔
164
        code = terrno;
1✔
165
        goto END;
1✔
166
      }
167
      void *tmp = taosConvInit(val);
4✔
168
      if (tmp == NULL) {
4✔
169
        code = terrno;
1✔
170
        goto END;
1✔
171
      }
172
      pObj->optionInfo.charsetCxt = tmp;
3✔
173
    } else {
174
      pObj->optionInfo.charsetCxt = NULL;
3✔
175
    }
176
  }
177
#endif
178
  if (option == TSDB_OPTION_CONNECTION_TIMEZONE || option == TSDB_OPTION_CONNECTION_CLEAR) {
34✔
179
#if !defined(WINDOWS) && !defined(TD_ASTRA)
180
    if (val != NULL) {
19✔
181
      if (val[0] == 0) {
17✔
182
        val = "UTC";
1✔
183
      }
184
      timezone_t tz = setConnnectionTz(val);
17✔
185
      if (tz == NULL) {
17!
186
        code = terrno;
×
187
        goto END;
×
188
      }
189
      pObj->optionInfo.timezone = tz;
17✔
190
    } else {
191
      pObj->optionInfo.timezone = NULL;
2✔
192
    }
193
#endif
194
  }
195

196
  if (option == TSDB_OPTION_CONNECTION_USER_APP || option == TSDB_OPTION_CONNECTION_CLEAR) {
34✔
197
    if (val != NULL) {
5✔
198
      tstrncpy(pObj->optionInfo.userApp, val, sizeof(pObj->optionInfo.userApp));
3✔
199
    } else {
200
      pObj->optionInfo.userApp[0] = 0;
2✔
201
    }
202
  }
203

204
  if (option == TSDB_OPTION_CONNECTION_USER_IP || option == TSDB_OPTION_CONNECTION_CLEAR) {
34✔
205
    if (val != NULL) {
7✔
206
      pObj->optionInfo.userIp = taosInetAddr(val);
5✔
207

208
      SIpAddr addr = {0};
5✔
209
      code = taosGetIpFromFqdn(tsEnableIpv6, val, &addr);
5✔
210
      if (code != 0) {
5✔
211
        goto END;
3✔
212
      }
213

214
      code = tIpStrToUint(&addr, &pObj->optionInfo.userDualIp);
2✔
215
      if (code != 0) {
2!
216
        goto END;
×
217
      }
218

219
    } else {
220
      SIpRange dualIp = {0};
2✔
221
      pObj->optionInfo.userIp = INADDR_NONE;
2✔
222
      pObj->optionInfo.userDualIp = dualIp;
2✔
223
    }
224
  }
225

226
END:
27✔
227
  releaseTscObj(*(int64_t *)taos);
36✔
228
  return terrno = code;
36✔
229
}
230

231
int taos_options_connection(TAOS *taos, TSDB_OPTION_CONNECTION option, const void *arg, ...) {
38✔
232
  return setConnectionOption(taos, option, (const char *)arg);
38✔
233
}
234

235
// this function may be called by user or system, or by both simultaneously.
236
void taos_cleanup(void) {
18,522✔
237
  tscInfo("start to cleanup client environment");
18,522!
238
  if (atomic_val_compare_exchange_32(&sentinel, TSC_VAR_NOT_RELEASE, TSC_VAR_RELEASED) != TSC_VAR_NOT_RELEASE) {
18,522✔
239
    return;
13✔
240
  }
241

242
  monitorClose();
18,509✔
243
  tscStopCrashReport();
18,509✔
244

245
  hbMgrCleanUp();
18,509✔
246

247
  catalogDestroy();
18,509✔
248
  schedulerDestroy();
18,509✔
249

250
  fmFuncMgtDestroy();
18,509✔
251
  qCleanupKeywordsTable();
18,509✔
252

253
  if (TSDB_CODE_SUCCESS != cleanupTaskQueue()) {
18,509!
254
    tscWarn("failed to cleanup task queue");
×
255
  }
256

257
#if !defined(WINDOWS) && !defined(TD_ASTRA)
258
  tzCleanup();
18,509✔
259
#endif
260
  tmqMgmtClose();
18,509✔
261

262
  int32_t id = clientReqRefPool;
18,509✔
263
  clientReqRefPool = -1;
18,509✔
264
  taosCloseRef(id);
18,509✔
265

266
  id = clientConnRefPool;
18,509✔
267
  clientConnRefPool = -1;
18,509✔
268
  taosCloseRef(id);
18,509✔
269

270
  nodesDestroyAllocatorSet();
18,509✔
271
  cleanupAppInfo();
18,509✔
272
  rpcCleanup();
18,509✔
273
  tscDebug("rpc cleanup");
18,509✔
274

275
  taosConvDestroy();
18,509✔
276
  DestroyRegexCache();
18,509✔
277
#ifdef TAOSD_INTEGRATED
278
  shellStopDaemon();
279
#endif
280
  tscInfo("all local resources released");
18,509!
281
  taosCleanupCfg();
18,509✔
282
#ifndef TAOSD_INTEGRATED
283
  taosCloseLog();
18,509✔
284
#endif
285
}
286

287
static setConfRet taos_set_config_imp(const char *config) {
×
288
  setConfRet ret = {SET_CONF_RET_SUCC, {0}};
×
289
  // TODO: need re-implementation
290
  return ret;
×
291
}
292

293
setConfRet taos_set_config(const char *config) {
×
294
  // TODO  pthread_mutex_lock(&setConfMutex);
295
  setConfRet ret = taos_set_config_imp(config);
×
296
  //  pthread_mutex_unlock(&setConfMutex);
297
  return ret;
×
298
}
299

300
TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port) {
32,765✔
301
  tscInfo("try to connect to %s:%u, user:%s db:%s", ip, port, user, db);
32,765!
302
  if (user == NULL) {
32,877✔
303
    user = TSDB_DEFAULT_USER;
2,918✔
304
  }
305

306
  if (pass == NULL) {
32,877✔
307
    pass = TSDB_DEFAULT_PASS;
2,918✔
308
  }
309

310
  STscObj *pObj = NULL;
32,877✔
311
  int32_t  code = taos_connect_internal(ip, user, pass, NULL, db, port, CONN_TYPE__QUERY, &pObj);
32,877✔
312
  if (TSDB_CODE_SUCCESS == code) {
32,876✔
313
    int64_t *rid = taosMemoryCalloc(1, sizeof(int64_t));
32,817!
314
    if (NULL == rid) {
32,816!
315
      tscError("out of memory when taos connect to %s:%u, user:%s db:%s", ip, port, user, db);
×
316
      return NULL;
×
317
    }
318
    *rid = pObj->id;
32,816✔
319
    return (TAOS *)rid;
32,816✔
320
  } else {
321
    terrno = code;
59✔
322
  }
323

324
  return NULL;
65✔
325
}
326

327
int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type) {
×
328
  if (taos == NULL) {
×
329
    terrno = TSDB_CODE_INVALID_PARA;
×
330
    return terrno;
×
331
  }
332

333
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
×
334
  if (NULL == pObj) {
×
335
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
336
    tscError("invalid parameter for %s", __func__);
×
337
    return terrno;
×
338
  }
339

340
  switch (type) {
×
341
    case TAOS_NOTIFY_PASSVER: {
×
342
      TSC_ERR_RET(taosThreadMutexLock(&pObj->mutex));
×
343
      pObj->passInfo.fp = fp;
×
344
      pObj->passInfo.param = param;
×
345
      TSC_ERR_RET(taosThreadMutexUnlock(&pObj->mutex));
×
346
      break;
×
347
    }
348
    case TAOS_NOTIFY_WHITELIST_VER: {
×
349
      TSC_ERR_RET(taosThreadMutexLock(&pObj->mutex));
×
350
      pObj->whiteListInfo.fp = fp;
×
351
      pObj->whiteListInfo.param = param;
×
352
      TSC_ERR_RET(taosThreadMutexUnlock(&pObj->mutex));
×
353
      break;
×
354
    }
355
    case TAOS_NOTIFY_USER_DROPPED: {
×
356
      TSC_ERR_RET(taosThreadMutexLock(&pObj->mutex));
×
357
      pObj->userDroppedInfo.fp = fp;
×
358
      pObj->userDroppedInfo.param = param;
×
359
      TSC_ERR_RET(taosThreadMutexUnlock(&pObj->mutex));
×
360
      break;
×
361
    }
362
    default: {
×
363
      terrno = TSDB_CODE_INVALID_PARA;
×
364
      releaseTscObj(*(int64_t *)taos);
×
365
      return terrno;
×
366
    }
367
  }
368

369
  releaseTscObj(*(int64_t *)taos);
×
370
  return 0;
×
371
}
372

373
typedef struct SFetchWhiteListInfo {
374
  int64_t                     connId;
375
  __taos_async_whitelist_fn_t userCbFn;
376
  void                       *userParam;
377
} SFetchWhiteListInfo;
378

379
int32_t fetchWhiteListCallbackFn(void *param, SDataBuf *pMsg, int32_t code) {
×
380
  SFetchWhiteListInfo *pInfo = (SFetchWhiteListInfo *)param;
×
381
  TAOS                *taos = &pInfo->connId;
×
382
  if (code != TSDB_CODE_SUCCESS) {
×
383
    pInfo->userCbFn(pInfo->userParam, code, taos, 0, NULL);
×
384
    taosMemoryFree(pMsg->pData);
×
385
    taosMemoryFree(pMsg->pEpSet);
×
386
    taosMemoryFree(pInfo);
×
387
    return code;
×
388
  }
389

390
  SGetUserWhiteListRsp wlRsp;
391
  if (TSDB_CODE_SUCCESS != tDeserializeSGetUserWhiteListRsp(pMsg->pData, pMsg->len, &wlRsp)) {
×
392
    taosMemoryFree(pMsg->pData);
×
393
    taosMemoryFree(pMsg->pEpSet);
×
394
    taosMemoryFree(pInfo);
×
395
    tFreeSGetUserWhiteListRsp(&wlRsp);
×
396
    return terrno;
×
397
  }
398

399
  uint64_t *pWhiteLists = taosMemoryMalloc(wlRsp.numWhiteLists * sizeof(uint64_t));
×
400
  if (pWhiteLists == NULL) {
×
401
    taosMemoryFree(pMsg->pData);
×
402
    taosMemoryFree(pMsg->pEpSet);
×
403
    taosMemoryFree(pInfo);
×
404
    tFreeSGetUserWhiteListRsp(&wlRsp);
×
405
    return terrno;
×
406
  }
407

408
  for (int i = 0; i < wlRsp.numWhiteLists; ++i) {
×
409
    pWhiteLists[i] = ((uint64_t)wlRsp.pWhiteLists[i].mask << 32) | wlRsp.pWhiteLists[i].ip;
×
410
  }
411

412
  pInfo->userCbFn(pInfo->userParam, code, taos, wlRsp.numWhiteLists, pWhiteLists);
×
413

414
  taosMemoryFree(pWhiteLists);
×
415
  taosMemoryFree(pMsg->pData);
×
416
  taosMemoryFree(pMsg->pEpSet);
×
417
  taosMemoryFree(pInfo);
×
418
  tFreeSGetUserWhiteListRsp(&wlRsp);
×
419
  return code;
×
420
}
421

422
void taos_fetch_whitelist_a(TAOS *taos, __taos_async_whitelist_fn_t fp, void *param) {
×
423
  if (NULL == taos) {
×
424
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
425
    return;
×
426
  }
427

428
  int64_t connId = *(int64_t *)taos;
×
429

430
  STscObj *pTsc = acquireTscObj(connId);
×
431
  if (NULL == pTsc) {
×
432
    fp(param, TSDB_CODE_TSC_DISCONNECTED, taos, 0, NULL);
×
433
    return;
×
434
  }
435

436
  SGetUserWhiteListReq req;
437
  (void)memcpy(req.user, pTsc->user, TSDB_USER_LEN);
×
438
  int32_t msgLen = tSerializeSGetUserWhiteListReq(NULL, 0, &req);
×
439
  if (msgLen < 0) {
×
440
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
441
    releaseTscObj(connId);
×
442
    return;
×
443
  }
444

445
  void *pReq = taosMemoryMalloc(msgLen);
×
446
  if (pReq == NULL) {
×
447
    fp(param, terrno, taos, 0, NULL);
×
448
    releaseTscObj(connId);
×
449
    return;
×
450
  }
451

452
  if (tSerializeSGetUserWhiteListReq(pReq, msgLen, &req) < 0) {
×
453
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
454
    taosMemoryFree(pReq);
×
455
    releaseTscObj(connId);
×
456
    return;
×
457
  }
458

459
  SFetchWhiteListInfo *pParam = taosMemoryMalloc(sizeof(SFetchWhiteListInfo));
×
460
  if (pParam == NULL) {
×
461
    fp(param, terrno, taos, 0, NULL);
×
462
    taosMemoryFree(pReq);
×
463
    releaseTscObj(connId);
×
464
    return;
×
465
  }
466

467
  pParam->connId = connId;
×
468
  pParam->userCbFn = fp;
×
469

470
  pParam->userParam = param;
×
471
  SMsgSendInfo *pSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
×
472
  if (pSendInfo == NULL) {
×
473
    fp(param, terrno, taos, 0, NULL);
×
474
    taosMemoryFree(pParam);
×
475
    taosMemoryFree(pReq);
×
476
    releaseTscObj(connId);
×
477
    return;
×
478
  }
479

480
  pSendInfo->msgInfo = (SDataBuf){.pData = pReq, .len = msgLen, .handle = NULL};
×
481
  pSendInfo->requestId = generateRequestId();
×
482
  pSendInfo->requestObjRefId = 0;
×
483
  pSendInfo->param = pParam;
×
484
  pSendInfo->fp = fetchWhiteListCallbackFn;
×
485
  pSendInfo->msgType = TDMT_MND_GET_USER_WHITELIST;
×
486

487
  SEpSet epSet = getEpSet_s(&pTsc->pAppInfo->mgmtEp);
×
488
  if (TSDB_CODE_SUCCESS != asyncSendMsgToServer(pTsc->pAppInfo->pTransporter, &epSet, NULL, pSendInfo)) {
×
489
    tscWarn("failed to async send msg to server");
×
490
  }
491
  releaseTscObj(connId);
×
492
  return;
×
493
}
494

495
typedef struct SFetchWhiteListDualStackInfo {
496
  int64_t connId;
497
  void   *userParam;
498

499
  __taos_async_whitelist_dual_stack_fn_t userCbFn;
500
} SFetchWhiteListDualStackInfo;
501

502
int32_t fetchWhiteListDualStackCallbackFn(void *param, SDataBuf *pMsg, int32_t code) {
×
503
  int32_t lino = 0;
×
504
  char  **pWhiteLists = NULL;
×
505

506
  SGetUserWhiteListRsp wlRsp = {0};
×
507

508
  SFetchWhiteListDualStackInfo *pInfo = (SFetchWhiteListDualStackInfo *)param;
×
509
  TAOS *taos = &pInfo->connId;
×
510

511
  if (code != TSDB_CODE_SUCCESS) {
×
512
    pInfo->userCbFn(pInfo->userParam, code, taos, 0, NULL);
×
513
    TAOS_CHECK_GOTO(code, &lino, _error);
×
514
  }
515

516
  if ((code = tDeserializeSGetUserWhiteListDualRsp(pMsg->pData, pMsg->len, &wlRsp)) != TSDB_CODE_SUCCESS) {
×
517
    TAOS_CHECK_GOTO(code, &lino, _error);
×
518
  }
519

520
  pWhiteLists = taosMemoryMalloc(wlRsp.numWhiteLists * sizeof(char *));
×
521
  if (pWhiteLists == NULL) {
×
522
    code = terrno;
×
523
    TAOS_CHECK_GOTO(code, &lino, _error);
×
524
  }
525

526
  for (int32_t i = 0; i < wlRsp.numWhiteLists; i++) {
×
527
    SIpRange *pIpRange = &wlRsp.pWhiteListsDual[i];
×
528
    SIpAddr   ipAddr = {0};
×
529

530
    code = tIpUintToStr(pIpRange, &ipAddr);
×
531
    TAOS_CHECK_GOTO(code, &lino, _error);
×
532

533
    char *ip = taosMemCalloc(1, IP_RESERVE_CAP);
×
534
    if (ip == NULL) {
×
535
      code = terrno;
×
536
      TAOS_CHECK_GOTO(code, &lino, _error);
×
537
    }
538
    if (ipAddr.type == 0) {
×
539
      snprintf(ip, IP_RESERVE_CAP, "%s/%d", ipAddr.ipv4, ipAddr.mask);
×
540
    } else {
541
      snprintf(ip, IP_RESERVE_CAP, "%s/%d", ipAddr.ipv6, ipAddr.mask);
×
542
    }
543
    pWhiteLists[i] = ip;
×
544
  }
545

546
  pInfo->userCbFn(pInfo->userParam, code, taos, wlRsp.numWhiteLists, pWhiteLists);
×
547
_error:
×
548
  if (pWhiteLists != NULL) {
×
549
    for (int32_t i = 0; i < wlRsp.numWhiteLists; i++) {
×
550
      taosMemFree(pWhiteLists[i]);
×
551
    }
552
    taosMemoryFree(pWhiteLists);
×
553
  }
554
  taosMemoryFree(pMsg->pData);
×
555
  taosMemoryFree(pMsg->pEpSet);
×
556
  taosMemoryFree(pInfo);
×
557
  tFreeSGetUserWhiteListDualRsp(&wlRsp);
×
558
  return code;
×
559
}
560
void taos_fetch_whitelist_dual_stack_a(TAOS *taos, __taos_async_whitelist_dual_stack_fn_t fp, void *param) {
×
561
  if (NULL == taos) {
×
562
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
563
    return;
×
564
  }
565

566
  int64_t connId = *(int64_t *)taos;
×
567

568
  STscObj *pTsc = acquireTscObj(connId);
×
569
  if (NULL == pTsc) {
×
570
    fp(param, TSDB_CODE_TSC_DISCONNECTED, taos, 0, NULL);
×
571
    return;
×
572
  }
573

574
  SGetUserWhiteListReq req;
575
  (void)memcpy(req.user, pTsc->user, TSDB_USER_LEN);
×
576
  int32_t msgLen = tSerializeSGetUserWhiteListReq(NULL, 0, &req);
×
577
  if (msgLen < 0) {
×
578
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
579
    releaseTscObj(connId);
×
580
    return;
×
581
  }
582

583
  void *pReq = taosMemoryMalloc(msgLen);
×
584
  if (pReq == NULL) {
×
585
    fp(param, terrno, taos, 0, NULL);
×
586
    releaseTscObj(connId);
×
587
    return;
×
588
  }
589

590
  if (tSerializeSGetUserWhiteListReq(pReq, msgLen, &req) < 0) {
×
591
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
592
    taosMemoryFree(pReq);
×
593
    releaseTscObj(connId);
×
594
    return;
×
595
  }
596

597
  SFetchWhiteListDualStackInfo *pParam = taosMemoryMalloc(sizeof(SFetchWhiteListDualStackInfo));
×
598
  if (pParam == NULL) {
×
599
    fp(param, terrno, taos, 0, NULL);
×
600
    taosMemoryFree(pReq);
×
601
    releaseTscObj(connId);
×
602
    return;
×
603
  }
604

605
  pParam->connId = connId;
×
606
  pParam->userCbFn = fp;
×
607
  pParam->userParam = param;
×
608

609
  SMsgSendInfo *pSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
×
610
  if (pSendInfo == NULL) {
×
611
    fp(param, terrno, taos, 0, NULL);
×
612
    taosMemoryFree(pParam);
×
613
    taosMemoryFree(pReq);
×
614
    releaseTscObj(connId);
×
615
    return;
×
616
  }
617

618
  pSendInfo->msgInfo = (SDataBuf){.pData = pReq, .len = msgLen, .handle = NULL};
×
619
  pSendInfo->requestId = generateRequestId();
×
620
  pSendInfo->requestObjRefId = 0;
×
621
  pSendInfo->param = pParam;
×
622
  pSendInfo->fp = fetchWhiteListDualStackCallbackFn;
×
623
  pSendInfo->msgType = TDMT_MND_GET_USER_WHITELIST_DUAL;
×
624

625
  SEpSet epSet = getEpSet_s(&pTsc->pAppInfo->mgmtEp);
×
626
  if (TSDB_CODE_SUCCESS != asyncSendMsgToServer(pTsc->pAppInfo->pTransporter, &epSet, NULL, pSendInfo)) {
×
627
    tscWarn("failed to async send msg to server");
×
628
  }
629
  releaseTscObj(connId);
×
630
  return;
×
631
}
632

633
void taos_close_internal(void *taos) {
33,318✔
634
  if (taos == NULL) {
33,318!
635
    return;
×
636
  }
637

638
  STscObj *pTscObj = (STscObj *)taos;
33,318✔
639
  tscDebug("conn:0x%" PRIx64 ", try to close connection, numOfReq:%d", pTscObj->id, pTscObj->numOfReqs);
33,318✔
640

641
  if (TSDB_CODE_SUCCESS != taosRemoveRef(clientConnRefPool, pTscObj->id)) {
33,318!
642
    tscError("conn:0x%" PRIx64 ", failed to remove ref from conn pool", pTscObj->id);
×
643
  }
644
}
645

646
void taos_close(TAOS *taos) {
33,710✔
647
  if (taos == NULL) {
33,710✔
648
    return;
890✔
649
  }
650

651
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
32,820✔
652
  if (NULL == pObj) {
32,822!
653
    taosMemoryFree(taos);
×
654
    return;
×
655
  }
656

657
  taos_close_internal(pObj);
32,822✔
658
  releaseTscObj(*(int64_t *)taos);
32,820✔
659
  taosMemoryFree(taos);
32,822!
660
}
661

662
int taos_errno(TAOS_RES *res) {
13,418,933✔
663
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
13,418,933!
664
    return terrno;
×
665
  }
666

667
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
13,429,168!
668
    return 0;
×
669
  }
670

671
  return ((SRequestObj *)res)->code;
13,429,905✔
672
}
673

674
const char *taos_errstr(TAOS_RES *res) {
152,918✔
675
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
152,918!
676
    return (const char *)tstrerror(terrno);
137✔
677
  }
678

679
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
152,781!
680
    return "success";
×
681
  }
682

683
  SRequestObj *pRequest = (SRequestObj *)res;
152,781✔
684
  if (NULL != pRequest->msgBuf && (strlen(pRequest->msgBuf) > 0 || pRequest->code == TSDB_CODE_RPC_FQDN_ERROR)) {
152,781!
685
    return pRequest->msgBuf;
138,667✔
686
  } else {
687
    return (const char *)tstrerror(pRequest->code);
14,114✔
688
  }
689
}
690

691
void taos_free_result(TAOS_RES *res) {
11,687,919✔
692
  if (NULL == res) {
11,687,919✔
693
    return;
41,461✔
694
  }
695

696
  tscTrace("res:%p, will be freed", res);
11,646,458✔
697

698
  if (TD_RES_QUERY(res)) {
11,655,851✔
699
    SRequestObj *pRequest = (SRequestObj *)res;
11,631,286✔
700
    tscDebug("QID:0x%" PRIx64 ", call taos_free_result to free query, res:%p", pRequest->requestId, res);
11,631,286✔
701
    destroyRequest(pRequest);
11,631,286✔
702
    return;
11,633,050✔
703
  }
704

705
  SMqRspObj *pRsp = (SMqRspObj *)res;
24,565✔
706
  if (TD_RES_TMQ(res)) {
24,565✔
707
    tDeleteMqDataRsp(&pRsp->dataRsp);
24,290✔
708
    doFreeReqResultInfo(&pRsp->resInfo);
24,290✔
709
  } else if (TD_RES_TMQ_METADATA(res)) {
275✔
710
    tDeleteSTaosxRsp(&pRsp->dataRsp);
12✔
711
    doFreeReqResultInfo(&pRsp->resInfo);
12✔
712
  } else if (TD_RES_TMQ_META(res)) {
263✔
713
    tDeleteMqMetaRsp(&pRsp->metaRsp);
227✔
714
  } else if (TD_RES_TMQ_BATCH_META(res)) {
36✔
715
    tDeleteMqBatchMetaRsp(&pRsp->batchMetaRsp);
19✔
716
  } else if (TD_RES_TMQ_RAW(res)) {
17!
717
    tDeleteMqRawDataRsp(&pRsp->dataRsp);
17✔
718
  }
719
  taosMemoryFree(pRsp);
24,565!
720
}
721

722
void taos_kill_query(TAOS *taos) {
10✔
723
  if (NULL == taos) {
10✔
724
    return;
5✔
725
  }
726

727
  int64_t  rid = *(int64_t *)taos;
5✔
728
  STscObj *pTscObj = acquireTscObj(rid);
5✔
729
  if (pTscObj) {
5!
730
    stopAllRequests(pTscObj->pRequests);
5✔
731
  }
732
  releaseTscObj(rid);
5✔
733
}
734

735
int taos_field_count(TAOS_RES *res) {
65,008,283✔
736
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
65,008,283!
737
    return 0;
×
738
  }
739

740
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
65,008,543✔
741
  return pResInfo->numOfCols;
65,008,543✔
742
}
743

744
int taos_num_fields(TAOS_RES *res) { return taos_field_count(res); }
43,213,365✔
745

746
TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) {
18,082,873✔
747
  if (taos_num_fields(res) == 0 || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
18,082,873!
748
    return NULL;
138,712✔
749
  }
750

751
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
17,934,568✔
752
  return pResInfo->userFields;
17,934,568✔
753
}
754

755
TAOS_RES *taos_query(TAOS *taos, const char *sql) { return taosQueryImpl(taos, sql, false, TD_REQ_FROM_APP); }
11,584,908✔
756
TAOS_RES *taos_query_with_reqid(TAOS *taos, const char *sql, int64_t reqid) {
×
757
  return taosQueryImplWithReqid(taos, sql, false, reqid);
×
758
}
759

760
TAOS_FIELD_E *taos_fetch_fields_e(TAOS_RES *res) {
6✔
761
  if (taos_num_fields(res) == 0 || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
6!
762
    return NULL;
×
763
  }
764
  SReqResultInfo* pResInfo = tscGetCurResInfo(res);
6✔
765
  return pResInfo->fields;
6✔
766
}
767

768
TAOS_ROW taos_fetch_row(TAOS_RES *res) {
35,654,230✔
769
  if (res == NULL) {
35,654,230!
770
    return NULL;
×
771
  }
772

773
  if (TD_RES_QUERY(res)) {
35,654,230✔
774
    SRequestObj *pRequest = (SRequestObj *)res;
19,079,250✔
775
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
19,079,250!
776
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0 || pRequest->killed) {
19,079,125!
777
      return NULL;
3✔
778
    }
779

780
    if (pRequest->inCallback) {
19,077,522✔
781
      tscError("can not call taos_fetch_row before query callback ends.");
1!
782
      terrno = TSDB_CODE_TSC_INVALID_OPERATION;
1✔
783
      return NULL;
1✔
784
    }
785

786
    return doAsyncFetchRows(pRequest, true, true);
19,077,521✔
787
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
16,574,980!
788
    SMqRspObj      *msg = ((SMqRspObj *)res);
16,574,980✔
789
    SReqResultInfo *pResultInfo = NULL;
16,574,980✔
790
    if (msg->resIter == -1) {
16,574,980✔
791
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
23,648!
792
        return NULL;
×
793
      }
794
    } else {
795
      pResultInfo = tmqGetCurResInfo(res);
16,551,332✔
796
    }
797

798
    if (pResultInfo->current < pResultInfo->numOfRows) {
16,574,980✔
799
      doSetOneRowPtr(pResultInfo);
16,237,864✔
800
      pResultInfo->current += 1;
16,182,286✔
801
      return pResultInfo->row;
16,182,286✔
802
    } else {
803
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
337,116✔
804
        return NULL;
23,643✔
805
      }
806

807
      doSetOneRowPtr(pResultInfo);
309,613✔
808
      pResultInfo->current += 1;
309,576✔
809
      return pResultInfo->row;
309,576✔
810
    }
811
  } else if (TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
×
812
    return NULL;
×
813
  } else {
814
    tscError("invalid result passed to taos_fetch_row");
×
815
    terrno = TSDB_CODE_TMQ_INVALID_DATA;
×
816
    return NULL;
×
817
  }
818
}
819

820
int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
16,484,998✔
821
  return taos_print_row_with_size(str, INT32_MAX, row, fields, num_fields);
16,484,998✔
822
}
823
int taos_print_row_with_size(char *str, uint32_t size, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
16,485,299✔
824
  int32_t len = 0;
16,485,299✔
825
  for (int i = 0; i < num_fields; ++i) {
99,966,270✔
826
    if (i > 0 && len < size - 1) {
83,397,240!
827
      str[len++] = ' ';
67,184,004✔
828
    }
829

830
    if (row[i] == NULL) {
83,397,240✔
831
      len += tsnprintf(str + len, size - len, "%s", TSDB_DATA_NULL_STR);
253,793✔
832
      continue;
253,791✔
833
    }
834

835
    switch (fields[i].type) {
83,143,447!
836
      case TSDB_DATA_TYPE_TINYINT:
298,750✔
837
        len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
298,750✔
838
        break;
300,288✔
839

840
      case TSDB_DATA_TYPE_UTINYINT:
2,300✔
841
        len += tsnprintf(str + len, size - len, "%u", *((uint8_t *)row[i]));
2,300✔
842
        break;
2,300✔
843

844
      case TSDB_DATA_TYPE_SMALLINT:
2,303✔
845
        len += tsnprintf(str + len, size - len, "%d", *((int16_t *)row[i]));
2,303✔
846
        break;
2,303✔
847

848
      case TSDB_DATA_TYPE_USMALLINT:
2,300✔
849
        len += tsnprintf(str + len, size - len, "%u", *((uint16_t *)row[i]));
2,300✔
850
        break;
2,300✔
851

852
      case TSDB_DATA_TYPE_INT:
18,574,247✔
853
        len += tsnprintf(str + len, size - len, "%d", *((int32_t *)row[i]));
18,574,247✔
854
        break;
18,574,323✔
855

856
      case TSDB_DATA_TYPE_UINT:
2,300✔
857
        len += tsnprintf(str + len, size - len, "%u", *((uint32_t *)row[i]));
2,300✔
858
        break;
2,300✔
859

860
      case TSDB_DATA_TYPE_BIGINT:
13,900,434✔
861
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
13,900,434✔
862
        break;
13,900,678✔
863

864
      case TSDB_DATA_TYPE_UBIGINT:
2,300✔
865
        len += tsnprintf(str + len, size - len, "%" PRIu64, *((uint64_t *)row[i]));
2,300✔
866
        break;
2,300✔
867

868
      case TSDB_DATA_TYPE_FLOAT: {
2,550,077✔
869
        float fv = 0;
2,550,077✔
870
        fv = GET_FLOAT_VAL(row[i]);
2,550,077✔
871
        len += snprintf(str + len, size - len, "%.*g", FLT_DIG, fv);
2,550,077✔
872
      } break;
2,550,077✔
873

874
      case TSDB_DATA_TYPE_DOUBLE: {
8,042,341✔
875
        double dv = 0;
8,042,341✔
876
        dv = GET_DOUBLE_VAL(row[i]);
8,042,341✔
877
        len += snprintf(str + len, size - len, "%.*g", DBL_DIG, dv);
8,042,341✔
878
      } break;
8,042,341✔
879

880
      case TSDB_DATA_TYPE_VARBINARY: {
2,202✔
881
        void    *data = NULL;
2,202✔
882
        uint32_t tmp = 0;
2,202✔
883
        int32_t  charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
2,202✔
884
        if (taosAscii2Hex(row[i], charLen, &data, &tmp) < 0) {
2,202!
885
          break;
×
886
        }
887
        uint32_t copyLen = TMIN(size - len - 1, tmp);
2,202✔
888
        (void)memcpy(str + len, data, copyLen);
2,202✔
889
        len += copyLen;
2,202✔
890
        taosMemoryFree(data);
2,202!
891
      } break;
2,202✔
892
      case TSDB_DATA_TYPE_BINARY:
18,280,986✔
893
      case TSDB_DATA_TYPE_NCHAR:
894
      case TSDB_DATA_TYPE_GEOMETRY: {
895
        int32_t charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
18,280,986✔
896
        if (fields[i].type == TSDB_DATA_TYPE_BINARY || fields[i].type == TSDB_DATA_TYPE_VARBINARY ||
18,280,986✔
897
            fields[i].type == TSDB_DATA_TYPE_GEOMETRY) {
5,479,433✔
898
          if (charLen > fields[i].bytes || charLen < 0) {
12,803,753!
899
            tscError("taos_print_row error binary. charLen:%d, fields[i].bytes:%d", charLen, fields[i].bytes);
1,776!
900
            break;
×
901
          }
902
        } else {
903
          if (charLen > fields[i].bytes * TSDB_NCHAR_SIZE || charLen < 0) {
5,477,233!
904
            tscError("taos_print_row error. charLen:%d, fields[i].bytes:%d", charLen, fields[i].bytes);
4,441!
905
            break;
×
906
          }
907
        }
908

909
        uint32_t copyLen = TMIN(size - len - 1, charLen);
18,274,769✔
910
        (void)memcpy(str + len, row[i], copyLen);
18,274,769✔
911
        len += copyLen;
18,274,769✔
912
      } break;
18,274,769✔
913

914
      case TSDB_DATA_TYPE_TIMESTAMP:
21,968,389✔
915
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
21,968,389✔
916
        break;
22,056,481✔
917

918
      case TSDB_DATA_TYPE_BOOL:
2,300✔
919
        len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
2,300✔
920
        break;
2,300✔
921
      case TSDB_DATA_TYPE_DECIMAL64:
×
922
      case TSDB_DATA_TYPE_DECIMAL: {
923
        uint32_t decimalLen = strlen(row[i]);
×
924
        uint32_t copyLen = TMIN(size - len - 1, decimalLen);
×
925
        (void)memcpy(str + len, row[i], copyLen);
×
926
        len += copyLen;
×
927
      } break;
×
928
      default:
×
929
        break;
×
930
    }
931

932
    if (len >= size - 1) {
83,227,180!
933
      break;
×
934
    }
935
  }
936
  if (len < size) {
16,569,030✔
937
    str[len] = 0;
16,554,350✔
938
  }
939

940
  return len;
16,569,030✔
941
}
942

943
int *taos_fetch_lengths(TAOS_RES *res) {
31,983,378✔
944
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
31,983,378!
945
    return NULL;
×
946
  }
947

948
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
31,983,505✔
949
  return pResInfo->length;
31,983,505✔
950
}
951

952
TAOS_ROW *taos_result_block(TAOS_RES *res) {
×
953
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
×
954
    terrno = TSDB_CODE_INVALID_PARA;
×
955
    return NULL;
×
956
  }
957

958
  if (taos_is_update_query(res)) {
×
959
    return NULL;
×
960
  }
961

962
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
×
963
  return &pResInfo->row;
×
964
}
965

966
// todo intergrate with tDataTypes
967
const char *taos_data_type(int type) {
×
968
  switch (type) {
×
969
    case TSDB_DATA_TYPE_NULL:
×
970
      return "TSDB_DATA_TYPE_NULL";
×
971
    case TSDB_DATA_TYPE_BOOL:
×
972
      return "TSDB_DATA_TYPE_BOOL";
×
973
    case TSDB_DATA_TYPE_TINYINT:
×
974
      return "TSDB_DATA_TYPE_TINYINT";
×
975
    case TSDB_DATA_TYPE_SMALLINT:
×
976
      return "TSDB_DATA_TYPE_SMALLINT";
×
977
    case TSDB_DATA_TYPE_INT:
×
978
      return "TSDB_DATA_TYPE_INT";
×
979
    case TSDB_DATA_TYPE_BIGINT:
×
980
      return "TSDB_DATA_TYPE_BIGINT";
×
981
    case TSDB_DATA_TYPE_FLOAT:
×
982
      return "TSDB_DATA_TYPE_FLOAT";
×
983
    case TSDB_DATA_TYPE_DOUBLE:
×
984
      return "TSDB_DATA_TYPE_DOUBLE";
×
985
    case TSDB_DATA_TYPE_VARCHAR:
×
986
      return "TSDB_DATA_TYPE_VARCHAR";
×
987
      //    case TSDB_DATA_TYPE_BINARY:          return "TSDB_DATA_TYPE_VARCHAR";
988
    case TSDB_DATA_TYPE_TIMESTAMP:
×
989
      return "TSDB_DATA_TYPE_TIMESTAMP";
×
990
    case TSDB_DATA_TYPE_NCHAR:
×
991
      return "TSDB_DATA_TYPE_NCHAR";
×
992
    case TSDB_DATA_TYPE_JSON:
×
993
      return "TSDB_DATA_TYPE_JSON";
×
994
    case TSDB_DATA_TYPE_GEOMETRY:
×
995
      return "TSDB_DATA_TYPE_GEOMETRY";
×
996
    case TSDB_DATA_TYPE_UTINYINT:
×
997
      return "TSDB_DATA_TYPE_UTINYINT";
×
998
    case TSDB_DATA_TYPE_USMALLINT:
×
999
      return "TSDB_DATA_TYPE_USMALLINT";
×
1000
    case TSDB_DATA_TYPE_UINT:
×
1001
      return "TSDB_DATA_TYPE_UINT";
×
1002
    case TSDB_DATA_TYPE_UBIGINT:
×
1003
      return "TSDB_DATA_TYPE_UBIGINT";
×
1004
    case TSDB_DATA_TYPE_VARBINARY:
×
1005
      return "TSDB_DATA_TYPE_VARBINARY";
×
1006
    case TSDB_DATA_TYPE_DECIMAL:
×
1007
      return "TSDB_DATA_TYPE_DECIMAL";
×
1008
    case TSDB_DATA_TYPE_BLOB:
×
1009
      return "TSDB_DATA_TYPE_BLOB";
×
1010
    case TSDB_DATA_TYPE_MEDIUMBLOB:
×
1011
      return "TSDB_DATA_TYPE_MEDIUMBLOB";
×
1012
    default:
×
1013
      return "UNKNOWN";
×
1014
  }
1015
}
1016

1017
const char *taos_get_client_info() { return td_version; }
15,641✔
1018

1019
// return int32_t
1020
int taos_affected_rows(TAOS_RES *res) {
2,183,123✔
1021
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
2,183,123!
1022
      TD_RES_TMQ_BATCH_META(res)) {
2,183,150!
1023
    return 0;
×
1024
  }
1025

1026
  SRequestObj    *pRequest = (SRequestObj *)res;
2,183,156✔
1027
  SReqResultInfo *pResInfo = &pRequest->body.resInfo;
2,183,156✔
1028
  return (int)pResInfo->numOfRows;
2,183,156✔
1029
}
1030

1031
// return int64_t
1032
int64_t taos_affected_rows64(TAOS_RES *res) {
128,084✔
1033
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
128,084!
1034
      TD_RES_TMQ_BATCH_META(res)) {
128,084!
1035
    return 0;
×
1036
  }
1037

1038
  SRequestObj    *pRequest = (SRequestObj *)res;
128,084✔
1039
  SReqResultInfo *pResInfo = &pRequest->body.resInfo;
128,084✔
1040
  return pResInfo->numOfRows;
128,084✔
1041
}
1042

1043
int taos_result_precision(TAOS_RES *res) {
16,495,411✔
1044
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
16,495,411!
1045
    return TSDB_TIME_PRECISION_MILLI;
×
1046
  }
1047

1048
  if (TD_RES_QUERY(res)) {
16,495,447✔
1049
    SRequestObj *pRequest = (SRequestObj *)res;
1,239,107✔
1050
    return pRequest->body.resInfo.precision;
1,239,107✔
1051
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
15,256,340!
1052
    SReqResultInfo *info = tmqGetCurResInfo(res);
15,256,340✔
1053
    return info->precision;
15,256,340✔
1054
  }
1055
  return TSDB_TIME_PRECISION_MILLI;
×
1056
}
1057

1058
int taos_select_db(TAOS *taos, const char *db) {
543✔
1059
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
543✔
1060
  if (pObj == NULL) {
544!
1061
    releaseTscObj(*(int64_t *)taos);
×
1062
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1063
    return TSDB_CODE_TSC_DISCONNECTED;
×
1064
  }
1065

1066
  if (db == NULL || strlen(db) == 0) {
544!
1067
    releaseTscObj(*(int64_t *)taos);
×
1068
    tscError("invalid parameter for %s", db == NULL ? "db is NULL" : "db is empty");
×
1069
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1070
    return terrno;
×
1071
  }
1072

1073
  char sql[256] = {0};
544✔
1074
  (void)snprintf(sql, tListLen(sql), "use %s", db);
544✔
1075

1076
  TAOS_RES *pRequest = taos_query(taos, sql);
544✔
1077
  int32_t   code = taos_errno(pRequest);
543✔
1078

1079
  taos_free_result(pRequest);
543✔
1080
  releaseTscObj(*(int64_t *)taos);
544✔
1081
  return code;
544✔
1082
}
1083

1084
void taos_stop_query(TAOS_RES *res) {
11,657,446✔
1085
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
11,657,446!
1086
      TD_RES_TMQ_BATCH_META(res)) {
11,670,298!
1087
    return;
×
1088
  }
1089

1090
  stopAllQueries((SRequestObj *)res);
11,671,691✔
1091
}
1092

1093
bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) {
×
1094
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
×
1095
    return true;
×
1096
  }
1097
  SReqResultInfo *pResultInfo = tscGetCurResInfo(res);
×
1098
  if (col >= pResultInfo->numOfCols || col < 0 || row >= pResultInfo->numOfRows || row < 0) {
×
1099
    return true;
×
1100
  }
1101

1102
  SResultColumn *pCol = &pResultInfo->pCol[col];
×
1103
  if (IS_VAR_DATA_TYPE(pResultInfo->fields[col].type)) {
×
1104
    return (pCol->offset[row] == -1);
×
1105
  } else {
1106
    return colDataIsNull_f(pCol->nullbitmap, row);
×
1107
  }
1108
}
1109

1110
bool taos_is_update_query(TAOS_RES *res) { return taos_num_fields(res) == 0; }
×
1111

1112
int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
1,635,940✔
1113
  int32_t numOfRows = 0;
1,635,940✔
1114
  /*int32_t code = */ terrno = taos_fetch_block_s(res, &numOfRows, rows);
1,635,940✔
1115
  return numOfRows;
1,635,937✔
1116
}
1117

1118
int taos_fetch_block_s(TAOS_RES *res, int *numOfRows, TAOS_ROW *rows) {
1,635,940✔
1119
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
1,635,940!
1120
    return 0;
×
1121
  }
1122

1123
  if (TD_RES_QUERY(res)) {
1,635,940✔
1124
    SRequestObj *pRequest = (SRequestObj *)res;
1,632,337✔
1125

1126
    (*rows) = NULL;
1,632,337✔
1127
    (*numOfRows) = 0;
1,632,337✔
1128

1129
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
1,632,337!
1130
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
1,630,240!
1131
      return pRequest->code;
7,160✔
1132
    }
1133

1134
    (void)doAsyncFetchRows(pRequest, false, true);
1,625,177✔
1135

1136
    // TODO refactor
1137
    SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
1,625,174✔
1138
    pResultInfo->current = pResultInfo->numOfRows;
1,625,174✔
1139

1140
    (*rows) = pResultInfo->row;
1,625,174✔
1141
    (*numOfRows) = pResultInfo->numOfRows;
1,625,174✔
1142
    return pRequest->code;
1,625,174✔
1143
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
3,603!
1144
    SReqResultInfo *pResultInfo = NULL;
3,603✔
1145
    int32_t         code = tmqGetNextResInfo(res, true, &pResultInfo);
3,603✔
1146
    if (code != 0) return code;
3,603✔
1147

1148
    pResultInfo->current = pResultInfo->numOfRows;
3,059✔
1149
    (*rows) = pResultInfo->row;
3,059✔
1150
    (*numOfRows) = pResultInfo->numOfRows;
3,059✔
1151
    return 0;
3,059✔
1152
  } else {
1153
    tscError("taos_fetch_block_s invalid res type");
×
1154
    return TSDB_CODE_TMQ_INVALID_DATA;
×
1155
  }
1156
}
1157

1158
int taos_fetch_raw_block(TAOS_RES *res, int *numOfRows, void **pData) {
8✔
1159
  *numOfRows = 0;
8✔
1160
  *pData = NULL;
8✔
1161

1162
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
8!
1163
    return 0;
×
1164
  }
1165

1166
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
8!
1167
    SReqResultInfo *pResultInfo = NULL;
×
1168
    int32_t         code = tmqGetNextResInfo(res, false, &pResultInfo);
×
1169
    if (code != 0) {
×
1170
      (*numOfRows) = 0;
×
1171
      return 0;
×
1172
    }
1173

1174
    pResultInfo->current = pResultInfo->numOfRows;
×
1175
    (*numOfRows) = pResultInfo->numOfRows;
×
1176
    (*pData) = (void *)pResultInfo->pData;
×
1177
    return 0;
×
1178
  }
1179

1180
  SRequestObj *pRequest = (SRequestObj *)res;
8✔
1181

1182
  if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
8!
1183
      pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
8!
1184
    return pRequest->code;
×
1185
  }
1186

1187
  (void)doAsyncFetchRows(pRequest, false, false);
8✔
1188

1189
  SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
8✔
1190

1191
  pResultInfo->current = pResultInfo->numOfRows;
8✔
1192
  (*numOfRows) = pResultInfo->numOfRows;
8✔
1193
  (*pData) = (void *)pResultInfo->pData;
8✔
1194

1195
  return pRequest->code;
8✔
1196
}
1197

1198
int *taos_get_column_data_offset(TAOS_RES *res, int columnIndex) {
813,945✔
1199
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
813,945!
1200
    return 0;
×
1201
  }
1202

1203
  int32_t numOfFields = taos_num_fields(res);
813,945✔
1204
  if (columnIndex < 0 || columnIndex >= numOfFields || numOfFields == 0) {
813,945!
1205
    return 0;
×
1206
  }
1207

1208
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
813,945✔
1209
  TAOS_FIELD     *pField = &pResInfo->userFields[columnIndex];
813,945✔
1210
  if (!IS_VAR_DATA_TYPE(pField->type)) {
813,945!
1211
    return 0;
×
1212
  }
1213

1214
  return pResInfo->pCol[columnIndex].offset;
813,945✔
1215
}
1216

1217
int taos_is_null_by_column(TAOS_RES *res, int columnIndex, bool result[], int *rows) {
2,350,392✔
1218
  if (res == NULL || result == NULL || rows == NULL || *rows <= 0 || columnIndex < 0 || TD_RES_TMQ_META(res) ||
2,350,392!
1219
      TD_RES_TMQ_RAW(res) || TD_RES_TMQ_BATCH_META(res)) {
2,350,392!
1220
    return TSDB_CODE_INVALID_PARA;
×
1221
  }
1222

1223
  int32_t numOfFields = taos_num_fields(res);
2,350,392✔
1224
  if (columnIndex >= numOfFields || numOfFields == 0) {
2,350,392!
1225
    return TSDB_CODE_INVALID_PARA;
×
1226
  }
1227

1228
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
2,350,392✔
1229
  TAOS_FIELD     *pField = &pResInfo->userFields[columnIndex];
2,350,392✔
1230
  SResultColumn  *pCol = &pResInfo->pCol[columnIndex];
2,350,392✔
1231

1232
  if (*rows > pResInfo->numOfRows) {
2,350,392!
1233
    *rows = pResInfo->numOfRows;
×
1234
  }
1235
  if (IS_VAR_DATA_TYPE(pField->type)) {
2,350,392!
1236
    for (int i = 0; i < *rows; i++) {
×
1237
      if (pCol->offset[i] == -1) {
×
1238
        result[i] = true;
×
1239
      } else {
1240
        result[i] = false;
×
1241
      }
1242
    }
1243
  } else {
1244
    for (int i = 0; i < *rows; i++) {
617,095,611✔
1245
      if (colDataIsNull_f(pCol->nullbitmap, i)) {
614,745,219✔
1246
        result[i] = true;
168,771,352✔
1247
      } else {
1248
        result[i] = false;
445,973,867✔
1249
      }
1250
    }
1251
  }
1252
  return 0;
2,350,392✔
1253
}
1254

1255
int taos_validate_sql(TAOS *taos, const char *sql) {
×
1256
  TAOS_RES *pObj = taosQueryImpl(taos, sql, true, TD_REQ_FROM_APP);
×
1257

1258
  int code = taos_errno(pObj);
×
1259

1260
  taos_free_result(pObj);
×
1261
  return code;
×
1262
}
1263

1264
void taos_reset_current_db(TAOS *taos) {
×
1265
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
×
1266
  if (pTscObj == NULL) {
×
1267
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1268
    return;
×
1269
  }
1270

1271
  resetConnectDB(pTscObj);
×
1272

1273
  releaseTscObj(*(int64_t *)taos);
×
1274
}
1275

1276
const char *taos_get_server_info(TAOS *taos) {
158✔
1277
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
158✔
1278
  if (pTscObj == NULL) {
158!
1279
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1280
    return NULL;
×
1281
  }
1282

1283
  releaseTscObj(*(int64_t *)taos);
158✔
1284

1285
  return pTscObj->sDetailVer;
158✔
1286
}
1287

1288
int taos_get_current_db(TAOS *taos, char *database, int len, int *required) {
4✔
1289
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
4✔
1290
  if (pTscObj == NULL) {
4!
1291
    return TSDB_CODE_TSC_DISCONNECTED;
×
1292
  }
1293

1294
  int code = TSDB_CODE_SUCCESS;
4✔
1295
  (void)taosThreadMutexLock(&pTscObj->mutex);
4✔
1296
  if (database == NULL || len <= 0) {
4!
1297
    if (required != NULL) *required = strlen(pTscObj->db) + 1;
2✔
1298
    TSC_ERR_JRET(TSDB_CODE_INVALID_PARA);
2!
1299
  } else if (len < strlen(pTscObj->db) + 1) {
2✔
1300
    tstrncpy(database, pTscObj->db, len);
1✔
1301
    if (required) *required = strlen(pTscObj->db) + 1;
1!
1302
    TSC_ERR_JRET(TSDB_CODE_INVALID_PARA);
1!
1303
  } else {
1304
    tstrncpy(database, pTscObj->db, len);
1✔
1305
    code = 0;
1✔
1306
  }
1307
_return:
4✔
1308
  (void)taosThreadMutexUnlock(&pTscObj->mutex);
4✔
1309
  releaseTscObj(*(int64_t *)taos);
4✔
1310
  return code;
4✔
1311
}
1312

1313
void destorySqlCallbackWrapper(SSqlCallbackWrapper *pWrapper) {
23,260,126✔
1314
  if (NULL == pWrapper) {
23,260,126✔
1315
    return;
11,677,891✔
1316
  }
1317
  destoryCatalogReq(pWrapper->pCatalogReq);
11,582,235✔
1318
  taosMemoryFree(pWrapper->pCatalogReq);
11,596,885!
1319
  qDestroyParseContext(pWrapper->pParseCtx);
11,615,887✔
1320
  taosMemoryFree(pWrapper);
11,614,323!
1321
}
1322

1323
void destroyCtxInRequest(SRequestObj *pRequest) {
18,597✔
1324
  schedulerFreeJob(&pRequest->body.queryJob, 0);
18,597✔
1325
  qDestroyQuery(pRequest->pQuery);
18,597✔
1326
  pRequest->pQuery = NULL;
18,597✔
1327
  destorySqlCallbackWrapper(pRequest->pWrapper);
18,597✔
1328
  pRequest->pWrapper = NULL;
18,597✔
1329
}
18,597✔
1330

1331
static void doAsyncQueryFromAnalyse(SMetaData *pResultMeta, void *param, int32_t code) {
1,403,715✔
1332
  SSqlCallbackWrapper *pWrapper = (SSqlCallbackWrapper *)param;
1,403,715✔
1333
  SRequestObj         *pRequest = pWrapper->pRequest;
1,403,715✔
1334
  SQuery              *pQuery = pRequest->pQuery;
1,403,715✔
1335

1336
  qDebug("req:0x%" PRIx64 ", start to semantic analysis, QID:0x%" PRIx64, pRequest->self, pRequest->requestId);
1,403,715✔
1337

1338
  int64_t analyseStart = taosGetTimestampUs();
1,403,715✔
1339
  pRequest->metric.ctgCostUs = analyseStart - pRequest->metric.ctgStart;
1,403,715✔
1340
  pWrapper->pParseCtx->parseOnly = pRequest->parseOnly;
1,403,715✔
1341

1342
  if (TSDB_CODE_SUCCESS == code) {
1,403,715✔
1343
    code = qAnalyseSqlSemantic(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
1,403,702✔
1344
  }
1345

1346
  pRequest->metric.analyseCostUs += taosGetTimestampUs() - analyseStart;
1,403,512✔
1347

1348
  if (pRequest->parseOnly) {
1,403,512✔
1349
    (void)memcpy(&pRequest->parseMeta, pResultMeta, sizeof(*pResultMeta));
1,248✔
1350
    (void)memset(pResultMeta, 0, sizeof(*pResultMeta));
1,248✔
1351
  }
1352

1353
  handleQueryAnslyseRes(pWrapper, pResultMeta, code);
1,403,512✔
1354
}
1,403,551✔
1355

1356
int32_t cloneCatalogReq(SCatalogReq **ppTarget, SCatalogReq *pSrc) {
476✔
1357
  int32_t      code = TSDB_CODE_SUCCESS;
476✔
1358
  SCatalogReq *pTarget = taosMemoryCalloc(1, sizeof(SCatalogReq));
476!
1359
  if (pTarget == NULL) {
476!
1360
    code = terrno;
×
1361
  } else {
1362
    pTarget->pDbVgroup = taosArrayDup(pSrc->pDbVgroup, NULL);
476✔
1363
    pTarget->pDbCfg = taosArrayDup(pSrc->pDbCfg, NULL);
476✔
1364
    pTarget->pDbInfo = taosArrayDup(pSrc->pDbInfo, NULL);
476✔
1365
    pTarget->pTableMeta = taosArrayDup(pSrc->pTableMeta, NULL);
476✔
1366
    pTarget->pTableHash = taosArrayDup(pSrc->pTableHash, NULL);
476✔
1367
    pTarget->pUdf = taosArrayDup(pSrc->pUdf, NULL);
476✔
1368
    pTarget->pIndex = taosArrayDup(pSrc->pIndex, NULL);
476✔
1369
    pTarget->pUser = taosArrayDup(pSrc->pUser, NULL);
476✔
1370
    pTarget->pTableIndex = taosArrayDup(pSrc->pTableIndex, NULL);
476✔
1371
    pTarget->pTableCfg = taosArrayDup(pSrc->pTableCfg, NULL);
476✔
1372
    pTarget->pTableTag = taosArrayDup(pSrc->pTableTag, NULL);
476✔
1373
    pTarget->pView = taosArrayDup(pSrc->pView, NULL);
476✔
1374
    pTarget->pTableTSMAs = taosArrayDup(pSrc->pTableTSMAs, NULL);
476✔
1375
    pTarget->pTSMAs = taosArrayDup(pSrc->pTSMAs, NULL);
476✔
1376
    pTarget->qNodeRequired = pSrc->qNodeRequired;
476✔
1377
    pTarget->dNodeRequired = pSrc->dNodeRequired;
476✔
1378
    pTarget->svrVerRequired = pSrc->svrVerRequired;
476✔
1379
    pTarget->forceUpdate = pSrc->forceUpdate;
476✔
1380
    pTarget->cloned = true;
476✔
1381

1382
    *ppTarget = pTarget;
476✔
1383
  }
1384

1385
  return code;
476✔
1386
}
1387

1388
void handleSubQueryFromAnalyse(SSqlCallbackWrapper *pWrapper, SMetaData *pResultMeta, SNode *pRoot) {
476✔
1389
  SRequestObj         *pNewRequest = NULL;
476✔
1390
  SSqlCallbackWrapper *pNewWrapper = NULL;
476✔
1391
  int32_t              code = buildPreviousRequest(pWrapper->pRequest, pWrapper->pRequest->sqlstr, &pNewRequest);
476✔
1392
  if (code) {
476!
1393
    handleQueryAnslyseRes(pWrapper, pResultMeta, code);
×
1394
    return;
×
1395
  }
1396

1397
  pNewRequest->pQuery = NULL;
476✔
1398
  code = nodesMakeNode(QUERY_NODE_QUERY, (SNode **)&pNewRequest->pQuery);
476✔
1399
  if (pNewRequest->pQuery) {
476!
1400
    pNewRequest->pQuery->pRoot = pRoot;
476✔
1401
    pRoot = NULL;
476✔
1402
    pNewRequest->pQuery->execStage = QUERY_EXEC_STAGE_ANALYSE;
476✔
1403
  }
1404
  if (TSDB_CODE_SUCCESS == code) {
476!
1405
    code = prepareAndParseSqlSyntax(&pNewWrapper, pNewRequest, false);
476✔
1406
  }
1407
  if (TSDB_CODE_SUCCESS == code) {
476!
1408
    code = cloneCatalogReq(&pNewWrapper->pCatalogReq, pWrapper->pCatalogReq);
476✔
1409
  }
1410
  if (TSDB_CODE_SUCCESS == code) {
476!
1411
    doAsyncQueryFromAnalyse(pResultMeta, pNewWrapper, code);
476✔
1412
    nodesDestroyNode(pRoot);
476✔
1413
  } else {
1414
    handleQueryAnslyseRes(pWrapper, pResultMeta, code);
×
1415
    return;
×
1416
  }
1417
}
1418

1419
void handleQueryAnslyseRes(SSqlCallbackWrapper *pWrapper, SMetaData *pResultMeta, int32_t code) {
1,403,896✔
1420
  SRequestObj *pRequest = pWrapper->pRequest;
1,403,896✔
1421
  SQuery      *pQuery = pRequest->pQuery;
1,403,896✔
1422

1423
  if (code == TSDB_CODE_SUCCESS && pQuery->pPrevRoot) {
1,403,896✔
1424
    SNode *prevRoot = pQuery->pPrevRoot;
476✔
1425
    pQuery->pPrevRoot = NULL;
476✔
1426
    handleSubQueryFromAnalyse(pWrapper, pResultMeta, prevRoot);
476✔
1427
    return;
476✔
1428
  }
1429

1430
  if (code == TSDB_CODE_SUCCESS) {
1,403,420✔
1431
    pRequest->stableQuery = pQuery->stableQuery;
1,300,820✔
1432
    if (pQuery->pRoot) {
1,300,820!
1433
      pRequest->stmtType = pQuery->pRoot->type;
1,300,834✔
1434
    }
1435

1436
    if (pQuery->haveResultSet) {
1,300,820✔
1437
      code = setResSchemaInfo(&pRequest->body.resInfo, pQuery->pResSchema, pQuery->numOfResCols, pQuery->pResExtSchema, pRequest->isStmtBind);
1,032,934✔
1438
      setResPrecision(&pRequest->body.resInfo, pQuery->precision);
1,032,934✔
1439
    }
1440
  }
1441

1442
  if (code == TSDB_CODE_SUCCESS) {
1,403,598✔
1443
    TSWAP(pRequest->dbList, (pQuery)->pDbList);
1,300,797✔
1444
    TSWAP(pRequest->tableList, (pQuery)->pTableList);
1,300,797✔
1445
    TSWAP(pRequest->targetTableList, (pQuery)->pTargetTableList);
1,300,797✔
1446

1447
    launchAsyncQuery(pRequest, pQuery, pResultMeta, pWrapper);
1,300,797✔
1448
  } else {
1449
    destorySqlCallbackWrapper(pWrapper);
102,801✔
1450
    pRequest->pWrapper = NULL;
102,801✔
1451
    qDestroyQuery(pRequest->pQuery);
102,801✔
1452
    pRequest->pQuery = NULL;
102,801✔
1453

1454
    if (NEED_CLIENT_HANDLE_ERROR(code)) {
102,801!
1455
      tscDebug("req:0x%" PRIx64 ", client retry to handle the error, code:%d - %s, tryCount:%d, QID:0x%" PRIx64,
18,198✔
1456
               pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId);
1457
      restartAsyncQuery(pRequest, code);
18,198✔
1458
      return;
18,198✔
1459
    }
1460

1461
    // return to app directly
1462
    tscError("req:0x%" PRIx64 ", error occurs, code:%s, return to user app, QID:0x%" PRIx64, pRequest->self, tstrerror(code),
84,603!
1463
             pRequest->requestId);
1464
    pRequest->code = code;
84,603✔
1465
    returnToUser(pRequest);
84,603✔
1466
  }
1467
}
1468

1469
static int32_t getAllMetaAsync(SSqlCallbackWrapper *pWrapper, catalogCallback fp) {
1,498,786✔
1470
  SRequestConnInfo conn = {.pTrans = pWrapper->pParseCtx->pTransporter,
1,498,786✔
1471
                           .requestId = pWrapper->pParseCtx->requestId,
1,498,786✔
1472
                           .requestObjRefId = pWrapper->pParseCtx->requestRid,
1,498,786✔
1473
                           .mgmtEps = pWrapper->pParseCtx->mgmtEpSet};
1,498,786✔
1474

1475
  pWrapper->pRequest->metric.ctgStart = taosGetTimestampUs();
1,498,786✔
1476

1477
  return catalogAsyncGetAllMeta(pWrapper->pParseCtx->pCatalog, &conn, pWrapper->pCatalogReq, fp, pWrapper,
2,997,842✔
1478
                                &pWrapper->pRequest->body.queryJob);
1,498,998✔
1479
}
1480

1481
static void doAsyncQueryFromParse(SMetaData *pResultMeta, void *param, int32_t code);
1482

1483
static int32_t phaseAsyncQuery(SSqlCallbackWrapper *pWrapper) {
11,583,298✔
1484
  int32_t code = TSDB_CODE_SUCCESS;
11,583,298✔
1485
  switch (pWrapper->pRequest->pQuery->execStage) {
11,583,298!
1486
    case QUERY_EXEC_STAGE_PARSE: {
95,814✔
1487
      // continue parse after get metadata
1488
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromParse);
95,814✔
1489
      break;
95,815✔
1490
    }
1491
    case QUERY_EXEC_STAGE_ANALYSE: {
1,403,118✔
1492
      // analysis after get metadata
1493
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromAnalyse);
1,403,118✔
1494
      break;
1,403,134✔
1495
    }
1496
    case QUERY_EXEC_STAGE_SCHEDULE: {
10,098,756✔
1497
      launchAsyncQuery(pWrapper->pRequest, pWrapper->pRequest->pQuery, NULL, pWrapper);
10,098,756✔
1498
      break;
10,097,729✔
1499
    }
1500
    default:
×
1501
      break;
×
1502
  }
1503
  return code;
11,582,288✔
1504
}
1505

1506
static void doAsyncQueryFromParse(SMetaData *pResultMeta, void *param, int32_t code) {
95,816✔
1507
  SSqlCallbackWrapper *pWrapper = (SSqlCallbackWrapper *)param;
95,816✔
1508
  SRequestObj         *pRequest = pWrapper->pRequest;
95,816✔
1509
  SQuery              *pQuery = pRequest->pQuery;
95,816✔
1510

1511
  pRequest->metric.ctgCostUs += taosGetTimestampUs() - pRequest->metric.ctgStart;
95,815✔
1512
  qDebug("req:0x%" PRIx64 ", continue parse query, QID:0x%" PRIx64 ", code:%s", pRequest->self, pRequest->requestId,
95,815✔
1513
         tstrerror(code));
1514

1515
  if (code == TSDB_CODE_SUCCESS) {
95,815✔
1516
    // pWrapper->pCatalogReq->forceUpdate = false;
1517
    code = qContinueParseSql(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
95,382✔
1518
  }
1519

1520
  if (TSDB_CODE_SUCCESS == code) {
95,808✔
1521
    code = phaseAsyncQuery(pWrapper);
83,418✔
1522
  }
1523

1524
  if (TSDB_CODE_SUCCESS != code) {
95,811✔
1525
    tscError("req:0x%" PRIx64 ", error happens, code:%d - %s, QID:0x%" PRIx64, pWrapper->pRequest->self, code,
12,391!
1526
             tstrerror(code), pWrapper->pRequest->requestId);
1527
    destorySqlCallbackWrapper(pWrapper);
12,392✔
1528
    pRequest->pWrapper = NULL;
12,392✔
1529
    terrno = code;
12,392✔
1530
    pRequest->code = code;
12,391✔
1531
    doRequestCallback(pRequest, code);
12,391✔
1532
  }
1533
}
95,812✔
1534

1535
void continueInsertFromCsv(SSqlCallbackWrapper *pWrapper, SRequestObj *pRequest) {
22✔
1536
  int32_t code = qParseSqlSyntax(pWrapper->pParseCtx, &pRequest->pQuery, pWrapper->pCatalogReq);
22✔
1537
  if (TSDB_CODE_SUCCESS == code) {
22!
1538
    code = phaseAsyncQuery(pWrapper);
22✔
1539
  }
1540

1541
  if (TSDB_CODE_SUCCESS != code) {
22!
1542
    tscError("req:0x%" PRIx64 ", error happens, code:%d - %s, QID:0x%" PRIx64, pWrapper->pRequest->self, code,
×
1543
             tstrerror(code), pWrapper->pRequest->requestId);
1544
    destorySqlCallbackWrapper(pWrapper);
×
1545
    pRequest->pWrapper = NULL;
×
1546
    terrno = code;
×
1547
    pRequest->code = code;
×
1548
    doRequestCallback(pRequest, code);
×
1549
  }
1550
}
22✔
1551

1552
void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param) {
522✔
1553
  int64_t connId = *(int64_t *)taos;
522✔
1554
  taosAsyncQueryImpl(connId, sql, fp, param, false, TD_REQ_FROM_APP);
522✔
1555
}
522✔
1556

1557
void taos_query_a_with_reqid(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param, int64_t reqid) {
×
1558
  int64_t connId = *(int64_t *)taos;
×
1559
  taosAsyncQueryImplWithReqid(connId, sql, fp, param, false, reqid);
×
1560
}
×
1561

1562
int32_t createParseContext(const SRequestObj *pRequest, SParseContext **pCxt, SSqlCallbackWrapper *pWrapper) {
11,597,743✔
1563
  const STscObj *pTscObj = pRequest->pTscObj;
11,597,743✔
1564

1565
  *pCxt = taosMemoryCalloc(1, sizeof(SParseContext));
11,597,743!
1566
  if (*pCxt == NULL) {
11,603,134!
1567
    return terrno;
×
1568
  }
1569

1570
  **pCxt = (SParseContext){.requestId = pRequest->requestId,
11,603,134✔
1571
                           .requestRid = pRequest->self,
11,603,134✔
1572
                           .acctId = pTscObj->acctId,
11,603,134✔
1573
                           .db = pRequest->pDb,
11,603,134✔
1574
                           .topicQuery = false,
1575
                           .pSql = pRequest->sqlstr,
11,603,134✔
1576
                           .sqlLen = pRequest->sqlLen,
11,603,134✔
1577
                           .pMsg = pRequest->msgBuf,
11,603,134✔
1578
                           .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE,
1579
                           .pTransporter = pTscObj->pAppInfo->pTransporter,
11,603,134✔
1580
                           .pStmtCb = NULL,
1581
                           .pUser = pTscObj->user,
11,603,134✔
1582
                           .pEffectiveUser = pRequest->effectiveUser,
11,603,134✔
1583
                           .isSuperUser = (0 == strcmp(pTscObj->user, TSDB_DEFAULT_USER)),
11,603,134✔
1584
                           .enableSysInfo = pTscObj->sysInfo,
11,603,134✔
1585
                           .async = true,
1586
                           .svrVer = pTscObj->sVer,
11,603,134✔
1587
                           .nodeOffline = (pTscObj->pAppInfo->onlineDnodes < pTscObj->pAppInfo->totalDnodes),
11,603,134✔
1588
                           .allocatorId = pRequest->allocatorRefId,
11,603,134✔
1589
                           .parseSqlFp = clientParseSql,
1590
                           .parseSqlParam = pWrapper,
1591
                           .setQueryFp = setQueryRequest,
1592
                           .timezone = pTscObj->optionInfo.timezone,
11,603,134✔
1593
                           .charsetCxt = pTscObj->optionInfo.charsetCxt,
11,603,134✔
1594
                           .streamRunHistory = pRequest->streamRunHistory};
11,603,134✔
1595
  int8_t biMode = atomic_load_8(&((STscObj *)pTscObj)->biMode);
11,603,134✔
1596
  (*pCxt)->biMode = biMode;
11,605,859✔
1597
  return TSDB_CODE_SUCCESS;
11,605,859✔
1598
}
1599

1600
int32_t prepareAndParseSqlSyntax(SSqlCallbackWrapper **ppWrapper, SRequestObj *pRequest, bool updateMetaForce) {
11,592,831✔
1601
  int32_t              code = TSDB_CODE_SUCCESS;
11,592,831✔
1602
  STscObj             *pTscObj = pRequest->pTscObj;
11,592,831✔
1603
  SSqlCallbackWrapper *pWrapper = taosMemoryCalloc(1, sizeof(SSqlCallbackWrapper));
11,592,831!
1604
  if (pWrapper == NULL) {
11,608,842!
1605
    code = terrno;
×
1606
  } else {
1607
    pWrapper->pRequest = pRequest;
11,608,842✔
1608
    pRequest->pWrapper = pWrapper;
11,608,842✔
1609
    *ppWrapper = pWrapper;
11,608,842✔
1610
  }
1611

1612
  if (TSDB_CODE_SUCCESS == code) {
11,608,842!
1613
    code = createParseContext(pRequest, &pWrapper->pParseCtx, pWrapper);
11,610,359✔
1614
  }
1615

1616
  if (TSDB_CODE_SUCCESS == code) {
11,603,742!
1617
    pWrapper->pParseCtx->mgmtEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
11,605,604✔
1618
    code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pWrapper->pParseCtx->pCatalog);
11,618,420✔
1619
  }
1620

1621
  if (TSDB_CODE_SUCCESS == code && NULL == pRequest->pQuery) {
11,599,292✔
1622
    int64_t syntaxStart = taosGetTimestampUs();
11,577,464✔
1623

1624
    pWrapper->pCatalogReq = taosMemoryCalloc(1, sizeof(SCatalogReq));
11,577,464!
1625
    if (pWrapper->pCatalogReq == NULL) {
11,608,478!
1626
      code = terrno;
×
1627
    } else {
1628
      pWrapper->pCatalogReq->forceUpdate = updateMetaForce;
11,608,478✔
1629
      TSC_ERR_RET(qnodeRequired(pRequest, &pWrapper->pCatalogReq->qNodeRequired));
11,608,478!
1630
      code = qParseSqlSyntax(pWrapper->pParseCtx, &pRequest->pQuery, pWrapper->pCatalogReq);
11,608,052✔
1631
    }
1632

1633
    pRequest->metric.parseCostUs += taosGetTimestampUs() - syntaxStart;
11,526,333✔
1634
  }
1635

1636
  return code;
11,550,034✔
1637
}
1638

1639
void doAsyncQuery(SRequestObj *pRequest, bool updateMetaForce) {
11,602,861✔
1640
  SSqlCallbackWrapper *pWrapper = NULL;
11,602,861✔
1641
  int32_t              code = TSDB_CODE_SUCCESS;
11,602,861✔
1642

1643
  if (pRequest->retry++ > REQUEST_TOTAL_EXEC_TIMES) {
11,602,861✔
1644
    code = pRequest->prevCode;
6,076✔
1645
    terrno = code;
6,076✔
1646
    pRequest->code = code;
6,076✔
1647
    tscDebug("req:0x%" PRIx64 ", call sync query cb with code:%s", pRequest->self, tstrerror(code));
6,076✔
1648
    doRequestCallback(pRequest, code);
6,076✔
1649
    return;
6,121✔
1650
  }
1651

1652
  if (TSDB_CODE_SUCCESS == code) {
11,596,785✔
1653
    code = prepareAndParseSqlSyntax(&pWrapper, pRequest, updateMetaForce);
11,595,468✔
1654
  }
1655

1656
  if (TSDB_CODE_SUCCESS == code) {
11,553,353✔
1657
    pRequest->stmtType = pRequest->pQuery->pRoot->type;
11,510,410✔
1658
    code = phaseAsyncQuery(pWrapper);
11,510,410✔
1659
  }
1660

1661
  if (TSDB_CODE_SUCCESS != code) {
11,555,699✔
1662
    tscError("req:0x%" PRIx64 ", error happens, code:%d - %s, QID:0x%" PRIx64, pRequest->self, code, tstrerror(code),
48,641!
1663
             pRequest->requestId);
1664
    destorySqlCallbackWrapper(pWrapper);
48,641✔
1665
    pRequest->pWrapper = NULL;
48,641✔
1666
    qDestroyQuery(pRequest->pQuery);
48,641✔
1667
    pRequest->pQuery = NULL;
48,641✔
1668

1669
    if (NEED_CLIENT_HANDLE_ERROR(code)) {
48,641!
1670
      tscDebug("req:0x%" PRIx64 ", client retry to handle the error, code:%d - %s, tryCount:%d, QID:0x%" PRIx64,
45✔
1671
               pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId);
1672
      code = refreshMeta(pRequest->pTscObj, pRequest);
45✔
1673
      if (code != 0) {
45!
1674
        tscWarn("req:0x%" PRIx64 ", refresh meta failed, code:%d - %s, QID:0x%" PRIx64, pRequest->self, code, tstrerror(code),
45!
1675
                pRequest->requestId);
1676
      }
1677
      pRequest->prevCode = code;
45✔
1678
      doAsyncQuery(pRequest, true);
45✔
1679
      return;
45✔
1680
    }
1681

1682
    terrno = code;
48,596✔
1683
    pRequest->code = code;
48,596✔
1684
    doRequestCallback(pRequest, code);
48,596✔
1685
  }
1686
}
1687

1688
void restartAsyncQuery(SRequestObj *pRequest, int32_t code) {
18,597✔
1689
  tscInfo("restart request:%s p:%p", pRequest->sqlstr, pRequest);
18,597!
1690
  SRequestObj *pUserReq = pRequest;
18,597✔
1691
  (void)acquireRequest(pRequest->self);
18,597✔
1692
  while (pUserReq) {
18,619!
1693
    if (pUserReq->self == pUserReq->relation.userRefId || pUserReq->relation.userRefId == 0) {
18,619!
1694
      break;
1695
    } else {
1696
      int64_t nextRefId = pUserReq->relation.nextRefId;
22✔
1697
      (void)releaseRequest(pUserReq->self);
22✔
1698
      if (nextRefId) {
22!
1699
        pUserReq = acquireRequest(nextRefId);
22✔
1700
      }
1701
    }
1702
  }
1703
  bool hasSubRequest = pUserReq != pRequest || pRequest->relation.prevRefId != 0;
18,597!
1704
  if (pUserReq) {
18,597!
1705
    destroyCtxInRequest(pUserReq);
18,597✔
1706
    pUserReq->prevCode = code;
18,597✔
1707
    (void)memset(&pUserReq->relation, 0, sizeof(pUserReq->relation));
18,597✔
1708
  } else {
1709
    tscError("User req is missing");
×
1710
    (void)removeFromMostPrevReq(pRequest);
×
1711
    return;
×
1712
  }
1713
  if (hasSubRequest)
18,597✔
1714
    (void)removeFromMostPrevReq(pRequest);
22✔
1715
  else
1716
    (void)releaseRequest(pUserReq->self);
18,575✔
1717
  doAsyncQuery(pUserReq, true);
18,597✔
1718
}
1719

1720
typedef struct SAsyncFetchParam {
1721
  SRequestObj      *pReq;
1722
  __taos_async_fn_t fp;
1723
  void             *param;
1724
} SAsyncFetchParam;
1725

1726
static int32_t doAsyncFetch(void *pParam) {
1,153,753✔
1727
  SAsyncFetchParam *param = pParam;
1,153,753✔
1728
  taosAsyncFetchImpl(param->pReq, param->fp, param->param);
1,153,753✔
1729
  taosMemoryFree(param);
1,153,745!
1730
  return TSDB_CODE_SUCCESS;
1,153,745✔
1731
}
1732

1733
void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
1,153,746✔
1734
  if (res == NULL || fp == NULL) {
1,153,746!
1735
    tscError("taos_fetch_rows_a invalid paras");
×
1736
    return;
×
1737
  }
1738
  if (!TD_RES_QUERY(res)) {
1,153,755!
1739
    tscError("taos_fetch_rows_a res is NULL");
×
1740
    fp(param, res, TSDB_CODE_APP_ERROR);
×
1741
    return;
×
1742
  }
1743

1744
  SRequestObj *pRequest = res;
1,153,755✔
1745
  if (TSDB_SQL_RETRIEVE_EMPTY_RESULT == pRequest->type) {
1,153,755✔
1746
    fp(param, res, 0);
10✔
1747
    return;
10✔
1748
  }
1749

1750
  SAsyncFetchParam *pParam = taosMemoryCalloc(1, sizeof(SAsyncFetchParam));
1,153,745!
1751
  if (!pParam) {
1,153,752!
1752
    fp(param, res, terrno);
×
1753
    return;
×
1754
  }
1755
  pParam->pReq = pRequest;
1,153,752✔
1756
  pParam->fp = fp;
1,153,752✔
1757
  pParam->param = param;
1,153,752✔
1758
  int32_t code = taosAsyncExec(doAsyncFetch, pParam, NULL);
1,153,752✔
1759
  if (TSDB_CODE_SUCCESS != code) {
1,153,751!
1760
    taosMemoryFree(pParam);
×
1761
    fp(param, res, code);
×
1762
    return;
×
1763
  }
1764
}
1765

1766
void taos_fetch_raw_block_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
4✔
1767
  if (res == NULL || fp == NULL) {
4!
1768
    tscError("taos_fetch_raw_block_a invalid paras");
×
1769
    return;
×
1770
  }
1771
  if (!TD_RES_QUERY(res)) {
4!
1772
    tscError("taos_fetch_raw_block_a res is NULL");
×
1773
    return;
×
1774
  }
1775
  SRequestObj    *pRequest = res;
4✔
1776
  SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
4✔
1777

1778
  // set the current block is all consumed
1779
  pResultInfo->convertUcs4 = false;
4✔
1780

1781
  // it is a local executed query, no need to do async fetch
1782
  taos_fetch_rows_a(pRequest, fp, param);
4✔
1783
}
1784

1785
const void *taos_get_raw_block(TAOS_RES *res) {
×
1786
  if (res == NULL) {
×
1787
    tscError("taos_get_raw_block invalid paras");
×
1788
    return NULL;
×
1789
  }
1790
  if (!TD_RES_QUERY(res)) {
×
1791
    tscError("taos_get_raw_block res is NULL");
×
1792
    return NULL;
×
1793
  }
1794
  SRequestObj *pRequest = res;
×
1795

1796
  return pRequest->body.resInfo.pData;
×
1797
}
1798

1799
int taos_get_db_route_info(TAOS *taos, const char *db, TAOS_DB_ROUTE_INFO *dbInfo) {
2✔
1800
  if (NULL == taos) {
2!
1801
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1802
    return terrno;
×
1803
  }
1804

1805
  if (NULL == db || NULL == dbInfo) {
2!
1806
    tscError("invalid input param, db:%p, dbInfo:%p", db, dbInfo);
×
1807
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1808
    return terrno;
×
1809
  }
1810

1811
  int64_t      connId = *(int64_t *)taos;
2✔
1812
  SRequestObj *pRequest = NULL;
2✔
1813
  char        *sql = "taos_get_db_route_info";
2✔
1814
  int32_t      code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
2✔
1815
  if (code != TSDB_CODE_SUCCESS) {
2!
1816
    terrno = code;
×
1817
    return terrno;
×
1818
  }
1819

1820
  STscObj  *pTscObj = pRequest->pTscObj;
2✔
1821
  SCatalog *pCtg = NULL;
2✔
1822
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
2✔
1823
  if (code != TSDB_CODE_SUCCESS) {
2!
1824
    goto _return;
×
1825
  }
1826

1827
  SRequestConnInfo conn = {
2✔
1828
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
2✔
1829

1830
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
2✔
1831

1832
  char dbFName[TSDB_DB_FNAME_LEN] = {0};
2✔
1833
  (void)snprintf(dbFName, sizeof(dbFName), "%d.%s", pTscObj->acctId, db);
2✔
1834

1835
  code = catalogGetDBVgInfo(pCtg, &conn, dbFName, dbInfo);
2✔
1836
  if (code) {
2!
1837
    goto _return;
×
1838
  }
1839

1840
_return:
2✔
1841

1842
  terrno = code;
2✔
1843

1844
  destroyRequest(pRequest);
2✔
1845
  return code;
2✔
1846
}
1847

1848
int taos_get_table_vgId(TAOS *taos, const char *db, const char *table, int *vgId) {
200✔
1849
  if (NULL == taos) {
200!
1850
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1851
    return terrno;
×
1852
  }
1853

1854
  if (NULL == db || NULL == table || NULL == vgId) {
200!
1855
    tscError("invalid input param, db:%p, table:%p, vgId:%p", db, table, vgId);
×
1856
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1857
    return terrno;
×
1858
  }
1859

1860
  int64_t      connId = *(int64_t *)taos;
200✔
1861
  SRequestObj *pRequest = NULL;
200✔
1862
  char        *sql = "taos_get_table_vgId";
200✔
1863
  int32_t      code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
200✔
1864
  if (code != TSDB_CODE_SUCCESS) {
200!
1865
    return terrno;
×
1866
  }
1867

1868
  pRequest->syncQuery = true;
200✔
1869

1870
  STscObj  *pTscObj = pRequest->pTscObj;
200✔
1871
  SCatalog *pCtg = NULL;
200✔
1872
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
200✔
1873
  if (code != TSDB_CODE_SUCCESS) {
200!
1874
    goto _return;
×
1875
  }
1876

1877
  SRequestConnInfo conn = {
200✔
1878
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
200✔
1879

1880
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
200✔
1881

1882
  SName tableName = {0};
200✔
1883
  toName(pTscObj->acctId, db, table, &tableName);
200✔
1884

1885
  SVgroupInfo vgInfo;
1886
  code = catalogGetTableHashVgroup(pCtg, &conn, &tableName, &vgInfo);
200✔
1887
  if (code) {
200!
1888
    goto _return;
×
1889
  }
1890

1891
  *vgId = vgInfo.vgId;
200✔
1892

1893
_return:
200✔
1894

1895
  terrno = code;
200✔
1896

1897
  destroyRequest(pRequest);
200✔
1898
  return code;
200✔
1899
}
1900

1901
int taos_get_tables_vgId(TAOS *taos, const char *db, const char *table[], int tableNum, int *vgId) {
1✔
1902
  if (NULL == taos) {
1!
1903
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1904
    return terrno;
×
1905
  }
1906

1907
  if (NULL == db || NULL == table || NULL == vgId || tableNum <= 0) {
1!
1908
    tscError("invalid input param, db:%p, table:%p, vgId:%p, tbNum:%d", db, table, vgId, tableNum);
×
1909
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1910
    return terrno;
×
1911
  }
1912

1913
  int64_t      connId = *(int64_t *)taos;
1✔
1914
  SRequestObj *pRequest = NULL;
1✔
1915
  char        *sql = "taos_get_table_vgId";
1✔
1916
  int32_t      code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
1✔
1917
  if (code != TSDB_CODE_SUCCESS) {
1!
1918
    return terrno;
×
1919
  }
1920

1921
  pRequest->syncQuery = true;
1✔
1922

1923
  STscObj  *pTscObj = pRequest->pTscObj;
1✔
1924
  SCatalog *pCtg = NULL;
1✔
1925
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
1✔
1926
  if (code != TSDB_CODE_SUCCESS) {
1!
1927
    goto _return;
×
1928
  }
1929

1930
  SRequestConnInfo conn = {
1✔
1931
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
1✔
1932

1933
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
1✔
1934

1935
  code = catalogGetTablesHashVgId(pCtg, &conn, pTscObj->acctId, db, table, tableNum, vgId);
1✔
1936
  if (code) {
1!
1937
    goto _return;
×
1938
  }
1939

1940
_return:
1✔
1941

1942
  terrno = code;
1✔
1943

1944
  destroyRequest(pRequest);
1✔
1945
  return code;
1✔
1946
}
1947

1948
int taos_load_table_info(TAOS *taos, const char *tableNameList) {
4✔
1949
  if (NULL == taos) {
4!
1950
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1951
    return terrno;
×
1952
  }
1953

1954
  int64_t       connId = *(int64_t *)taos;
4✔
1955
  const int32_t MAX_TABLE_NAME_LENGTH = 12 * 1024 * 1024;  // 12MB list
4✔
1956
  int32_t       code = 0;
4✔
1957
  SRequestObj  *pRequest = NULL;
4✔
1958
  SCatalogReq   catalogReq = {0};
4✔
1959

1960
  if (NULL == tableNameList) {
4!
1961
    return TSDB_CODE_SUCCESS;
×
1962
  }
1963

1964
  int32_t length = (int32_t)strlen(tableNameList);
4✔
1965
  if (0 == length) {
4!
1966
    return TSDB_CODE_SUCCESS;
×
1967
  } else if (length > MAX_TABLE_NAME_LENGTH) {
4!
1968
    tscError("tableNameList too long, length:%d, maximum allowed:%d", length, MAX_TABLE_NAME_LENGTH);
×
1969
    return TSDB_CODE_TSC_INVALID_OPERATION;
×
1970
  }
1971

1972
  char *sql = "taos_load_table_info";
4✔
1973
  code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
4✔
1974
  if (code != TSDB_CODE_SUCCESS) {
4!
1975
    terrno = code;
×
1976
    goto _return;
×
1977
  }
1978

1979
  pRequest->syncQuery = true;
4✔
1980

1981
  STscObj *pTscObj = pRequest->pTscObj;
4✔
1982
  code = transferTableNameList(tableNameList, pTscObj->acctId, pTscObj->db, &catalogReq.pTableMeta);
4✔
1983
  if (code) {
4!
1984
    goto _return;
×
1985
  }
1986

1987
  SCatalog *pCtg = NULL;
4✔
1988
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
4✔
1989
  if (code != TSDB_CODE_SUCCESS) {
4!
1990
    goto _return;
×
1991
  }
1992

1993
  SRequestConnInfo conn = {
4✔
1994
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
4✔
1995

1996
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
4✔
1997

1998
  code = catalogAsyncGetAllMeta(pCtg, &conn, &catalogReq, syncCatalogFn, pRequest->body.interParam, NULL);
4✔
1999
  if (code) {
4!
2000
    goto _return;
×
2001
  }
2002

2003
  SSyncQueryParam *pParam = pRequest->body.interParam;
4✔
2004
  code = tsem_wait(&pParam->sem);
4✔
2005
  if (code) {
4!
2006
    tscError("tsem wait failed, code:%d - %s", code, tstrerror(code));
×
2007
    goto _return;
×
2008
  }
2009
_return:
4✔
2010
  destoryCatalogReq(&catalogReq);
4✔
2011
  destroyRequest(pRequest);
4✔
2012
  return code;
4✔
2013
}
2014

2015
TAOS_STMT *taos_stmt_init(TAOS *taos) {
657✔
2016
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
657✔
2017
  if (NULL == pObj) {
660!
2018
    tscError("invalid parameter for %s", __FUNCTION__);
×
2019
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
2020
    return NULL;
×
2021
  }
2022

2023
  TAOS_STMT *pStmt = stmtInit(pObj, 0, NULL);
660✔
2024
  if (NULL == pStmt) {
658!
2025
    tscError("stmt init failed, errcode:%s", terrstr());
×
2026
  }
2027
  releaseTscObj(*(int64_t *)taos);
658✔
2028

2029
  return pStmt;
660✔
2030
}
2031

2032
TAOS_STMT *taos_stmt_init_with_reqid(TAOS *taos, int64_t reqid) {
×
2033
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
×
2034
  if (NULL == pObj) {
×
2035
    tscError("invalid parameter for %s", __FUNCTION__);
×
2036
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
2037
    return NULL;
×
2038
  }
2039

2040
  TAOS_STMT *pStmt = stmtInit(pObj, reqid, NULL);
×
2041
  if (NULL == pStmt) {
×
2042
    tscError("stmt init failed, errcode:%s", terrstr());
×
2043
  }
2044
  releaseTscObj(*(int64_t *)taos);
×
2045

2046
  return pStmt;
×
2047
}
2048

2049
TAOS_STMT *taos_stmt_init_with_options(TAOS *taos, TAOS_STMT_OPTIONS *options) {
134✔
2050
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
134✔
2051
  if (NULL == pObj) {
134!
2052
    tscError("invalid parameter for %s", __FUNCTION__);
×
2053
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
2054
    return NULL;
×
2055
  }
2056

2057
  TAOS_STMT *pStmt = stmtInit(pObj, options->reqId, options);
134✔
2058
  if (NULL == pStmt) {
134!
2059
    tscError("stmt init failed, errcode:%s", terrstr());
×
2060
  }
2061
  releaseTscObj(*(int64_t *)taos);
134✔
2062

2063
  return pStmt;
134✔
2064
}
2065

2066
int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length) {
20,764✔
2067
  if (stmt == NULL || sql == NULL) {
20,764!
2068
    tscError("NULL parameter for %s", __FUNCTION__);
×
2069
    terrno = TSDB_CODE_INVALID_PARA;
×
2070
    return terrno;
×
2071
  }
2072

2073
  return stmtPrepare(stmt, sql, length);
20,772✔
2074
}
2075

2076
int taos_stmt_set_tbname_tags(TAOS_STMT *stmt, const char *name, TAOS_MULTI_BIND *tags) {
12✔
2077
  if (stmt == NULL || name == NULL) {
12!
2078
    tscError("NULL parameter for %s", __FUNCTION__);
×
2079
    terrno = TSDB_CODE_INVALID_PARA;
×
2080
    return terrno;
×
2081
  }
2082

2083
  int32_t code = stmtSetTbName(stmt, name);
12✔
2084
  if (code) {
12✔
2085
    return code;
1✔
2086
  }
2087

2088
  if (tags) {
11!
2089
    return stmtSetTbTags(stmt, tags);
11✔
2090
  }
2091

2092
  return TSDB_CODE_SUCCESS;
×
2093
}
2094

2095
int taos_stmt_set_tbname(TAOS_STMT *stmt, const char *name) {
91,153✔
2096
  if (stmt == NULL || name == NULL) {
91,153!
2097
    tscError("NULL parameter for %s", __FUNCTION__);
×
2098
    terrno = TSDB_CODE_INVALID_PARA;
×
2099
    return terrno;
×
2100
  }
2101

2102
  return stmtSetTbName(stmt, name);
91,184✔
2103
}
2104

2105
int taos_stmt_set_tags(TAOS_STMT *stmt, TAOS_MULTI_BIND *tags) {
4✔
2106
  if (stmt == NULL || tags == NULL) {
4!
2107
    tscError("NULL parameter for %s", __FUNCTION__);
×
2108
    terrno = TSDB_CODE_INVALID_PARA;
×
2109
    return terrno;
×
2110
  }
2111

2112
  return stmtSetTbTags(stmt, tags);
4✔
2113
}
2114

2115
int taos_stmt_set_sub_tbname(TAOS_STMT *stmt, const char *name) { return taos_stmt_set_tbname(stmt, name); }
2✔
2116

2117
int taos_stmt_get_tag_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields) {
4✔
2118
  if (stmt == NULL || NULL == fieldNum) {
4!
2119
    tscError("NULL parameter for %s", __FUNCTION__);
×
2120
    terrno = TSDB_CODE_INVALID_PARA;
×
2121
    return terrno;
×
2122
  }
2123

2124
  return stmtGetTagFields(stmt, fieldNum, fields);
4✔
2125
}
2126

2127
int taos_stmt_get_col_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields) {
152✔
2128
  if (stmt == NULL || NULL == fieldNum) {
152!
2129
    tscError("NULL parameter for %s", __FUNCTION__);
×
2130
    terrno = TSDB_CODE_INVALID_PARA;
×
2131
    return terrno;
×
2132
  }
2133

2134
  return stmtGetColFields(stmt, fieldNum, fields);
152✔
2135
}
2136

2137
// let stmt to reclaim TAOS_FIELD_E that was allocated by `taos_stmt_get_tag_fields`/`taos_stmt_get_col_fields`
2138
void taos_stmt_reclaim_fields(TAOS_STMT *stmt, TAOS_FIELD_E *fields) {
×
2139
  (void)stmt;
2140
  if (!fields) return;
×
2141
  taosMemoryFree(fields);
×
2142
}
2143

2144
int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
117✔
2145
  if (stmt == NULL || bind == NULL) {
117!
2146
    tscError("NULL parameter for %s", __FUNCTION__);
×
2147
    terrno = TSDB_CODE_INVALID_PARA;
×
2148
    return terrno;
×
2149
  }
2150

2151
  if (bind->num > 1) {
117!
2152
    tscError("invalid bind number %d for %s", bind->num, __FUNCTION__);
×
2153
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
2154
    return terrno;
×
2155
  }
2156

2157
  return stmtBindBatch(stmt, bind, -1);
117✔
2158
}
2159

2160
int taos_stmt_bind_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
1,111,436✔
2161
  if (stmt == NULL || bind == NULL) {
1,111,436!
2162
    tscError("NULL parameter for %s", __FUNCTION__);
×
2163
    terrno = TSDB_CODE_INVALID_PARA;
×
2164
    return terrno;
×
2165
  }
2166

2167
  if (bind->num <= 0 || bind->num > INT16_MAX) {
1,111,803!
2168
    tscError("invalid bind num %d", bind->num);
184!
2169
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
184✔
2170
    return terrno;
×
2171
  }
2172

2173
  int32_t insert = 0;
1,111,619✔
2174
  int32_t code = stmtIsInsert(stmt, &insert);
1,111,619✔
2175
  if (TSDB_CODE_SUCCESS != code) {
1,106,980!
2176
    tscError("stmt insert failed, errcode:%s", tstrerror(code));
×
2177
    return code;
×
2178
  }
2179
  if (0 == insert && bind->num > 1) {
1,106,980!
2180
    tscError("only one row data allowed for query");
×
2181
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
2182
    return terrno;
×
2183
  }
2184

2185
  return stmtBindBatch(stmt, bind, -1);
1,106,980✔
2186
}
2187

2188
int taos_stmt_bind_single_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int colIdx) {
450✔
2189
  if (stmt == NULL || bind == NULL) {
450!
2190
    tscError("NULL parameter for %s", __FUNCTION__);
×
2191
    terrno = TSDB_CODE_INVALID_PARA;
×
2192
    return terrno;
×
2193
  }
2194

2195
  if (colIdx < 0) {
450!
2196
    tscError("invalid bind column idx %d", colIdx);
×
2197
    terrno = TSDB_CODE_INVALID_PARA;
×
2198
    return terrno;
×
2199
  }
2200

2201
  int32_t insert = 0;
450✔
2202
  int32_t code = stmtIsInsert(stmt, &insert);
450✔
2203
  if (TSDB_CODE_SUCCESS != code) {
450!
2204
    tscError("stmt insert failed, errcode:%s", tstrerror(code));
×
2205
    return code;
×
2206
  }
2207
  if (0 == insert && bind->num > 1) {
450!
2208
    tscError("only one row data allowed for query");
×
2209
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
2210
    return terrno;
×
2211
  }
2212

2213
  return stmtBindBatch(stmt, bind, colIdx);
450✔
2214
}
2215

2216
int taos_stmt_add_batch(TAOS_STMT *stmt) {
1,058,657✔
2217
  if (stmt == NULL) {
1,058,657!
2218
    tscError("NULL parameter for %s", __FUNCTION__);
×
2219
    terrno = TSDB_CODE_INVALID_PARA;
×
2220
    return terrno;
×
2221
  }
2222

2223
  return stmtAddBatch(stmt);
1,058,657✔
2224
}
2225

2226
int taos_stmt_execute(TAOS_STMT *stmt) {
58,723✔
2227
  if (stmt == NULL) {
58,723!
2228
    tscError("NULL parameter for %s", __FUNCTION__);
×
2229
    terrno = TSDB_CODE_INVALID_PARA;
×
2230
    return terrno;
×
2231
  }
2232

2233
  return stmtExec(stmt);
58,723✔
2234
}
2235

2236
int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert) {
6✔
2237
  if (stmt == NULL || insert == NULL) {
6!
2238
    tscError("NULL parameter for %s", __FUNCTION__);
×
2239
    terrno = TSDB_CODE_INVALID_PARA;
×
2240
    return terrno;
×
2241
  }
2242

2243
  return stmtIsInsert(stmt, insert);
6✔
2244
}
2245

2246
int taos_stmt_num_params(TAOS_STMT *stmt, int *nums) {
×
2247
  if (stmt == NULL || nums == NULL) {
×
2248
    tscError("NULL parameter for %s", __FUNCTION__);
×
2249
    terrno = TSDB_CODE_INVALID_PARA;
×
2250
    return terrno;
×
2251
  }
2252

2253
  return stmtGetParamNum(stmt, nums);
×
2254
}
2255

2256
int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) {
906✔
2257
  if (stmt == NULL || type == NULL || NULL == bytes || idx < 0) {
906!
2258
    tscError("invalid parameter for %s", __FUNCTION__);
×
2259
    terrno = TSDB_CODE_INVALID_PARA;
×
2260
    return terrno;
×
2261
  }
2262

2263
  return stmtGetParam(stmt, idx, type, bytes);
906✔
2264
}
2265

2266
TAOS_RES *taos_stmt_use_result(TAOS_STMT *stmt) {
17✔
2267
  if (stmt == NULL) {
17!
2268
    tscError("NULL parameter for %s", __FUNCTION__);
×
2269
    terrno = TSDB_CODE_INVALID_PARA;
×
2270
    return NULL;
×
2271
  }
2272

2273
  return stmtUseResult(stmt);
17✔
2274
}
2275

2276
char *taos_stmt_errstr(TAOS_STMT *stmt) { return (char *)stmtErrstr(stmt); }
6✔
2277

2278
int taos_stmt_affected_rows(TAOS_STMT *stmt) {
8✔
2279
  if (stmt == NULL) {
8!
2280
    tscError("NULL parameter for %s", __FUNCTION__);
×
2281
    terrno = TSDB_CODE_INVALID_PARA;
×
2282
    return 0;
×
2283
  }
2284

2285
  return stmtAffectedRows(stmt);
8✔
2286
}
2287

2288
int taos_stmt_affected_rows_once(TAOS_STMT *stmt) {
28✔
2289
  if (stmt == NULL) {
28!
2290
    tscError("NULL parameter for %s", __FUNCTION__);
×
2291
    terrno = TSDB_CODE_INVALID_PARA;
×
2292
    return 0;
×
2293
  }
2294

2295
  return stmtAffectedRowsOnce(stmt);
28✔
2296
}
2297

2298
int taos_stmt_close(TAOS_STMT *stmt) {
790✔
2299
  if (stmt == NULL) {
790!
2300
    tscError("NULL parameter for %s", __FUNCTION__);
×
2301
    terrno = TSDB_CODE_INVALID_PARA;
×
2302
    return terrno;
×
2303
  }
2304

2305
  return stmtClose(stmt);
790✔
2306
}
2307

2308
TAOS_STMT2 *taos_stmt2_init(TAOS *taos, TAOS_STMT2_OPTION *option) {
151✔
2309
  if (NULL == taos) {
151✔
2310
    tscError("NULL parameter for %s", __FUNCTION__);
1!
2311
    terrno = TSDB_CODE_INVALID_PARA;
1✔
2312
    return NULL;
1✔
2313
  }
2314
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
150✔
2315
  if (NULL == pObj) {
150!
2316
    tscError("invalid parameter for %s", __FUNCTION__);
×
2317
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
2318
    return NULL;
×
2319
  }
2320

2321
  TAOS_STMT2 *pStmt = stmtInit2(pObj, option);
150✔
2322

2323
  releaseTscObj(*(int64_t *)taos);
150✔
2324

2325
  return pStmt;
150✔
2326
}
2327

2328
int taos_stmt2_prepare(TAOS_STMT2 *stmt, const char *sql, unsigned long length) {
171✔
2329
  if (stmt == NULL || sql == NULL) {
171!
2330
    tscError("NULL parameter for %s", __FUNCTION__);
1!
2331
    terrno = TSDB_CODE_INVALID_PARA;
1✔
2332
    return terrno;
1✔
2333
  }
2334

2335
  return stmtPrepare2(stmt, sql, length);
171✔
2336
}
2337

2338
int taos_stmt2_bind_param(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx) {
4,485✔
2339
  if (stmt == NULL) {
4,485!
2340
    tscError("NULL parameter for %s", __FUNCTION__);
×
2341
    terrno = TSDB_CODE_INVALID_PARA;
×
2342
    return terrno;
×
2343
  }
2344

2345
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
4,485✔
2346
  STMT2_DLOG_E("start to bind param");
4,485!
2347
  if (atomic_load_8((int8_t *)&pStmt->asyncBindParam.asyncBindNum) > 1) {
4,485!
2348
    STMT2_ELOG_E("async bind param is still working, please try again later");
×
2349
    return TSDB_CODE_TSC_STMT_API_ERROR;
×
2350
  }
2351

2352
  if (pStmt->options.asyncExecFn && !pStmt->execSemWaited) {
4,484!
2353
    if (tsem_wait(&pStmt->asyncExecSem) != 0) {
12!
2354
      STMT2_ELOG_E("bind param wait asyncExecSem failed");
×
2355
    }
2356
    pStmt->execSemWaited = true;
12✔
2357
  }
2358

2359
  SSHashObj *hashTbnames = tSimpleHashInit(100, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR));
4,484✔
2360
  if (NULL == hashTbnames) {
4,493!
2361
    STMT2_ELOG_E("cannot init hashTbnames for same tbname check");
×
2362
    return terrno;
×
2363
  }
2364

2365
  int32_t code = TSDB_CODE_SUCCESS;
4,493✔
2366
  for (int i = 0; i < bindv->count; ++i) {
10,384✔
2367
    if (bindv->tbnames && bindv->tbnames[i]) {
5,903!
2368
      if (pStmt->sql.stbInterlaceMode) {
5,888✔
2369
        if (tSimpleHashGet(hashTbnames, bindv->tbnames[i], strlen(bindv->tbnames[i])) != NULL) {
5,781!
2370
          code = terrno = TSDB_CODE_PAR_TBNAME_DUPLICATED;
×
2371
          STMT2_ELOG("interlace mode don't support same tbname:%s in one bind", bindv->tbnames[i]);
×
2372
          goto out;
5✔
2373
        }
2374

2375
        code = tSimpleHashPut(hashTbnames, bindv->tbnames[i], strlen(bindv->tbnames[i]), NULL, 0);
5,773✔
2376
        if (code) {
5,773!
2377
          STMT2_ELOG("unexpected error happens, code:%s", tstrerror(code));
×
2378
          goto out;
×
2379
        }
2380
      }
2381

2382
      code = stmtSetTbName2(stmt, bindv->tbnames[i]);
5,880✔
2383
      if (code) {
5,885✔
2384
        STMT2_ELOG("set tbname failed, code:%s", tstrerror(code));
1!
2385
        goto out;
1✔
2386
      }
2387
    }
2388

2389
    SVCreateTbReq *pCreateTbReq = NULL;
5,899✔
2390
    if (bindv->tags && bindv->tags[i]) {
5,899!
2391
      code = stmtSetTbTags2(stmt, bindv->tags[i], &pCreateTbReq);
132✔
2392
    } else if (pStmt->bInfo.tbNameFlag & IS_FIXED_TAG) {
5,767✔
2393
      code = stmtCheckTags2(stmt, &pCreateTbReq);
26✔
2394
    } else {
2395
      if (pStmt->sql.autoCreateTbl) {
5,741✔
2396
        pStmt->sql.autoCreateTbl = false;
3✔
2397
        STMT2_WLOG_E("sql is autoCreateTbl, but no tags");
3!
2398
      }
2399
    }
2400

2401
    if (code) {
5,899✔
2402
      STMT2_ELOG("set tags failed, code:%s", tstrerror(code));
1!
2403
      goto out;
1✔
2404
    }
2405

2406
    if (bindv->bind_cols && bindv->bind_cols[i]) {
5,898!
2407
      TAOS_STMT2_BIND *bind = bindv->bind_cols[i];
5,898✔
2408

2409
      if (bind->num <= 0 || bind->num > INT16_MAX) {
5,898!
2410
        STMT2_ELOG("bind num:%d must > 0 and < INT16_MAX", bind->num);
×
2411
        code = terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
2412
        goto out;
3✔
2413
      }
2414

2415
      int32_t insert = 0;
5,900✔
2416
      (void)stmtIsInsert2(stmt, &insert);
5,900✔
2417
      if (0 == insert && bind->num > 1) {
5,900✔
2418
        STMT2_ELOG_E("only one row data allowed for query");
1!
2419
        code = terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
1✔
2420
        goto out;
1✔
2421
      }
2422

2423
      code = stmtBindBatch2(stmt, bind, col_idx, pCreateTbReq);
5,899✔
2424
      if (TSDB_CODE_SUCCESS != code) {
5,893✔
2425
        STMT2_ELOG("bind batch failed, code:%s", tstrerror(code));
2!
2426
        goto out;
2✔
2427
      }
2428
    }
2429
  }
2430

2431
out:
4,481✔
2432
  tSimpleHashCleanup(hashTbnames);
4,486✔
2433

2434
  return code;
4,489✔
2435
}
2436

2437
int taos_stmt2_bind_param_a(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx, __taos_async_fn_t fp,
×
2438
                            void *param) {
2439
  if (stmt == NULL || bindv == NULL || fp == NULL) {
×
2440
    terrno = TSDB_CODE_INVALID_PARA;
×
2441
    return terrno;
×
2442
  }
2443

2444
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
×
2445

2446
  ThreadArgs *args = (ThreadArgs *)taosMemoryMalloc(sizeof(ThreadArgs));
×
2447
  args->stmt = stmt;
×
2448
  args->bindv = bindv;
×
2449
  args->col_idx = col_idx;
×
2450
  args->fp = fp;
×
2451
  args->param = param;
×
2452

2453
  (void)taosThreadMutexLock(&(pStmt->asyncBindParam.mutex));
×
2454
  if (atomic_load_8((int8_t *)&pStmt->asyncBindParam.asyncBindNum) > 0) {
×
2455
    (void)taosThreadMutexUnlock(&(pStmt->asyncBindParam.mutex));
×
2456
    tscError("async bind param is still working, please try again later");
×
2457
    return TSDB_CODE_TSC_STMT_API_ERROR;
×
2458
  }
2459
  (void)atomic_add_fetch_8(&pStmt->asyncBindParam.asyncBindNum, 1);
×
2460
  (void)taosThreadMutexUnlock(&(pStmt->asyncBindParam.mutex));
×
2461

2462
  int code_s = taosStmt2AsyncBind(stmtAsyncBindThreadFunc, (void *)args);
×
2463
  if (code_s != TSDB_CODE_SUCCESS) {
×
2464
    (void)taosThreadMutexLock(&(pStmt->asyncBindParam.mutex));
×
2465
    (void)taosThreadCondSignal(&(pStmt->asyncBindParam.waitCond));
×
2466
    (void)atomic_sub_fetch_8(&pStmt->asyncBindParam.asyncBindNum, 1);
×
2467
    (void)taosThreadMutexUnlock(&(pStmt->asyncBindParam.mutex));
×
2468
    tscError("async bind failed, code:%d , %s", code_s, tstrerror(code_s));
×
2469
  }
2470

2471
  return code_s;
×
2472
}
2473

2474
int taos_stmt2_exec(TAOS_STMT2 *stmt, int *affected_rows) {
4,478✔
2475
  if (stmt == NULL) {
4,478!
2476
    tscError("NULL parameter for %s", __FUNCTION__);
×
2477
    terrno = TSDB_CODE_INVALID_PARA;
×
2478
    return terrno;
×
2479
  }
2480

2481
  return stmtExec2(stmt, affected_rows);
4,478✔
2482
}
2483

2484
int taos_stmt2_close(TAOS_STMT2 *stmt) {
148✔
2485
  if (stmt == NULL) {
148!
2486
    tscError("NULL parameter for %s", __FUNCTION__);
×
2487
    terrno = TSDB_CODE_INVALID_PARA;
×
2488
    return terrno;
×
2489
  }
2490

2491
  return stmtClose2(stmt);
148✔
2492
}
2493

2494
int taos_stmt2_is_insert(TAOS_STMT2 *stmt, int *insert) {
×
2495
  if (stmt == NULL || insert == NULL) {
×
2496
    tscError("NULL parameter for %s", __FUNCTION__);
×
2497
    terrno = TSDB_CODE_INVALID_PARA;
×
2498
    return terrno;
×
2499
  }
2500

2501
  return stmtIsInsert2(stmt, insert);
×
2502
}
2503

2504
int taos_stmt2_get_fields(TAOS_STMT2 *stmt, int *count, TAOS_FIELD_ALL **fields) {
69✔
2505
  if (stmt == NULL || count == NULL) {
69!
2506
    tscError("NULL parameter for %s", __FUNCTION__);
1!
2507
    terrno = TSDB_CODE_INVALID_PARA;
1✔
2508
    return terrno;
1✔
2509
  }
2510

2511
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
68✔
2512
  if (pStmt->sql.type == 0) {
68✔
2513
    int isInsert = 0;
61✔
2514
    (void)stmtIsInsert2(stmt, &isInsert);
61✔
2515
    if (!isInsert) {
61✔
2516
      pStmt->sql.type = STMT_TYPE_QUERY;
11✔
2517
    }
2518
  }
2519

2520
  if (pStmt->sql.type == STMT_TYPE_QUERY) {
68✔
2521
    return stmtGetParamNum2(stmt, count);
11✔
2522
  }
2523

2524
  return stmtGetStbColFields2(stmt, count, fields);
57✔
2525
}
2526

2527
DLL_EXPORT void taos_stmt2_free_fields(TAOS_STMT2 *stmt, TAOS_FIELD_ALL *fields) {
56✔
2528
  (void)stmt;
2529
  if (!fields) return;
56✔
2530
  taosMemoryFree(fields);
33!
2531
}
2532

2533
TAOS_RES *taos_stmt2_result(TAOS_STMT2 *stmt) {
5✔
2534
  if (stmt == NULL) {
5!
2535
    tscError("NULL parameter for %s", __FUNCTION__);
×
2536
    terrno = TSDB_CODE_INVALID_PARA;
×
2537
    return NULL;
×
2538
  }
2539

2540
  return stmtUseResult2(stmt);
5✔
2541
}
2542

2543
char *taos_stmt2_error(TAOS_STMT2 *stmt) { return (char *)stmtErrstr2(stmt); }
3✔
2544

2545
int taos_set_conn_mode(TAOS *taos, int mode, int value) {
8✔
2546
  if (taos == NULL) {
8!
2547
    terrno = TSDB_CODE_INVALID_PARA;
×
2548
    return terrno;
×
2549
  }
2550

2551
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
8✔
2552
  if (NULL == pObj) {
8!
2553
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
2554
    tscError("invalid parameter for %s", __func__);
×
2555
    return terrno;
×
2556
  }
2557
  switch (mode) {
8!
2558
    case TAOS_CONN_MODE_BI:
8✔
2559
      atomic_store_8(&pObj->biMode, value);
8✔
2560
      break;
8✔
2561
    default:
×
2562
      tscError("not supported mode.");
×
2563
      return TSDB_CODE_INVALID_PARA;
×
2564
  }
2565
  return 0;
8✔
2566
}
2567

2568
char *getBuildInfo() { return td_buildinfo; }
×
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