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

taosdata / TDengine / #4324

18 Jun 2025 07:25AM UTC coverage: 62.916% (-0.2%) from 63.116%
#4324

push

travis-ci

web-flow
docs: add IPv6 support information for taosAdapter (#31362)

158158 of 319881 branches covered (49.44%)

Branch coverage included in aggregate %.

243705 of 318846 relevant lines covered (76.43%)

17827866.93 hits per line

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

52.76
/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,372✔
46
  if (arg == NULL) {
3,372!
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) {
3,372!
52
    if (i % 1000 == 0) {
×
53
      (void)sched_yield();
×
54
    }
55
  }
56

57
  int ret = taos_options_imp(option, (const char *)arg);
3,372✔
58
  atomic_store_32(&lock, 0);
3,372✔
59
  return ret;
3,372✔
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,056✔
69
  pTimezoneMap = taosHashInit(0, MurmurHash3_32, false, HASH_ENTRY_LOCK);
18,056✔
70
  if (pTimezoneMap == NULL) {
18,056!
71
    return terrno;
×
72
  }
73
  taosHashSetFreeFp(pTimezoneMap, freeTz);
18,056✔
74

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

82
void tzCleanup() {
18,057✔
83
  taosHashCleanup(pTimezoneMap);
18,057✔
84
  taosHashCleanup(pTimezoneNameMap);
18,057✔
85
}
18,057✔
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
    SIpRange dualIp = {0};
7✔
206
    if (val != NULL) {
7✔
207
      pObj->optionInfo.userIp = taosInetAddr(val);
5✔
208
      SIpAddr addr = {0};
5✔
209
      code = taosGetIpFromFqdn(tsEnableIpv6, val, &addr);
5✔
210
      if (code == 0) {
5✔
211
        code = tIpStrToUint(&addr, &pObj->optionInfo.userDualIp);
2✔
212
      } 
213
      if (code != 0) {
5✔
214
        tscError("ipv6 flag %d failed to convert user ip %s to dual ip since %s", tsEnableIpv6 ?  1:0, val, tstrerror(code));
3!
215
        pObj->optionInfo.userIp = INADDR_NONE; 
3✔
216
        pObj->optionInfo.userDualIp = dualIp;  
3✔
217
        code = 0;
3✔
218
      }
219
    } else {
220
      pObj->optionInfo.userIp = INADDR_NONE;
2✔
221
      pObj->optionInfo.userDualIp = dualIp;
2✔
222
    }
223
  }
224

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

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

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

241
  monitorClose();
18,057✔
242
  tscStopCrashReport();
18,057✔
243

244
  hbMgrCleanUp();
18,057✔
245

246
  catalogDestroy();
18,057✔
247
  schedulerDestroy();
18,057✔
248

249
  fmFuncMgtDestroy();
18,057✔
250
  qCleanupKeywordsTable();
18,057✔
251

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

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

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

265
  id = clientConnRefPool;
18,057✔
266
  clientConnRefPool = -1;
18,057✔
267
  taosCloseRef(id);
18,057✔
268

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

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

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

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

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

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

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

323
  return NULL;
63✔
324
}
325

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

498
  __taos_async_whitelist_dual_stack_fn_t userCbFn;
499
} SFetchWhiteListDualStackInfo;
500

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

505
  SGetUserWhiteListRsp wlRsp = {0};
×
506

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

634
void taos_close_internal(void *taos) {
32,674✔
635
  if (taos == NULL) {
32,674!
636
    return;
×
637
  }
638

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

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

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

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

658
  taos_close_internal(pObj);
32,185✔
659
  releaseTscObj(*(int64_t *)taos);
32,181✔
660
  taosMemoryFree(taos);
32,183!
661
}
662

663
int taos_errno(TAOS_RES *res) {
12,814,734✔
664
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
12,814,734!
665
    return terrno;
×
666
  }
667

668
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
12,824,896!
669
    return 0;
×
670
  }
671

672
  return ((SRequestObj *)res)->code;
12,825,241✔
673
}
674

675
const char *taos_errstr(TAOS_RES *res) {
146,232✔
676
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
146,232!
677
    return (const char *)tstrerror(terrno);
135✔
678
  }
