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

taosdata / TDengine / #4817

20 Oct 2025 02:09AM UTC coverage: 61.125% (-0.05%) from 61.177%
#4817

push

travis-ci

web-flow
Merge e6f7b1ad7 into 21184b20f

155539 of 324487 branches covered (47.93%)

Branch coverage included in aggregate %.

72 of 84 new or added lines in 6 files covered. (85.71%)

476 existing lines in 111 files now uncovered.

207605 of 269610 relevant lines covered (77.0%)

126509550.12 hits per line

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

48.64
/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, ...) {
672,171✔
46
  if (arg == NULL) {
672,171!
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) {
37,090,705✔
52
    if (i % 1000 == 0) {
36,418,534✔
53
      (void)sched_yield();
36,359✔
54
    }
55
  }
56

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

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

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

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

82
void tzCleanup() {
1,542,374✔
83
  taosHashCleanup(pTimezoneMap);
1,542,374✔
84
  taosHashCleanup(pTimezoneNameMap);
1,542,374✔
85
}
1,542,374✔
86

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

95
  tscDebug("set timezone to %s", val);
12!
96
  tz = tzalloc(val);
12✔
97
  if (tz == NULL) {
12✔
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));
12!
107
  if (code != 0) {
12!
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();
12✔
115
  char   output[TD_TIMEZONE_LEN] = {0};
12✔
116
  code = taosFormatTimezoneStr(tx1, val, tz, output);
12✔
117
  if (code == 0) {
12!
118
    code = taosHashPut(pTimezoneNameMap, &tz, sizeof(timezone_t), output, strlen(output) + 1);
12✔
119
  }
120
  if (code != 0) {
12!
121
    tscError("failed to put timezone %s to map", val);
×
122
  }
123

124
END:
12✔
125
  return tz;
20✔
126
}
127
#endif
128

129
static int32_t setConnectionOption(TAOS *taos, TSDB_OPTION_CONNECTION option, const char *val) {
43✔
130
  if (taos == NULL) {
43✔
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) {
42!
141
    return terrno = TSDB_CODE_INVALID_PARA;
1✔
142
  }
143

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

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

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

160
#ifndef DISALLOW_NCHAR_WITHOUT_ICONV
161
  if (option == TSDB_OPTION_CONNECTION_CHARSET || option == TSDB_OPTION_CONNECTION_CLEAR) {
41✔
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) {
39✔
179
#if !defined(WINDOWS) && !defined(TD_ASTRA)
180
    if (val != NULL) {
22✔
181
      if (val[0] == 0) {
20✔
182
        val = "UTC";
1✔
183
      }
184
      timezone_t tz = setConnnectionTz(val);
20✔
185
      if (tz == NULL) {
20!
186
        code = terrno;
×
187
        goto END;
×
188
      }
189
      pObj->optionInfo.timezone = tz;
20✔
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) {
39✔
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) {
39✔
205
    SIpRange dualIp = {0};
9✔
206
    if (val != NULL) {
9✔
207
      pObj->optionInfo.userIp = taosInetAddr(val);
6✔
208
      SIpAddr addr = {0};
6✔
209
      code = taosGetIpFromFqdn(tsEnableIpv6, val, &addr);
6✔
210
      if (code == 0) {
6✔
211
        code = tIpStrToUint(&addr, &pObj->optionInfo.userDualIp);
3✔
212
      } 
213
      if (code != 0) {
6✔
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;
3✔
221
      pObj->optionInfo.userDualIp = dualIp;
3✔
222
    }
223
  }
224

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

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

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

241
  monitorClose();
1,542,374✔
242
  tscStopCrashReport();
1,542,374✔
243

244
  hbMgrCleanUp();
1,542,374✔
245

246
  catalogDestroy();
1,542,374✔
247
  schedulerDestroy();
1,542,374✔
248

249
  fmFuncMgtDestroy();
1,542,374✔
250
  qCleanupKeywordsTable();
1,542,374✔
251

252
#if !defined(WINDOWS) && !defined(TD_ASTRA)
253
  tzCleanup();
1,542,374✔
254
#endif
255
  tmqMgmtClose();
1,542,374✔
256

257
  int32_t id = clientReqRefPool;
1,542,374✔
258
  clientReqRefPool = -1;
1,542,374✔
259
  taosCloseRef(id);
1,542,374✔
260

261
  id = clientConnRefPool;
1,542,374✔
262
  clientConnRefPool = -1;
1,542,374✔
263
  taosCloseRef(id);
1,542,374✔
264

265
  nodesDestroyAllocatorSet();
1,542,374✔
266
  cleanupAppInfo();
1,542,374✔
267
  rpcCleanup();
1,542,374✔
268
  tscDebug("rpc cleanup");
1,542,374✔
269

270
  if (TSDB_CODE_SUCCESS != cleanupTaskQueue()) {
1,542,374!
271
    tscWarn("failed to cleanup task queue");
×
272
  }
273

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

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

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

299
TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port) {
3,452,349✔
300
  tscInfo("try to connect to %s:%u, user:%s db:%s", ip, port, user, db);
3,452,349✔
301
  if (user == NULL) {
3,454,962✔
302
    user = TSDB_DEFAULT_USER;
340,372✔
303
  }
304

305
  if (pass == NULL) {
3,454,962✔
306
    pass = TSDB_DEFAULT_PASS;
340,372✔
307
  }
308

309
  STscObj *pObj = NULL;
3,454,962✔
310
  int32_t  code = taos_connect_internal(ip, user, pass, NULL, db, port, CONN_TYPE__QUERY, &pObj);
3,455,377✔
311
  if (TSDB_CODE_SUCCESS == code) {
3,455,150✔
312
    int64_t *rid = taosMemoryCalloc(1, sizeof(int64_t));
3,449,131!
313
    if (NULL == rid) {
3,448,682!
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;
3,448,682✔
318
    return (TAOS *)rid;
3,449,023✔
319
  } else {
320
    terrno = code;
6,019✔
321
  }
322

323
  return NULL;
6,019✔
324
}
325

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

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

339
  switch (type) {
3,290!
340
    case TAOS_NOTIFY_PASSVER: {
940✔
341
      TSC_ERR_RET(taosThreadMutexLock(&pObj->mutex));
940!
342
      pObj->passInfo.fp = fp;
940✔
343
      pObj->passInfo.param = param;
940✔
344
      TSC_ERR_RET(taosThreadMutexUnlock(&pObj->mutex));
940!
345
      break;
940✔
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: {
2,350✔
355
      TSC_ERR_RET(taosThreadMutexLock(&pObj->mutex));
2,350!
356
      pObj->userDroppedInfo.fp = fp;
2,350✔
357
      pObj->userDroppedInfo.param = param;
2,350✔
358
      TSC_ERR_RET(taosThreadMutexUnlock(&pObj->mutex));
2,350!
359
      break;
2,350✔
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);
3,290✔
369
  return 0;
3,290✔
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) {
3,493,156✔
635
  if (taos == NULL) {
3,493,156!
636
    return;
×
637
  }
638

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

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

647
void taos_close(TAOS *taos) {
3,448,503✔
648
  if (taos == NULL) {
3,448,503✔
649
    return;
681✔
650
  }
651

652
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
3,447,822✔
653
  if (NULL == pObj) {
3,447,886!
654
    taosMemoryFree(taos);
×
655
    return;
×
656
  }
657

658
  taos_close_internal(pObj);
3,447,886✔
659
  releaseTscObj(*(int64_t *)taos);
3,447,886✔
660
  taosMemoryFree(taos);
3,448,767!
661
}
662

663
int taos_errno(TAOS_RES *res) {
918,224,932✔
664
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
918,224,932!
665
    return terrno;
27,415✔
666
  }
667

668
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
918,197,175✔
669
    return 0;
293,793✔
670
  }
671

672
  return ((SRequestObj *)res)->code;
917,898,207✔
673
}
674

675
const char *taos_errstr(TAOS_RES *res) {
45,265,001✔
676
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
45,265,001!
677
    return (const char *)tstrerror(terrno);
31,936✔
678
  }
679

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

684
  SRequestObj *pRequest = (SRequestObj *)res;
45,233,065✔
685
  if (NULL != pRequest->msgBuf && (strlen(pRequest->msgBuf) > 0 || pRequest->code == TSDB_CODE_RPC_FQDN_ERROR)) {
45,233,065!
686
    return pRequest->msgBuf;
40,778,748✔
687
  } else {
688
    return (const char *)tstrerror(pRequest->code);
4,454,317✔
689
  }
690
}
691

692
void taos_free_result(TAOS_RES *res) {
719,222,993✔
693
  if (NULL == res) {
719,222,993✔
694
    return;
1,702,945✔
695
  }
696

697
  tscTrace("res:%p, will be freed", res);
717,520,048✔
698

699
  if (TD_RES_QUERY(res)) {
717,520,198✔
700
    SRequestObj *pRequest = (SRequestObj *)res;
715,469,729✔
701
    tscDebug("QID:0x%" PRIx64 ", call taos_free_result to free query, res:%p", pRequest->requestId, res);
715,469,729✔
702
    destroyRequest(pRequest);
715,470,140✔
703
    return;
715,462,140✔
704
  }
705

706
  SMqRspObj *pRsp = (SMqRspObj *)res;
2,049,635✔
707
  if (TD_RES_TMQ(res)) {
2,049,635✔
708
    tDeleteMqDataRsp(&pRsp->dataRsp);
2,042,841✔
709
    doFreeReqResultInfo(&pRsp->resInfo);
2,042,745✔
710
  } else if (TD_RES_TMQ_METADATA(res)) {
8,444✔
711
    tDeleteSTaosxRsp(&pRsp->dataRsp);
343✔
712
    doFreeReqResultInfo(&pRsp->resInfo);
343✔
713
  } else if (TD_RES_TMQ_META(res)) {
8,101✔
714
    tDeleteMqMetaRsp(&pRsp->metaRsp);
7,074✔
715
  } else if (TD_RES_TMQ_BATCH_META(res)) {
1,027!
716
    tDeleteMqBatchMetaRsp(&pRsp->batchMetaRsp);
1,027✔
717
  } else if (TD_RES_TMQ_RAW(res)) {
×
718
    tDeleteMqRawDataRsp(&pRsp->dataRsp);
×
719
  }
720
  taosMemoryFree(pRsp);
2,050,805!
721
}
722

723
void taos_kill_query(TAOS *taos) {
1,362✔
724
  if (NULL == taos) {
1,362✔
725
    return;
681✔
726
  }
727

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

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

741
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
2,147,483,647✔
742
  return pResInfo->numOfCols;
2,147,483,647✔
743
}
744

745
int taos_num_fields(TAOS_RES *res) { return taos_field_count(res); }
2,147,483,647✔
746

747
TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) {
1,356,562,483✔
748
  if (taos_num_fields(res) == 0 || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
1,356,562,483!
749
    return NULL;
3,810,432✔
750
  }
751

752
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
1,352,752,395✔
753
  return pResInfo->userFields;
1,352,752,395✔
754
}
755

756
TAOS_RES *taos_query(TAOS *taos, const char *sql) { return taosQueryImpl(taos, sql, false, TD_REQ_FROM_APP); }
713,704,810✔
757
TAOS_RES *taos_query_with_reqid(TAOS *taos, const char *sql, int64_t reqid) {
208✔
758
  return taosQueryImplWithReqid(taos, sql, false, reqid);
208✔
759
}
760

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

769
TAOS_ROW taos_fetch_row(TAOS_RES *res) {
2,147,483,647✔
770
  if (res == NULL) {
2,147,483,647!
771
    return NULL;
×
772
  }
773

774
  if (TD_RES_QUERY(res)) {
2,147,483,647✔
775
    SRequestObj *pRequest = (SRequestObj *)res;
1,084,416,063✔
776
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
1,084,416,063!
777
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0 || pRequest->killed) {
1,084,418,461✔
778
      return NULL;
91✔
779
    }
780

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

787
    return doAsyncFetchRows(pRequest, true, true);
1,084,398,903✔
788
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
1,239,121,628!
789
    SMqRspObj      *msg = ((SMqRspObj *)res);
1,239,122,199✔
790
    SReqResultInfo *pResultInfo = NULL;
1,239,122,199✔
791
    if (msg->resIter == -1) {
1,239,122,105✔
792
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
1,746,555!
793
        return NULL;
×
794
      }
795
    } else {
796
      pResultInfo = tmqGetCurResInfo(res);
1,237,375,371✔
797
    }
798

799
    if (pResultInfo->current < pResultInfo->numOfRows) {
1,239,121,926✔
800
      doSetOneRowPtr(pResultInfo);
1,215,367,594✔
801
      pResultInfo->current += 1;
1,215,244,732✔
802
      return pResultInfo->row;
1,215,245,926✔
803
    } else {
804
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
23,754,591✔
805
        return NULL;
1,746,375✔
806
      }
807

808
      doSetOneRowPtr(pResultInfo);
22,082,483✔
809
      pResultInfo->current += 1;
22,084,401✔
810
      return pResultInfo->row;
22,084,593✔
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) {
1,240,647,850✔
822
  return taos_print_row_with_size(str, INT32_MAX, row, fields, num_fields);
1,240,647,850✔
823
}
824
int taos_print_row_with_size(char *str, uint32_t size, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
1,240,729,251✔
825
  int32_t len = 0;
1,240,729,251✔
826
  for (int i = 0; i < num_fields; ++i) {
2,147,483,647✔
827
    if (i > 0 && len < size - 1) {
2,147,483,647!
828
      str[len++] = ' ';
2,147,483,647✔
829
    }
830

831
    if (row[i] == NULL) {
2,147,483,647✔
832
      len += tsnprintf(str + len, size - len, "%s", TSDB_DATA_NULL_STR);
29,395,686✔
833
      continue;
29,395,765✔
834
    }
835

836
    switch (fields[i].type) {
2,147,483,647!
837
      case TSDB_DATA_TYPE_TINYINT:
769,812✔
838
        len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
769,812✔
839
        break;
769,812✔
840

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

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

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

853
      case TSDB_DATA_TYPE_INT:
1,225,252,818✔
854
        len += tsnprintf(str + len, size - len, "%d", *((int32_t *)row[i]));
1,225,252,818✔
855
        break;
1,225,404,000✔
856

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

861
      case TSDB_DATA_TYPE_BIGINT:
1,077,128,614✔
862
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
1,077,128,614✔
863
        break;
1,077,134,659✔
864

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

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

875
      case TSDB_DATA_TYPE_DOUBLE: {
493,012,940✔
876
        double dv = 0;
493,012,940✔
877
        dv = GET_DOUBLE_VAL(row[i]);
493,012,940✔
878
        len += snprintf(str + len, size - len, "%.*g", DBL_DIG, dv);
493,013,256✔
879
      } break;
493,009,171✔
880

881
      case TSDB_DATA_TYPE_VARBINARY: {
770,286✔
882
        void    *data = NULL;
770,286✔
883
        uint32_t tmp = 0;
770,286✔
884
        int32_t  charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
770,286✔
885
        if (taosAscii2Hex(row[i], charLen, &data, &tmp) < 0) {
770,286!
886
          break;
×
887
        }
888
        uint32_t copyLen = TMIN(size - len - 1, tmp);
770,286✔
889
        (void)memcpy(str + len, data, copyLen);
770,286!
890
        len += copyLen;
770,286✔
891
        taosMemoryFree(data);
770,286!
892
      } break;
770,286✔
893
      case TSDB_DATA_TYPE_BINARY:
1,416,686,457✔
894
      case TSDB_DATA_TYPE_NCHAR:
895
      case TSDB_DATA_TYPE_GEOMETRY: {
896
        int32_t charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
1,416,686,457✔
897
        if (fields[i].type == TSDB_DATA_TYPE_BINARY || fields[i].type == TSDB_DATA_TYPE_VARBINARY ||
1,416,684,416✔
898
            fields[i].type == TSDB_DATA_TYPE_GEOMETRY) {
381,912,595✔
899
          if (charLen > fields[i].bytes || charLen < 0) {
1,035,550,791!
900
            tscError("taos_print_row error binary. charLen:%d, fields[i].bytes:%d", charLen, fields[i].bytes);
737!
901
            break;
×
902
          }
903
        } else {
904
          if (charLen > fields[i].bytes * TSDB_NCHAR_SIZE || charLen < 0) {
381,142,957!
905
            tscError("taos_print_row error. charLen:%d, fields[i].bytes:%d", charLen, fields[i].bytes);
57,816!
906
            break;
×
907
          }
908
        }
909

910
        uint32_t copyLen = TMIN(size - len - 1, charLen);
1,416,716,270✔
911
        (void)memcpy(str + len, row[i], copyLen);
1,416,716,270!
912
        len += copyLen;
1,416,695,756✔
913
      } break;
1,416,695,756✔
914
      case TSDB_DATA_TYPE_BLOB:
×
915
      case TSDB_DATA_TYPE_MEDIUMBLOB: {
916
        void    *data = NULL;
×
917
        uint32_t tmp = 0;
×
918
        int32_t  charLen = blobDataLen((char *)row[i] - BLOBSTR_HEADER_SIZE);
×
919
        if (taosAscii2Hex(row[i], charLen, &data, &tmp) < 0) {
×
920
          break;
×
921
        }
922

923
        uint32_t copyLen = TMIN(size - len - 1, tmp);
×
924
        (void)memcpy(str + len, data, copyLen);
×
925
        len += copyLen;
×
926

927
        taosMemoryFree(data);
×
928
      } break;
×
929

930
      case TSDB_DATA_TYPE_TIMESTAMP:
1,641,969,562✔
931
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
1,641,969,562✔
932
        break;
1,642,018,377✔
933

934
      case TSDB_DATA_TYPE_BOOL:
769,800✔
935
        len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
769,800✔
936
        break;
558,100✔
937
      case TSDB_DATA_TYPE_DECIMAL64:
×
938
      case TSDB_DATA_TYPE_DECIMAL: {
939
        uint32_t decimalLen = strlen(row[i]);
×
940
        uint32_t copyLen = TMIN(size - len - 1, decimalLen);
×
941
        (void)memcpy(str + len, row[i], copyLen);
×
942
        len += copyLen;
×
943
      } break;
×
944
      default:
×
945
        break;
×
946
    }
947

948
    if (len >= size - 1) {
2,147,483,647!
949
      break;
×
950
    }
951
  }
952
  if (len < size) {
1,240,930,556✔
953
    str[len] = 0;
1,240,722,889✔
954
  }
955

956
  return len;
1,240,845,706✔
957
}
958