679

680
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
146,097!
681
    return "success";
×
682
  }
683

684
  SRequestObj *pRequest = (SRequestObj *)res;
146,097✔
685
  if (NULL != pRequest->msgBuf && (strlen(pRequest->msgBuf) > 0 || pRequest->code == TSDB_CODE_RPC_FQDN_ERROR)) {
146,097!
686
    return pRequest->msgBuf;
133,247✔
687
  } else {
688
    return (const char *)tstrerror(pRequest->code);
12,850✔
689
  }
690
}
691

692
void taos_free_result(TAOS_RES *res) {
11,151,601✔
693
  if (NULL == res) {
11,151,601✔
694
    return;
41,479✔
695
  }
696

697
  tscTrace("res:%p, will be freed", res);
11,110,122✔
698

699
  if (TD_RES_QUERY(res)) {
11,119,399✔
700
    SRequestObj *pRequest = (SRequestObj *)res;
11,095,846✔
701
    tscDebug("QID:0x%" PRIx64 ", call taos_free_result to free query, res:%p", pRequest->requestId, res);
11,095,846✔
702
    destroyRequest(pRequest);
11,095,846✔
703
    return;
11,096,819✔
704
  }
705

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

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

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

736
int taos_field_count(TAOS_RES *res) {
63,934,011✔
737
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
63,934,011!
738
    return 0;
×
739
  }
740

741
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
63,934,280✔
742
  return pResInfo->numOfCols;
63,934,280✔
743
}
744

745
int taos_num_fields(TAOS_RES *res) { return taos_field_count(res); }
42,814,362✔
746

747
TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) {
18,002,787✔
748
  if (taos_num_fields(res) == 0 || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
18,002,787!
749
    return NULL;
139,026✔
750
  }
751

752
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
17,849,941✔
753
  return pResInfo->userFields;
17,849,941✔
754
}
755

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

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

769
TAOS_ROW taos_fetch_row(TAOS_RES *res) {
35,586,181✔
770
  if (res == NULL) {
35,586,181!
771
    return NULL;
×
772
  }
773

774
  if (TD_RES_QUERY(res)) {
35,586,181✔
775
    SRequestObj *pRequest = (SRequestObj *)res;
19,067,657✔
776
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
19,067,657✔
777
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0 || pRequest->killed) {
19,067,489!
778
      return NULL;
3✔
779
    }
780

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

787
    return doAsyncFetchRows(pRequest, true, true);
19,063,701✔
788
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
16,518,524!
789
    SMqRspObj      *msg = ((SMqRspObj *)res);
16,518,524✔
790
    SReqResultInfo *pResultInfo = NULL;
16,518,524✔
791
    if (msg->resIter == -1) {
16,518,524✔
792
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
22,398!
793
        return NULL;
×
794
      }
795
    } else {
796
      pResultInfo = tmqGetCurResInfo(res);
16,496,126✔
797
    }
798

799
    if (pResultInfo->current < pResultInfo->numOfRows) {
16,518,524✔
800
      doSetOneRowPtr(pResultInfo);
16,187,399✔
801
      pResultInfo->current += 1;
16,136,574✔
802
      return pResultInfo->row;
16,136,574✔
803
    } else {
804
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
331,125✔
805
        return NULL;
22,393✔
806
      }
807

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

821
int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
16,429,410✔
822
  return taos_print_row_with_size(str, INT32_MAX, row, fields, num_fields);
16,429,410✔
823
}
824
int taos_print_row_with_size(char *str, uint32_t size, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
16,429,353✔
825
  int32_t len = 0;
16,429,353✔
826
  for (int i = 0; i < num_fields; ++i) {
99,865,425✔
827
    if (i > 0 && len < size - 1) {
83,344,119!
828
      str[len++] = ' ';
67,158,474✔
829
    }
830

831
    if (row[i] == NULL) {
83,344,119✔
832
      len += tsnprintf(str + len, size - len, "%s", TSDB_DATA_NULL_STR);
249,681✔
833
      continue;
249,705✔
834
    }
835

836
    switch (fields[i].type) {
83,094,438!
837
      case TSDB_DATA_TYPE_TINYINT:
299,200✔
838
        len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
299,200✔
839
        break;
300,541✔
840

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

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

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

853
      case TSDB_DATA_TYPE_INT:
18,584,775✔
854
        len += tsnprintf(str + len, size - len, "%d", *((int32_t *)row[i]));
18,584,775✔
855
        break;
18,588,085✔
856

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

861
      case TSDB_DATA_TYPE_BIGINT:
13,887,945✔
862
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
13,887,945✔
863
        break;
13,888,037✔
864

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

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

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

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

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

915
      case TSDB_DATA_TYPE_TIMESTAMP:
21,912,783✔
916
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
21,912,783✔
917
        break;
22,004,811✔
918

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

933
    if (len >= size - 1) {
83,186,367!
934
      break;
×
935
    }
936
  }
937
  if (len < size) {
16,521,306✔
938
    str[len] = 0;
16,503,917✔
939
  }
940

941
  return len;
16,521,306✔
942
}
943

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

949
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
31,913,701✔
950
  return pResInfo->length;
31,913,701✔
951
}
952

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

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

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

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

1018
const char *taos_get_client_info() { return td_version; }
15,645✔
1019

1020
// return int32_t
1021
int taos_affected_rows(TAOS_RES *res) {
1,693,565✔
1022
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
1,693,565!
1023
      TD_RES_TMQ_BATCH_META(res)) {
1,693,618!
1024
    return 0;
×
1025
  }
1026

1027
  SRequestObj    *pRequest = (SRequestObj *)res;
1,693,619✔
1028
  SReqResultInfo *pResInfo = &pRequest->body.resInfo;
1,693,619✔
1029
  return (int)pResInfo->numOfRows;
1,693,619✔
1030
}
1031

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

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

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

1049
  if (TD_RES_QUERY(res)) {
16,404,548✔
1050
    SRequestObj *pRequest = (SRequestObj *)res;
1,202,076✔
1051
    return pRequest->body.resInfo.precision;
1,202,076✔
1052
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
15,202,472!
1053
    SReqResultInfo *info = tmqGetCurResInfo(res);
15,202,472✔
1054
    return info->precision;
15,202,472✔
1055
  }
1056
  return TSDB_TIME_PRECISION_MILLI;
×
1057
}
1058

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

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

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

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

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

1085
void taos_stop_query(TAOS_RES *res) {
11,119,739✔
1086
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
11,119,739!
1087
      TD_RES_TMQ_BATCH_META(res)) {
11,132,633!
1088
    return;
×
1089
  }
1090

1091
  stopAllQueries((SRequestObj *)res);
11,133,781✔
1092
}
1093

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

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

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

1113
int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
1,566,468✔
1114
  int32_t numOfRows = 0;
1,566,468✔
1115
  /*int32_t code = */ terrno = taos_fetch_block_s(res, &numOfRows, rows);
1,566,468✔
1116
  return numOfRows;
1,566,465✔
1117
}
1118

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

1124
  if (TD_RES_QUERY(res)) {
1,566,468✔
1125
    SRequestObj *pRequest = (SRequestObj *)res;
1,562,572✔
1126

1127
    (*rows) = NULL;
1,562,572✔
1128
    (*numOfRows) = 0;
1,562,572✔
1129

1130
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
1,562,572!
1131
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
1,560,637!
1132
      return pRequest->code;
7,051✔
1133
    }
1134

1135
    (void)doAsyncFetchRows(pRequest, false, true);
1,555,521✔
1136

1137
    // TODO refactor
1138
    SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
1,555,520✔
1139
    pResultInfo->current = pResultInfo->numOfRows;
1,555,520✔
1140

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1215
  return pResInfo->pCol[columnIndex].offset;
772,846✔
1216
}
1217

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

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

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

1233
  if (*rows > pResInfo->numOfRows) {
2,190,722!
1234
    *rows = pResInfo->numOfRows;
×
1235
  }