959
int *taos_fetch_lengths(TAOS_RES *res) {
2,147,483,647✔
960
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
2,147,483,647!
UNCOV
961
    return NULL;
×
962
  }
963

964
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
2,147,483,647✔
965
  return pResInfo->length;
2,147,483,647✔
966
}
967

968
TAOS_ROW *taos_result_block(TAOS_RES *res) {
×
969
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
×
970
    terrno = TSDB_CODE_INVALID_PARA;
×
971
    return NULL;
×
972
  }
973

974
  if (taos_is_update_query(res)) {
×
975
    return NULL;
×
976
  }
977

978
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
×
979
  return &pResInfo->row;
×
980
}
981

982
// todo intergrate with tDataTypes
983
const char *taos_data_type(int type) {
×
984
  switch (type) {
×
985
    case TSDB_DATA_TYPE_NULL:
×
986
      return "TSDB_DATA_TYPE_NULL";
×
987
    case TSDB_DATA_TYPE_BOOL:
×
988
      return "TSDB_DATA_TYPE_BOOL";
×
989
    case TSDB_DATA_TYPE_TINYINT:
×
990
      return "TSDB_DATA_TYPE_TINYINT";
×
991
    case TSDB_DATA_TYPE_SMALLINT:
×
992
      return "TSDB_DATA_TYPE_SMALLINT";
×
993
    case TSDB_DATA_TYPE_INT:
×
994
      return "TSDB_DATA_TYPE_INT";
×
995
    case TSDB_DATA_TYPE_BIGINT:
×
996
      return "TSDB_DATA_TYPE_BIGINT";
×
997
    case TSDB_DATA_TYPE_FLOAT:
×
998
      return "TSDB_DATA_TYPE_FLOAT";
×
999
    case TSDB_DATA_TYPE_DOUBLE:
×
1000
      return "TSDB_DATA_TYPE_DOUBLE";
×
1001
    case TSDB_DATA_TYPE_VARCHAR:
×
1002
      return "TSDB_DATA_TYPE_VARCHAR";
×
1003
      //    case TSDB_DATA_TYPE_BINARY:          return "TSDB_DATA_TYPE_VARCHAR";
1004
    case TSDB_DATA_TYPE_TIMESTAMP:
×
1005
      return "TSDB_DATA_TYPE_TIMESTAMP";
×
1006
    case TSDB_DATA_TYPE_NCHAR:
×
1007
      return "TSDB_DATA_TYPE_NCHAR";
×
1008
    case TSDB_DATA_TYPE_JSON:
×
1009
      return "TSDB_DATA_TYPE_JSON";
×
1010
    case TSDB_DATA_TYPE_GEOMETRY:
×
1011
      return "TSDB_DATA_TYPE_GEOMETRY";
×
1012
    case TSDB_DATA_TYPE_UTINYINT:
×
1013
      return "TSDB_DATA_TYPE_UTINYINT";
×
1014
    case TSDB_DATA_TYPE_USMALLINT:
×
1015
      return "TSDB_DATA_TYPE_USMALLINT";
×
1016
    case TSDB_DATA_TYPE_UINT:
×
1017
      return "TSDB_DATA_TYPE_UINT";
×
1018
    case TSDB_DATA_TYPE_UBIGINT:
×
1019
      return "TSDB_DATA_TYPE_UBIGINT";
×
1020
    case TSDB_DATA_TYPE_VARBINARY:
×
1021
      return "TSDB_DATA_TYPE_VARBINARY";
×
1022
    case TSDB_DATA_TYPE_DECIMAL:
×
1023
      return "TSDB_DATA_TYPE_DECIMAL";
×
1024
    case TSDB_DATA_TYPE_BLOB:
×
1025
      return "TSDB_DATA_TYPE_BLOB";
×
1026
    case TSDB_DATA_TYPE_MEDIUMBLOB:
×
1027
      return "TSDB_DATA_TYPE_MEDIUMBLOB";
×
1028
    default:
×
1029
      return "UNKNOWN";
×
1030
  }
1031
}
1032

1033
const char *taos_get_client_info() { return td_version; }
993,516✔
1034

1035
// return int32_t
1036
int taos_affected_rows(TAOS_RES *res) {
523,794,269✔
1037
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
523,794,269!
1038
      TD_RES_TMQ_BATCH_META(res)) {
523,797,905✔
UNCOV
1039
    return 0;
×
1040
  }
1041

1042
  SRequestObj    *pRequest = (SRequestObj *)res;
523,793,346✔
1043
  SReqResultInfo *pResInfo = &pRequest->body.resInfo;
523,793,346✔
1044
  return (int)pResInfo->numOfRows;
523,797,069✔
1045
}
1046

1047
// return int64_t
1048
int64_t taos_affected_rows64(TAOS_RES *res) {
1,525,722✔
1049
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
1,525,722!
1050
      TD_RES_TMQ_BATCH_META(res)) {
1,525,722!
1051
    return 0;
×
1052
  }
1053

1054
  SRequestObj    *pRequest = (SRequestObj *)res;
1,525,722✔
1055
  SReqResultInfo *pResInfo = &pRequest->body.resInfo;
1,525,722✔
1056
  return pResInfo->numOfRows;
1,525,722✔
1057
}
1058

1059
int taos_result_precision(TAOS_RES *res) {
1,273,686,809✔
1060
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
1,273,686,809!
1061
    return TSDB_TIME_PRECISION_MILLI;
×
1062
  }
1063

1064
  if (TD_RES_QUERY(res)) {
1,273,618,450✔
1065
    SRequestObj *pRequest = (SRequestObj *)res;
107,140,764✔
1066
    return pRequest->body.resInfo.precision;
107,140,764✔
1067
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
1,166,550,947!
1068
    SReqResultInfo *info = tmqGetCurResInfo(res);
1,166,557,874✔
1069
    return info->precision;
1,166,557,874✔
1070
  }
1071
  return TSDB_TIME_PRECISION_MILLI;
×
1072
}
1073

1074
int taos_select_db(TAOS *taos, const char *db) {
172,975✔
1075
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
172,975✔
1076
  if (pObj == NULL) {
172,975!
1077
    releaseTscObj(*(int64_t *)taos);
×
1078
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1079
    return TSDB_CODE_TSC_DISCONNECTED;
×
1080
  }
1081

1082
  if (db == NULL || strlen(db) == 0) {
172,975!
1083
    releaseTscObj(*(int64_t *)taos);
×
1084
    tscError("invalid parameter for %s", db == NULL ? "db is NULL" : "db is empty");
×
1085
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1086
    return terrno;
×
1087
  }
1088

1089
  char sql[256] = {0};
172,975✔
1090
  (void)snprintf(sql, tListLen(sql), "use %s", db);
172,975!
1091

1092
  TAOS_RES *pRequest = taos_query(taos, sql);
172,975✔
1093
  int32_t   code = taos_errno(pRequest);
172,975✔
1094

1095
  taos_free_result(pRequest);
172,975✔
1096
  releaseTscObj(*(int64_t *)taos);
172,975✔
1097
  return code;
172,975✔
1098
}
1099

1100
void taos_stop_query(TAOS_RES *res) {
720,025,020✔
1101
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
720,025,020!
1102
      TD_RES_TMQ_BATCH_META(res)) {
720,026,619✔
UNCOV
1103
    return;
×
1104
  }
1105

1106
  stopAllQueries((SRequestObj *)res);
720,025,526✔
1107
}
1108

1109
bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) {
×
1110
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
×
1111
    return true;
×
1112
  }
1113
  SReqResultInfo *pResultInfo = tscGetCurResInfo(res);
×
1114
  if (col >= pResultInfo->numOfCols || col < 0 || row >= pResultInfo->numOfRows || row < 0) {
×
1115
    return true;
×
1116
  }
1117

1118
  SResultColumn *pCol = &pResultInfo->pCol[col];
×
1119
  if (IS_VAR_DATA_TYPE(pResultInfo->fields[col].type)) {
×
1120
    return (pCol->offset[row] == -1);
×
1121
  } else {
1122
    return colDataIsNull_f(pCol, row);
×
1123
  }
1124
}
1125

1126
bool taos_is_update_query(TAOS_RES *res) { return taos_num_fields(res) == 0; }
166,044✔
1127

1128
int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
194,509,830✔
1129
  int32_t numOfRows = 0;
194,509,830✔
1130
  /*int32_t code = */ terrno = taos_fetch_block_s(res, &numOfRows, rows);
194,509,830✔
1131
  return numOfRows;
194,508,698✔
1132
}
1133

1134
int taos_fetch_block_s(TAOS_RES *res, int *numOfRows, TAOS_ROW *rows) {
194,509,830✔
1135
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
194,509,830!
1136
    return 0;
×
1137
  }
1138

1139
  if (TD_RES_QUERY(res)) {
194,509,830✔
1140
    SRequestObj *pRequest = (SRequestObj *)res;
192,730,512✔
1141

1142
    (*rows) = NULL;
192,730,512✔
1143
    (*numOfRows) = 0;
192,730,512✔
1144

1145
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
192,730,512!
1146
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
192,518,614!
1147
      return pRequest->code;
1,358,998✔
1148
    }
1149

1150
    (void)doAsyncFetchRows(pRequest, false, true);
191,371,514✔
1151

1152
    // TODO refactor
1153
    SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
191,370,326✔
1154
    pResultInfo->current = pResultInfo->numOfRows;
191,371,514✔
1155

1156
    (*rows) = pResultInfo->row;
191,371,514✔
1157
    (*numOfRows) = pResultInfo->numOfRows;
191,370,948✔
1158
    return pRequest->code;
191,371,231✔
1159
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
1,779,318!
1160
    SReqResultInfo *pResultInfo = NULL;
1,779,318✔
1161
    int32_t         code = tmqGetNextResInfo(res, true, &pResultInfo);
1,779,318✔
1162
    if (code != 0) return code;
1,779,318✔
1163

1164
    pResultInfo->current = pResultInfo->numOfRows;
1,491,039✔
1165
    (*rows) = pResultInfo->row;
1,491,039✔
1166
    (*numOfRows) = pResultInfo->numOfRows;
1,491,039✔
1167
    return 0;
1,491,039✔
1168
  } else {
1169
    tscError("taos_fetch_block_s invalid res type");
×
1170
    return TSDB_CODE_TMQ_INVALID_DATA;
×
1171
  }
1172
}
1173

1174
int taos_fetch_raw_block(TAOS_RES *res, int *numOfRows, void **pData) {
26,260✔
1175
  *numOfRows = 0;
26,260✔
1176
  *pData = NULL;
26,260✔
1177

1178
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
26,260!
1179
    return 0;
×
1180
  }
1181

1182
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
26,260!
1183
    SReqResultInfo *pResultInfo = NULL;
25,329✔
1184
    int32_t         code = tmqGetNextResInfo(res, false, &pResultInfo);
25,329✔
1185
    if (code != 0) {
25,329✔
1186
      (*numOfRows) = 0;
277✔
1187
      return 0;
277✔
1188
    }
1189

1190
    pResultInfo->current = pResultInfo->numOfRows;
25,052✔
1191
    (*numOfRows) = pResultInfo->numOfRows;
25,052✔
1192
    (*pData) = (void *)pResultInfo->pData;
25,052✔
1193
    return 0;
25,052✔
1194
  }
1195

1196
  SRequestObj *pRequest = (SRequestObj *)res;
931✔
1197

1198
  if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
931!
1199
      pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
931!
1200
    return pRequest->code;
×
1201
  }
1202

1203
  (void)doAsyncFetchRows(pRequest, false, false);
931✔
1204

1205
  SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
931✔
1206

1207
  pResultInfo->current = pResultInfo->numOfRows;
931✔
1208
  (*numOfRows) = pResultInfo->numOfRows;
931✔
1209
  (*pData) = (void *)pResultInfo->pData;
931✔
1210

1211
  return pRequest->code;
931✔
1212
}
1213

1214
int *taos_get_column_data_offset(TAOS_RES *res, int columnIndex) {
129,471,882✔
1215
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
129,471,882!
1216
    return 0;
×
1217
  }
1218

1219
  int32_t numOfFields = taos_num_fields(res);
129,471,882✔
1220
  if (columnIndex < 0 || columnIndex >= numOfFields || numOfFields == 0) {
129,471,882!
1221
    return 0;
×
1222
  }
1223

1224
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
129,471,882✔
1225
  TAOS_FIELD     *pField = &pResInfo->userFields[columnIndex];
129,471,882✔
1226
  if (!IS_VAR_DATA_TYPE(pField->type)) {
129,471,882!
1227
    return 0;
×
1228
  }
1229

1230
  return pResInfo->pCol[columnIndex].offset;
129,471,882✔
1231
}
1232

1233
int taos_is_null_by_column(TAOS_RES *res, int columnIndex, bool result[], int *rows) {
360,983,589✔
1234
  if (res == NULL || result == NULL || rows == NULL || *rows <= 0 || columnIndex < 0 || TD_RES_TMQ_META(res) ||
360,983,589!
1235
      TD_RES_TMQ_RAW(res) || TD_RES_TMQ_BATCH_META(res)) {
360,983,589!
1236
    return TSDB_CODE_INVALID_PARA;
×
1237
  }
1238

1239
  int32_t numOfFields = taos_num_fields(res);
360,983,589✔
1240
  if (columnIndex >= numOfFields || numOfFields == 0) {
360,983,589!
1241
    return TSDB_CODE_INVALID_PARA;
×
1242
  }
1243

1244
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
360,983,589✔
1245
  TAOS_FIELD     *pField = &pResInfo->userFields[columnIndex];
360,983,589✔
1246
  SResultColumn  *pCol = &pResInfo->pCol[columnIndex];
360,983,023✔
1247

1248
  if (*rows > pResInfo->numOfRows) {
360,983,589!
1249
    *rows = pResInfo->numOfRows;
×
1250
  }
1251
  if (IS_VAR_DATA_TYPE(pField->type)) {
360,983,589!
1252
    for (int i = 0; i < *rows; i++) {
×
1253
      if (pCol->offset[i] == -1) {
×
1254
        result[i] = true;
×
1255
      } else {
1256
        result[i] = false;
×
1257
      }
1258
    }
1259
  } else {
1260
    for (int i = 0; i < *rows; i++) {
2,147,483,647✔
1261
      if (colDataIsNull_f(pCol, i)) {
2,147,483,647!
1262
        result[i] = true;
2,147,483,647✔
1263
      } else {
1264
        result[i] = false;
2,147,483,647✔
1265
      }
1266
    }
1267
  }
1268
  return 0;
360,983,589✔
1269
}
1270

1271
int taos_validate_sql(TAOS *taos, const char *sql) {
×
1272
  TAOS_RES *pObj = taosQueryImpl(taos, sql, true, TD_REQ_FROM_APP);
×
1273

1274
  int code = taos_errno(pObj);
×
1275

1276
  taos_free_result(pObj);
×
1277
  return code;
×
1278
}
1279

1280
void taos_reset_current_db(TAOS *taos) {
×
1281
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
×
1282
  if (pTscObj == NULL) {
×
1283
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1284
    return;
×
1285
  }
1286

1287
  resetConnectDB(pTscObj);
×
1288

1289
  releaseTscObj(*(int64_t *)taos);
×
1290
}
1291

1292
const char *taos_get_server_info(TAOS *taos) {
38,987✔
1293
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
38,987✔
1294
  if (pTscObj == NULL) {
38,987!
1295
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1296
    return NULL;
×
1297
  }
1298

1299
  releaseTscObj(*(int64_t *)taos);
38,987✔
1300

1301
  return pTscObj->sDetailVer;
38,987✔
1302
}
1303

1304
int taos_get_current_db(TAOS *taos, char *database, int len, int *required) {
864✔
1305
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
864✔
1306
  if (pTscObj == NULL) {
864!
1307
    return TSDB_CODE_TSC_DISCONNECTED;
×
1308
  }
1309

1310
  int code = TSDB_CODE_SUCCESS;
864✔
1311
  (void)taosThreadMutexLock(&pTscObj->mutex);
864✔
1312
  if (database == NULL || len <= 0) {
864!
1313
    if (required != NULL) *required = strlen(pTscObj->db) + 1;
432!
1314
    TSC_ERR_JRET(TSDB_CODE_INVALID_PARA);
432!
1315
  } else if (len < strlen(pTscObj->db) + 1) {
432!
1316
    tstrncpy(database, pTscObj->db, len);
216!
1317
    if (required) *required = strlen(pTscObj->db) + 1;
216!
1318
    TSC_ERR_JRET(TSDB_CODE_INVALID_PARA);
216!
1319
  } else {
1320
    tstrncpy(database, pTscObj->db, len);
216!
1321
    code = 0;
216✔
1322
  }
1323
_return:
864✔
1324
  (void)taosThreadMutexUnlock(&pTscObj->mutex);
864✔
1325
  releaseTscObj(*(int64_t *)taos);
864✔
1326
  return code;
864✔
1327
}
1328