1236
  if (IS_VAR_DATA_TYPE(pField->type)) {
2,190,722!
1237
    for (int i = 0; i < *rows; i++) {
×
1238
      if (pCol->offset[i] == -1) {
×
1239
        result[i] = true;
×
1240
      } else {
1241
        result[i] = false;
×
1242
      }
1243
    }
1244
  } else {
1245
    for (int i = 0; i < *rows; i++) {
574,140,706✔
1246
      if (colDataIsNull_f(pCol->nullbitmap, i)) {
571,949,984✔
1247
        result[i] = true;
153,863,169✔
1248
      } else {
1249
        result[i] = false;
418,086,815✔
1250
      }
1251
    }
1252
  }
1253
  return 0;
2,190,722✔
1254
}
1255

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

1259
  int code = taos_errno(pObj);
×
1260

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

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

1272
  resetConnectDB(pTscObj);
×
1273

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

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

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

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

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

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

1314
void destorySqlCallbackWrapper(SSqlCallbackWrapper *pWrapper) {
22,186,874✔
1315
  if (NULL == pWrapper) {
22,186,874✔
1316
    return;
11,140,350✔
1317
  }
1318
  destoryCatalogReq(pWrapper->pCatalogReq);
11,046,524✔
1319
  taosMemoryFree(pWrapper->pCatalogReq);
11,059,417!
1320
  qDestroyParseContext(pWrapper->pParseCtx);
11,078,246✔
1321
  taosMemoryFree(pWrapper);
11,077,576!
1322
}
1323

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

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

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

1339
  int64_t analyseStart = taosGetTimestampUs();
1,348,526✔
1340
  pRequest->metric.ctgCostUs = analyseStart - pRequest->metric.ctgStart;
1,348,526✔
1341
  pWrapper->pParseCtx->parseOnly = pRequest->parseOnly;
1,348,526✔
1342

1343
  if (TSDB_CODE_SUCCESS == code) {
1,348,526✔
1344
    code = qAnalyseSqlSemantic(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
1,348,490✔
1345
  }
1346

1347
  pRequest->metric.analyseCostUs += taosGetTimestampUs() - analyseStart;
1,348,330✔
1348

1349
  if (pRequest->parseOnly) {
1,348,330✔
1350
    (void)memcpy(&pRequest->parseMeta, pResultMeta, sizeof(*pResultMeta));
637✔
1351
    (void)memset(pResultMeta, 0, sizeof(*pResultMeta));
637✔
1352
  }
1353

1354
  handleQueryAnslyseRes(pWrapper, pResultMeta, code);
1,348,330✔
1355
}
1,348,355✔
1356

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

1383
    *ppTarget = pTarget;
461✔
1384
  }
1385

1386
  return code;
461✔
1387
}
1388

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

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

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

1424
  if (code == TSDB_CODE_SUCCESS && pQuery->pPrevRoot) {
1,348,695✔
1425
    SNode *prevRoot = pQuery->pPrevRoot;
461✔
1426
    pQuery->pPrevRoot = NULL;
461✔
1427
    handleSubQueryFromAnalyse(pWrapper, pResultMeta, prevRoot);
461✔
1428
    return;
461✔
1429
  }
1430

1431
  if (code == TSDB_CODE_SUCCESS) {
1,348,234✔
1432
    pRequest->stableQuery = pQuery->stableQuery;
1,249,392✔
1433
    if (pQuery->pRoot) {
1,249,392!
1434
      pRequest->stmtType = pQuery->pRoot->type;
1,249,399✔
1435
    }
1436

1437
    if (pQuery->haveResultSet) {
1,249,392✔
1438
      code = setResSchemaInfo(&pRequest->body.resInfo, pQuery->pResSchema, pQuery->numOfResCols, pQuery->pResExtSchema, pRequest->isStmtBind);
1,000,947✔
1439
      setResPrecision(&pRequest->body.resInfo, pQuery->precision);
1,000,942✔
1440
    }
1441
  }
1442

1443
  if (code == TSDB_CODE_SUCCESS) {
1,348,394✔
1444
    TSWAP(pRequest->dbList, (pQuery)->pDbList);
1,249,352✔
1445
    TSWAP(pRequest->tableList, (pQuery)->pTableList);
1,249,352✔
1446
    TSWAP(pRequest->targetTableList, (pQuery)->pTargetTableList);
1,249,352✔
1447

1448
    launchAsyncQuery(pRequest, pQuery, pResultMeta, pWrapper);
1,249,352✔
1449
  } else {
1450
    destorySqlCallbackWrapper(pWrapper);
99,042✔
1451
    pRequest->pWrapper = NULL;
99,042✔
1452
    qDestroyQuery(pRequest->pQuery);
99,042✔
1453
    pRequest->pQuery = NULL;
99,042✔
1454

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

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

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

1476
  pWrapper->pRequest->metric.ctgStart = taosGetTimestampUs();
1,422,324✔
1477

1478
  return catalogAsyncGetAllMeta(pWrapper->pParseCtx->pCatalog, &conn, pWrapper->pCatalogReq, fp, pWrapper,
2,844,936✔
1479
                                &pWrapper->pRequest->body.queryJob);
1,422,530✔
1480
}
1481

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

1484
static int32_t phaseAsyncQuery(SSqlCallbackWrapper *pWrapper) {
11,027,318✔
1485
  int32_t code = TSDB_CODE_SUCCESS;
11,027,318✔
1486
  switch (pWrapper->pRequest->pQuery->execStage) {
11,027,318!
1487
    case QUERY_EXEC_STAGE_PARSE: {
74,510✔
1488
      // continue parse after get metadata
1489
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromParse);
74,510✔
1490
      break;
74,510✔
1491
    }
1492
    case QUERY_EXEC_STAGE_ANALYSE: {
1,347,940✔
1493
      // analysis after get metadata
1494
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromAnalyse);
1,347,940✔
1495
      break;
1,347,959✔
1496
    }
1497
    case QUERY_EXEC_STAGE_SCHEDULE: {
9,620,038✔
1498
      launchAsyncQuery(pWrapper->pRequest, pWrapper->pRequest->pQuery, NULL, pWrapper);
9,620,038✔
1499
      break;
9,621,033✔
1500
    }
1501
    default:
×
1502
      break;
×
1503
  }
1504
  return code;
11,028,332✔
1505
}
1506

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

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

1516
  if (code == TSDB_CODE_SUCCESS) {
74,515✔
1517
    // pWrapper->pCatalogReq->forceUpdate = false;
1518
    code = qContinueParseSql(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
74,028✔
1519
  }
1520

1521
  if (TSDB_CODE_SUCCESS == code) {
74,512✔
1522
    code = phaseAsyncQuery(pWrapper);
62,397✔
1523
  }
1524

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

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

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

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

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

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

1566
  *pCxt = taosMemoryCalloc(1, sizeof(SParseContext));
11,061,758!
1567
  if (*pCxt == NULL) {
11,065,116!
1568
    return terrno;
×
1569
  }
1570

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

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

1613
  if (TSDB_CODE_SUCCESS == code) {
11,071,458!
1614
    code = createParseContext(pRequest, &pWrapper->pParseCtx, pWrapper);
11,073,033✔
1615
  }
1616

1617
  if (TSDB_CODE_SUCCESS == code) {
11,066,522!
1618
    pWrapper->pParseCtx->mgmtEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
11,068,536✔
1619
    code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pWrapper->pParseCtx->pCatalog);
11,080,752✔
1620
  }
1621

1622
  if (TSDB_CODE_SUCCESS == code && NULL == pRequest->pQuery) {
11,066,553!
1623
    int64_t syntaxStart = taosGetTimestampUs();
11,038,374✔
1624

1625
    pWrapper->pCatalogReq = taosMemoryCalloc(1, sizeof(SCatalogReq));
11,038,374!
1626
    if (pWrapper->pCatalogReq == NULL) {
11,071,369!
1627
      code = terrno;
×
1628
    } else {
1629
      pWrapper->pCatalogReq->forceUpdate = updateMetaForce;
11,071,369✔
1630
      TSC_ERR_RET(qnodeRequired(pRequest, &pWrapper->pCatalogReq->qNodeRequired));
11,071,369!
1631
      code = qParseSqlSyntax(pWrapper->pParseCtx, &pRequest->pQuery, pWrapper->pCatalogReq);
11,070,636✔
1632
    }
1633

1634
    pRequest->metric.parseCostUs += taosGetTimestampUs() - syntaxStart;
10,992,794✔
1635
  }