1329
void destorySqlCallbackWrapper(SSqlCallbackWrapper *pWrapper) {
1,440,023,283✔
1330
  if (NULL == pWrapper) {
1,440,023,283✔
1331
    return;
723,228,563✔
1332
  }
1333
  destoryCatalogReq(pWrapper->pCatalogReq);
716,794,720✔
1334
  taosMemoryFree(pWrapper->pCatalogReq);
716,780,547!
1335
  qDestroyParseContext(pWrapper->pParseCtx);
716,775,866✔
1336
  taosMemoryFree(pWrapper);
716,766,787!
1337
}
1338

1339
void destroyCtxInRequest(SRequestObj *pRequest) {
3,611,182✔
1340
  schedulerFreeJob(&pRequest->body.queryJob, 0);
3,611,182✔
1341
  qDestroyQuery(pRequest->pQuery);
3,611,182✔
1342
  pRequest->pQuery = NULL;
3,611,182✔
1343
  destorySqlCallbackWrapper(pRequest->pWrapper);
3,611,182✔
1344
  pRequest->pWrapper = NULL;
3,611,182✔
1345
}
3,611,182✔
1346

1347
static void doAsyncQueryFromAnalyse(SMetaData *pResultMeta, void *param, int32_t code) {
200,892,504✔
1348
  SSqlCallbackWrapper *pWrapper = (SSqlCallbackWrapper *)param;
200,892,504✔
1349
  SRequestObj         *pRequest = pWrapper->pRequest;
200,892,504✔
1350
  SQuery              *pQuery = pRequest->pQuery;
200,893,196✔
1351

1352
  qDebug("req:0x%" PRIx64 ", start to semantic analysis, QID:0x%" PRIx64, pRequest->self, pRequest->requestId);
200,894,234✔
1353

1354
  int64_t analyseStart = taosGetTimestampUs();
200,895,056✔
1355
  pRequest->metric.ctgCostUs = analyseStart - pRequest->metric.ctgStart;
200,895,056✔
1356
  pWrapper->pParseCtx->parseOnly = pRequest->parseOnly;
200,894,710!
1357

1358
  if (TSDB_CODE_SUCCESS == code) {
200,895,056✔
1359
    code = qAnalyseSqlSemantic(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
200,893,194✔
1360
  }
1361

1362
  pRequest->metric.analyseCostUs += taosGetTimestampUs() - analyseStart;
200,877,116✔
1363

1364
  if (pRequest->parseOnly) {
200,883,959✔
1365
    (void)memcpy(&pRequest->parseMeta, pResultMeta, sizeof(*pResultMeta));
377,606!
1366
    (void)memset(pResultMeta, 0, sizeof(*pResultMeta));
377,606!
1367
  }
1368

1369
  handleQueryAnslyseRes(pWrapper, pResultMeta, code);
200,883,028✔
1370
}
200,877,820✔
1371

1372
int32_t cloneCatalogReq(SCatalogReq **ppTarget, SCatalogReq *pSrc) {
×
1373
  int32_t      code = TSDB_CODE_SUCCESS;
×
1374
  SCatalogReq *pTarget = taosMemoryCalloc(1, sizeof(SCatalogReq));
×
1375
  if (pTarget == NULL) {
×
1376
    code = terrno;
×
1377
  } else {
1378
    pTarget->pDbVgroup = taosArrayDup(pSrc->pDbVgroup, NULL);
×
1379
    pTarget->pDbCfg = taosArrayDup(pSrc->pDbCfg, NULL);
×
1380
    pTarget->pDbInfo = taosArrayDup(pSrc->pDbInfo, NULL);
×
1381
    pTarget->pTableMeta = taosArrayDup(pSrc->pTableMeta, NULL);
×
1382
    pTarget->pTableHash = taosArrayDup(pSrc->pTableHash, NULL);
×
1383
    pTarget->pUdf = taosArrayDup(pSrc->pUdf, NULL);
×
1384
    pTarget->pIndex = taosArrayDup(pSrc->pIndex, NULL);
×
1385
    pTarget->pUser = taosArrayDup(pSrc->pUser, NULL);
×
1386
    pTarget->pTableIndex = taosArrayDup(pSrc->pTableIndex, NULL);
×
1387
    pTarget->pTableCfg = taosArrayDup(pSrc->pTableCfg, NULL);
×
1388
    pTarget->pTableTag = taosArrayDup(pSrc->pTableTag, NULL);
×
1389
    pTarget->pView = taosArrayDup(pSrc->pView, NULL);
×
1390
    pTarget->pTableTSMAs = taosArrayDup(pSrc->pTableTSMAs, NULL);
×
1391
    pTarget->pTSMAs = taosArrayDup(pSrc->pTSMAs, NULL);
×
1392
    pTarget->pVStbRefDbs = taosArrayDup(pSrc->pVStbRefDbs, NULL);
×
1393
    pTarget->qNodeRequired = pSrc->qNodeRequired;
×
1394
    pTarget->dNodeRequired = pSrc->dNodeRequired;
×
1395
    pTarget->svrVerRequired = pSrc->svrVerRequired;
×
1396
    pTarget->forceUpdate = pSrc->forceUpdate;
×
1397
    pTarget->cloned = true;
×
1398

1399
    *ppTarget = pTarget;
×
1400
  }
1401

1402
  return code;
×
1403
}
1404

1405
void handleSubQueryFromAnalyse(SSqlCallbackWrapper *pWrapper, SMetaData *pResultMeta, SNode *pRoot) {
×
1406
  SRequestObj         *pNewRequest = NULL;
×
1407
  SSqlCallbackWrapper *pNewWrapper = NULL;
×
1408
  int32_t              code = buildPreviousRequest(pWrapper->pRequest, pWrapper->pRequest->sqlstr, &pNewRequest);
×
1409
  if (code) {
×
1410
    handleQueryAnslyseRes(pWrapper, pResultMeta, code);
×
1411
    return;
×
1412
  }
1413

1414
  pNewRequest->pQuery = NULL;
×
1415
  code = nodesMakeNode(QUERY_NODE_QUERY, (SNode **)&pNewRequest->pQuery);
×
1416
  if (pNewRequest->pQuery) {
×
1417
    pNewRequest->pQuery->pRoot = pRoot;
×
1418
    pRoot = NULL;
×
1419
    pNewRequest->pQuery->execStage = QUERY_EXEC_STAGE_ANALYSE;
×
1420
  }
1421
  if (TSDB_CODE_SUCCESS == code) {
×
1422
    code = prepareAndParseSqlSyntax(&pNewWrapper, pNewRequest, false);
×
1423
  }
1424
  if (TSDB_CODE_SUCCESS == code) {
×
1425
    code = cloneCatalogReq(&pNewWrapper->pCatalogReq, pWrapper->pCatalogReq);
×
1426
  }
1427
  if (TSDB_CODE_SUCCESS == code) {
×
1428
    doAsyncQueryFromAnalyse(pResultMeta, pNewWrapper, code);
×
1429
    nodesDestroyNode(pRoot);
×
1430
  } else {
1431
    handleQueryAnslyseRes(pWrapper, pResultMeta, code);
×
1432
    return;
×
1433
  }
1434
}
1435

1436
void handleQueryAnslyseRes(SSqlCallbackWrapper *pWrapper, SMetaData *pResultMeta, int32_t code) {
200,871,705✔
1437
  SRequestObj *pRequest = pWrapper->pRequest;
200,871,705✔
1438
  SQuery      *pQuery = pRequest->pQuery;
200,880,256✔
1439

1440
  if (code == TSDB_CODE_SUCCESS && pQuery->pPrevRoot) {
200,873,571!
1441
    SNode *prevRoot = pQuery->pPrevRoot;
×
1442
    pQuery->pPrevRoot = NULL;
×
1443
    handleSubQueryFromAnalyse(pWrapper, pResultMeta, prevRoot);
×
1444
    return;
×
1445
  }
1446

1447
  if (code == TSDB_CODE_SUCCESS) {
200,871,341✔
1448
    pRequest->stableQuery = pQuery->stableQuery;
177,956,157!
1449
    if (pQuery->pRoot) {
177,950,049!
1450
      pRequest->stmtType = pQuery->pRoot->type;
177,963,102✔
1451
    }
1452

1453
    if (pQuery->haveResultSet) {
177,939,516✔
1454
      code = setResSchemaInfo(&pRequest->body.resInfo, pQuery->pResSchema, pQuery->numOfResCols, pQuery->pResExtSchema,
107,992,267✔
1455
                              pRequest->stmtBindVersion > 0);
107,991,197✔
1456
      setResPrecision(&pRequest->body.resInfo, pQuery->precision);
107,999,019✔
1457
    }
1458
  }
1459

1460
  if (code == TSDB_CODE_SUCCESS) {
200,873,165✔
1461
    TSWAP(pRequest->dbList, (pQuery)->pDbList);
177,955,047✔
1462
    TSWAP(pRequest->tableList, (pQuery)->pTableList);
177,946,721✔
1463
    TSWAP(pRequest->targetTableList, (pQuery)->pTargetTableList);
177,941,592✔
1464

1465
    launchAsyncQuery(pRequest, pQuery, pResultMeta, pWrapper);
177,942,362✔
1466
  } else {
1467
    destorySqlCallbackWrapper(pWrapper);
22,918,118✔
1468
    pRequest->pWrapper = NULL;
22,918,118✔
1469
    qDestroyQuery(pRequest->pQuery);
22,918,118✔
1470
    pRequest->pQuery = NULL;
22,918,118✔
1471

1472
    if (NEED_CLIENT_HANDLE_ERROR(code) && pRequest->stmtBindVersion == 0) {
22,918,118!
1473
      tscDebug("req:0x%" PRIx64 ", client retry to handle the error, code:%d - %s, tryCount:%d, QID:0x%" PRIx64,
3,581,171✔
1474
               pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId);
1475
      restartAsyncQuery(pRequest, code);
3,581,171✔
1476
      return;
3,581,171✔
1477
    }
1478

1479
    // return to app directly
1480
    tscError("req:0x%" PRIx64 ", error occurs, code:%s, return to user app, QID:0x%" PRIx64, pRequest->self, tstrerror(code),
19,336,947!
1481
             pRequest->requestId);
1482
    pRequest->code = code;
19,336,947✔
1483
    returnToUser(pRequest);
19,336,947✔
1484
  }
1485
}
1486

1487
static int32_t getAllMetaAsync(SSqlCallbackWrapper *pWrapper, catalogCallback fp) {
226,367,828✔
1488
  SRequestConnInfo conn = {.pTrans = pWrapper->pParseCtx->pTransporter,
448,230,145✔
1489
                           .requestId = pWrapper->pParseCtx->requestId,
226,378,614✔
1490
                           .requestObjRefId = pWrapper->pParseCtx->requestRid,
226,367,273✔
1491
                           .mgmtEps = pWrapper->pParseCtx->mgmtEpSet};
226,374,196✔
1492

1493
  pWrapper->pRequest->metric.ctgStart = taosGetTimestampUs();
448,241,577✔
1494

1495
  return catalogAsyncGetAllMeta(pWrapper->pParseCtx->pCatalog, &conn, pWrapper->pCatalogReq, fp, pWrapper,
230,870,077✔
1496
                                &pWrapper->pRequest->body.queryJob);
226,362,648✔
1497
}
1498

1499
static void doAsyncQueryFromParse(SMetaData *pResultMeta, void *param, int32_t code);
1500

1501
static int32_t phaseAsyncQuery(SSqlCallbackWrapper *pWrapper) {
720,422,034✔
1502
  int32_t code = TSDB_CODE_SUCCESS;
720,422,034✔
1503
  switch (pWrapper->pRequest->pQuery->execStage) {
720,422,034!
1504
    case QUERY_EXEC_STAGE_PARSE: {
25,500,103✔
1505
      // continue parse after get metadata
1506
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromParse);
25,500,103✔
1507
      break;
25,500,103✔
1508
    }
1509
    case QUERY_EXEC_STAGE_ANALYSE: {
200,873,145✔
1510
      // analysis after get metadata
1511
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromAnalyse);
200,873,145✔
1512
      break;
200,875,563✔
1513
    }
1514
    case QUERY_EXEC_STAGE_SCHEDULE: {
494,065,778✔
1515
      launchAsyncQuery(pWrapper->pRequest, pWrapper->pRequest->pQuery, NULL, pWrapper);
494,065,778✔
1516
      break;
494,066,864✔
1517
    }
1518
    default:
×
1519
      break;
×
1520
  }
1521
  return code;
720,441,435✔
1522
}
1523

1524
static void doAsyncQueryFromParse(SMetaData *pResultMeta, void *param, int32_t code) {
25,500,103✔
1525
  SSqlCallbackWrapper *pWrapper = (SSqlCallbackWrapper *)param;
25,500,103✔
1526
  SRequestObj         *pRequest = pWrapper->pRequest;
25,500,103✔
1527
  SQuery              *pQuery = pRequest->pQuery;
25,500,103✔
1528

1529
  pRequest->metric.ctgCostUs += taosGetTimestampUs() - pRequest->metric.ctgStart;
25,500,103✔
1530
  qDebug("req:0x%" PRIx64 ", continue parse query, QID:0x%" PRIx64 ", code:%s", pRequest->self, pRequest->requestId,
25,500,103✔
1531
         tstrerror(code));
1532

1533
  if (code == TSDB_CODE_SUCCESS) {
25,500,103✔
1534
    // pWrapper->pCatalogReq->forceUpdate = false;
1535
    code = qContinueParseSql(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
25,497,609✔
1536
  }
1537

1538
  if (TSDB_CODE_SUCCESS == code) {
25,500,103✔
1539
    code = phaseAsyncQuery(pWrapper);
17,024,202✔
1540
  }
1541

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

1553
void continueInsertFromCsv(SSqlCallbackWrapper *pWrapper, SRequestObj *pRequest) {
13,414✔
1554
  int32_t code = qParseSqlSyntax(pWrapper->pParseCtx, &pRequest->pQuery, pWrapper->pCatalogReq);
13,414✔
1555
  if (TSDB_CODE_SUCCESS == code) {
13,414!
1556
    code = phaseAsyncQuery(pWrapper);
13,414✔
1557
  }
1558

1559
  if (TSDB_CODE_SUCCESS != code) {
13,414!
1560
    tscError("req:0x%" PRIx64 ", error happens, code:%d - %s, QID:0x%" PRIx64, pWrapper->pRequest->self, code,
×
1561
             tstrerror(code), pWrapper->pRequest->requestId);
1562
    destorySqlCallbackWrapper(pWrapper);
×
1563
    pRequest->pWrapper = NULL;
×
1564
    terrno = code;
×
1565
    pRequest->code = code;
×
1566
    doRequestCallback(pRequest, code);
×
1567
  }
1568
}
13,414✔
1569

1570
void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param) {
45,038✔
1571
  int64_t connId = *(int64_t *)taos;
45,038✔
1572
  taosAsyncQueryImpl(connId, sql, fp, param, false, TD_REQ_FROM_APP);
45,038✔
1573
}
45,038✔
1574

1575
void taos_query_a_with_reqid(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param, int64_t reqid) {
×
1576
  int64_t connId = *(int64_t *)taos;
×
1577
  taosAsyncQueryImplWithReqid(connId, sql, fp, param, false, reqid);
×
1578
}
×
1579

1580
int32_t createParseContext(const SRequestObj *pRequest, SParseContext **pCxt, SSqlCallbackWrapper *pWrapper) {
716,784,538✔
1581
  const STscObj *pTscObj = pRequest->pTscObj;
716,784,538✔
1582

1583
  *pCxt = taosMemoryCalloc(1, sizeof(SParseContext));
716,793,530!
1584
  if (*pCxt == NULL) {
716,769,309!
1585
    return terrno;
×
1586
  }
1587

1588
  **pCxt = (SParseContext){.requestId = pRequest->requestId,
1,425,026,932✔
1589
                           .requestRid = pRequest->self,
716,775,661✔
1590
                           .acctId = pTscObj->acctId,
716,787,266✔
1591
                           .db = pRequest->pDb,
716,789,713✔
1592
                           .topicQuery = false,
1593
                           .pSql = pRequest->sqlstr,
716,790,063✔
1594
                           .sqlLen = pRequest->sqlLen,
716,790,888✔
1595
                           .pMsg = pRequest->msgBuf,
716,789,833✔
1596
                           .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE,
1597
                           .pTransporter = pTscObj->pAppInfo->pTransporter,
716,787,554✔
1598
                           .pStmtCb = NULL,
1599
                           .pUser = pTscObj->user,
716,786,588✔
1600
                           .pEffectiveUser = pRequest->effectiveUser,
716,792,687✔
1601
                           .isSuperUser = (0 == strcmp(pTscObj->user, TSDB_DEFAULT_USER)),
716,796,171!
1602
                           .enableSysInfo = pTscObj->sysInfo,
716,789,801✔
1603
                           .async = true,
1604
                           .svrVer = pTscObj->sVer,
716,784,421✔
1605
                           .nodeOffline = (pTscObj->pAppInfo->onlineDnodes < pTscObj->pAppInfo->totalDnodes),
716,795,427✔
1606
                           .allocatorId = pRequest->allocatorRefId,
716,785,362✔
1607
                           .parseSqlFp = clientParseSql,
1608
                           .parseSqlParam = pWrapper,
1609
                           .setQueryFp = setQueryRequest,
1610
                           .timezone = pTscObj->optionInfo.timezone,
716,797,936✔
1611
                           .charsetCxt = pTscObj->optionInfo.charsetCxt};
716,792,969✔
1612
  int8_t biMode = atomic_load_8(&((STscObj *)pTscObj)->biMode);
716,779,603✔
1613
  (*pCxt)->biMode = biMode;
716,771,809✔
1614
  return TSDB_CODE_SUCCESS;
716,782,355✔
1615
}
1616

1617
int32_t prepareAndParseSqlSyntax(SSqlCallbackWrapper **ppWrapper, SRequestObj *pRequest, bool updateMetaForce) {
716,785,203✔
1618
  int32_t              code = TSDB_CODE_SUCCESS;
716,785,203✔
1619
  STscObj             *pTscObj = pRequest->pTscObj;
716,785,203✔
1620
  SSqlCallbackWrapper *pWrapper = taosMemoryCalloc(1, sizeof(SSqlCallbackWrapper));
716,787,753!
1621
  if (pWrapper == NULL) {
716,771,244!
1622
    code = terrno;
×
1623
  } else {
1624
    pWrapper->pRequest = pRequest;
716,771,244✔
1625
    pRequest->pWrapper = pWrapper;
716,772,769✔
1626
    *ppWrapper = pWrapper;
716,783,676✔
1627
  }
1628

1629
  if (TSDB_CODE_SUCCESS == code) {
716,775,765!
1630
    code = createParseContext(pRequest, &pWrapper->pParseCtx, pWrapper);
716,778,546✔
1631
  }
1632

1633
  if (TSDB_CODE_SUCCESS == code) {
716,785,869!
1634
    pWrapper->pParseCtx->mgmtEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
716,786,265✔
1635
    code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pWrapper->pParseCtx->pCatalog);
716,800,403✔
1636
  }
1637

1638
  if (TSDB_CODE_SUCCESS == code && NULL == pRequest->pQuery) {
716,783,784✔
1639
    int64_t syntaxStart = taosGetTimestampUs();
716,793,478✔
1640

1641
    pWrapper->pCatalogReq = taosMemoryCalloc(1, sizeof(SCatalogReq));
716,793,478!
1642
    if (pWrapper->pCatalogReq == NULL) {
716,766,679!
1643
      code = terrno;
×
1644
    } else {
1645
      pWrapper->pCatalogReq->forceUpdate = updateMetaForce;
716,771,236✔
1646
      TSC_ERR_RET(qnodeRequired(pRequest, &pWrapper->pCatalogReq->qNodeRequired));
716,782,969!
1647
      code = qParseSqlSyntax(pWrapper->pParseCtx, &pRequest->pQuery, pWrapper->pCatalogReq);
716,773,502✔
1648
    }
1649

1650
    pRequest->metric.parseCostUs += taosGetTimestampUs() - syntaxStart;
716,785,899✔
1651
  }
1652

1653
  return code;
716,800,292✔
1654
}
1655

1656
void doAsyncQuery(SRequestObj *pRequest, bool updateMetaForce) {
717,977,197✔
1657
  SSqlCallbackWrapper *pWrapper = NULL;
717,977,197✔
1658
  int32_t              code = TSDB_CODE_SUCCESS;
717,989,286✔
1659

1660
  if (pRequest->retry++ > REQUEST_TOTAL_EXEC_TIMES) {
717,989,286✔
1661
    code = pRequest->prevCode;
1,194,462✔
1662
    terrno = code;
1,194,462✔
1663
    pRequest->code = code;
1,194,462✔
1664
    tscDebug("req:0x%" PRIx64 ", call sync query cb with code:%s", pRequest->self, tstrerror(code));
1,194,462✔
1665
    doRequestCallback(pRequest, code);
1,194,462✔
1666
    return;
1,194,462✔
1667
  }
1668

1669
  if (TSDB_CODE_SUCCESS == code) {
716,774,712✔
1670
    code = prepareAndParseSqlSyntax(&pWrapper, pRequest, updateMetaForce);
716,781,012✔
1671
  }
1672

1673
  if (TSDB_CODE_SUCCESS == code) {
716,763,268✔
1674
    pRequest->stmtType = pRequest->pQuery->pRoot->type;
703,404,349✔
1675
    code = phaseAsyncQuery(pWrapper);
703,397,274✔
1676
  }
1677

1678
  if (TSDB_CODE_SUCCESS != code) {
716,779,119✔
1679
    if (NULL != pRequest->msgBuf && strlen(pRequest->msgBuf) > 0) {
13,375,080!
1680
      tscError("req:0x%" PRIx64 ", error happens, code:%d - %s, QID:0x%" PRIx64, pRequest->self, code, pRequest->msgBuf,
13,203,097✔
1681
               pRequest->requestId);
1682
    } else {
1683
      tscError("req:0x%" PRIx64 ", error happens, code:%d - %s, QID:0x%" PRIx64, pRequest->self, code, tstrerror(code),
171,983!
1684
               pRequest->requestId);
1685
    }
1686

1687
    destorySqlCallbackWrapper(pWrapper);
13,375,080✔
1688
    pRequest->pWrapper = NULL;
13,375,080✔
1689
    qDestroyQuery(pRequest->pQuery);
13,375,080✔
1690
    pRequest->pQuery = NULL;
13,375,080✔
1691

1692
    if (NEED_CLIENT_HANDLE_ERROR(code) && pRequest->stmtBindVersion == 0) {
13,375,080!
1693
      tscDebug("req:0x%" PRIx64 ", client retry to handle the error, code:%d - %s, tryCount:%d, QID:0x%" PRIx64,
20,927!
1694
               pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId);
1695
      code = refreshMeta(pRequest->pTscObj, pRequest);
20,927✔
1696
      if (code != 0) {
20,927!
1697
        tscWarn("req:0x%" PRIx64 ", refresh meta failed, code:%d - %s, QID:0x%" PRIx64, pRequest->self, code, tstrerror(code),
20,927!
1698
                pRequest->requestId);
1699
      }
1700
      pRequest->prevCode = code;
20,927✔
1701
      doAsyncQuery(pRequest, true);
20,927✔
1702
      return;
20,927✔
1703
    }
1704

1705
    terrno = code;
13,354,153✔
1706
    pRequest->code = code;
13,354,153✔
1707
    doRequestCallback(pRequest, code);
13,354,153✔
1708
  }
1709
}
1710