1636

1637
  return code;
11,022,700✔
1638
}
1639

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

1644
  if (pRequest->retry++ > REQUEST_TOTAL_EXEC_TIMES) {
11,068,635✔
1645
    code = pRequest->prevCode;
5,818✔
1646
    terrno = code;
5,818✔
1647
    pRequest->code = code;
5,818✔
1648
    tscDebug("req:0x%" PRIx64 ", call sync query cb with code:%s", pRequest->self, tstrerror(code));
5,818✔
1649
    doRequestCallback(pRequest, code);
5,818✔
1650
    return;
5,852✔
1651
  }
1652

1653
  if (TSDB_CODE_SUCCESS == code) {
11,062,817✔
1654
    code = prepareAndParseSqlSyntax(&pWrapper, pRequest, updateMetaForce);
11,061,241✔
1655
  }
1656

1657
  if (TSDB_CODE_SUCCESS == code) {
11,014,840✔
1658
    pRequest->stmtType = pRequest->pQuery->pRoot->type;
10,974,570✔
1659
    code = phaseAsyncQuery(pWrapper);
10,974,570✔
1660
  }
1661

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

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

1683
    terrno = code;
46,194✔
1684
    pRequest->code = code;
46,194✔
1685
    doRequestCallback(pRequest, code);
46,194✔
1686
  }
1687
}
1688

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1841
_return:
2✔
1842

1843
  terrno = code;
2✔
1844

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

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

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

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

1869
  pRequest->syncQuery = true;
200✔
1870

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

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

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

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

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

1892
  *vgId = vgInfo.vgId;
200✔
1893

1894
_return:
200✔
1895

1896
  terrno = code;
200✔
1897

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

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

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

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

1922
  pRequest->syncQuery = true;
1✔
1923

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

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

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

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

1941
_return:
1✔
1942

1943
  terrno = code;
1✔
1944

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

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

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

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

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

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

1980
  pRequest->syncQuery = true;
4✔
1981

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

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

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

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

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

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

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

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

2030
  return pStmt;
660✔
2031
}
2032

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

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

2047
  return pStmt;
×
2048
}
2049

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

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

2064
  return pStmt;
134✔
2065
}
2066

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

2074
  return stmtPrepare(stmt, sql, length);
20,779✔
2075
}
2076

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

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

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

2093
  return TSDB_CODE_SUCCESS;
×
2094
}
2095

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

2103
  return stmtSetTbName(stmt, name);
91,268✔
2104
}
2105

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2186
  return stmtBindBatch(stmt, bind, -1);
1,111,747✔
2187
}
2188

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

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

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

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

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

2224
  return stmtAddBatch(stmt);
1,061,205✔
2225
}
2226

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

2234
  return stmtExec(stmt);
58,828✔
2235
}
2236

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2322
  TAOS_STMT2 *pStmt = stmtInit2(pObj, option);
154✔
2323

2324
  releaseTscObj(*(int64_t *)taos);
154✔
2325

2326
  return pStmt;
154✔
2327
}
2328

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

2336
  return stmtPrepare2(stmt, sql, length);
178✔
2337
}
2338

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

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

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

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

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

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

2385
      code = stmtSetTbName2(stmt, bindv->tbnames[i]);
5,880✔
2386
      if (code) {
5,876✔
2387
        terrno = code;
1✔
2388
        STMT2_ELOG("set tbname failed, code:%s", tstrerror(code));
1!
2389
        goto out;
1✔
2390
      }
2391
    }
2392

2393
    SVCreateTbReq *pCreateTbReq = NULL;
5,892✔
2394
    if (bindv->tags && bindv->tags[i]) {
5,892!
2395
      code = stmtSetTbTags2(stmt, bindv->tags[i], &pCreateTbReq);
138✔
2396
    } else if (pStmt->bInfo.tbNameFlag & IS_FIXED_TAG) {
5,754✔
2397
      code = stmtCheckTags2(stmt, &pCreateTbReq);
26✔
2398
    } else {
2399
      if (pStmt->sql.autoCreateTbl) {
5,728✔
2400
        pStmt->sql.autoCreateTbl = false;
3✔
2401
        STMT2_WLOG_E("sql is autoCreateTbl, but no tags");
3!
2402
      }
2403
    }