1711
void restartAsyncQuery(SRequestObj *pRequest, int32_t code) {
3,611,182✔
1712
  tscInfo("restart request:%s p:%p", pRequest->sqlstr, pRequest);
3,611,182!
1713
  SRequestObj *pUserReq = pRequest;
3,611,182✔
1714
  (void)acquireRequest(pRequest->self);
3,611,182✔
1715
  while (pUserReq) {
3,611,182!
1716
    if (pUserReq->self == pUserReq->relation.userRefId || pUserReq->relation.userRefId == 0) {
3,611,182!
1717
      break;
1718
    } else {
1719
      int64_t nextRefId = pUserReq->relation.nextRefId;
×
1720
      (void)releaseRequest(pUserReq->self);
×
1721
      if (nextRefId) {
×
1722
        pUserReq = acquireRequest(nextRefId);
×
1723
      }
1724
    }
1725
  }
1726
  bool hasSubRequest = pUserReq != pRequest || pRequest->relation.prevRefId != 0;
3,611,182!
1727
  if (pUserReq) {
3,611,182!
1728
    destroyCtxInRequest(pUserReq);
3,611,182✔
1729
    pUserReq->prevCode = code;
3,611,182✔
1730
    (void)memset(&pUserReq->relation, 0, sizeof(pUserReq->relation));
3,611,182!
1731
  } else {
1732
    tscError("User req is missing");
×
1733
    (void)removeFromMostPrevReq(pRequest);
×
1734
    return;
×
1735
  }
1736
  if (hasSubRequest)
3,611,182!
1737
    (void)removeFromMostPrevReq(pRequest);
×
1738
  else
1739
    (void)releaseRequest(pUserReq->self);
3,611,182✔
1740
  doAsyncQuery(pUserReq, true);
3,611,182✔
1741
}
1742

1743
typedef struct SAsyncFetchParam {
1744
  SRequestObj      *pReq;
1745
  __taos_async_fn_t fp;
1746
  void             *param;
1747
} SAsyncFetchParam;
1748

1749
static int32_t doAsyncFetch(void *pParam) {
124,950,780✔
1750
  SAsyncFetchParam *param = pParam;
124,950,780✔
1751
  taosAsyncFetchImpl(param->pReq, param->fp, param->param);
124,950,780✔
1752
  taosMemoryFree(param);
124,949,635!
1753
  return TSDB_CODE_SUCCESS;
124,949,758✔
1754
}
1755

1756
void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
124,956,162✔
1757
  if (res == NULL || fp == NULL) {
124,956,162!
1758
    tscError("taos_fetch_rows_a invalid paras");
×
1759
    return;
×
1760
  }
1761
  if (!TD_RES_QUERY(res)) {
124,956,162!
1762
    tscError("taos_fetch_rows_a res is NULL");
×
1763
    fp(param, res, TSDB_CODE_APP_ERROR);
×
1764
    return;
×
1765
  }
1766

1767
  SRequestObj *pRequest = res;
124,956,162✔
1768
  if (TSDB_SQL_RETRIEVE_EMPTY_RESULT == pRequest->type) {
124,956,162✔
1769
    fp(param, res, 0);
5,805✔
1770
    return;
5,805✔
1771
  }
1772

1773
  SAsyncFetchParam *pParam = taosMemoryCalloc(1, sizeof(SAsyncFetchParam));
124,950,357!
1774
  if (!pParam) {
124,950,426!
1775
    fp(param, res, terrno);
×
1776
    return;
×
1777
  }
1778
  pParam->pReq = pRequest;
124,950,426✔
1779
  pParam->fp = fp;
124,950,426✔
1780
  pParam->param = param;
124,950,426✔
1781
  int32_t code = taosAsyncExec(doAsyncFetch, pParam, NULL);
124,950,426✔
1782
  if (TSDB_CODE_SUCCESS != code) {
124,949,989!
1783
    taosMemoryFree(pParam);
×
1784
    fp(param, res, code);
×
1785
    return;
×
1786
  }
1787
}
1788

1789
void taos_fetch_raw_block_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
140✔
1790
  if (res == NULL || fp == NULL) {
140!
1791
    tscError("taos_fetch_raw_block_a invalid paras");
×
1792
    return;
×
1793
  }
1794
  if (!TD_RES_QUERY(res)) {
140!
1795
    tscError("taos_fetch_raw_block_a res is NULL");
×
1796
    return;
×
1797
  }
1798
  SRequestObj    *pRequest = res;
140✔
1799
  SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
140✔
1800

1801
  // set the current block is all consumed
1802
  pResultInfo->convertUcs4 = false;
140✔
1803

1804
  // it is a local executed query, no need to do async fetch
1805
  taos_fetch_rows_a(pRequest, fp, param);
140✔
1806
}
1807

1808
const void *taos_get_raw_block(TAOS_RES *res) {
80✔
1809
  if (res == NULL) {
80!
1810
    tscError("taos_get_raw_block invalid paras");
×
1811
    return NULL;
×
1812
  }
1813
  if (!TD_RES_QUERY(res)) {
80!
1814
    tscError("taos_get_raw_block res is NULL");
×
1815
    return NULL;
×
1816
  }
1817
  SRequestObj *pRequest = res;
80✔
1818

1819
  return pRequest->body.resInfo.pData;
80✔
1820
}
1821