2404

2405
    if (code) {
5,891✔
2406
      terrno = code;
1✔
2407
      STMT2_ELOG("set tags failed, code:%s", tstrerror(code));
1!
2408
      goto out;
1✔
2409
    }
2410

2411
    if (bindv->bind_cols && bindv->bind_cols[i]) {
5,890!
2412
      TAOS_STMT2_BIND *bind = bindv->bind_cols[i];
5,889✔
2413

2414
      if (bind->num <= 0 || bind->num > INT16_MAX) {
5,889!
2415
        STMT2_ELOG("bind num:%d must > 0 and < INT16_MAX", bind->num);
×
2416
        code = terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
2417
        goto out;
5✔
2418
      }
2419

2420
      int32_t insert = 0;
5,892✔
2421
      (void)stmtIsInsert2(stmt, &insert);
5,892✔
2422
      if (0 == insert && bind->num > 1) {
5,893✔
2423
        STMT2_ELOG_E("only one row data allowed for query");
1!
2424
        code = terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
1✔
2425
        goto out;
1✔
2426
      }
2427

2428
      code = stmtBindBatch2(stmt, bind, col_idx, pCreateTbReq);
5,892✔
2429
      if (TSDB_CODE_SUCCESS != code) {
5,903✔
2430
        terrno = code;
4✔
2431
        STMT2_ELOG("bind batch failed, code:%s", tstrerror(code));
4!
2432
        goto out;
4✔
2433
      }
2434
    }
2435
  }
2436

2437
out:
4,492✔
2438
  tSimpleHashCleanup(hashTbnames);
4,499✔
2439

2440
  return code;
4,503✔
2441
}
2442

2443
int taos_stmt2_bind_param_a(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx, __taos_async_fn_t fp,
×
2444
                            void *param) {
2445
  if (stmt == NULL || bindv == NULL || fp == NULL) {
×
2446
    terrno = TSDB_CODE_INVALID_PARA;
×
2447
    return terrno;
×
2448
  }
2449

2450
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
×
2451

2452
  ThreadArgs *args = (ThreadArgs *)taosMemoryMalloc(sizeof(ThreadArgs));
×
2453
  args->stmt = stmt;
×
2454
  args->bindv = bindv;
×
2455
  args->col_idx = col_idx;
×
2456
  args->fp = fp;
×
2457
  args->param = param;
×
2458

2459
  (void)taosThreadMutexLock(&(pStmt->asyncBindParam.mutex));
×
2460
  if (atomic_load_8((int8_t *)&pStmt->asyncBindParam.asyncBindNum) > 0) {
×
2461
    (void)taosThreadMutexUnlock(&(pStmt->asyncBindParam.mutex));
×
2462
    tscError("async bind param is still working, please try again later");
×
2463
    terrno = TSDB_CODE_TSC_STMT_API_ERROR;
×
2464
    return terrno;
×
2465
  }
2466
  (void)atomic_add_fetch_8(&pStmt->asyncBindParam.asyncBindNum, 1);
×
2467
  (void)taosThreadMutexUnlock(&(pStmt->asyncBindParam.mutex));
×
2468

2469
  int code_s = taosStmt2AsyncBind(stmtAsyncBindThreadFunc, (void *)args);
×
2470
  if (code_s != TSDB_CODE_SUCCESS) {
×
2471
    terrno = code_s;
×
2472
    (void)taosThreadMutexLock(&(pStmt->asyncBindParam.mutex));
×
2473
    (void)taosThreadCondSignal(&(pStmt->asyncBindParam.waitCond));
×
2474
    (void)atomic_sub_fetch_8(&pStmt->asyncBindParam.asyncBindNum, 1);
×
2475
    (void)taosThreadMutexUnlock(&(pStmt->asyncBindParam.mutex));
×
2476
    tscError("async bind failed, code:%d , %s", code_s, tstrerror(code_s));
×
2477
  }
2478

2479
  return code_s;
×
2480
}
2481