1822
int taos_get_db_route_info(TAOS *taos, const char *db, TAOS_DB_ROUTE_INFO *dbInfo) {
×
1823
  if (NULL == taos) {
×
1824
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1825
    return terrno;
×
1826
  }
1827

1828
  if (NULL == db || NULL == dbInfo) {
×
1829
    tscError("invalid input param, db:%p, dbInfo:%p", db, dbInfo);
×
1830
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1831
    return terrno;
×
1832
  }
1833

1834
  int64_t      connId = *(int64_t *)taos;
×
1835
  SRequestObj *pRequest = NULL;
×
1836
  char        *sql = "taos_get_db_route_info";
×
1837
  int32_t      code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
×
1838
  if (code != TSDB_CODE_SUCCESS) {
×
1839
    terrno = code;
×
1840
    return terrno;
×
1841
  }
1842

1843
  STscObj  *pTscObj = pRequest->pTscObj;
×
1844
  SCatalog *pCtg = NULL;
×
1845
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
×
1846
  if (code != TSDB_CODE_SUCCESS) {
×
1847
    goto _return;
×
1848
  }
1849

1850
  SRequestConnInfo conn = {
×
1851
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
×
1852

1853
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
×
1854

1855
  char dbFName[TSDB_DB_FNAME_LEN] = {0};
×
1856
  (void)snprintf(dbFName, sizeof(dbFName), "%d.%s", pTscObj->acctId, db);
×
1857

1858
  code = catalogGetDBVgInfo(pCtg, &conn, dbFName, dbInfo);
×
1859
  if (code) {
×
1860
    goto _return;
×
1861
  }
1862

1863
_return:
×
1864

1865
  terrno = code;
×
1866

1867
  destroyRequest(pRequest);
×
1868
  return code;
×
1869
}
1870

1871
int taos_get_table_vgId(TAOS *taos, const char *db, const char *table, int *vgId) {
×
1872
  if (NULL == taos) {
×
1873
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1874
    return terrno;
×
1875
  }
1876

1877
  if (NULL == db || NULL == table || NULL == vgId) {
×
1878
    tscError("invalid input param, db:%p, table:%p, vgId:%p", db, table, vgId);
×
1879
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1880
    return terrno;
×
1881
  }
1882

1883
  int64_t      connId = *(int64_t *)taos;
×
1884
  SRequestObj *pRequest = NULL;
×
1885
  char        *sql = "taos_get_table_vgId";
×
1886
  int32_t      code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
×
1887
  if (code != TSDB_CODE_SUCCESS) {
×
1888
    return terrno;
×
1889
  }
1890

1891
  pRequest->syncQuery = true;
×
1892

1893
  STscObj  *pTscObj = pRequest->pTscObj;
×
1894
  SCatalog *pCtg = NULL;
×
1895
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
×
1896
  if (code != TSDB_CODE_SUCCESS) {
×
1897
    goto _return;
×
1898
  }
1899

1900
  SRequestConnInfo conn = {
×
1901
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
×
1902

1903
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
×
1904

1905
  SName tableName = {0};
×
1906
  toName(pTscObj->acctId, db, table, &tableName);
×
1907

1908
  SVgroupInfo vgInfo;
×
1909
  code = catalogGetTableHashVgroup(pCtg, &conn, &tableName, &vgInfo);
×
1910
  if (code) {
×
1911
    goto _return;
×
1912
  }
1913

1914
  *vgId = vgInfo.vgId;
×
1915

1916
_return:
×
1917

1918
  terrno = code;
×
1919

1920
  destroyRequest(pRequest);
×
1921
  return code;
×
1922
}
1923

1924
int taos_get_tables_vgId(TAOS *taos, const char *db, const char *table[], int tableNum, int *vgId) {
×
1925
  if (NULL == taos) {
×
1926
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1927
    return terrno;
×
1928
  }
1929

1930
  if (NULL == db || NULL == table || NULL == vgId || tableNum <= 0) {
×
1931
    tscError("invalid input param, db:%p, table:%p, vgId:%p, tbNum:%d", db, table, vgId, tableNum);
×
1932
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1933
    return terrno;
×
1934
  }
1935

1936
  int64_t      connId = *(int64_t *)taos;
×
1937
  SRequestObj *pRequest = NULL;
×
1938
  char        *sql = "taos_get_table_vgId";
×
1939
  int32_t      code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
×
1940
  if (code != TSDB_CODE_SUCCESS) {
×
1941
    return terrno;
×
1942
  }
1943

1944
  pRequest->syncQuery = true;
×
1945

1946
  STscObj  *pTscObj = pRequest->pTscObj;
×
1947
  SCatalog *pCtg = NULL;
×
1948
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
×
1949
  if (code != TSDB_CODE_SUCCESS) {
×
1950
    goto _return;
×
1951
  }
1952

1953
  SRequestConnInfo conn = {
×
1954
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
×
1955

1956
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
×
1957

1958
  code = catalogGetTablesHashVgId(pCtg, &conn, pTscObj->acctId, db, table, tableNum, vgId);
×
1959
  if (code) {
×
1960
    goto _return;
×
1961
  }
1962

1963
_return:
×
1964

1965
  terrno = code;
×
1966

1967
  destroyRequest(pRequest);
×
1968
  return code;
×
1969
}
1970

1971
int taos_load_table_info(TAOS *taos, const char *tableNameList) {
1,478✔
1972
  if (NULL == taos) {
1,478!
1973
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1974
    return terrno;
×
1975
  }
1976

1977
  int64_t       connId = *(int64_t *)taos;
1,478✔
1978
  const int32_t MAX_TABLE_NAME_LENGTH = 12 * 1024 * 1024;  // 12MB list
1,478✔
1979
  int32_t       code = 0;
1,478✔
1980
  SRequestObj  *pRequest = NULL;
1,478✔
1981
  SCatalogReq   catalogReq = {0};
1,478✔
1982

1983
  if (NULL == tableNameList) {
1,478!
1984
    return TSDB_CODE_SUCCESS;
×
1985
  }
1986

1987
  int32_t length = (int32_t)strlen(tableNameList);
1,478!
1988
  if (0 == length) {
1,478!
1989
    return TSDB_CODE_SUCCESS;
×
1990
  } else if (length > MAX_TABLE_NAME_LENGTH) {
1,478!
1991
    tscError("tableNameList too long, length:%d, maximum allowed:%d", length, MAX_TABLE_NAME_LENGTH);
×
1992
    return TSDB_CODE_TSC_INVALID_OPERATION;
×
1993
  }
1994

1995
  char *sql = "taos_load_table_info";
1,478✔
1996
  code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
1,478!
1997
  if (code != TSDB_CODE_SUCCESS) {
1,478!
1998
    terrno = code;
×
1999
    goto _return;
×
2000
  }
2001

2002
  pRequest->syncQuery = true;
1,478✔
2003

2004
  STscObj *pTscObj = pRequest->pTscObj;
1,478✔
2005
  code = transferTableNameList(tableNameList, pTscObj->acctId, pTscObj->db, &catalogReq.pTableMeta);
1,478✔
2006
  if (code) {
1,478!
2007
    goto _return;
×
2008
  }
2009

2010
  SCatalog *pCtg = NULL;
1,478✔
2011
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
1,478✔
2012
  if (code != TSDB_CODE_SUCCESS) {
1,478!
2013
    goto _return;
×
2014
  }
2015

2016
  SRequestConnInfo conn = {
1,478✔
2017
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
1,478✔
2018

2019
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
1,478✔
2020

2021
  code = catalogAsyncGetAllMeta(pCtg, &conn, &catalogReq, syncCatalogFn, pRequest->body.interParam, NULL);
1,478✔
2022
  if (code) {
1,478!
2023
    goto _return;
×
2024
  }
2025

2026
  SSyncQueryParam *pParam = pRequest->body.interParam;
1,478✔
2027
  code = tsem_wait(&pParam->sem);
1,478✔
2028
  if (code) {
1,478!
2029
    tscError("tsem wait failed, code:%d - %s", code, tstrerror(code));
×
2030
    goto _return;
×
2031
  }
2032
_return:
1,478✔
2033
  destoryCatalogReq(&catalogReq);
1,478✔
2034
  destroyRequest(pRequest);
1,478✔
2035
  return code;
1,478✔
2036
}
2037

2038
TAOS_STMT *taos_stmt_init(TAOS *taos) {
421,437✔
2039
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
421,437✔
2040
  if (NULL == pObj) {
422,498!
2041
    tscError("invalid parameter for %s", __FUNCTION__);
×
2042
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
2043
    return NULL;
×
2044
  }
2045

2046
  TAOS_STMT *pStmt = stmtInit(pObj, 0, NULL);
422,498✔
2047
  if (NULL == pStmt) {
422,390!
2048
    tscError("stmt init failed, errcode:%s", terrstr());
×
2049
  }
2050
  releaseTscObj(*(int64_t *)taos);
422,390✔
2051

2052
  return pStmt;
422,498✔
2053
}
2054

2055
TAOS_STMT *taos_stmt_init_with_reqid(TAOS *taos, int64_t reqid) {
×
2056
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
×
2057
  if (NULL == pObj) {
×
2058
    tscError("invalid parameter for %s", __FUNCTION__);
×
2059
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
2060
    return NULL;
×
2061
  }
2062

2063
  TAOS_STMT *pStmt = stmtInit(pObj, reqid, NULL);
×
2064
  if (NULL == pStmt) {
×
2065
    tscError("stmt init failed, errcode:%s", terrstr());
×
2066
  }
2067
  releaseTscObj(*(int64_t *)taos);
×
2068

2069
  return pStmt;
×
2070
}
2071

2072
TAOS_STMT *taos_stmt_init_with_options(TAOS *taos, TAOS_STMT_OPTIONS *options) {
35,512✔
2073
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
35,512✔
2074
  if (NULL == pObj) {
35,512!
2075
    tscError("invalid parameter for %s", __FUNCTION__);
×
2076
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
2077
    return NULL;
×
2078
  }
2079

2080
  TAOS_STMT *pStmt = stmtInit(pObj, options->reqId, options);
35,512✔
2081
  if (NULL == pStmt) {
35,512!
2082
    tscError("stmt init failed, errcode:%s", terrstr());
×
2083
  }
2084
  releaseTscObj(*(int64_t *)taos);
35,512✔
2085

2086
  return pStmt;
35,512✔
2087
}
2088

2089
int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length) {
889,982✔
2090
  if (stmt == NULL || sql == NULL) {
889,982!
2091
    tscError("NULL parameter for %s", __FUNCTION__);
×
2092
    terrno = TSDB_CODE_INVALID_PARA;
×
2093
    return terrno;
×
2094
  }
2095

2096
  return stmtPrepare(stmt, sql, length);
890,565✔
2097
}
2098

2099
int taos_stmt_set_tbname_tags(TAOS_STMT *stmt, const char *name, TAOS_MULTI_BIND *tags) {
7,011✔
2100
  if (stmt == NULL || name == NULL) {
7,011!
2101
    tscError("NULL parameter for %s", __FUNCTION__);
×
2102
    terrno = TSDB_CODE_INVALID_PARA;
×
2103
    return terrno;
×
2104
  }
2105

2106
  int32_t code = stmtSetTbName(stmt, name);
7,011✔
2107
  if (code) {
7,011✔
2108
    return code;
739✔
2109
  }
2110

2111
  if (tags) {
6,272!
2112
    return stmtSetTbTags(stmt, tags);
6,272✔
2113
  }
2114

2115
  return TSDB_CODE_SUCCESS;
×
2116
}
2117

2118
int taos_stmt_set_tbname(TAOS_STMT *stmt, const char *name) {
5,979,609✔
2119
  if (stmt == NULL || name == NULL) {
5,979,609!
2120
    tscError("NULL parameter for %s", __FUNCTION__);
×
2121
    terrno = TSDB_CODE_INVALID_PARA;
×
2122
    return terrno;
×
2123
  }
2124

2125
  return stmtSetTbName(stmt, name);
5,981,132✔
2126
}
2127

2128
int taos_stmt_set_tags(TAOS_STMT *stmt, TAOS_MULTI_BIND *tags) {
180✔
2129
  if (stmt == NULL || tags == NULL) {
180!
2130
    tscError("NULL parameter for %s", __FUNCTION__);
×
2131
    terrno = TSDB_CODE_INVALID_PARA;
×
2132
    return terrno;
×
2133
  }
2134

2135
  return stmtSetTbTags(stmt, tags);
180✔
2136
}
2137

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

2140
int taos_stmt_get_tag_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields) {
4✔
2141
  if (stmt == NULL || NULL == fieldNum) {
4!
2142
    tscError("NULL parameter for %s", __FUNCTION__);
×
2143
    terrno = TSDB_CODE_INVALID_PARA;
×
2144
    return terrno;
×
2145
  }
2146

2147
  return stmtGetTagFields(stmt, fieldNum, fields);
4✔
2148
}
2149

2150
int taos_stmt_get_col_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields) {
6✔
2151
  if (stmt == NULL || NULL == fieldNum) {
6!
2152
    tscError("NULL parameter for %s", __FUNCTION__);
×
2153
    terrno = TSDB_CODE_INVALID_PARA;
×
2154
    return terrno;
×
2155
  }
2156

2157
  return stmtGetColFields(stmt, fieldNum, fields);
6✔
2158
}
2159

2160
// let stmt to reclaim TAOS_FIELD_E that was allocated by `taos_stmt_get_tag_fields`/`taos_stmt_get_col_fields`
2161
void taos_stmt_reclaim_fields(TAOS_STMT *stmt, TAOS_FIELD_E *fields) {
×
2162
  (void)stmt;
2163
  if (!fields) return;
×
2164
  taosMemoryFree(fields);
×
2165
}
2166

2167
int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
36,007✔
2168
  if (stmt == NULL || bind == NULL) {
36,007!
2169
    tscError("NULL parameter for %s", __FUNCTION__);
×
2170
    terrno = TSDB_CODE_INVALID_PARA;
×
2171
    return terrno;
×
2172
  }
2173

2174
  if (bind->num > 1) {
36,007✔
2175
    tscError("invalid bind number %d for %s", bind->num, __FUNCTION__);
4,494!
2176
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
4,494✔
2177
    return terrno;
4,494✔
2178
  }
2179

2180
  return stmtBindBatch(stmt, bind, -1);
31,513✔
2181
}
2182

2183
int taos_stmt_bind_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
108,556,537✔
2184
  if (stmt == NULL || bind == NULL) {
108,556,537!
2185
    tscError("NULL parameter for %s", __FUNCTION__);
×
2186
    terrno = TSDB_CODE_INVALID_PARA;
×
2187
    return terrno;
×
2188
  }
2189

2190
  if (bind->num <= 0 || bind->num > INT16_MAX) {
109,937,279!
2191
    tscError("invalid bind num %d", bind->num);
6,954!
2192
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
6,954✔
2193
    return terrno;
×
2194
  }
2195

2196
  int32_t insert = 0;
110,230,371✔
2197
  int32_t code = stmtIsInsert(stmt, &insert);
109,839,691✔
2198
  if (TSDB_CODE_SUCCESS != code) {
110,226,669!
2199
    tscError("stmt insert failed, errcode:%s", tstrerror(code));
×
2200
    return code;
×
2201
  }
2202
  if (0 == insert && bind->num > 1) {
110,226,669!
2203
    tscError("only one row data allowed for query");
×
2204
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
2205
    return terrno;
×
2206
  }
2207

2208
  return stmtBindBatch(stmt, bind, -1);
110,226,669✔
2209
}
2210

2211
int taos_stmt_bind_single_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int colIdx) {
420✔
2212
  if (stmt == NULL || bind == NULL) {
420!
2213
    tscError("NULL parameter for %s", __FUNCTION__);
×
2214
    terrno = TSDB_CODE_INVALID_PARA;
×
2215
    return terrno;
×
2216
  }
2217

2218
  if (colIdx < 0) {
420!
2219
    tscError("invalid bind column idx %d", colIdx);
×
2220
    terrno = TSDB_CODE_INVALID_PARA;
×
2221
    return terrno;
×
2222
  }
2223

2224
  int32_t insert = 0;
420✔
2225
  int32_t code = stmtIsInsert(stmt, &insert);
420✔
2226
  if (TSDB_CODE_SUCCESS != code) {
420!
2227
    tscError("stmt insert failed, errcode:%s", tstrerror(code));
×
2228
    return code;
×
2229
  }
2230
  if (0 == insert && bind->num > 1) {
420!
2231
    tscError("only one row data allowed for query");
×
2232
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
2233
    return terrno;
×
2234
  }
2235

2236
  return stmtBindBatch(stmt, bind, colIdx);
420✔
2237
}
2238

2239
int taos_stmt_add_batch(TAOS_STMT *stmt) {
104,480,729✔
2240
  if (stmt == NULL) {
104,480,729!
2241
    tscError("NULL parameter for %s", __FUNCTION__);
×
2242
    terrno = TSDB_CODE_INVALID_PARA;
×
2243
    return terrno;
×
2244
  }
2245

2246
  return stmtAddBatch(stmt);
104,480,729✔
2247
}
2248