2482
int taos_stmt2_exec(TAOS_STMT2 *stmt, int *affected_rows) {
4,484✔
2483
  if (stmt == NULL) {
4,484!
2484
    tscError("NULL parameter for %s", __FUNCTION__);
×
2485
    terrno = TSDB_CODE_INVALID_PARA;
×
2486
    return terrno;
×
2487
  }
2488

2489
  return stmtExec2(stmt, affected_rows);
4,484✔
2490
}
2491

2492
int taos_stmt2_close(TAOS_STMT2 *stmt) {
152✔
2493
  if (stmt == NULL) {
152!
2494
    tscError("NULL parameter for %s", __FUNCTION__);
×
2495
    terrno = TSDB_CODE_INVALID_PARA;
×
2496
    return terrno;
×
2497
  }
2498

2499
  return stmtClose2(stmt);
152✔
2500
}
2501

2502
int taos_stmt2_is_insert(TAOS_STMT2 *stmt, int *insert) {
1✔
2503
  if (stmt == NULL || insert == NULL) {
1!
2504
    tscError("NULL parameter for %s", __FUNCTION__);
×
2505
    terrno = TSDB_CODE_INVALID_PARA;
×
2506
    return terrno;
×
2507
  }
2508

2509
  return stmtIsInsert2(stmt, insert);
1✔
2510
}
2511

2512
int taos_stmt2_get_fields(TAOS_STMT2 *stmt, int *count, TAOS_FIELD_ALL **fields) {
71✔
2513
  if (stmt == NULL || count == NULL) {
71!
2514
    tscError("NULL parameter for %s", __FUNCTION__);
1!
2515
    terrno = TSDB_CODE_INVALID_PARA;
1✔
2516
    return terrno;
1✔
2517
  }
2518

2519
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
70✔
2520
  if (pStmt->sql.type == 0) {
70✔
2521
    int isInsert = 0;
63✔
2522
    (void)stmtIsInsert2(stmt, &isInsert);
63✔
2523
    if (!isInsert) {
63✔
2524
      pStmt->sql.type = STMT_TYPE_QUERY;
13✔
2525
    }
2526
  }
2527

2528
  if (pStmt->sql.type == STMT_TYPE_QUERY) {
70✔
2529
    return stmtGetParamNum2(stmt, count);
13✔
2530
  }
2531

2532
  return stmtGetStbColFields2(stmt, count, fields);
57✔
2533
}
2534

2535
DLL_EXPORT void taos_stmt2_free_fields(TAOS_STMT2 *stmt, TAOS_FIELD_ALL *fields) {
56✔
2536
  (void)stmt;
2537
  if (!fields) return;
56✔
2538
  taosMemoryFree(fields);
33!
2539
}
2540

2541
TAOS_RES *taos_stmt2_result(TAOS_STMT2 *stmt) {
5✔
2542
  if (stmt == NULL) {
5!
2543
    tscError("NULL parameter for %s", __FUNCTION__);
×
2544
    terrno = TSDB_CODE_INVALID_PARA;
×
2545
    return NULL;
×
2546
  }
2547

2548
  return stmtUseResult2(stmt);
5✔
2549
}
2550

2551
char *taos_stmt2_error(TAOS_STMT2 *stmt) { return (char *)stmtErrstr2(stmt); }
5✔
2552

2553
int taos_set_conn_mode(TAOS *taos, int mode, int value) {
8✔
2554
  if (taos == NULL) {
8!
2555
    terrno = TSDB_CODE_INVALID_PARA;
×
2556
    return terrno;
×
2557
  }
2558

2559
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
8✔
2560
  if (NULL == pObj) {
8!
2561
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
2562
    tscError("invalid parameter for %s", __func__);
×
2563
    return terrno;
×
2564
  }
2565
  switch (mode) {
8!
2566
    case TAOS_CONN_MODE_BI:
8✔
2567
      atomic_store_8(&pObj->biMode, value);
8✔
2568
      break;
8✔
2569
    default:
×
2570
      tscError("not supported mode.");
×
2571
      return TSDB_CODE_INVALID_PARA;
×
2572
  }
2573
  return 0;
8✔
2574
}
2575

2576
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