2249
int taos_stmt_execute(TAOS_STMT *stmt) {
3,421,078✔
2250
  if (stmt == NULL) {
3,421,078!
2251
    tscError("NULL parameter for %s", __FUNCTION__);
×
2252
    terrno = TSDB_CODE_INVALID_PARA;
×
2253
    return terrno;
×
2254
  }
2255

2256
  return stmtExec(stmt);
3,421,078✔
2257
}
2258

2259
int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert) {
×
2260
  if (stmt == NULL || insert == NULL) {
×
2261
    tscError("NULL parameter for %s", __FUNCTION__);
×
2262
    terrno = TSDB_CODE_INVALID_PARA;
×
2263
    return terrno;
×
2264
  }
2265

2266
  return stmtIsInsert(stmt, insert);
×
2267
}
2268

2269
int taos_stmt_num_params(TAOS_STMT *stmt, int *nums) {
×
2270
  if (stmt == NULL || nums == NULL) {
×
2271
    tscError("NULL parameter for %s", __FUNCTION__);
×
2272
    terrno = TSDB_CODE_INVALID_PARA;
×
2273
    return terrno;
×
2274
  }
2275

2276
  return stmtGetParamNum(stmt, nums);
×
2277
}
2278

2279
int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) {
4✔
2280
  if (stmt == NULL || type == NULL || NULL == bytes || idx < 0) {
4!
2281
    tscError("invalid parameter for %s", __FUNCTION__);
×
2282
    terrno = TSDB_CODE_INVALID_PARA;
×
2283
    return terrno;
×
2284
  }
2285

2286
  return stmtGetParam(stmt, idx, type, bytes);
4✔
2287
}
2288

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

2296
  return stmtUseResult(stmt);
12,325✔
2297
}
2298

2299
char *taos_stmt_errstr(TAOS_STMT *stmt) { return (char *)stmtErrstr(stmt); }
11,956✔
2300

2301
int taos_stmt_affected_rows(TAOS_STMT *stmt) {
3,129✔
2302
  if (stmt == NULL) {
3,129!
2303
    tscError("NULL parameter for %s", __FUNCTION__);
×
2304
    terrno = TSDB_CODE_INVALID_PARA;
×
2305
    return 0;
×
2306
  }
2307

2308
  return stmtAffectedRows(stmt);
3,129✔
2309
}
2310

2311
int taos_stmt_affected_rows_once(TAOS_STMT *stmt) {
118✔
2312
  if (stmt == NULL) {
118!
2313
    tscError("NULL parameter for %s", __FUNCTION__);
×
2314
    terrno = TSDB_CODE_INVALID_PARA;
×
2315
    return 0;
×
2316
  }
2317

2318
  return stmtAffectedRowsOnce(stmt);
118✔
2319
}
2320

2321
int taos_stmt_close(TAOS_STMT *stmt) {
457,394✔
2322
  if (stmt == NULL) {
457,394!
2323
    tscError("NULL parameter for %s", __FUNCTION__);
×
2324
    terrno = TSDB_CODE_INVALID_PARA;
×
2325
    return terrno;
×
2326
  }
2327

2328
  return stmtClose(stmt);
457,394✔
2329
}
2330

2331
TAOS_STMT2 *taos_stmt2_init(TAOS *taos, TAOS_STMT2_OPTION *option) {
28,740✔
2332
  if (NULL == taos) {
28,740✔
2333
    tscError("NULL parameter for %s", __FUNCTION__);
1!
2334
    terrno = TSDB_CODE_INVALID_PARA;
1✔
2335
    return NULL;
1✔
2336
  }
2337
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
28,739✔
2338
  if (NULL == pObj) {
28,739!
2339
    tscError("invalid parameter for %s", __FUNCTION__);
×
2340
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
2341
    return NULL;
×
2342
  }
2343

2344
  TAOS_STMT2 *pStmt = stmtInit2(pObj, option);
28,739✔
2345

2346
  releaseTscObj(*(int64_t *)taos);
28,739✔
2347

2348
  return pStmt;
28,739✔
2349
}
2350

2351
int taos_stmt2_prepare(TAOS_STMT2 *stmt, const char *sql, unsigned long length) {
29,000✔
2352
  if (stmt == NULL || sql == NULL) {
29,000!
2353
    tscError("NULL parameter for %s", __FUNCTION__);
1!
2354
    terrno = TSDB_CODE_INVALID_PARA;
1✔
2355
    return terrno;
1✔
2356
  }
2357

2358
  return stmtPrepare2(stmt, sql, length);
28,999✔
2359
}
2360

2361
int taos_stmt2_bind_param(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx) {
1,746,752✔
2362
  if (stmt == NULL) {
1,746,752!
2363
    tscError("NULL parameter for %s", __FUNCTION__);
×
2364
    terrno = TSDB_CODE_INVALID_PARA;
×
2365
    return terrno;
×
2366
  }
2367

2368
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
1,746,752✔
2369
  STMT2_DLOG_E("start to bind param");
1,746,752!
2370
  if (atomic_load_8((int8_t *)&pStmt->asyncBindParam.asyncBindNum) > 1) {
1,746,752!
2371
    STMT2_ELOG_E("async bind param is still working, please try again later");
×
2372
    terrno = TSDB_CODE_TSC_STMT_API_ERROR;
×
2373
    return terrno;
×
2374
  }
2375

2376
  if (pStmt->options.asyncExecFn && !pStmt->execSemWaited) {
1,747,526!
2377
    if (tsem_wait(&pStmt->asyncExecSem) != 0) {
18!
2378
      STMT2_ELOG_E("bind param wait asyncExecSem failed");
×
2379
    }
2380
    pStmt->execSemWaited = true;
18✔
2381
  }
2382

2383
  int32_t code = TSDB_CODE_SUCCESS;
1,747,139✔
2384
  for (int i = 0; i < bindv->count; ++i) {
4,696,591✔
2385
    if (bindv->tbnames && bindv->tbnames[i]) {
2,948,304!
2386
      code = stmtSetTbName2(stmt, bindv->tbnames[i]);
2,949,851✔
2387
      if (code) {
2,949,440✔
2388
        terrno = code;
5✔
2389
        STMT2_ELOG("set tbname failed, code:%s", tstrerror(code));
5!
2390
        return terrno;
13✔
2391
      }
2392
    }
2393

2394
    SVCreateTbReq *pCreateTbReq = NULL;
2,946,703✔
2395
    if (bindv->tags && bindv->tags[i]) {
2,947,888!
2396
      code = stmtSetTbTags2(stmt, bindv->tags[i], &pCreateTbReq);
382✔
2397
    } else if (pStmt->bInfo.tbNameFlag & IS_FIXED_TAG) {
2,947,530✔
2398
      code = stmtCheckTags2(stmt, &pCreateTbReq);
339✔
2399
    } else if (pStmt->sql.autoCreateTbl) {
2,946,804!
2400
      // if (pStmt->sql.autoCreateTbl) {
2401
      //   pStmt->sql.autoCreateTbl = false;
2402
      //   STMT2_WLOG_E("sql is autoCreateTbl, but no tags");
2403
      // }
2404
      code = stmtSetTbTags2(stmt, NULL, &pCreateTbReq);
21✔
2405
    }
2406

2407
    if (code) {
2,946,727✔
2408
      terrno = code;
1✔
2409
      STMT2_ELOG("set tags failed, code:%s", tstrerror(code));
1!
2410
      return terrno;
1✔
2411
    }
2412

2413
    if (bindv->bind_cols && bindv->bind_cols[i]) {
2,946,726✔
2414
      TAOS_STMT2_BIND *bind = bindv->bind_cols[i];
2,947,523✔
2415

2416
      if (bind->num <= 0 || bind->num > INT16_MAX) {
2,949,071✔
2417
        STMT2_ELOG("bind num:%d must > 0 and < INT16_MAX", bind->num);
1,548!
2418
        code = terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
1,548✔
2419
        return terrno;
×
2420
      }
2421

2422
      if (!stmt2IsInsert(stmt) && bind->num > 1) {
2,947,934✔
2423
        STMT2_ELOG_E("only one row data allowed for query");
1!
2424
        code = terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
1✔
2425
        return terrno;
1✔
2426
      }
2427

2428
      code = stmtBindBatch2(stmt, bind, col_idx, pCreateTbReq);
2,949,481✔
2429
      if (TSDB_CODE_SUCCESS != code) {
2,948,635✔
2430
        terrno = code;
6✔
2431
        STMT2_ELOG("bind batch failed, code:%s", tstrerror(code));
6!
2432
        return terrno;
6✔
2433
      }
2434
    }
2435
  }
2436

2437
  return code;
1,748,287✔
2438
}
2439

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

2447
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
×
2448

2449
  ThreadArgs *args = (ThreadArgs *)taosMemoryMalloc(sizeof(ThreadArgs));
×
2450
  args->stmt = stmt;
×
2451
  args->bindv = bindv;
×
2452
  args->col_idx = col_idx;
×
2453
  args->fp = fp;
×
2454
  args->param = param;
×
2455

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

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

2476
  return code_s;
×
2477
}
2478

2479
int taos_stmt2_exec(TAOS_STMT2 *stmt, int *affected_rows) {
1,748,271✔
2480
  if (stmt == NULL) {
1,748,271!
2481
    tscError("NULL parameter for %s", __FUNCTION__);
×
2482
    terrno = TSDB_CODE_INVALID_PARA;
×
2483
    return terrno;
×
2484
  }
2485

2486
  return stmtExec2(stmt, affected_rows);
1,748,271✔
2487
}
2488

2489
int taos_stmt2_close(TAOS_STMT2 *stmt) {
28,736✔
2490
  if (stmt == NULL) {
28,736!
2491
    tscError("NULL parameter for %s", __FUNCTION__);
×
2492
    terrno = TSDB_CODE_INVALID_PARA;
×
2493
    return terrno;
×
2494
  }
2495

2496
  return stmtClose2(stmt);
28,736✔
2497
}
2498

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

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

2516
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
91✔
2517
  if (STMT_TYPE_INSERT == pStmt->sql.type || STMT_TYPE_MULTI_INSERT == pStmt->sql.type ||
91!
2518
      (pStmt->sql.type == 0 && stmt2IsInsert(stmt))) {
84✔
2519
    return stmtGetStbColFields2(stmt, count, fields);
80✔
2520
  }
2521
  if (STMT_TYPE_QUERY == pStmt->sql.type || (pStmt->sql.type == 0 && stmt2IsSelect(stmt))) {
11!
2522
    return stmtGetParamNum2(stmt, count);
10✔
2523
  }
2524

2525
  tscError("Invalid sql for stmt %s", pStmt->sql.sqlStr);
1!
2526
  return TSDB_CODE_PAR_SYNTAX_ERROR;
1✔
2527
}
2528

2529
DLL_EXPORT void taos_stmt2_free_fields(TAOS_STMT2 *stmt, TAOS_FIELD_ALL *fields) {
69✔
2530
  (void)stmt;
2531
  if (!fields) return;
69✔
2532
  taosMemoryFree(fields);
51!
2533
}
2534

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

2542
  return stmtUseResult2(stmt);
8✔
2543
}
2544

2545
char *taos_stmt2_error(TAOS_STMT2 *stmt) { return (char *)stmtErrstr2(stmt); }
25✔
2546

2547
int taos_set_conn_mode(TAOS *taos, int mode, int value) {
4,279✔
2548
  if (taos == NULL) {
4,279!
2549
    terrno = TSDB_CODE_INVALID_PARA;
×
2550
    return terrno;
×
2551
  }
2552

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

2570
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