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

taosdata / TDengine / #4872

04 Dec 2025 01:55AM UTC coverage: 64.678% (+0.02%) from 64.654%
#4872

push

travis-ci

guanshengliang
Merge branch '3.0' into cover/3.0

880 of 2219 new or added lines in 36 files covered. (39.66%)

6146 existing lines in 122 files now uncovered.

159679 of 246882 relevant lines covered (64.68%)

110947965.82 hits per line

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

40.74
/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 "tmisce.h"
31
#include "tmsg.h"
32
#include "tref.h"
33
#include "trpc.h"
34
#include "tversion.h"
35
#include "version.h"
36

37
#define TSC_VAR_NOT_RELEASE 1
38
#define TSC_VAR_RELEASED    0
39

40
#ifdef TAOSD_INTEGRATED
41
extern void shellStopDaemon();
42
#endif
43

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

47
int taos_options(TSDB_OPTION option, const void *arg, ...) {
601,764✔
48
  if (arg == NULL) {
601,764✔
UNCOV
49
    return TSDB_CODE_INVALID_PARA;
×
50
  }
51
  static int32_t lock = 0;
52

53
  for (int i = 1; atomic_val_compare_exchange_32(&lock, 0, 1) != 0; ++i) {
52,636,896✔
54
    if (i % 1000 == 0) {
51,936,748✔
55
      (void)sched_yield();
52,255✔
56
    }
57
  }
58

59
  int ret = taos_options_imp(option, (const char *)arg);
439,316✔
60
  atomic_store_32(&lock, 0);
601,764✔
61
  return ret;
601,764✔
62
}
63

64
#if !defined(WINDOWS) && !defined(TD_ASTRA)
UNCOV
65
static void freeTz(void *p) {
×
UNCOV
66
  timezone_t tz = *(timezone_t *)p;
×
67
  tzfree(tz);
×
68
}
×
69

70
int32_t tzInit() {
1,663,876✔
71
  pTimezoneMap = taosHashInit(0, MurmurHash3_32, false, HASH_ENTRY_LOCK);
1,663,876✔
72
  if (pTimezoneMap == NULL) {
1,663,876✔
UNCOV
73
    return terrno;
×
74
  }
75
  taosHashSetFreeFp(pTimezoneMap, freeTz);
1,663,876✔
76

77
  pTimezoneNameMap = taosHashInit(0, taosIntHash_64, false, HASH_ENTRY_LOCK);
1,663,876✔
78
  if (pTimezoneNameMap == NULL) {
1,663,876✔
UNCOV
79
    return terrno;
×
80
  }
81
  return 0;
1,663,876✔
82
}
83

84
void tzCleanup() {
1,664,140✔
85
  taosHashCleanup(pTimezoneMap);
1,664,140✔
86
  taosHashCleanup(pTimezoneNameMap);
1,664,140✔
87
}
1,664,140✔
88

UNCOV
89
static timezone_t setConnnectionTz(const char *val) {
×
UNCOV
90
  timezone_t  tz = NULL;
×
91
  timezone_t *tmp = taosHashGet(pTimezoneMap, val, strlen(val));
×
92
  if (tmp != NULL && *tmp != NULL) {
×
93
    tz = *tmp;
×
94
    goto END;
×
95
  }
96

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

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

UNCOV
126
END:
×
UNCOV
127
  return tz;
×
128
}
129
#endif
130

UNCOV
131
static int32_t setConnectionOption(TAOS *taos, TSDB_OPTION_CONNECTION option, const char *val) {
×
UNCOV
132
  if (taos == NULL) {
×
133
    return terrno = TSDB_CODE_INVALID_PARA;
×
134
  }
135

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

UNCOV
142
  if (option < TSDB_OPTION_CONNECTION_CLEAR || option >= TSDB_MAX_OPTIONS_CONNECTION) {
×
UNCOV
143
    return terrno = TSDB_CODE_INVALID_PARA;
×
144
  }
145

UNCOV
146
  int32_t code = taos_init();
×
147
  // initialize global config
148
  if (code != 0) {
×
UNCOV
149
    return terrno = code;
×
150
  }
151

UNCOV
152
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
×
UNCOV
153
  if (NULL == pObj) {
×
154
    tscError("invalid parameter for %s", __func__);
×
155
    return terrno;
×
156
  }
157

UNCOV
158
  if (option == TSDB_OPTION_CONNECTION_CLEAR) {
×
UNCOV
159
    val = NULL;
×
160
  }
161

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

UNCOV
198
  if (option == TSDB_OPTION_CONNECTION_USER_APP || option == TSDB_OPTION_CONNECTION_CLEAR) {
×
UNCOV
199
    if (val != NULL) {
×
200
      tstrncpy(pObj->optionInfo.userApp, val, sizeof(pObj->optionInfo.userApp));
×
201
    } else {
202
      pObj->optionInfo.userApp[0] = 0;
×
203
    }
204
  }
205

UNCOV
206
  if (option == TSDB_OPTION_CONNECTION_CONNECTOR_INFO || option == TSDB_OPTION_CONNECTION_CLEAR) {
×
UNCOV
207
    if (val != NULL) {
×
208
      tstrncpy(pObj->optionInfo.cInfo, val, sizeof(pObj->optionInfo.cInfo));
×
209
    } else {
210
      pObj->optionInfo.cInfo[0] = 0;
×
211
    }
212
  }
213

UNCOV
214
  if (option == TSDB_OPTION_CONNECTION_USER_IP || option == TSDB_OPTION_CONNECTION_CLEAR) {
×
UNCOV
215
    SIpRange dualIp = {0};
×
216
    if (val != NULL) {
×
217
      pObj->optionInfo.userIp = taosInetAddr(val);
×
218
      SIpAddr addr = {0};
×
219
      code = taosGetIpFromFqdn(tsEnableIpv6, val, &addr);
×
220
      if (code == 0) {
×
221
        code = tIpStrToUint(&addr, &pObj->optionInfo.userDualIp);
×
222
      }
223
      if (code != 0) {
×
NEW
224
        tscError("ipv6 flag %d failed to convert user ip %s to dual ip since %s", tsEnableIpv6 ? 1 : 0, val,
×
225
                 tstrerror(code));
NEW
226
        pObj->optionInfo.userIp = INADDR_NONE;
×
NEW
227
        pObj->optionInfo.userDualIp = dualIp;
×
228
        code = 0;
×
229
      }
230
    } else {
231
      pObj->optionInfo.userIp = INADDR_NONE;
×
UNCOV
232
      pObj->optionInfo.userDualIp = dualIp;
×
233
    }
234
  }
235

UNCOV
236
END:
×
UNCOV
237
  releaseTscObj(*(int64_t *)taos);
×
UNCOV
238
  return terrno = code;
×
239
}
240

241
int taos_options_connection(TAOS *taos, TSDB_OPTION_CONNECTION option, const void *arg, ...) {
×
UNCOV
242
  return setConnectionOption(taos, option, (const char *)arg);
×
243
}
244

245
// this function may be called by user or system, or by both simultaneously.
246
void taos_cleanup(void) {
1,667,467✔
247
  tscInfo("start to cleanup client environment");
1,667,467✔
248
  if (atomic_val_compare_exchange_32(&sentinel, TSC_VAR_NOT_RELEASE, TSC_VAR_RELEASED) != TSC_VAR_NOT_RELEASE) {
1,667,467✔
249
    return;
3,327✔
250
  }
251

252
  monitorClose();
1,664,140✔
253
  tscStopCrashReport();
1,664,140✔
254

255
  hbMgrCleanUp();
1,664,140✔
256

257
  catalogDestroy();
1,664,140✔
258
  schedulerDestroy();
1,664,140✔
259

260
  fmFuncMgtDestroy();
1,664,140✔
261
  qCleanupKeywordsTable();
1,664,140✔
262

263
#if !defined(WINDOWS) && !defined(TD_ASTRA)
264
  tzCleanup();
1,664,140✔
265
#endif
266
  tmqMgmtClose();
1,664,140✔
267

268
  int32_t id = clientReqRefPool;
1,664,140✔
269
  clientReqRefPool = -1;
1,664,140✔
270
  taosCloseRef(id);
1,664,140✔
271

272
  id = clientConnRefPool;
1,664,140✔
273
  clientConnRefPool = -1;
1,664,140✔
274
  taosCloseRef(id);
1,664,140✔
275

276
  nodesDestroyAllocatorSet();
1,664,140✔
277
  cleanupAppInfo();
1,664,140✔
278
  rpcCleanup();
1,664,140✔
279
  tscDebug("rpc cleanup");
1,664,140✔
280

281
  if (TSDB_CODE_SUCCESS != cleanupTaskQueue()) {
1,664,140✔
UNCOV
282
    tscWarn("failed to cleanup task queue");
×
283
  }
284

285
  taosConvDestroy();
1,664,140✔
286
  DestroyRegexCache();
1,664,140✔
287
#ifdef TAOSD_INTEGRATED
288
  shellStopDaemon();
289
#endif
290
  tscInfo("all local resources released");
1,664,140✔
291
  taosCleanupCfg();
1,664,140✔
292
#ifndef TAOSD_INTEGRATED
293
  taosCloseLog();
1,664,140✔
294
#endif
295
}
296

297
static setConfRet taos_set_config_imp(const char *config) {
486✔
298
  setConfRet ret = {SET_CONF_RET_SUCC, {0}};
486✔
299
  // TODO: need re-implementation
300
  return ret;
486✔
301
}
302

303
setConfRet taos_set_config(const char *config) {
486✔
304
  // TODO  pthread_mutex_lock(&setConfMutex);
305
  setConfRet ret = taos_set_config_imp(config);
486✔
306
  //  pthread_mutex_unlock(&setConfMutex);
307
  return ret;
486✔
308
}
309

310
TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port) {
3,550,741✔
311
  tscInfo("try to connect to %s:%u, user:%s db:%s", ip, port, user, db);
3,550,741✔
312
  if (user == NULL) {
3,551,916✔
313
    user = TSDB_DEFAULT_USER;
397,407✔
314
  }
315

316
  if (pass == NULL) {
3,551,916✔
317
    pass = TSDB_DEFAULT_PASS;
397,407✔
318
  }
319

320
  STscObj *pObj = NULL;
3,551,916✔
321
  int32_t  code = taos_connect_internal(ip, user, pass, NULL, db, port, CONN_TYPE__QUERY, &pObj);
3,551,660✔
322
  if (TSDB_CODE_SUCCESS == code) {
3,551,489✔
323
    int64_t *rid = taosMemoryCalloc(1, sizeof(int64_t));
3,532,416✔
324
    if (NULL == rid) {
3,532,573✔
UNCOV
325
      tscError("out of memory when taos connect to %s:%u, user:%s db:%s", ip, port, user, db);
×
UNCOV
326
      return NULL;
×
327
    }
328
    *rid = pObj->id;
3,532,573✔
329
    return (TAOS *)rid;
3,532,829✔
330
  } else {
331
    terrno = code;
19,073✔
332
  }
333

334
  return NULL;
19,073✔
335
}
336

337
int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type) {
17,290✔
338
  if (taos == NULL) {
17,290✔
UNCOV
339
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
340
    return terrno;
×
341
  }
342

343
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
17,290✔
344
  if (NULL == pObj) {
17,290✔
UNCOV
345
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
UNCOV
346
    tscError("invalid parameter for %s", __func__);
×
UNCOV
347
    return terrno;
×
348
  }
349

350
  switch (type) {
17,290✔
351
    case TAOS_NOTIFY_PASSVER: {
4,940✔
352
      TSC_ERR_RET(taosThreadMutexLock(&pObj->mutex));
4,940✔
353
      pObj->passInfo.fp = fp;
4,940✔
354
      pObj->passInfo.param = param;
4,940✔
355
      TSC_ERR_RET(taosThreadMutexUnlock(&pObj->mutex));
4,940✔
356
      break;
4,940✔
357
    }
UNCOV
358
    case TAOS_NOTIFY_WHITELIST_VER: {
×
UNCOV
359
      TSC_ERR_RET(taosThreadMutexLock(&pObj->mutex));
×
UNCOV
360
      pObj->whiteListInfo.fp = fp;
×
361
      pObj->whiteListInfo.param = param;
×
362
      TSC_ERR_RET(taosThreadMutexUnlock(&pObj->mutex));
×
363
      break;
×
364
    }
365
    case TAOS_NOTIFY_USER_DROPPED: {
12,350✔
366
      TSC_ERR_RET(taosThreadMutexLock(&pObj->mutex));
12,350✔
367
      pObj->userDroppedInfo.fp = fp;
12,350✔
368
      pObj->userDroppedInfo.param = param;
12,350✔
369
      TSC_ERR_RET(taosThreadMutexUnlock(&pObj->mutex));
12,350✔
370
      break;
12,350✔
371
    }
UNCOV
372
    default: {
×
UNCOV
373
      terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
374
      releaseTscObj(*(int64_t *)taos);
×
375
      return terrno;
×
376
    }
377
  }
378

379
  releaseTscObj(*(int64_t *)taos);
17,290✔
380
  return 0;
17,290✔
381
}
382

383
typedef struct SFetchWhiteListInfo {
384
  int64_t                     connId;
385
  __taos_async_whitelist_fn_t userCbFn;
386
  void                       *userParam;
387
} SFetchWhiteListInfo;
388

UNCOV
389
int32_t fetchWhiteListCallbackFn(void *param, SDataBuf *pMsg, int32_t code) {
×
UNCOV
390
  SFetchWhiteListInfo *pInfo = (SFetchWhiteListInfo *)param;
×
UNCOV
391
  TAOS                *taos = &pInfo->connId;
×
392
  if (code != TSDB_CODE_SUCCESS) {
×
393
    pInfo->userCbFn(pInfo->userParam, code, taos, 0, NULL);
×
394
    taosMemoryFree(pMsg->pData);
×
395
    taosMemoryFree(pMsg->pEpSet);
×
396
    taosMemoryFree(pInfo);
×
397
    return code;
×
398
  }
399

400
  SGetUserWhiteListRsp wlRsp;
×
UNCOV
401
  if (TSDB_CODE_SUCCESS != tDeserializeSGetUserWhiteListRsp(pMsg->pData, pMsg->len, &wlRsp)) {
×
UNCOV
402
    taosMemoryFree(pMsg->pData);
×
403
    taosMemoryFree(pMsg->pEpSet);
×
404
    taosMemoryFree(pInfo);
×
405
    tFreeSGetUserWhiteListRsp(&wlRsp);
×
406
    return terrno;
×
407
  }
408

409
  uint64_t *pWhiteLists = taosMemoryMalloc(wlRsp.numWhiteLists * sizeof(uint64_t));
×
UNCOV
410
  if (pWhiteLists == NULL) {
×
UNCOV
411
    taosMemoryFree(pMsg->pData);
×
412
    taosMemoryFree(pMsg->pEpSet);
×
413
    taosMemoryFree(pInfo);
×
414
    tFreeSGetUserWhiteListRsp(&wlRsp);
×
415
    return terrno;
×
416
  }
417

418
  for (int i = 0; i < wlRsp.numWhiteLists; ++i) {
×
UNCOV
419
    pWhiteLists[i] = ((uint64_t)wlRsp.pWhiteLists[i].mask << 32) | wlRsp.pWhiteLists[i].ip;
×
420
  }
421

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

UNCOV
424
  taosMemoryFree(pWhiteLists);
×
425
  taosMemoryFree(pMsg->pData);
×
UNCOV
426
  taosMemoryFree(pMsg->pEpSet);
×
427
  taosMemoryFree(pInfo);
×
428
  tFreeSGetUserWhiteListRsp(&wlRsp);
×
429
  return code;
×
430
}
431

432
void taos_fetch_whitelist_a(TAOS *taos, __taos_async_whitelist_fn_t fp, void *param) {
×
UNCOV
433
  if (NULL == taos) {
×
UNCOV
434
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
435
    return;
×
436
  }
437

438
  int64_t connId = *(int64_t *)taos;
×
439

UNCOV
440
  STscObj *pTsc = acquireTscObj(connId);
×
441
  if (NULL == pTsc) {
×
UNCOV
442
    fp(param, TSDB_CODE_TSC_DISCONNECTED, taos, 0, NULL);
×
443
    return;
×
444
  }
445

446
  SGetUserWhiteListReq req;
×
UNCOV
447
  (void)memcpy(req.user, pTsc->user, TSDB_USER_LEN);
×
UNCOV
448
  int32_t msgLen = tSerializeSGetUserWhiteListReq(NULL, 0, &req);
×
449
  if (msgLen < 0) {
×
450
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
451
    releaseTscObj(connId);
×
452
    return;
×
453
  }
454

455
  void *pReq = taosMemoryMalloc(msgLen);
×
UNCOV
456
  if (pReq == NULL) {
×
UNCOV
457
    fp(param, terrno, taos, 0, NULL);
×
458
    releaseTscObj(connId);
×
459
    return;
×
460
  }
461

462
  if (tSerializeSGetUserWhiteListReq(pReq, msgLen, &req) < 0) {
×
UNCOV
463
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
UNCOV
464
    taosMemoryFree(pReq);
×
465
    releaseTscObj(connId);
×
466
    return;
×
467
  }
468

469
  SFetchWhiteListInfo *pParam = taosMemoryMalloc(sizeof(SFetchWhiteListInfo));
×
UNCOV
470
  if (pParam == NULL) {
×
UNCOV
471
    fp(param, terrno, taos, 0, NULL);
×
472
    taosMemoryFree(pReq);
×
473
    releaseTscObj(connId);
×
474
    return;
×
475
  }
476

477
  pParam->connId = connId;
×
UNCOV
478
  pParam->userCbFn = fp;
×
479

480
  pParam->userParam = param;
×
481
  SMsgSendInfo *pSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
×
UNCOV
482
  if (pSendInfo == NULL) {
×
483
    fp(param, terrno, taos, 0, NULL);
×
484
    taosMemoryFree(pParam);
×
485
    taosMemoryFree(pReq);
×
486
    releaseTscObj(connId);
×
487
    return;
×
488
  }
489

490
  pSendInfo->msgInfo = (SDataBuf){.pData = pReq, .len = msgLen, .handle = NULL};
×
UNCOV
491
  pSendInfo->requestId = generateRequestId();
×
UNCOV
492
  pSendInfo->requestObjRefId = 0;
×
493
  pSendInfo->param = pParam;
×
494
  pSendInfo->fp = fetchWhiteListCallbackFn;
×
495
  pSendInfo->msgType = TDMT_MND_GET_USER_WHITELIST;
×
496

497
  SEpSet epSet = getEpSet_s(&pTsc->pAppInfo->mgmtEp);
×
498
  if (TSDB_CODE_SUCCESS != asyncSendMsgToServer(pTsc->pAppInfo->pTransporter, &epSet, NULL, pSendInfo)) {
×
UNCOV
499
    tscWarn("failed to async send msg to server");
×
500
  }
501
  releaseTscObj(connId);
×
502
  return;
×
503
}
504

505
typedef struct SFetchWhiteListDualStackInfo {
506
  int64_t connId;
507
  void   *userParam;
508

509
  __taos_async_whitelist_dual_stack_fn_t userCbFn;
510
} SFetchWhiteListDualStackInfo;
511

UNCOV
512
int32_t fetchWhiteListDualStackCallbackFn(void *param, SDataBuf *pMsg, int32_t code) {
×
UNCOV
513
  int32_t lino = 0;
×
UNCOV
514
  char  **pWhiteLists = NULL;
×
515

516
  SGetUserWhiteListRsp wlRsp = {0};
×
517

UNCOV
518
  SFetchWhiteListDualStackInfo *pInfo = (SFetchWhiteListDualStackInfo *)param;
×
NEW
519
  TAOS                         *taos = &pInfo->connId;
×
520

521
  if (code != TSDB_CODE_SUCCESS) {
×
522
    pInfo->userCbFn(pInfo->userParam, code, taos, 0, NULL);
×
UNCOV
523
    TAOS_CHECK_GOTO(code, &lino, _error);
×
524
  }
525

526
  if ((code = tDeserializeSGetUserWhiteListDualRsp(pMsg->pData, pMsg->len, &wlRsp)) != TSDB_CODE_SUCCESS) {
×
UNCOV
527
    TAOS_CHECK_GOTO(code, &lino, _error);
×
528
  }
529

530
  pWhiteLists = taosMemoryMalloc(wlRsp.numWhiteLists * sizeof(char *));
×
UNCOV
531
  if (pWhiteLists == NULL) {
×
UNCOV
532
    code = terrno;
×
533
    TAOS_CHECK_GOTO(code, &lino, _error);
×
534
  }
535

536
  for (int32_t i = 0; i < wlRsp.numWhiteLists; i++) {
×
UNCOV
537
    SIpRange *pIpRange = &wlRsp.pWhiteListsDual[i];
×
UNCOV
538
    SIpAddr   ipAddr = {0};
×
539

540
    code = tIpUintToStr(pIpRange, &ipAddr);
×
541
    TAOS_CHECK_GOTO(code, &lino, _error);
×
542

543
    char *ip = taosMemCalloc(1, IP_RESERVE_CAP);
×
544
    if (ip == NULL) {
×
UNCOV
545
      code = terrno;
×
546
      TAOS_CHECK_GOTO(code, &lino, _error);
×
547
    }
548
    if (ipAddr.type == 0) {
×
549
      snprintf(ip, IP_RESERVE_CAP, "%s/%d", ipAddr.ipv4, ipAddr.mask);
×
550
    } else {
551
      if (ipAddr.ipv6[0] == 0) {
×
552
        memcpy(ipAddr.ipv6, "::", 2);
×
553
      }
554
      snprintf(ip, IP_RESERVE_CAP, "%s/%d", ipAddr.ipv6, ipAddr.mask);
×
555
    }
UNCOV
556
    pWhiteLists[i] = ip;
×
557
  }
558

559
  pInfo->userCbFn(pInfo->userParam, code, taos, wlRsp.numWhiteLists, pWhiteLists);
×
UNCOV
560
_error:
×
UNCOV
561
  if (pWhiteLists != NULL) {
×
562
    for (int32_t i = 0; i < wlRsp.numWhiteLists; i++) {
×
563
      taosMemFree(pWhiteLists[i]);
×
564
    }
565
    taosMemoryFree(pWhiteLists);
×
566
  }
UNCOV
567
  taosMemoryFree(pMsg->pData);
×
568
  taosMemoryFree(pMsg->pEpSet);
×
UNCOV
569
  taosMemoryFree(pInfo);
×
570
  tFreeSGetUserWhiteListDualRsp(&wlRsp);
×
571
  return code;
×
572
}
573
void taos_fetch_whitelist_dual_stack_a(TAOS *taos, __taos_async_whitelist_dual_stack_fn_t fp, void *param) {
×
574
  if (NULL == taos) {
×
UNCOV
575
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
576
    return;
×
577
  }
578
  int64_t connId = *(int64_t *)taos;
×
579

UNCOV
580
  STscObj *pTsc = acquireTscObj(connId);
×
581
  if (NULL == pTsc) {
×
UNCOV
582
    fp(param, TSDB_CODE_TSC_DISCONNECTED, taos, 0, NULL);
×
583
    return;
×
584
  }
585

586
  SGetUserWhiteListReq req;
×
UNCOV
587
  (void)memcpy(req.user, pTsc->user, TSDB_USER_LEN);
×
UNCOV
588
  int32_t msgLen = tSerializeSGetUserWhiteListReq(NULL, 0, &req);
×
589
  if (msgLen < 0) {
×
590
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
591
    releaseTscObj(connId);
×
592
    return;
×
593
  }
594

595
  void *pReq = taosMemoryMalloc(msgLen);
×
UNCOV
596
  if (pReq == NULL) {
×
UNCOV
597
    fp(param, terrno, taos, 0, NULL);
×
598
    releaseTscObj(connId);
×
599
    return;
×
600
  }
601

602
  if (tSerializeSGetUserWhiteListReq(pReq, msgLen, &req) < 0) {
×
UNCOV
603
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
UNCOV
604
    taosMemoryFree(pReq);
×
605
    releaseTscObj(connId);
×
606
    return;
×
607
  }
608

609
  SFetchWhiteListDualStackInfo *pParam = taosMemoryMalloc(sizeof(SFetchWhiteListDualStackInfo));
×
UNCOV
610
  if (pParam == NULL) {
×
UNCOV
611
    fp(param, terrno, taos, 0, NULL);
×
612
    taosMemoryFree(pReq);
×
613
    releaseTscObj(connId);
×
614
    return;
×
615
  }
616

617
  pParam->connId = connId;
×
UNCOV
618
  pParam->userCbFn = fp;
×
UNCOV
619
  pParam->userParam = param;
×
620

621
  SMsgSendInfo *pSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
×
622
  if (pSendInfo == NULL) {
×
UNCOV
623
    fp(param, terrno, taos, 0, NULL);
×
624
    taosMemoryFree(pParam);
×
625
    taosMemoryFree(pReq);
×
626
    releaseTscObj(connId);
×
627
    return;
×
628
  }
629

630
  pSendInfo->msgInfo = (SDataBuf){.pData = pReq, .len = msgLen, .handle = NULL};
×
UNCOV
631
  pSendInfo->requestId = generateRequestId();
×
UNCOV
632
  pSendInfo->requestObjRefId = 0;
×
633
  pSendInfo->param = pParam;
×
634
  pSendInfo->fp = fetchWhiteListDualStackCallbackFn;
×
635
  pSendInfo->msgType = TDMT_MND_GET_USER_WHITELIST_DUAL;
×
636

637
  SEpSet epSet = getEpSet_s(&pTsc->pAppInfo->mgmtEp);
×
638
  if (TSDB_CODE_SUCCESS != asyncSendMsgToServer(pTsc->pAppInfo->pTransporter, &epSet, NULL, pSendInfo)) {
×
UNCOV
639
    tscWarn("failed to async send msg to server");
×
640
  }
641
  releaseTscObj(connId);
×
642
  return;
×
643
}
644

645
void taos_close_internal(void *taos) {
3,635,495✔
646
  if (taos == NULL) {
3,635,495✔
UNCOV
647
    return;
×
648
  }
649

650
  STscObj *pTscObj = (STscObj *)taos;
3,635,495✔
651
  tscDebug("conn:0x%" PRIx64 ", try to close connection, numOfReq:%d", pTscObj->id, pTscObj->numOfReqs);
3,635,495✔
652

653
  if (TSDB_CODE_SUCCESS != taosRemoveRef(clientConnRefPool, pTscObj->id)) {
3,635,495✔
UNCOV
654
    tscError("conn:0x%" PRIx64 ", failed to remove ref from conn pool", pTscObj->id);
×
655
  }
656
}
657

658
void taos_close(TAOS *taos) {
3,531,829✔
659
  if (taos == NULL) {
3,531,829✔
660
    return;
272✔
661
  }
662

663
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
3,531,557✔
664
  if (NULL == pObj) {
3,531,557✔
UNCOV
665
    taosMemoryFree(taos);
×
UNCOV
666
    return;
×
667
  }
668

669
  taos_close_internal(pObj);
3,531,557✔
670
  releaseTscObj(*(int64_t *)taos);
3,531,557✔
671
  taosMemoryFree(taos);
3,531,557✔
672
}
673

674
int taos_errno(TAOS_RES *res) {
821,401,005✔
675
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
821,401,005✔
676
    return terrno;
39,982✔
677
  }
678

679
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
821,360,704✔
680
    return 0;
373,500✔
681
  }
682

683
  return ((SRequestObj *)res)->code;
820,987,353✔
684
}
685

686
const char *taos_errstr(TAOS_RES *res) {
21,570,445✔
687
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
21,570,445✔
688
    return (const char *)tstrerror(terrno);
40,120✔
689
  }
690

691
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
21,530,325✔
UNCOV
692
    return "success";
×
693
  }
694

695
  SRequestObj *pRequest = (SRequestObj *)res;
21,530,325✔
696
  if (NULL != pRequest->msgBuf && (strlen(pRequest->msgBuf) > 0 || pRequest->code == TSDB_CODE_RPC_FQDN_ERROR)) {
21,530,325✔
697
    return pRequest->msgBuf;
17,547,131✔
698
  } else {
699
    return (const char *)tstrerror(pRequest->code);
3,983,194✔
700
  }
701
}
702

703
void taos_free_result(TAOS_RES *res) {
648,412,899✔
704
  if (NULL == res) {
648,412,899✔
705
    return;
1,461,065✔
706
  }
707

708
  tscTrace("res:%p, will be freed", res);
646,951,834✔
709

710
  if (TD_RES_QUERY(res)) {
646,951,919✔
711
    SRequestObj *pRequest = (SRequestObj *)res;
643,840,942✔
712
    tscDebug("QID:0x%" PRIx64 ", call taos_free_result to free query, res:%p", pRequest->requestId, res);
643,840,942✔
713
    destroyRequest(pRequest);
643,840,942✔
714
    return;
643,839,548✔
715
  }
716

717
  SMqRspObj *pRsp = (SMqRspObj *)res;
3,110,670✔
718
  if (TD_RES_TMQ(res)) {
3,110,670✔
719
    tDeleteMqDataRsp(&pRsp->dataRsp);
3,102,279✔
720
    doFreeReqResultInfo(&pRsp->resInfo);
3,102,279✔
721
  } else if (TD_RES_TMQ_METADATA(res)) {
10,090✔
722
    tDeleteSTaosxRsp(&pRsp->dataRsp);
376✔
723
    doFreeReqResultInfo(&pRsp->resInfo);
376✔
724
  } else if (TD_RES_TMQ_META(res)) {
9,714✔
725
    tDeleteMqMetaRsp(&pRsp->metaRsp);
8,392✔
726
  } else if (TD_RES_TMQ_BATCH_META(res)) {
1,322✔
727
    tDeleteMqBatchMetaRsp(&pRsp->batchMetaRsp);
1,322✔
UNCOV
728
  } else if (TD_RES_TMQ_RAW(res)) {
×
UNCOV
729
    tDeleteMqRawDataRsp(&pRsp->dataRsp);
×
730
  }
731
  taosMemoryFree(pRsp);
3,112,075✔
732
}
733

734
void taos_kill_query(TAOS *taos) {
544✔
735
  if (NULL == taos) {
544✔
736
    return;
272✔
737
  }
738

739
  int64_t  rid = *(int64_t *)taos;
272✔
740
  STscObj *pTscObj = acquireTscObj(rid);
272✔
741
  if (pTscObj) {
272✔
742
    stopAllRequests(pTscObj->pRequests);
136✔
743
  }
744
  releaseTscObj(rid);
272✔
745
}
746

747
int taos_field_count(TAOS_RES *res) {
2,147,483,647✔
748
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
2,147,483,647✔
UNCOV
749
    return 0;
×
750
  }
751

752
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
2,147,483,647✔
753
  return pResInfo->numOfCols;
2,147,483,647✔
754
}
755

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

758
TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) {
1,450,299,272✔
759
  if (taos_num_fields(res) == 0 || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
1,450,299,272✔
760
    return NULL;
2,527,329✔
761
  }
762

763
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
1,448,347,118✔
764
  return pResInfo->userFields;
1,448,347,118✔
765
}
766

767
TAOS_RES *taos_query(TAOS *taos, const char *sql) { return taosQueryImpl(taos, sql, false, TD_REQ_FROM_APP); }
642,313,706✔
768
TAOS_RES *taos_query_with_reqid(TAOS *taos, const char *sql, int64_t reqid) {
6,919✔
769
  return taosQueryImplWithReqid(taos, sql, false, reqid);
6,919✔
770
}
771

772
TAOS_FIELD_E *taos_fetch_fields_e(TAOS_RES *res) {
1,460✔
773
  if (taos_num_fields(res) == 0 || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
1,460✔
UNCOV
774
    return NULL;
×
775
  }
776
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
1,460✔
777
  return pResInfo->fields;
1,460✔
778
}
779

780
TAOS_ROW taos_fetch_row(TAOS_RES *res) {
2,147,483,647✔
781
  if (res == NULL) {
2,147,483,647✔
UNCOV
782
    return NULL;
×
783
  }
784

785
  if (TD_RES_QUERY(res)) {
2,147,483,647✔
786
    SRequestObj *pRequest = (SRequestObj *)res;
1,618,939,427✔
787
    if (pRequest->killed) {
1,618,939,427✔
UNCOV
788
      tscInfo("query has been killed, can not fetch more row.");
×
UNCOV
789
      pRequest->code = TSDB_CODE_TSC_QUERY_KILLED;
×
UNCOV
790
      return NULL;
×
791
    }
792

793
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
1,618,940,384✔
794
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
1,618,946,410✔
UNCOV
795
      return NULL;
×
796
    }
797

798
    if (pRequest->inCallback) {
1,618,918,088✔
UNCOV
799
      tscError("can not call taos_fetch_row before query callback ends.");
×
UNCOV
800
      terrno = TSDB_CODE_TSC_INVALID_OPERATION;
×
UNCOV
801
      return NULL;
×
802
    }
803

804
    return doAsyncFetchRows(pRequest, true, true);
1,618,920,381✔
805
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
1,350,878,960✔
806
    SMqRspObj      *msg = ((SMqRspObj *)res);
1,350,699,921✔
807
    SReqResultInfo *pResultInfo = NULL;
1,350,699,921✔
808
    if (msg->resIter == -1) {
1,350,717,038✔
809
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
2,700,127✔
UNCOV
810
        return NULL;
×
811
      }
812
    } else {
813
      pResultInfo = tmqGetCurResInfo(res);
1,348,310,028✔
814
    }
815

816
    if (pResultInfo->current < pResultInfo->numOfRows) {
1,351,010,155✔
817
      doSetOneRowPtr(pResultInfo);
1,323,380,350✔
818
      pResultInfo->current += 1;
1,323,327,856✔
819
      return pResultInfo->row;
1,323,380,162✔
820
    } else {
821
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
27,780,519✔
822
        return NULL;
2,699,972✔
823
      }
824

825
      doSetOneRowPtr(pResultInfo);
25,079,763✔
826
      pResultInfo->current += 1;
25,080,042✔
827
      return pResultInfo->row;
25,080,042✔
828
    }
UNCOV
829
  } else if (TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
×
UNCOV
830
    return NULL;
×
831
  } else {
832
    tscError("invalid result passed to taos_fetch_row");
×
833
    terrno = TSDB_CODE_TMQ_INVALID_DATA;
×
UNCOV
834
    return NULL;
×
835
  }
836
}
837

838
int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
1,351,161,051✔
839
  return taos_print_row_with_size(str, INT32_MAX, row, fields, num_fields);
1,351,161,051✔
840
}
841
int taos_print_row_with_size(char *str, uint32_t size, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
1,350,902,413✔
842
  int32_t len = 0;
1,350,902,413✔
843
  for (int i = 0; i < num_fields; ++i) {
2,147,483,647✔
844
    if (i > 0 && len < size - 1) {
2,147,483,647✔
845
      str[len++] = ' ';
2,147,483,647✔
846
    }
847

848
    if (row[i] == NULL) {
2,147,483,647✔
849
      len += tsnprintf(str + len, size - len, "%s", TSDB_DATA_NULL_STR);
29,543,474✔
850
      continue;
29,543,758✔
851
    }
852

853
    switch (fields[i].type) {
2,147,483,647✔
854
      case TSDB_DATA_TYPE_TINYINT:
76,764,843✔
855
        len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
76,764,843✔
856
        break;
76,985,060✔
857

858
      case TSDB_DATA_TYPE_UTINYINT:
1,067,000✔
859
        len += tsnprintf(str + len, size - len, "%u", *((uint8_t *)row[i]));
1,067,000✔
860
        break;
1,067,000✔
861

862
      case TSDB_DATA_TYPE_SMALLINT:
1,067,000✔
863
        len += tsnprintf(str + len, size - len, "%d", *((int16_t *)row[i]));
1,067,000✔
864
        break;
1,067,000✔
865

866
      case TSDB_DATA_TYPE_USMALLINT:
1,067,000✔
867
        len += tsnprintf(str + len, size - len, "%u", *((uint16_t *)row[i]));
1,067,000✔
868
        break;
1,067,000✔
869

870
      case TSDB_DATA_TYPE_INT:
1,408,739,783✔
871
        len += tsnprintf(str + len, size - len, "%d", *((int32_t *)row[i]));
1,408,739,783✔
872
        break;
1,408,567,228✔
873

874
      case TSDB_DATA_TYPE_UINT:
1,067,000✔
875
        len += tsnprintf(str + len, size - len, "%u", *((uint32_t *)row[i]));
1,067,000✔
876
        break;
1,067,000✔
877

878
      case TSDB_DATA_TYPE_BIGINT:
1,038,519,242✔
879
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
1,038,519,242✔
880
        break;
1,038,543,073✔
881

882
      case TSDB_DATA_TYPE_UBIGINT:
1,067,000✔
883
        len += tsnprintf(str + len, size - len, "%" PRIu64, *((uint64_t *)row[i]));
1,067,000✔
884
        break;
1,067,000✔
885

886
      case TSDB_DATA_TYPE_FLOAT: {
152,384,014✔
887
        float fv = 0;
152,384,014✔
888
        fv = GET_FLOAT_VAL(row[i]);
152,384,014✔
889
        len += snprintf(str + len, size - len, "%.*g", FLT_DIG, fv);
152,581,118✔
890
      } break;
152,618,712✔
891

892
      case TSDB_DATA_TYPE_DOUBLE: {
721,613,907✔
893
        double dv = 0;
721,613,907✔
894
        dv = GET_DOUBLE_VAL(row[i]);
721,613,907✔
895
        len += snprintf(str + len, size - len, "%.*g", DBL_DIG, dv);
721,651,010✔
896
      } break;
721,649,129✔
897

898
      case TSDB_DATA_TYPE_VARBINARY: {
1,067,328✔
899
        void    *data = NULL;
1,067,328✔
900
        uint32_t tmp = 0;
1,067,328✔
901
        int32_t  charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
1,067,328✔
902
        if (taosAscii2Hex(row[i], charLen, &data, &tmp) < 0) {
1,067,328✔
UNCOV
903
          break;
×
904
        }
905
        uint32_t copyLen = TMIN(size - len - 1, tmp);
1,066,822✔
906
        (void)memcpy(str + len, data, copyLen);
1,066,822✔
907
        len += copyLen;
1,066,822✔
908
        taosMemoryFree(data);
1,066,822✔
909
      } break;
1,067,328✔
910
      case TSDB_DATA_TYPE_BINARY:
1,351,655,681✔
911
      case TSDB_DATA_TYPE_NCHAR:
912
      case TSDB_DATA_TYPE_GEOMETRY: {
913
        int32_t charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
1,351,655,681✔
914
        if (fields[i].type == TSDB_DATA_TYPE_BINARY || fields[i].type == TSDB_DATA_TYPE_VARBINARY ||
1,351,778,791✔
915
            fields[i].type == TSDB_DATA_TYPE_GEOMETRY) {
357,819,721✔
916
          if (charLen > fields[i].bytes || charLen < 0) {
995,264,852✔
917
            tscError("taos_print_row error binary. charLen:%d, fields[i].bytes:%d", charLen, fields[i].bytes);
87,500✔
UNCOV
918
            break;
×
919
          }
920
        } else {
921
          if (charLen > fields[i].bytes * TSDB_NCHAR_SIZE || charLen < 0) {
356,752,650✔
UNCOV
922
            tscError("taos_print_row error. charLen:%d, fields[i].bytes:%d", charLen, fields[i].bytes);
×
UNCOV
923
            break;
×
924
          }
925
        }
926

927
        uint32_t copyLen = TMIN(size - len - 1, charLen);
1,351,898,011✔
928
        (void)memcpy(str + len, row[i], copyLen);
1,351,898,011✔
929
        len += copyLen;
1,352,097,088✔
930
      } break;
1,352,097,088✔
UNCOV
931
      case TSDB_DATA_TYPE_BLOB:
×
932
      case TSDB_DATA_TYPE_MEDIUMBLOB: {
UNCOV
933
        void    *data = NULL;
×
934
        uint32_t tmp = 0;
×
UNCOV
935
        int32_t  charLen = blobDataLen((char *)row[i] - BLOBSTR_HEADER_SIZE);
×
936
        if (taosAscii2Hex(row[i], charLen, &data, &tmp) < 0) {
×
937
          break;
×
938
        }
939

940
        uint32_t copyLen = TMIN(size - len - 1, tmp);
×
UNCOV
941
        (void)memcpy(str + len, data, copyLen);
×
UNCOV
942
        len += copyLen;
×
943

944
        taosMemoryFree(data);
×
945
      } break;
×
946

947
      case TSDB_DATA_TYPE_TIMESTAMP:
1,742,666,469✔
948
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
1,742,666,469✔
949
        break;
1,743,187,295✔
950

951
      case TSDB_DATA_TYPE_BOOL:
1,066,241✔
952
        len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
1,066,241✔
953
        break;
2,200✔
UNCOV
954
      case TSDB_DATA_TYPE_DECIMAL64:
×
955
      case TSDB_DATA_TYPE_DECIMAL: {
UNCOV
956
        uint32_t decimalLen = strlen(row[i]);
×
957
        uint32_t copyLen = TMIN(size - len - 1, decimalLen);
×
UNCOV
958
        (void)memcpy(str + len, row[i], copyLen);
×
959
        len += copyLen;
×
960
      } break;
×
961
      default:
×
962
        break;
×
963
    }
964

965
    if (len >= size - 1) {
2,147,483,647✔
UNCOV
966
      break;
×
967
    }
968
  }
969
  if (len < size) {
1,351,353,616✔
970
    str[len] = 0;
1,351,581,067✔
971
  }
972

973
  return len;
1,351,830,349✔
974
}
975

976
int *taos_fetch_lengths(TAOS_RES *res) {
2,147,483,647✔
977
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
2,147,483,647✔
UNCOV
978
    return NULL;
×
979
  }
980

981
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
2,147,483,647✔
982
  return pResInfo->length;
2,147,483,647✔
983
}
984

UNCOV
985
TAOS_ROW *taos_result_block(TAOS_RES *res) {
×
UNCOV
986
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
×
UNCOV
987
    terrno = TSDB_CODE_INVALID_PARA;
×
988
    return NULL;
×
989
  }
990

991
  if (taos_is_update_query(res)) {
×
UNCOV
992
    return NULL;
×
993
  }
994

995
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
×
UNCOV
996
  return &pResInfo->row;
×
997
}
998

999
// todo intergrate with tDataTypes
UNCOV
1000
const char *taos_data_type(int type) {
×
UNCOV
1001
  switch (type) {
×
UNCOV
1002
    case TSDB_DATA_TYPE_NULL:
×
1003
      return "TSDB_DATA_TYPE_NULL";
×
1004
    case TSDB_DATA_TYPE_BOOL:
×
1005
      return "TSDB_DATA_TYPE_BOOL";
×
1006
    case TSDB_DATA_TYPE_TINYINT:
×
1007
      return "TSDB_DATA_TYPE_TINYINT";
×
1008
    case TSDB_DATA_TYPE_SMALLINT:
×
1009
      return "TSDB_DATA_TYPE_SMALLINT";
×
1010
    case TSDB_DATA_TYPE_INT:
×
1011
      return "TSDB_DATA_TYPE_INT";
×
1012
    case TSDB_DATA_TYPE_BIGINT:
×
1013
      return "TSDB_DATA_TYPE_BIGINT";
×
1014
    case TSDB_DATA_TYPE_FLOAT:
×
1015
      return "TSDB_DATA_TYPE_FLOAT";
×
1016
    case TSDB_DATA_TYPE_DOUBLE:
×
1017
      return "TSDB_DATA_TYPE_DOUBLE";
×
1018
    case TSDB_DATA_TYPE_VARCHAR:
×
1019
      return "TSDB_DATA_TYPE_VARCHAR";
×
1020
      //    case TSDB_DATA_TYPE_BINARY:          return "TSDB_DATA_TYPE_VARCHAR";
1021
    case TSDB_DATA_TYPE_TIMESTAMP:
×
1022
      return "TSDB_DATA_TYPE_TIMESTAMP";
×
UNCOV
1023
    case TSDB_DATA_TYPE_NCHAR:
×
1024
      return "TSDB_DATA_TYPE_NCHAR";
×
1025
    case TSDB_DATA_TYPE_JSON:
×
1026
      return "TSDB_DATA_TYPE_JSON";
×
1027
    case TSDB_DATA_TYPE_GEOMETRY:
×
1028
      return "TSDB_DATA_TYPE_GEOMETRY";
×
1029
    case TSDB_DATA_TYPE_UTINYINT:
×
1030
      return "TSDB_DATA_TYPE_UTINYINT";
×
1031
    case TSDB_DATA_TYPE_USMALLINT:
×
1032
      return "TSDB_DATA_TYPE_USMALLINT";
×
1033
    case TSDB_DATA_TYPE_UINT:
×
1034
      return "TSDB_DATA_TYPE_UINT";
×
1035
    case TSDB_DATA_TYPE_UBIGINT:
×
1036
      return "TSDB_DATA_TYPE_UBIGINT";
×
1037
    case TSDB_DATA_TYPE_VARBINARY:
×
1038
      return "TSDB_DATA_TYPE_VARBINARY";
×
1039
    case TSDB_DATA_TYPE_DECIMAL:
×
1040
      return "TSDB_DATA_TYPE_DECIMAL";
×
1041
    case TSDB_DATA_TYPE_BLOB:
×
1042
      return "TSDB_DATA_TYPE_BLOB";
×
1043
    case TSDB_DATA_TYPE_MEDIUMBLOB:
×
1044
      return "TSDB_DATA_TYPE_MEDIUMBLOB";
×
1045
    default:
×
1046
      return "UNKNOWN";
×
1047
  }
1048
}
1049

1050
const char *taos_get_client_info() { return td_version; }
1,144,639✔
1051

1052
// return int32_t
1053
int taos_affected_rows(TAOS_RES *res) {
504,698,873✔
1054
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
504,698,873✔
1055
      TD_RES_TMQ_BATCH_META(res)) {
504,701,954✔
UNCOV
1056
    return 0;
×
1057
  }
1058

1059
  SRequestObj    *pRequest = (SRequestObj *)res;
504,701,617✔
1060
  SReqResultInfo *pResInfo = &pRequest->body.resInfo;
504,701,617✔
1061
  return (int)pResInfo->numOfRows;
504,701,931✔
1062
}
1063

1064
// return int64_t
1065
int64_t taos_affected_rows64(TAOS_RES *res) {
1,310,193✔
1066
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
1,310,193✔
1067
      TD_RES_TMQ_BATCH_META(res)) {
1,310,193✔
UNCOV
1068
    return 0;
×
1069
  }
1070

1071
  SRequestObj    *pRequest = (SRequestObj *)res;
1,310,193✔
1072
  SReqResultInfo *pResInfo = &pRequest->body.resInfo;
1,310,193✔
1073
  return pResInfo->numOfRows;
1,310,193✔
1074
}
1075

1076
int taos_result_precision(TAOS_RES *res) {
1,373,247,374✔
1077
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
1,373,247,374✔
UNCOV
1078
    return TSDB_TIME_PRECISION_MILLI;
×
1079
  }
1080

1081
  if (TD_RES_QUERY(res)) {
1,373,237,664✔
1082
    SRequestObj *pRequest = (SRequestObj *)res;
94,654,043✔
1083
    return pRequest->body.resInfo.precision;
94,654,043✔
1084
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
1,278,596,434✔
1085
    SReqResultInfo *info = tmqGetCurResInfo(res);
1,278,592,794✔
1086
    return info->precision;
1,278,592,794✔
1087
  }
UNCOV
1088
  return TSDB_TIME_PRECISION_MILLI;
×
1089
}
1090

1091
int taos_select_db(TAOS *taos, const char *db) {
147,656✔
1092
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
147,656✔
1093
  if (pObj == NULL) {
147,656✔
UNCOV
1094
    releaseTscObj(*(int64_t *)taos);
×
UNCOV
1095
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
UNCOV
1096
    return TSDB_CODE_TSC_DISCONNECTED;
×
1097
  }
1098

1099
  if (db == NULL || strlen(db) == 0) {
147,656✔
UNCOV
1100
    releaseTscObj(*(int64_t *)taos);
×
UNCOV
1101
    tscError("invalid parameter for %s", db == NULL ? "db is NULL" : "db is empty");
×
UNCOV
1102
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1103
    return terrno;
×
1104
  }
1105

1106
  char sql[256] = {0};
147,656✔
1107
  (void)snprintf(sql, tListLen(sql), "use %s", db);
147,656✔
1108

1109
  TAOS_RES *pRequest = taos_query(taos, sql);
147,656✔
1110
  int32_t   code = taos_errno(pRequest);
147,416✔
1111

1112
  taos_free_result(pRequest);
147,656✔
1113
  releaseTscObj(*(int64_t *)taos);
147,571✔
1114
  return code;
147,571✔
1115
}
1116

1117
void taos_stop_query(TAOS_RES *res) {
648,432,982✔
1118
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
648,432,982✔
1119
      TD_RES_TMQ_BATCH_META(res)) {
648,435,932✔
1120
    return;
72✔
1121
  }
1122

1123
  stopAllQueries((SRequestObj *)res);
648,432,664✔
1124
}
1125

UNCOV
1126
bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) {
×
UNCOV
1127
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
×
UNCOV
1128
    return true;
×
1129
  }
1130
  SReqResultInfo *pResultInfo = tscGetCurResInfo(res);
×
1131
  if (col >= pResultInfo->numOfCols || col < 0 || row >= pResultInfo->numOfRows || row < 0) {
×
UNCOV
1132
    return true;
×
1133
  }
1134

1135
  SResultColumn *pCol = &pResultInfo->pCol[col];
×
UNCOV
1136
  if (IS_VAR_DATA_TYPE(pResultInfo->fields[col].type)) {
×
UNCOV
1137
    return (pCol->offset[row] == -1);
×
1138
  } else {
1139
    return colDataIsNull_f(pCol, row);
×
1140
  }
1141
}
1142

1143
bool taos_is_update_query(TAOS_RES *res) { return taos_num_fields(res) == 0; }
8,805,693✔
1144

1145
int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
175,940,422✔
1146
  int32_t numOfRows = 0;
175,940,422✔
1147
  /*int32_t code = */ terrno = taos_fetch_block_s(res, &numOfRows, rows);
175,940,422✔
1148
  return numOfRows;
175,940,220✔
1149
}
1150

1151
int taos_fetch_block_s(TAOS_RES *res, int *numOfRows, TAOS_ROW *rows) {
175,940,422✔
1152
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
175,940,422✔
UNCOV
1153
    return 0;
×
1154
  }
1155

1156
  if (TD_RES_QUERY(res)) {
175,940,422✔
1157
    SRequestObj *pRequest = (SRequestObj *)res;
168,717,264✔
1158

1159
    (*rows) = NULL;
168,717,264✔
1160
    (*numOfRows) = 0;
168,717,264✔
1161

1162
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
168,717,264✔
1163
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
168,567,481✔
1164
      return pRequest->code;
758,351✔
1165
    }
1166

1167
    (void)doAsyncFetchRows(pRequest, false, true);
167,958,913✔
1168

1169
    // TODO refactor
1170
    SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
167,958,509✔
1171
    pResultInfo->current = pResultInfo->numOfRows;
167,958,913✔
1172

1173
    (*rows) = pResultInfo->row;
167,958,913✔
1174
    (*numOfRows) = pResultInfo->numOfRows;
167,958,913✔
1175
    return pRequest->code;
167,958,913✔
1176
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
7,223,158✔
1177
    SReqResultInfo *pResultInfo = NULL;
7,223,158✔
1178
    int32_t         code = tmqGetNextResInfo(res, true, &pResultInfo);
7,223,158✔
1179
    if (code != 0) return code;
7,222,710✔
1180

1181
    pResultInfo->current = pResultInfo->numOfRows;
6,856,049✔
1182
    (*rows) = pResultInfo->row;
6,856,497✔
1183
    (*numOfRows) = pResultInfo->numOfRows;
6,856,497✔
1184
    return 0;
6,856,049✔
1185
  } else {
UNCOV
1186
    tscError("taos_fetch_block_s invalid res type");
×
UNCOV
1187
    return TSDB_CODE_TMQ_INVALID_DATA;
×
1188
  }
1189
}
1190

1191
int taos_fetch_raw_block(TAOS_RES *res, int *numOfRows, void **pData) {
1,495,656✔
1192
  *numOfRows = 0;
1,495,656✔
1193
  *pData = NULL;
1,495,656✔
1194

1195
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
1,495,656✔
UNCOV
1196
    return 0;
×
1197
  }
1198

1199
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
1,495,656✔
1200
    SReqResultInfo *pResultInfo = NULL;
1,456,972✔
1201
    int32_t         code = tmqGetNextResInfo(res, false, &pResultInfo);
1,456,972✔
1202
    if (code != 0) {
1,456,972✔
1203
      (*numOfRows) = 0;
24,926✔
1204
      return 0;
24,926✔
1205
    }
1206

1207
    pResultInfo->current = pResultInfo->numOfRows;
1,432,046✔
1208
    (*numOfRows) = pResultInfo->numOfRows;
1,432,046✔
1209
    (*pData) = (void *)pResultInfo->pData;
1,432,046✔
1210
    return 0;
1,432,046✔
1211
  }
1212

1213
  SRequestObj *pRequest = (SRequestObj *)res;
38,684✔
1214

1215
  if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
38,684✔
1216
      pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
38,684✔
UNCOV
1217
    return pRequest->code;
×
1218
  }
1219

1220
  (void)doAsyncFetchRows(pRequest, false, false);
38,684✔
1221

1222
  SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
38,684✔
1223

1224
  pResultInfo->current = pResultInfo->numOfRows;
38,684✔
1225
  (*numOfRows) = pResultInfo->numOfRows;
38,684✔
1226
  (*pData) = (void *)pResultInfo->pData;
38,684✔
1227

1228
  return pRequest->code;
38,684✔
1229
}
1230

1231
int *taos_get_column_data_offset(TAOS_RES *res, int columnIndex) {
118,267,194✔
1232
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
118,267,194✔
UNCOV
1233
    return 0;
×
1234
  }
1235

1236
  int32_t numOfFields = taos_num_fields(res);
118,267,194✔
1237
  if (columnIndex < 0 || columnIndex >= numOfFields || numOfFields == 0) {
118,267,194✔
UNCOV
1238
    return 0;
×
1239
  }
1240

1241
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
118,267,194✔
1242
  TAOS_FIELD     *pField = &pResInfo->userFields[columnIndex];
118,267,194✔
1243
  if (!IS_VAR_DATA_TYPE(pField->type)) {
118,267,194✔
UNCOV
1244
    return 0;
×
1245
  }
1246

1247
  return pResInfo->pCol[columnIndex].offset;
118,267,194✔
1248
}
1249

1250
int taos_is_null_by_column(TAOS_RES *res, int columnIndex, bool result[], int *rows) {
333,267,160✔
1251
  if (res == NULL || result == NULL || rows == NULL || *rows <= 0 || columnIndex < 0 || TD_RES_TMQ_META(res) ||
333,267,160✔
1252
      TD_RES_TMQ_RAW(res) || TD_RES_TMQ_BATCH_META(res)) {
333,267,160✔
UNCOV
1253
    return TSDB_CODE_INVALID_PARA;
×
1254
  }
1255

1256
  int32_t numOfFields = taos_num_fields(res);
333,267,160✔
1257
  if (columnIndex >= numOfFields || numOfFields == 0) {
333,267,160✔
UNCOV
1258
    return TSDB_CODE_INVALID_PARA;
×
1259
  }
1260

1261
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
333,267,160✔
1262
  TAOS_FIELD     *pField = &pResInfo->userFields[columnIndex];
333,267,160✔
1263
  SResultColumn  *pCol = &pResInfo->pCol[columnIndex];
333,267,160✔
1264

1265
  if (*rows > pResInfo->numOfRows) {
333,267,160✔
UNCOV
1266
    *rows = pResInfo->numOfRows;
×
1267
  }
1268
  if (IS_VAR_DATA_TYPE(pField->type)) {
333,267,160✔
1269
    for (int i = 0; i < *rows; i++) {
×
UNCOV
1270
      if (pCol->offset[i] == -1) {
×
UNCOV
1271
        result[i] = true;
×
1272
      } else {
1273
        result[i] = false;
×
1274
      }
1275
    }
1276
  } else {
1277
    for (int i = 0; i < *rows; i++) {
2,147,483,647✔
1278
      if (colDataIsNull_f(pCol, i)) {
2,147,483,647✔
1279
        result[i] = true;
2,147,483,647✔
1280
      } else {
1281
        result[i] = false;
2,147,483,647✔
1282
      }
1283
    }
1284
  }
1285
  return 0;
333,267,160✔
1286
}
1287

UNCOV
1288
int taos_validate_sql(TAOS *taos, const char *sql) {
×
UNCOV
1289
  TAOS_RES *pObj = taosQueryImpl(taos, sql, true, TD_REQ_FROM_APP);
×
1290

1291
  int code = taos_errno(pObj);
×
1292

UNCOV
1293
  taos_free_result(pObj);
×
1294
  return code;
×
1295
}
1296

1297
void taos_reset_current_db(TAOS *taos) {
×
UNCOV
1298
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
×
UNCOV
1299
  if (pTscObj == NULL) {
×
1300
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1301
    return;
×
1302
  }
1303

1304
  resetConnectDB(pTscObj);
×
1305

UNCOV
1306
  releaseTscObj(*(int64_t *)taos);
×
1307
}
1308

1309
const char *taos_get_server_info(TAOS *taos) {
37,638✔
1310
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
37,638✔
1311
  if (pTscObj == NULL) {
37,638✔
UNCOV
1312
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
UNCOV
1313
    return NULL;
×
1314
  }
1315

1316
  releaseTscObj(*(int64_t *)taos);
37,638✔
1317

1318
  return pTscObj->sDetailVer;
37,638✔
1319
}
1320

1321
int taos_get_current_db(TAOS *taos, char *database, int len, int *required) {
560✔
1322
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
560✔
1323
  if (pTscObj == NULL) {
560✔
UNCOV
1324
    return TSDB_CODE_TSC_DISCONNECTED;
×
1325
  }
1326

1327
  int code = TSDB_CODE_SUCCESS;
560✔
1328
  (void)taosThreadMutexLock(&pTscObj->mutex);
560✔
1329
  if (database == NULL || len <= 0) {
560✔
1330
    if (required != NULL) *required = strlen(pTscObj->db) + 1;
280✔
1331
    TSC_ERR_JRET(TSDB_CODE_INVALID_PARA);
280✔
1332
  } else if (len < strlen(pTscObj->db) + 1) {
280✔
1333
    tstrncpy(database, pTscObj->db, len);
140✔
1334
    if (required) *required = strlen(pTscObj->db) + 1;
140✔
1335
    TSC_ERR_JRET(TSDB_CODE_INVALID_PARA);
140✔
1336
  } else {
1337
    tstrncpy(database, pTscObj->db, len);
140✔
1338
    code = 0;
140✔
1339
  }
1340
_return:
560✔
1341
  (void)taosThreadMutexUnlock(&pTscObj->mutex);
560✔
1342
  releaseTscObj(*(int64_t *)taos);
560✔
1343
  return code;
560✔
1344
}
1345

1346
void destorySqlCallbackWrapper(SSqlCallbackWrapper *pWrapper) {
1,295,476,379✔
1347
  if (NULL == pWrapper) {
1,295,476,379✔
1348
    return;
650,707,431✔
1349
  }
1350
  destoryCatalogReq(pWrapper->pCatalogReq);
644,768,948✔
1351
  taosMemoryFree(pWrapper->pCatalogReq);
644,764,458✔
1352
  qDestroyParseContext(pWrapper->pParseCtx);
644,762,837✔
1353
  taosMemoryFree(pWrapper);
644,758,488✔
1354
}
1355

1356
void destroyCtxInRequest(SRequestObj *pRequest) {
2,619,134✔
1357
  schedulerFreeJob(&pRequest->body.queryJob, 0);
2,619,134✔
1358
  qDestroyQuery(pRequest->pQuery);
2,619,134✔
1359
  pRequest->pQuery = NULL;
2,619,134✔
1360
  destorySqlCallbackWrapper(pRequest->pWrapper);
2,619,134✔
1361
  pRequest->pWrapper = NULL;
2,619,134✔
1362
}
2,619,134✔
1363

1364
static void doAsyncQueryFromAnalyse(SMetaData *pResultMeta, void *param, int32_t code) {
178,777,147✔
1365
  SSqlCallbackWrapper *pWrapper = (SSqlCallbackWrapper *)param;
178,777,147✔
1366
  SRequestObj         *pRequest = pWrapper->pRequest;
178,777,147✔
1367
  SQuery              *pQuery = pRequest->pQuery;
178,777,619✔
1368

1369
  qDebug("req:0x%" PRIx64 ", start to semantic analysis, QID:0x%" PRIx64, pRequest->self, pRequest->requestId);
178,778,105✔
1370

1371
  int64_t analyseStart = taosGetTimestampUs();
178,778,060✔
1372
  pRequest->metric.ctgCostUs = analyseStart - pRequest->metric.ctgStart;
178,778,060✔
1373
  pWrapper->pParseCtx->parseOnly = pRequest->parseOnly;
178,777,830✔
1374

1375
  if (TSDB_CODE_SUCCESS == code) {
178,778,316✔
1376
    code = qAnalyseSqlSemantic(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
178,773,568✔
1377
  }
1378

1379
  pRequest->metric.analyseCostUs += taosGetTimestampUs() - analyseStart;
178,765,971✔
1380

1381
  if (pRequest->parseOnly) {
178,772,624✔
1382
    (void)memcpy(&pRequest->parseMeta, pResultMeta, sizeof(*pResultMeta));
296,957✔
1383
    (void)memset(pResultMeta, 0, sizeof(*pResultMeta));
296,957✔
1384
  }
1385

1386
  handleQueryAnslyseRes(pWrapper, pResultMeta, code);
178,770,766✔
1387
}
178,766,615✔
1388

UNCOV
1389
int32_t cloneCatalogReq(SCatalogReq **ppTarget, SCatalogReq *pSrc) {
×
UNCOV
1390
  int32_t      code = TSDB_CODE_SUCCESS;
×
UNCOV
1391
  SCatalogReq *pTarget = taosMemoryCalloc(1, sizeof(SCatalogReq));
×
1392
  if (pTarget == NULL) {
×
1393
    code = terrno;
×
1394
  } else {
1395
    pTarget->pDbVgroup = taosArrayDup(pSrc->pDbVgroup, NULL);
×
1396
    pTarget->pDbCfg = taosArrayDup(pSrc->pDbCfg, NULL);
×
UNCOV
1397
    pTarget->pDbInfo = taosArrayDup(pSrc->pDbInfo, NULL);
×
1398
    pTarget->pTableMeta = taosArrayDup(pSrc->pTableMeta, NULL);
×
1399
    pTarget->pTableHash = taosArrayDup(pSrc->pTableHash, NULL);
×
1400
    pTarget->pUdf = taosArrayDup(pSrc->pUdf, NULL);
×
1401
    pTarget->pIndex = taosArrayDup(pSrc->pIndex, NULL);
×
1402
    pTarget->pUser = taosArrayDup(pSrc->pUser, NULL);
×
1403
    pTarget->pTableIndex = taosArrayDup(pSrc->pTableIndex, NULL);
×
1404
    pTarget->pTableCfg = taosArrayDup(pSrc->pTableCfg, NULL);
×
1405
    pTarget->pTableTag = taosArrayDup(pSrc->pTableTag, NULL);
×
1406
    pTarget->pView = taosArrayDup(pSrc->pView, NULL);
×
1407
    pTarget->pTableTSMAs = taosArrayDup(pSrc->pTableTSMAs, NULL);
×
1408
    pTarget->pTSMAs = taosArrayDup(pSrc->pTSMAs, NULL);
×
1409
    pTarget->pVStbRefDbs = taosArrayDup(pSrc->pVStbRefDbs, NULL);
×
1410
    pTarget->qNodeRequired = pSrc->qNodeRequired;
×
1411
    pTarget->dNodeRequired = pSrc->dNodeRequired;
×
1412
    pTarget->svrVerRequired = pSrc->svrVerRequired;
×
1413
    pTarget->forceUpdate = pSrc->forceUpdate;
×
1414
    pTarget->cloned = true;
×
1415

1416
    *ppTarget = pTarget;
×
1417
  }
1418

1419
  return code;
×
1420
}
1421

1422
void handleSubQueryFromAnalyse(SSqlCallbackWrapper *pWrapper, SMetaData *pResultMeta, SNode *pRoot) {
×
UNCOV
1423
  SRequestObj         *pNewRequest = NULL;
×
UNCOV
1424
  SSqlCallbackWrapper *pNewWrapper = NULL;
×
1425
  int32_t              code = buildPreviousRequest(pWrapper->pRequest, pWrapper->pRequest->sqlstr, &pNewRequest);
×
1426
  if (code) {
×
1427
    handleQueryAnslyseRes(pWrapper, pResultMeta, code);
×
1428
    return;
×
1429
  }
1430

1431
  pNewRequest->pQuery = NULL;
×
UNCOV
1432
  code = nodesMakeNode(QUERY_NODE_QUERY, (SNode **)&pNewRequest->pQuery);
×
UNCOV
1433
  if (pNewRequest->pQuery) {
×
1434
    pNewRequest->pQuery->pRoot = pRoot;
×
1435
    pRoot = NULL;
×
1436
    pNewRequest->pQuery->execStage = QUERY_EXEC_STAGE_ANALYSE;
×
1437
  }
1438
  if (TSDB_CODE_SUCCESS == code) {
×
1439
    code = prepareAndParseSqlSyntax(&pNewWrapper, pNewRequest, false);
×
1440
  }
1441
  if (TSDB_CODE_SUCCESS == code) {
×
1442
    code = cloneCatalogReq(&pNewWrapper->pCatalogReq, pWrapper->pCatalogReq);
×
1443
  }
1444
  if (TSDB_CODE_SUCCESS == code) {
×
1445
    doAsyncQueryFromAnalyse(pResultMeta, pNewWrapper, code);
×
UNCOV
1446
    nodesDestroyNode(pRoot);
×
1447
  } else {
1448
    handleQueryAnslyseRes(pWrapper, pResultMeta, code);
×
1449
    return;
×
1450
  }
1451
}
1452

1453
void handleQueryAnslyseRes(SSqlCallbackWrapper *pWrapper, SMetaData *pResultMeta, int32_t code) {
178,759,878✔
1454
  SRequestObj *pRequest = pWrapper->pRequest;
178,759,878✔
1455
  SQuery      *pQuery = pRequest->pQuery;
178,768,828✔
1456

1457
  if (code == TSDB_CODE_SUCCESS && pQuery->pPrevRoot) {
178,765,689✔
UNCOV
1458
    SNode *prevRoot = pQuery->pPrevRoot;
×
UNCOV
1459
    pQuery->pPrevRoot = NULL;
×
UNCOV
1460
    handleSubQueryFromAnalyse(pWrapper, pResultMeta, prevRoot);
×
1461
    return;
×
1462
  }
1463

1464
  if (code == TSDB_CODE_SUCCESS) {
178,758,834✔
1465
    pRequest->stableQuery = pQuery->stableQuery;
163,629,798✔
1466
    if (pQuery->pRoot) {
163,621,673✔
1467
      pRequest->stmtType = pQuery->pRoot->type;
163,635,354✔
1468
    }
1469

1470
    if (pQuery->haveResultSet) {
163,605,828✔
1471
      code = setResSchemaInfo(&pRequest->body.resInfo, pQuery->pResSchema, pQuery->numOfResCols, pQuery->pResExtSchema,
89,159,062✔
1472
                              pRequest->stmtBindVersion > 0);
89,158,597✔
1473
      setResPrecision(&pRequest->body.resInfo, pQuery->precision);
89,158,032✔
1474
    }
1475
  }
1476

1477
  if (code == TSDB_CODE_SUCCESS) {
178,758,338✔
1478
    TSWAP(pRequest->dbList, (pQuery)->pDbList);
163,625,126✔
1479
    TSWAP(pRequest->tableList, (pQuery)->pTableList);
163,624,552✔
1480
    TSWAP(pRequest->targetTableList, (pQuery)->pTargetTableList);
163,618,271✔
1481

1482
    launchAsyncQuery(pRequest, pQuery, pResultMeta, pWrapper);
163,622,403✔
1483
  } else {
1484
    destorySqlCallbackWrapper(pWrapper);
15,133,212✔
1485
    pRequest->pWrapper = NULL;
15,133,212✔
1486
    qDestroyQuery(pRequest->pQuery);
15,133,212✔
1487
    pRequest->pQuery = NULL;
15,133,212✔
1488

1489
    if (NEED_CLIENT_HANDLE_ERROR(code) && pRequest->stmtBindVersion == 0) {
15,133,212✔
1490
      tscDebug("req:0x%" PRIx64 ", client retry to handle the error, code:%d - %s, tryCount:%d, QID:0x%" PRIx64,
2,566,367✔
1491
               pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId);
1492
      restartAsyncQuery(pRequest, code);
2,566,367✔
1493
      return;
2,566,367✔
1494
    }
1495

1496
    // return to app directly
1497
    tscError("req:0x%" PRIx64 ", error occurs, code:%s, return to user app, QID:0x%" PRIx64, pRequest->self,
12,566,845✔
1498
             tstrerror(code), pRequest->requestId);
1499
    pRequest->code = code;
12,566,845✔
1500
    returnToUser(pRequest);
12,566,845✔
1501
  }
1502
}
1503

1504
static int32_t getAllMetaAsync(SSqlCallbackWrapper *pWrapper, catalogCallback fp) {
188,874,022✔
1505
  SRequestConnInfo conn = {.pTrans = pWrapper->pParseCtx->pTransporter,
370,056,042✔
1506
                           .requestId = pWrapper->pParseCtx->requestId,
188,878,647✔
1507
                           .requestObjRefId = pWrapper->pParseCtx->requestRid,
188,877,106✔
1508
                           .mgmtEps = pWrapper->pParseCtx->mgmtEpSet};
188,878,494✔
1509

1510
  pWrapper->pRequest->metric.ctgStart = taosGetTimestampUs();
370,058,383✔
1511

1512
  return catalogAsyncGetAllMeta(pWrapper->pParseCtx->pCatalog, &conn, pWrapper->pCatalogReq, fp, pWrapper,
196,568,403✔
1513
                                &pWrapper->pRequest->body.queryJob);
188,875,645✔
1514
}
1515

1516
static void doAsyncQueryFromParse(SMetaData *pResultMeta, void *param, int32_t code);
1517

1518
static int32_t phaseAsyncQuery(SSqlCallbackWrapper *pWrapper) {
649,448,168✔
1519
  int32_t code = TSDB_CODE_SUCCESS;
649,448,168✔
1520
  switch (pWrapper->pRequest->pQuery->execStage) {
649,448,168✔
1521
    case QUERY_EXEC_STAGE_PARSE: {
10,105,717✔
1522
      // continue parse after get metadata
1523
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromParse);
10,105,717✔
1524
      break;
10,105,872✔
1525
    }
1526
    case QUERY_EXEC_STAGE_ANALYSE: {
178,768,882✔
1527
      // analysis after get metadata
1528
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromAnalyse);
178,768,882✔
1529
      break;
178,770,303✔
1530
    }
1531
    case QUERY_EXEC_STAGE_SCHEDULE: {
460,576,048✔
1532
      launchAsyncQuery(pWrapper->pRequest, pWrapper->pRequest->pQuery, NULL, pWrapper);
460,576,048✔
1533
      break;
460,577,960✔
1534
    }
UNCOV
1535
    default:
×
UNCOV
1536
      break;
×
1537
  }
1538
  return code;
649,453,412✔
1539
}
1540

1541
static void doAsyncQueryFromParse(SMetaData *pResultMeta, void *param, int32_t code) {
10,105,872✔
1542
  SSqlCallbackWrapper *pWrapper = (SSqlCallbackWrapper *)param;
10,105,872✔
1543
  SRequestObj         *pRequest = pWrapper->pRequest;
10,105,872✔
1544
  SQuery              *pQuery = pRequest->pQuery;
10,105,872✔
1545

1546
  pRequest->metric.ctgCostUs += taosGetTimestampUs() - pRequest->metric.ctgStart;
10,105,872✔
1547
  qDebug("req:0x%" PRIx64 ", continue parse query, QID:0x%" PRIx64 ", code:%s", pRequest->self, pRequest->requestId,
10,105,872✔
1548
         tstrerror(code));
1549

1550
  if (code == TSDB_CODE_SUCCESS) {
10,105,872✔
1551
    // pWrapper->pCatalogReq->forceUpdate = false;
1552
    code = qContinueParseSql(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
10,103,659✔
1553
  }
1554

1555
  if (TSDB_CODE_SUCCESS == code) {
10,105,872✔
1556
    code = phaseAsyncQuery(pWrapper);
9,604,263✔
1557
  }
1558

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

1570
void continueInsertFromCsv(SSqlCallbackWrapper *pWrapper, SRequestObj *pRequest) {
12,164✔
1571
  int32_t code = qParseSqlSyntax(pWrapper->pParseCtx, &pRequest->pQuery, pWrapper->pCatalogReq);
12,164✔
1572
  if (TSDB_CODE_SUCCESS == code) {
12,164✔
1573
    code = phaseAsyncQuery(pWrapper);
12,164✔
1574
  }
1575

1576
  if (TSDB_CODE_SUCCESS != code) {
12,164✔
UNCOV
1577
    tscError("req:0x%" PRIx64 ", error happens, code:%d - %s, QID:0x%" PRIx64, pWrapper->pRequest->self, code,
×
1578
             tstrerror(code), pWrapper->pRequest->requestId);
UNCOV
1579
    destorySqlCallbackWrapper(pWrapper);
×
1580
    pRequest->pWrapper = NULL;
×
UNCOV
1581
    terrno = code;
×
1582
    pRequest->code = code;
×
1583
    doRequestCallback(pRequest, code);
×
1584
  }
1585
}
12,164✔
1586

1587
void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param) {
106,586✔
1588
  int64_t connId = *(int64_t *)taos;
106,586✔
1589
  taosAsyncQueryImpl(connId, sql, fp, param, false, TD_REQ_FROM_APP);
106,586✔
1590
}
106,586✔
1591

UNCOV
1592
void taos_query_a_with_reqid(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param, int64_t reqid) {
×
UNCOV
1593
  int64_t connId = *(int64_t *)taos;
×
UNCOV
1594
  taosAsyncQueryImplWithReqid(connId, sql, fp, param, false, reqid);
×
1595
}
×
1596

1597
int32_t createParseContext(const SRequestObj *pRequest, SParseContext **pCxt, SSqlCallbackWrapper *pWrapper) {
644,766,768✔
1598
  const STscObj *pTscObj = pRequest->pTscObj;
644,766,768✔
1599

1600
  *pCxt = taosMemoryCalloc(1, sizeof(SParseContext));
644,770,872✔
1601
  if (*pCxt == NULL) {
644,763,376✔
UNCOV
1602
    return terrno;
×
1603
  }
1604

1605
  **pCxt = (SParseContext){.requestId = pRequest->requestId,
1,265,078,668✔
1606
                           .requestRid = pRequest->self,
644,766,903✔
1607
                           .acctId = pTscObj->acctId,
644,768,365✔
1608
                           .db = pRequest->pDb,
644,768,826✔
1609
                           .topicQuery = false,
1610
                           .pSql = pRequest->sqlstr,
644,770,450✔
1611
                           .sqlLen = pRequest->sqlLen,
644,768,756✔
1612
                           .pMsg = pRequest->msgBuf,
644,767,433✔
1613
                           .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE,
1614
                           .pTransporter = pTscObj->pAppInfo->pTransporter,
644,770,374✔
1615
                           .pStmtCb = NULL,
1616
                           .pUser = pTscObj->user,
644,769,549✔
1617
                           .pEffectiveUser = pRequest->effectiveUser,
644,768,603✔
1618
                           .isSuperUser = (0 == strcmp(pTscObj->user, TSDB_DEFAULT_USER)),
644,770,681✔
1619
                           .enableSysInfo = pTscObj->sysInfo,
644,770,010✔
1620
                           .async = true,
1621
                           .svrVer = pTscObj->sVer,
644,769,623✔
1622
                           .nodeOffline = (pTscObj->pAppInfo->onlineDnodes < pTscObj->pAppInfo->totalDnodes),
644,771,653✔
1623
                           .allocatorId = pRequest->allocatorRefId,
644,765,713✔
1624
                           .parseSqlFp = clientParseSql,
1625
                           .parseSqlParam = pWrapper,
1626
                           .setQueryFp = setQueryRequest,
1627
                           .timezone = pTscObj->optionInfo.timezone,
644,770,471✔
1628
                           .charsetCxt = pTscObj->optionInfo.charsetCxt};
644,769,549✔
1629
  int8_t biMode = atomic_load_8(&((STscObj *)pTscObj)->biMode);
644,769,438✔
1630
  (*pCxt)->biMode = biMode;
644,762,862✔
1631
  return TSDB_CODE_SUCCESS;
644,764,419✔
1632
}
1633

1634
int32_t prepareAndParseSqlSyntax(SSqlCallbackWrapper **ppWrapper, SRequestObj *pRequest, bool updateMetaForce) {
644,765,872✔
1635
  int32_t              code = TSDB_CODE_SUCCESS;
644,765,872✔
1636
  STscObj             *pTscObj = pRequest->pTscObj;
644,765,872✔
1637
  SSqlCallbackWrapper *pWrapper = taosMemoryCalloc(1, sizeof(SSqlCallbackWrapper));
644,770,264✔
1638
  if (pWrapper == NULL) {
644,766,155✔
UNCOV
1639
    code = terrno;
×
1640
  } else {
1641
    pWrapper->pRequest = pRequest;
644,766,155✔
1642
    pRequest->pWrapper = pWrapper;
644,765,472✔
1643
    *ppWrapper = pWrapper;
644,770,147✔
1644
  }
1645

1646
  if (TSDB_CODE_SUCCESS == code) {
644,767,264✔
1647
    code = createParseContext(pRequest, &pWrapper->pParseCtx, pWrapper);
644,767,337✔
1648
  }
1649

1650
  if (TSDB_CODE_SUCCESS == code) {
644,770,209✔
1651
    pWrapper->pParseCtx->mgmtEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
644,770,364✔
1652
    code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pWrapper->pParseCtx->pCatalog);
644,772,078✔
1653
  }
1654

1655
  if (TSDB_CODE_SUCCESS == code && NULL == pRequest->pQuery) {
644,765,497✔
1656
    int64_t syntaxStart = taosGetTimestampUs();
644,770,493✔
1657

1658
    pWrapper->pCatalogReq = taosMemoryCalloc(1, sizeof(SCatalogReq));
644,770,493✔
1659
    if (pWrapper->pCatalogReq == NULL) {
644,756,768✔
UNCOV
1660
      code = terrno;
×
1661
    } else {
1662
      pWrapper->pCatalogReq->forceUpdate = updateMetaForce;
644,760,020✔
1663
      TSC_ERR_RET(qnodeRequired(pRequest, &pWrapper->pCatalogReq->qNodeRequired));
644,763,955✔
1664
      code = qParseSqlSyntax(pWrapper->pParseCtx, &pRequest->pQuery, pWrapper->pCatalogReq);
644,762,028✔
1665
    }
1666

1667
    pRequest->metric.parseCostUs += taosGetTimestampUs() - syntaxStart;
644,767,109✔
1668
  }
1669

1670
  return code;
644,771,469✔
1671
}
1672

1673
void doAsyncQuery(SRequestObj *pRequest, bool updateMetaForce) {
645,622,059✔
1674
  SSqlCallbackWrapper *pWrapper = NULL;
645,622,059✔
1675
  int32_t              code = TSDB_CODE_SUCCESS;
645,624,769✔
1676

1677
  if (pRequest->retry++ > REQUEST_TOTAL_EXEC_TIMES) {
645,624,769✔
1678
    code = pRequest->prevCode;
854,652✔
1679
    terrno = code;
854,652✔
1680
    pRequest->code = code;
854,652✔
1681
    tscDebug("req:0x%" PRIx64 ", call sync query cb with code:%s", pRequest->self, tstrerror(code));
854,652✔
1682
    doRequestCallback(pRequest, code);
854,652✔
1683
    return;
854,652✔
1684
  }
1685

1686
  if (TSDB_CODE_SUCCESS == code) {
644,761,850✔
1687
    code = prepareAndParseSqlSyntax(&pWrapper, pRequest, updateMetaForce);
644,763,975✔
1688
  }
1689

1690
  if (TSDB_CODE_SUCCESS == code) {
644,756,930✔
1691
    pRequest->stmtType = pRequest->pQuery->pRoot->type;
639,836,376✔
1692
    code = phaseAsyncQuery(pWrapper);
639,836,162✔
1693
  }
1694

1695
  if (TSDB_CODE_SUCCESS != code) {
644,761,835✔
1696
    if (NULL != pRequest->msgBuf && strlen(pRequest->msgBuf) > 0) {
4,925,982✔
1697
      tscError("req:0x%" PRIx64 ", error happens, code:%d - %s, QID:0x%" PRIx64, pRequest->self, code, pRequest->msgBuf,
4,797,969✔
1698
               pRequest->requestId);
1699
    } else {
1700
      tscError("req:0x%" PRIx64 ", error happens, code:%d - %s, QID:0x%" PRIx64, pRequest->self, code, tstrerror(code),
128,013✔
1701
               pRequest->requestId);
1702
    }
1703

1704
    destorySqlCallbackWrapper(pWrapper);
4,926,262✔
1705
    pRequest->pWrapper = NULL;
4,926,262✔
1706
    qDestroyQuery(pRequest->pQuery);
4,926,262✔
1707
    pRequest->pQuery = NULL;
4,926,262✔
1708

1709
    if (NEED_CLIENT_HANDLE_ERROR(code) && pRequest->stmtBindVersion == 0) {
4,926,262✔
1710
      tscDebug("req:0x%" PRIx64 ", client retry to handle the error, code:%d - %s, tryCount:%d, QID:0x%" PRIx64,
11,086✔
1711
               pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId);
1712
      code = refreshMeta(pRequest->pTscObj, pRequest);
11,086✔
1713
      if (code != 0) {
11,086✔
1714
        tscWarn("req:0x%" PRIx64 ", refresh meta failed, code:%d - %s, QID:0x%" PRIx64, pRequest->self, code,
11,086✔
1715
                tstrerror(code), pRequest->requestId);
1716
      }
1717
      pRequest->prevCode = code;
11,086✔
1718
      doAsyncQuery(pRequest, true);
11,086✔
1719
      return;
11,086✔
1720
    }
1721

1722
    terrno = code;
4,915,176✔
1723
    pRequest->code = code;
4,915,176✔
1724
    doRequestCallback(pRequest, code);
4,915,176✔
1725
  }
1726
}
1727

1728
void restartAsyncQuery(SRequestObj *pRequest, int32_t code) {
2,619,134✔
1729
  tscInfo("restart request:%s p:%p", pRequest->sqlstr, pRequest);
2,619,134✔
1730
  SRequestObj *pUserReq = pRequest;
2,619,134✔
1731
  (void)acquireRequest(pRequest->self);
2,619,134✔
1732
  while (pUserReq) {
2,619,134✔
1733
    if (pUserReq->self == pUserReq->relation.userRefId || pUserReq->relation.userRefId == 0) {
2,619,134✔
1734
      break;
1735
    } else {
UNCOV
1736
      int64_t nextRefId = pUserReq->relation.nextRefId;
×
UNCOV
1737
      (void)releaseRequest(pUserReq->self);
×
UNCOV
1738
      if (nextRefId) {
×
1739
        pUserReq = acquireRequest(nextRefId);
×
1740
      }
1741
    }
1742
  }
1743
  bool hasSubRequest = pUserReq != pRequest || pRequest->relation.prevRefId != 0;
2,619,134✔
1744
  if (pUserReq) {
2,619,134✔
1745
    destroyCtxInRequest(pUserReq);
2,619,134✔
1746
    pUserReq->prevCode = code;
2,619,134✔
1747
    (void)memset(&pUserReq->relation, 0, sizeof(pUserReq->relation));
2,619,134✔
1748
  } else {
UNCOV
1749
    tscError("User req is missing");
×
UNCOV
1750
    (void)removeFromMostPrevReq(pRequest);
×
UNCOV
1751
    return;
×
1752
  }
1753
  if (hasSubRequest)
2,619,134✔
1754
    (void)removeFromMostPrevReq(pRequest);
×
1755
  else
1756
    (void)releaseRequest(pUserReq->self);
2,619,134✔
1757
  doAsyncQuery(pUserReq, true);
2,619,134✔
1758
}
1759

1760
typedef struct SAsyncFetchParam {
1761
  SRequestObj      *pReq;
1762
  __taos_async_fn_t fp;
1763
  void             *param;
1764
} SAsyncFetchParam;
1765

1766
static int32_t doAsyncFetch(void *pParam) {
106,141,235✔
1767
  SAsyncFetchParam *param = pParam;
106,141,235✔
1768
  taosAsyncFetchImpl(param->pReq, param->fp, param->param);
106,141,235✔
1769
  taosMemoryFree(param);
106,141,235✔
1770
  return TSDB_CODE_SUCCESS;
106,140,497✔
1771
}
1772

1773
void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
106,143,940✔
1774
  if (res == NULL || fp == NULL) {
106,143,940✔
UNCOV
1775
    tscError("taos_fetch_rows_a invalid paras");
×
UNCOV
1776
    return;
×
1777
  }
1778
  if (!TD_RES_QUERY(res)) {
106,143,940✔
1779
    tscError("taos_fetch_rows_a res is NULL");
×
UNCOV
1780
    fp(param, res, TSDB_CODE_APP_ERROR);
×
UNCOV
1781
    return;
×
1782
  }
1783

1784
  SRequestObj *pRequest = res;
106,143,940✔
1785
  if (TSDB_SQL_RETRIEVE_EMPTY_RESULT == pRequest->type) {
106,143,940✔
1786
    fp(param, res, 0);
2,935✔
1787
    return;
2,935✔
1788
  }
1789

1790
  SAsyncFetchParam *pParam = taosMemoryCalloc(1, sizeof(SAsyncFetchParam));
106,140,751✔
1791
  if (!pParam) {
106,140,751✔
UNCOV
1792
    fp(param, res, terrno);
×
UNCOV
1793
    return;
×
1794
  }
1795
  pParam->pReq = pRequest;
106,140,751✔
1796
  pParam->fp = fp;
106,141,005✔
1797
  pParam->param = param;
106,141,235✔
1798
  int32_t code = taosAsyncExec(doAsyncFetch, pParam, NULL);
106,141,005✔
1799
  if (TSDB_CODE_SUCCESS != code) {
106,141,235✔
UNCOV
1800
    taosMemoryFree(pParam);
×
UNCOV
1801
    fp(param, res, code);
×
UNCOV
1802
    return;
×
1803
  }
1804
}
1805

1806
void taos_fetch_raw_block_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
3,876✔
1807
  if (res == NULL || fp == NULL) {
3,876✔
UNCOV
1808
    tscError("taos_fetch_raw_block_a invalid paras");
×
UNCOV
1809
    return;
×
1810
  }
1811
  if (!TD_RES_QUERY(res)) {
3,876✔
1812
    tscError("taos_fetch_raw_block_a res is NULL");
×
UNCOV
1813
    return;
×
1814
  }
1815
  SRequestObj    *pRequest = res;
3,876✔
1816
  SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
3,876✔
1817

1818
  // set the current block is all consumed
1819
  pResultInfo->convertUcs4 = false;
3,876✔
1820

1821
  // it is a local executed query, no need to do async fetch
1822
  taos_fetch_rows_a(pRequest, fp, param);
3,876✔
1823
}
1824

1825
const void *taos_get_raw_block(TAOS_RES *res) {
2,279✔
1826
  if (res == NULL) {
2,279✔
UNCOV
1827
    tscError("taos_get_raw_block invalid paras");
×
UNCOV
1828
    return NULL;
×
1829
  }
1830
  if (!TD_RES_QUERY(res)) {
2,279✔
1831
    tscError("taos_get_raw_block res is NULL");
×
UNCOV
1832
    return NULL;
×
1833
  }
1834
  SRequestObj *pRequest = res;
2,279✔
1835

1836
  return pRequest->body.resInfo.pData;
2,279✔
1837
}
1838

UNCOV
1839
int taos_get_db_route_info(TAOS *taos, const char *db, TAOS_DB_ROUTE_INFO *dbInfo) {
×
UNCOV
1840
  if (NULL == taos) {
×
UNCOV
1841
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1842
    return terrno;
×
1843
  }
1844

1845
  if (NULL == db || NULL == dbInfo) {
×
UNCOV
1846
    tscError("invalid input param, db:%p, dbInfo:%p", db, dbInfo);
×
UNCOV
1847
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1848
    return terrno;
×
1849
  }
1850

1851
  int64_t      connId = *(int64_t *)taos;
×
UNCOV
1852
  SRequestObj *pRequest = NULL;
×
UNCOV
1853
  char        *sql = "taos_get_db_route_info";
×
1854
  int32_t      code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
×
1855
  if (code != TSDB_CODE_SUCCESS) {
×
1856
    terrno = code;
×
1857
    return terrno;
×
1858
  }
1859

1860
  STscObj  *pTscObj = pRequest->pTscObj;
×
UNCOV
1861
  SCatalog *pCtg = NULL;
×
UNCOV
1862
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
×
1863
  if (code != TSDB_CODE_SUCCESS) {
×
1864
    goto _return;
×
1865
  }
1866

1867
  SRequestConnInfo conn = {
×
UNCOV
1868
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
×
1869

1870
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
×
1871

UNCOV
1872
  char dbFName[TSDB_DB_FNAME_LEN] = {0};
×
1873
  (void)snprintf(dbFName, sizeof(dbFName), "%d.%s", pTscObj->acctId, db);
×
1874

1875
  code = catalogGetDBVgInfo(pCtg, &conn, dbFName, dbInfo);
×
1876
  if (code) {
×
UNCOV
1877
    goto _return;
×
1878
  }
1879

1880
_return:
×
1881

UNCOV
1882
  terrno = code;
×
1883

UNCOV
1884
  destroyRequest(pRequest);
×
1885
  return code;
×
1886
}
1887

1888
int taos_get_table_vgId(TAOS *taos, const char *db, const char *table, int *vgId) {
×
UNCOV
1889
  if (NULL == taos) {
×
UNCOV
1890
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1891
    return terrno;
×
1892
  }
1893

1894
  if (NULL == db || NULL == table || NULL == vgId) {
×
UNCOV
1895
    tscError("invalid input param, db:%p, table:%p, vgId:%p", db, table, vgId);
×
UNCOV
1896
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1897
    return terrno;
×
1898
  }
1899

1900
  int64_t      connId = *(int64_t *)taos;
×
UNCOV
1901
  SRequestObj *pRequest = NULL;
×
UNCOV
1902
  char        *sql = "taos_get_table_vgId";
×
1903
  int32_t      code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
×
1904
  if (code != TSDB_CODE_SUCCESS) {
×
1905
    return terrno;
×
1906
  }
1907

1908
  pRequest->syncQuery = true;
×
1909

UNCOV
1910
  STscObj  *pTscObj = pRequest->pTscObj;
×
1911
  SCatalog *pCtg = NULL;
×
UNCOV
1912
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
×
1913
  if (code != TSDB_CODE_SUCCESS) {
×
1914
    goto _return;
×
1915
  }
1916

1917
  SRequestConnInfo conn = {
×
UNCOV
1918
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
×
1919

1920
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
×
1921

UNCOV
1922
  SName tableName = {0};
×
1923
  toName(pTscObj->acctId, db, table, &tableName);
×
1924

1925
  SVgroupInfo vgInfo;
×
1926
  code = catalogGetTableHashVgroup(pCtg, &conn, &tableName, &vgInfo);
×
UNCOV
1927
  if (code) {
×
1928
    goto _return;
×
1929
  }
1930

1931
  *vgId = vgInfo.vgId;
×
1932

UNCOV
1933
_return:
×
1934

UNCOV
1935
  terrno = code;
×
1936

UNCOV
1937
  destroyRequest(pRequest);
×
1938
  return code;
×
1939
}
1940

1941
int taos_get_tables_vgId(TAOS *taos, const char *db, const char *table[], int tableNum, int *vgId) {
×
UNCOV
1942
  if (NULL == taos) {
×
UNCOV
1943
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1944
    return terrno;
×
1945
  }
1946

1947
  if (NULL == db || NULL == table || NULL == vgId || tableNum <= 0) {
×
UNCOV
1948
    tscError("invalid input param, db:%p, table:%p, vgId:%p, tbNum:%d", db, table, vgId, tableNum);
×
UNCOV
1949
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1950
    return terrno;
×
1951
  }
1952

1953
  int64_t      connId = *(int64_t *)taos;
×
UNCOV
1954
  SRequestObj *pRequest = NULL;
×
UNCOV
1955
  char        *sql = "taos_get_table_vgId";
×
1956
  int32_t      code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
×
1957
  if (code != TSDB_CODE_SUCCESS) {
×
1958
    return terrno;
×
1959
  }
1960

1961
  pRequest->syncQuery = true;
×
1962

UNCOV
1963
  STscObj  *pTscObj = pRequest->pTscObj;
×
1964
  SCatalog *pCtg = NULL;
×
UNCOV
1965
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
×
1966
  if (code != TSDB_CODE_SUCCESS) {
×
1967
    goto _return;
×
1968
  }
1969

1970
  SRequestConnInfo conn = {
×
UNCOV
1971
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
×
1972

1973
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
×
1974

UNCOV
1975
  code = catalogGetTablesHashVgId(pCtg, &conn, pTscObj->acctId, db, table, tableNum, vgId);
×
1976
  if (code) {
×
UNCOV
1977
    goto _return;
×
1978
  }
1979

1980
_return:
×
1981

UNCOV
1982
  terrno = code;
×
1983

UNCOV
1984
  destroyRequest(pRequest);
×
1985
  return code;
×
1986
}
1987

1988
int taos_load_table_info(TAOS *taos, const char *tableNameList) {
1,244✔
1989
  if (NULL == taos) {
1,244✔
UNCOV
1990
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
UNCOV
1991
    return terrno;
×
1992
  }
1993

1994
  int64_t       connId = *(int64_t *)taos;
1,244✔
1995
  const int32_t MAX_TABLE_NAME_LENGTH = 12 * 1024 * 1024;  // 12MB list
1,244✔
1996
  int32_t       code = 0;
1,244✔
1997
  SRequestObj  *pRequest = NULL;
1,244✔
1998
  SCatalogReq   catalogReq = {0};
1,244✔
1999

2000
  if (NULL == tableNameList) {
1,244✔
UNCOV
2001
    return TSDB_CODE_SUCCESS;
×
2002
  }
2003

2004
  int32_t length = (int32_t)strlen(tableNameList);
1,244✔
2005
  if (0 == length) {
1,244✔
UNCOV
2006
    return TSDB_CODE_SUCCESS;
×
2007
  } else if (length > MAX_TABLE_NAME_LENGTH) {
1,244✔
UNCOV
2008
    tscError("tableNameList too long, length:%d, maximum allowed:%d", length, MAX_TABLE_NAME_LENGTH);
×
2009
    return TSDB_CODE_TSC_INVALID_OPERATION;
×
2010
  }
2011

2012
  char *sql = "taos_load_table_info";
1,244✔
2013
  code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
1,244✔
2014
  if (code != TSDB_CODE_SUCCESS) {
1,244✔
UNCOV
2015
    terrno = code;
×
UNCOV
2016
    goto _return;
×
2017
  }
2018

2019
  pRequest->syncQuery = true;
1,244✔
2020

2021
  STscObj *pTscObj = pRequest->pTscObj;
1,244✔
2022
  code = transferTableNameList(tableNameList, pTscObj->acctId, pTscObj->db, &catalogReq.pTableMeta);
1,244✔
2023
  if (code) {
1,244✔
UNCOV
2024
    goto _return;
×
2025
  }
2026

2027
  SCatalog *pCtg = NULL;
1,244✔
2028
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
1,244✔
2029
  if (code != TSDB_CODE_SUCCESS) {
1,244✔
UNCOV
2030
    goto _return;
×
2031
  }
2032

2033
  SRequestConnInfo conn = {
1,244✔
2034
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
1,244✔
2035

2036
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
1,244✔
2037

2038
  code = catalogAsyncGetAllMeta(pCtg, &conn, &catalogReq, syncCatalogFn, pRequest->body.interParam, NULL);
1,244✔
2039
  if (code) {
1,244✔
UNCOV
2040
    goto _return;
×
2041
  }
2042

2043
  SSyncQueryParam *pParam = pRequest->body.interParam;
1,244✔
2044
  code = tsem_wait(&pParam->sem);
1,244✔
2045
  if (code) {
1,244✔
UNCOV
2046
    tscError("tsem wait failed, code:%d - %s", code, tstrerror(code));
×
UNCOV
2047
    goto _return;
×
2048
  }
2049
_return:
1,244✔
2050
  destoryCatalogReq(&catalogReq);
1,244✔
2051
  destroyRequest(pRequest);
1,244✔
2052
  return code;
1,244✔
2053
}
2054

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

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

2069
  return pStmt;
381,132✔
2070
}
2071

UNCOV
2072
TAOS_STMT *taos_stmt_init_with_reqid(TAOS *taos, int64_t reqid) {
×
UNCOV
2073
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
×
UNCOV
2074
  if (NULL == pObj) {
×
2075
    tscError("invalid parameter for %s", __FUNCTION__);
×
2076
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
2077
    return NULL;
×
2078
  }
2079

2080
  TAOS_STMT *pStmt = stmtInit(pObj, reqid, NULL);
×
UNCOV
2081
  if (NULL == pStmt) {
×
UNCOV
2082
    tscError("stmt init failed, errcode:%s", terrstr());
×
2083
  }
2084
  releaseTscObj(*(int64_t *)taos);
×
2085

UNCOV
2086
  return pStmt;
×
2087
}
2088

2089
TAOS_STMT *taos_stmt_init_with_options(TAOS *taos, TAOS_STMT_OPTIONS *options) {
26,595✔
2090
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
26,595✔
2091
  if (NULL == pObj) {
26,857✔
UNCOV
2092
    tscError("invalid parameter for %s", __FUNCTION__);
×
UNCOV
2093
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
UNCOV
2094
    return NULL;
×
2095
  }
2096

2097
  TAOS_STMT *pStmt = stmtInit(pObj, options->reqId, options);
26,857✔
2098
  if (NULL == pStmt) {
26,857✔
UNCOV
2099
    tscError("stmt init failed, errcode:%s", terrstr());
×
2100
  }
2101
  releaseTscObj(*(int64_t *)taos);
26,857✔
2102

2103
  return pStmt;
26,857✔
2104
}
2105

2106
int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length) {
759,338✔
2107
  if (stmt == NULL || sql == NULL) {
759,338✔
UNCOV
2108
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2109
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2110
    return terrno;
×
2111
  }
2112

2113
  return stmtPrepare(stmt, sql, length);
759,338✔
2114
}
2115

2116
int taos_stmt_set_tbname_tags(TAOS_STMT *stmt, const char *name, TAOS_MULTI_BIND *tags) {
18,260✔
2117
  if (stmt == NULL || name == NULL) {
18,260✔
UNCOV
2118
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2119
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2120
    return terrno;
×
2121
  }
2122

2123
  int32_t code = stmtSetTbName(stmt, name);
18,260✔
2124
  if (code) {
18,260✔
2125
    return code;
622✔
2126
  }
2127

2128
  if (tags) {
17,638✔
2129
    return stmtSetTbTags(stmt, tags);
17,638✔
2130
  }
2131

UNCOV
2132
  return TSDB_CODE_SUCCESS;
×
2133
}
2134

2135
int taos_stmt_set_tbname(TAOS_STMT *stmt, const char *name) {
13,067,009✔
2136
  if (stmt == NULL || name == NULL) {
13,067,009✔
UNCOV
2137
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2138
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2139
    return terrno;
×
2140
  }
2141

2142
  return stmtSetTbName(stmt, name);
13,078,319✔
2143
}
2144

2145
int taos_stmt_set_tags(TAOS_STMT *stmt, TAOS_MULTI_BIND *tags) {
4,997✔
2146
  if (stmt == NULL || tags == NULL) {
4,997✔
UNCOV
2147
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2148
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2149
    return terrno;
×
2150
  }
2151

2152
  return stmtSetTbTags(stmt, tags);
4,997✔
2153
}
2154

UNCOV
2155
int taos_stmt_set_sub_tbname(TAOS_STMT *stmt, const char *name) { return taos_stmt_set_tbname(stmt, name); }
×
2156

UNCOV
2157
int taos_stmt_get_tag_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields) {
×
2158
  if (stmt == NULL || NULL == fieldNum) {
×
UNCOV
2159
    tscError("NULL parameter for %s", __FUNCTION__);
×
2160
    terrno = TSDB_CODE_INVALID_PARA;
×
2161
    return terrno;
×
2162
  }
2163

2164
  return stmtGetTagFields(stmt, fieldNum, fields);
×
2165
}
2166

2167
int taos_stmt_get_col_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields) {
×
UNCOV
2168
  if (stmt == NULL || NULL == fieldNum) {
×
UNCOV
2169
    tscError("NULL parameter for %s", __FUNCTION__);
×
2170
    terrno = TSDB_CODE_INVALID_PARA;
×
2171
    return terrno;
×
2172
  }
2173

2174
  return stmtGetColFields(stmt, fieldNum, fields);
×
2175
}
2176

2177
// let stmt to reclaim TAOS_FIELD_E that was allocated by `taos_stmt_get_tag_fields`/`taos_stmt_get_col_fields`
UNCOV
2178
void taos_stmt_reclaim_fields(TAOS_STMT *stmt, TAOS_FIELD_E *fields) {
×
2179
  (void)stmt;
UNCOV
2180
  if (!fields) return;
×
2181
  taosMemoryFree(fields);
×
2182
}
2183

2184
int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
55,651✔
2185
  if (stmt == NULL || bind == NULL) {
55,651✔
UNCOV
2186
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2187
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2188
    return terrno;
×
2189
  }
2190

2191
  if (bind->num > 1) {
55,651✔
2192
    tscError("invalid bind number %d for %s", bind->num, __FUNCTION__);
4,002✔
2193
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
4,002✔
2194
    return terrno;
4,002✔
2195
  }
2196

2197
  return stmtBindBatch(stmt, bind, -1);
51,649✔
2198
}
2199

2200
int taos_stmt_bind_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
639,494,387✔
2201
  if (stmt == NULL || bind == NULL) {
639,494,387✔
UNCOV
2202
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2203
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2204
    return terrno;
×
2205
  }
2206

2207
  if (bind->num <= 0 || bind->num > INT16_MAX) {
647,009,383✔
UNCOV
2208
    tscError("invalid bind num %d", bind->num);
×
UNCOV
2209
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
UNCOV
2210
    return terrno;
×
2211
  }
2212

2213
  int32_t insert = 0;
648,940,712✔
2214
  int32_t code = stmtIsInsert(stmt, &insert);
643,573,469✔
2215
  if (TSDB_CODE_SUCCESS != code) {
641,627,576✔
UNCOV
2216
    tscError("stmt insert failed, errcode:%s", tstrerror(code));
×
UNCOV
2217
    return code;
×
2218
  }
2219
  if (0 == insert && bind->num > 1) {
641,627,576✔
2220
    tscError("only one row data allowed for query");
×
UNCOV
2221
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
UNCOV
2222
    return terrno;
×
2223
  }
2224

2225
  return stmtBindBatch(stmt, bind, -1);
641,627,576✔
2226
}
2227

2228
int taos_stmt_bind_single_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int colIdx) {
28,840✔
2229
  if (stmt == NULL || bind == NULL) {
28,840✔
UNCOV
2230
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2231
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2232
    return terrno;
×
2233
  }
2234

2235
  if (colIdx < 0) {
28,840✔
UNCOV
2236
    tscError("invalid bind column idx %d", colIdx);
×
UNCOV
2237
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2238
    return terrno;
×
2239
  }
2240

2241
  int32_t insert = 0;
28,840✔
2242
  int32_t code = stmtIsInsert(stmt, &insert);
28,840✔
2243
  if (TSDB_CODE_SUCCESS != code) {
28,840✔
UNCOV
2244
    tscError("stmt insert failed, errcode:%s", tstrerror(code));
×
UNCOV
2245
    return code;
×
2246
  }
2247
  if (0 == insert && bind->num > 1) {
28,840✔
2248
    tscError("only one row data allowed for query");
×
UNCOV
2249
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
UNCOV
2250
    return terrno;
×
2251
  }
2252

2253
  return stmtBindBatch(stmt, bind, colIdx);
28,840✔
2254
}
2255

2256
int taos_stmt_add_batch(TAOS_STMT *stmt) {
625,592,965✔
2257
  if (stmt == NULL) {
625,592,965✔
UNCOV
2258
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2259
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2260
    return terrno;
×
2261
  }
2262

2263
  return stmtAddBatch(stmt);
625,592,965✔
2264
}
2265

2266
int taos_stmt_execute(TAOS_STMT *stmt) {
4,521,899✔
2267
  if (stmt == NULL) {
4,521,899✔
UNCOV
2268
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2269
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2270
    return terrno;
×
2271
  }
2272

2273
  return stmtExec(stmt);
4,521,899✔
2274
}
2275

UNCOV
2276
int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert) {
×
UNCOV
2277
  if (stmt == NULL || insert == NULL) {
×
UNCOV
2278
    tscError("NULL parameter for %s", __FUNCTION__);
×
2279
    terrno = TSDB_CODE_INVALID_PARA;
×
2280
    return terrno;
×
2281
  }
2282

2283
  return stmtIsInsert(stmt, insert);
×
2284
}
2285

2286
int taos_stmt_num_params(TAOS_STMT *stmt, int *nums) {
×
UNCOV
2287
  if (stmt == NULL || nums == NULL) {
×
UNCOV
2288
    tscError("NULL parameter for %s", __FUNCTION__);
×
2289
    terrno = TSDB_CODE_INVALID_PARA;
×
2290
    return terrno;
×
2291
  }
2292

2293
  return stmtGetParamNum(stmt, nums);
×
2294
}
2295

2296
int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) {
×
UNCOV
2297
  if (stmt == NULL || type == NULL || NULL == bytes || idx < 0) {
×
UNCOV
2298
    tscError("invalid parameter for %s", __FUNCTION__);
×
2299
    terrno = TSDB_CODE_INVALID_PARA;
×
2300
    return terrno;
×
2301
  }
2302

2303
  return stmtGetParam(stmt, idx, type, bytes);
×
2304
}
2305

2306
TAOS_RES *taos_stmt_use_result(TAOS_STMT *stmt) {
10,340✔
2307
  if (stmt == NULL) {
10,340✔
UNCOV
2308
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2309
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2310
    return NULL;
×
2311
  }
2312

2313
  return stmtUseResult(stmt);
10,340✔
2314
}
2315

2316
char *taos_stmt_errstr(TAOS_STMT *stmt) { return (char *)stmtErrstr(stmt); }
10,501✔
2317

2318
int taos_stmt_affected_rows(TAOS_STMT *stmt) {
4,866✔
2319
  if (stmt == NULL) {
4,866✔
UNCOV
2320
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2321
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2322
    return 0;
×
2323
  }
2324

2325
  return stmtAffectedRows(stmt);
4,866✔
2326
}
2327

2328
int taos_stmt_affected_rows_once(TAOS_STMT *stmt) {
2,390✔
2329
  if (stmt == NULL) {
2,390✔
UNCOV
2330
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2331
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2332
    return 0;
×
2333
  }
2334

2335
  return stmtAffectedRowsOnce(stmt);
2,390✔
2336
}
2337

2338
int taos_stmt_close(TAOS_STMT *stmt) {
407,989✔
2339
  if (stmt == NULL) {
407,989✔
UNCOV
2340
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2341
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2342
    return terrno;
×
2343
  }
2344

2345
  return stmtClose(stmt);
407,989✔
2346
}
2347

2348
TAOS_STMT2 *taos_stmt2_init(TAOS *taos, TAOS_STMT2_OPTION *option) {
18,728✔
2349
  if (NULL == taos) {
18,728✔
UNCOV
2350
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2351
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2352
    return NULL;
×
2353
  }
2354
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
18,728✔
2355
  if (NULL == pObj) {
18,728✔
UNCOV
2356
    tscError("invalid parameter for %s", __FUNCTION__);
×
UNCOV
2357
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
UNCOV
2358
    return NULL;
×
2359
  }
2360

2361
  TAOS_STMT2 *pStmt = stmtInit2(pObj, option);
18,728✔
2362

2363
  releaseTscObj(*(int64_t *)taos);
18,728✔
2364

2365
  return pStmt;
18,728✔
2366
}
2367

2368
int taos_stmt2_prepare(TAOS_STMT2 *stmt, const char *sql, unsigned long length) {
20,640✔
2369
  if (stmt == NULL || sql == NULL) {
20,640✔
UNCOV
2370
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2371
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2372
    return terrno;
×
2373
  }
2374

2375
  return stmtPrepare2(stmt, sql, length);
20,640✔
2376
}
2377

2378
int taos_stmt2_bind_param(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx) {
7,029,629✔
2379
  if (stmt == NULL) {
7,029,629✔
UNCOV
2380
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2381
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2382
    return terrno;
×
2383
  }
2384

2385
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
7,029,629✔
2386
  STMT2_DLOG_E("start to bind param");
7,029,629✔
2387
  if (atomic_load_8((int8_t *)&pStmt->asyncBindParam.asyncBindNum) > 1) {
7,029,629✔
2388
    STMT2_ELOG_E("async bind param is still working, please try again later");
1,901✔
2389
    terrno = TSDB_CODE_TSC_STMT_API_ERROR;
1,901✔
UNCOV
2390
    return terrno;
×
2391
  }
2392

2393
  if (pStmt->options.asyncExecFn && !pStmt->execSemWaited) {
7,029,469✔
UNCOV
2394
    if (tsem_wait(&pStmt->asyncExecSem) != 0) {
×
UNCOV
2395
      STMT2_ELOG_E("bind param wait asyncExecSem failed");
×
2396
    }
2397
    pStmt->execSemWaited = true;
×
2398
  }
2399

2400
  int32_t code = TSDB_CODE_SUCCESS;
7,029,469✔
2401
  for (int i = 0; i < bindv->count; ++i) {
22,434,705✔
2402
    if (bindv->tbnames && bindv->tbnames[i]) {
15,402,045✔
2403
      code = stmtSetTbName2(stmt, bindv->tbnames[i]);
15,404,450✔
2404
      if (code) {
15,404,075✔
2405
        terrno = code;
2✔
UNCOV
2406
        STMT2_ELOG("set tbname failed, code:%s", tstrerror(code));
×
UNCOV
2407
        return terrno;
×
2408
      }
2409
    }
2410

2411
    SVCreateTbReq *pCreateTbReq = NULL;
15,402,157✔
2412
    if (bindv->tags && bindv->tags[i]) {
15,404,206✔
2413
      code = stmtSetTbTags2(stmt, bindv->tags[i], &pCreateTbReq);
9,498,656✔
2414
    } else if (pStmt->bInfo.tbNameFlag & IS_FIXED_TAG) {
5,905,807✔
2415
      code = stmtCheckTags2(stmt, &pCreateTbReq);
1,910,880✔
2416
    } else if (pStmt->sql.autoCreateTbl) {
3,994,157✔
2417
      // if (pStmt->sql.autoCreateTbl) {
2418
      //   pStmt->sql.autoCreateTbl = false;
2419
      //   STMT2_WLOG_E("sql is autoCreateTbl, but no tags");
2420
      // }
UNCOV
2421
      code = stmtSetTbTags2(stmt, NULL, &pCreateTbReq);
×
2422
    }
2423

2424
    if (code) {
15,400,656✔
UNCOV
2425
      terrno = code;
×
UNCOV
2426
      STMT2_ELOG("set tags failed, code:%s", tstrerror(code));
×
UNCOV
2427
      return terrno;
×
2428
    }
2429

2430
    if (bindv->bind_cols && bindv->bind_cols[i]) {
15,400,656✔
2431
      TAOS_STMT2_BIND *bind = bindv->bind_cols[i];
15,405,166✔
2432

2433
      if (bind->num <= 0 || bind->num > INT16_MAX) {
15,404,909✔
2434
        STMT2_ELOG("bind num:%d must > 0 and < INT16_MAX", bind->num);
718✔
2435
        code = terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
718✔
UNCOV
2436
        return terrno;
×
2437
      }
2438

2439
      if (!stmt2IsInsert(stmt) && bind->num > 1) {
15,404,527✔
UNCOV
2440
        STMT2_ELOG_E("only one row data allowed for query");
×
UNCOV
2441
        code = terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
UNCOV
2442
        return terrno;
×
2443
      }
2444

2445
      code = stmtBindBatch2(stmt, bind, col_idx, pCreateTbReq);
15,403,497✔
2446
      if (TSDB_CODE_SUCCESS != code) {
15,405,627✔
UNCOV
2447
        terrno = code;
×
UNCOV
2448
        STMT2_ELOG("bind batch failed, code:%s", tstrerror(code));
×
UNCOV
2449
        return terrno;
×
2450
      }
2451
    }
2452
  }
2453

2454
  return code;
7,032,403✔
2455
}
2456

UNCOV
2457
int taos_stmt2_bind_param_a(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx, __taos_async_fn_t fp,
×
2458
                            void *param) {
UNCOV
2459
  if (stmt == NULL || bindv == NULL || fp == NULL) {
×
2460
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2461
    return terrno;
×
2462
  }
2463

2464
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
×
2465

UNCOV
2466
  ThreadArgs *args = (ThreadArgs *)taosMemoryMalloc(sizeof(ThreadArgs));
×
2467
  args->stmt = stmt;
×
UNCOV
2468
  args->bindv = bindv;
×
2469
  args->col_idx = col_idx;
×
2470
  args->fp = fp;
×
2471
  args->param = param;
×
2472

2473
  (void)taosThreadMutexLock(&(pStmt->asyncBindParam.mutex));
×
2474
  if (atomic_load_8((int8_t *)&pStmt->asyncBindParam.asyncBindNum) > 0) {
×
UNCOV
2475
    (void)taosThreadMutexUnlock(&(pStmt->asyncBindParam.mutex));
×
2476
    tscError("async bind param is still working, please try again later");
×
2477
    terrno = TSDB_CODE_TSC_STMT_API_ERROR;
×
2478
    return terrno;
×
2479
  }
2480
  (void)atomic_add_fetch_8(&pStmt->asyncBindParam.asyncBindNum, 1);
×
2481
  (void)taosThreadMutexUnlock(&(pStmt->asyncBindParam.mutex));
×
2482

2483
  int code_s = taosStmt2AsyncBind(stmtAsyncBindThreadFunc, (void *)args);
×
2484
  if (code_s != TSDB_CODE_SUCCESS) {
×
UNCOV
2485
    terrno = code_s;
×
2486
    (void)taosThreadMutexLock(&(pStmt->asyncBindParam.mutex));
×
2487
    (void)taosThreadCondSignal(&(pStmt->asyncBindParam.waitCond));
×
2488
    (void)atomic_sub_fetch_8(&pStmt->asyncBindParam.asyncBindNum, 1);
×
2489
    (void)taosThreadMutexUnlock(&(pStmt->asyncBindParam.mutex));
×
2490
    tscError("async bind failed, code:%d , %s", code_s, tstrerror(code_s));
×
2491
  }
2492

2493
  return code_s;
×
2494
}
2495

2496
int taos_stmt2_exec(TAOS_STMT2 *stmt, int *affected_rows) {
7,031,601✔
2497
  if (stmt == NULL) {
7,031,601✔
UNCOV
2498
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2499
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2500
    return terrno;
×
2501
  }
2502

2503
  return stmtExec2(stmt, affected_rows);
7,031,601✔
2504
}
2505

2506
int taos_stmt2_close(TAOS_STMT2 *stmt) {
18,728✔
2507
  if (stmt == NULL) {
18,728✔
UNCOV
2508
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2509
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2510
    return terrno;
×
2511
  }
2512

2513
  return stmtClose2(stmt);
18,728✔
2514
}
2515

2516
int taos_stmt2_is_insert(TAOS_STMT2 *stmt, int *insert) {
879✔
2517
  if (stmt == NULL || insert == NULL) {
879✔
UNCOV
2518
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2519
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2520
    return terrno;
×
2521
  }
2522
  *insert = stmt2IsInsert(stmt);
879✔
2523
  return TSDB_CODE_SUCCESS;
879✔
2524
}
2525

2526
int taos_stmt2_get_fields(TAOS_STMT2 *stmt, int *count, TAOS_FIELD_ALL **fields) {
649✔
2527
  if (stmt == NULL || count == NULL) {
649✔
UNCOV
2528
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2529
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2530
    return terrno;
×
2531
  }
2532

2533
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
649✔
2534
  if (STMT_TYPE_INSERT == pStmt->sql.type || STMT_TYPE_MULTI_INSERT == pStmt->sql.type ||
649✔
2535
      (pStmt->sql.type == 0 && stmt2IsInsert(stmt))) {
649✔
2536
    return stmtGetStbColFields2(stmt, count, fields);
649✔
2537
  }
UNCOV
2538
  if (STMT_TYPE_QUERY == pStmt->sql.type || (pStmt->sql.type == 0 && stmt2IsSelect(stmt))) {
×
UNCOV
2539
    return stmtGetParamNum2(stmt, count);
×
2540
  }
2541

2542
  tscError("Invalid sql for stmt %s", pStmt->sql.sqlStr);
×
UNCOV
2543
  return TSDB_CODE_PAR_SYNTAX_ERROR;
×
2544
}
2545

2546
DLL_EXPORT void taos_stmt2_free_fields(TAOS_STMT2 *stmt, TAOS_FIELD_ALL *fields) {
649✔
2547
  (void)stmt;
2548
  if (!fields) return;
649✔
2549
  taosMemoryFree(fields);
649✔
2550
}
2551

2552
TAOS_RES *taos_stmt2_result(TAOS_STMT2 *stmt) {
230✔
2553
  if (stmt == NULL) {
230✔
UNCOV
2554
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2555
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2556
    return NULL;
×
2557
  }
2558

2559
  return stmtUseResult2(stmt);
230✔
2560
}
2561

UNCOV
2562
char *taos_stmt2_error(TAOS_STMT2 *stmt) { return (char *)stmtErrstr2(stmt); }
×
2563

2564
int taos_set_conn_mode(TAOS *taos, int mode, int value) {
3,319✔
2565
  if (taos == NULL) {
3,319✔
UNCOV
2566
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2567
    return terrno;
×
2568
  }
2569

2570
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
3,319✔
2571
  if (NULL == pObj) {
3,319✔
UNCOV
2572
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
UNCOV
2573
    tscError("invalid parameter for %s", __func__);
×
UNCOV
2574
    return terrno;
×
2575
  }
2576
  switch (mode) {
3,319✔
2577
    case TAOS_CONN_MODE_BI:
3,319✔
2578
      atomic_store_8(&pObj->biMode, value);
3,319✔
2579
      break;
3,319✔
UNCOV
2580
    default:
×
UNCOV
2581
      tscError("not supported mode.");
×
UNCOV
2582
      return TSDB_CODE_INVALID_PARA;
×
2583
  }
2584
  return 0;
3,319✔
2585
}
2586

UNCOV
2587
char *getBuildInfo() { return td_buildinfo; }
×
2588

NEW
2589
static int32_t buildInstanceRegisterSql(const SInstanceRegisterReq *req, char **ppSql, uint32_t *pLen) {
×
NEW
2590
  const char *action = (req->expire < 0) ? "UNREGISTER" : "REGISTER";
×
NEW
2591
  int32_t     len = 0;
×
2592

NEW
2593
  len += snprintf(NULL, 0, "%s INSTANCE '%s'", action, req->id);
×
NEW
2594
  if (req->type[0] != 0) {
×
NEW
2595
    len += snprintf(NULL, 0, " TYPE '%s'", req->type);
×
2596
  }
NEW
2597
  if (req->desc[0] != 0) {
×
NEW
2598
    len += snprintf(NULL, 0, " DESC '%s'", req->desc);
×
2599
  }
NEW
2600
  if (req->expire >= 0) {
×
NEW
2601
    len += snprintf(NULL, 0, " EXPIRE %d", req->expire);
×
2602
  }
2603

NEW
2604
  char *sql = taosMemoryMalloc((size_t)len + 1);
×
NEW
2605
  if (sql == NULL) {
×
NEW
2606
    return terrno;
×
2607
  }
2608

NEW
2609
  int32_t offset = snprintf(sql, (size_t)len + 1, "%s INSTANCE '%s'", action, req->id);
×
NEW
2610
  if (req->type[0] != 0) {
×
NEW
2611
    offset += snprintf(sql + offset, (size_t)len + 1 - (size_t)offset, " TYPE '%s'", req->type);
×
2612
  }
NEW
2613
  if (req->desc[0] != 0) {
×
NEW
2614
    offset += snprintf(sql + offset, (size_t)len + 1 - (size_t)offset, " DESC '%s'", req->desc);
×
2615
  }
NEW
2616
  if (req->expire >= 0) {
×
NEW
2617
    (void)snprintf(sql + offset, (size_t)len + 1 - (size_t)offset, " EXPIRE %d", req->expire);
×
2618
  }
2619

NEW
2620
  *ppSql = sql;
×
NEW
2621
  if (pLen != NULL) {
×
NEW
2622
    *pLen = (uint32_t)len;
×
2623
  }
NEW
2624
  return TSDB_CODE_SUCCESS;
×
2625
}
2626

NEW
2627
static int32_t sendInstanceRegisterReq(STscObj *pObj, const SInstanceRegisterReq *req) {
×
NEW
2628
  SRequestObj *pRequest = NULL;
×
NEW
2629
  int32_t      code = createRequest(pObj->id, TDMT_MND_REGISTER_INSTANCE, 0, &pRequest);
×
NEW
2630
  if (code != TSDB_CODE_SUCCESS) {
×
NEW
2631
    terrno = code;
×
NEW
2632
    return code;
×
2633
  }
2634

NEW
2635
  code = buildInstanceRegisterSql(req, &pRequest->sqlstr, &pRequest->sqlLen);
×
NEW
2636
  if (code != TSDB_CODE_SUCCESS) {
×
NEW
2637
    goto _cleanup;
×
2638
  }
2639

NEW
2640
  int32_t msgLen = tSerializeSInstanceRegisterReq(NULL, 0, (SInstanceRegisterReq *)req);
×
NEW
2641
  if (msgLen <= 0) {
×
NEW
2642
    code = terrno != 0 ? terrno : TSDB_CODE_TSC_INTERNAL_ERROR;
×
NEW
2643
    goto _cleanup;
×
2644
  }
2645

NEW
2646
  void *pMsg = taosMemoryMalloc(msgLen);
×
NEW
2647
  if (pMsg == NULL) {
×
NEW
2648
    code = terrno != 0 ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
NEW
2649
    goto _cleanup;
×
2650
  }
2651

NEW
2652
  if (tSerializeSInstanceRegisterReq(pMsg, msgLen, (SInstanceRegisterReq *)req) < 0) {
×
NEW
2653
    code = terrno != 0 ? terrno : TSDB_CODE_TSC_INTERNAL_ERROR;
×
NEW
2654
    taosMemoryFree(pMsg);
×
NEW
2655
    goto _cleanup;
×
2656
  }
2657

NEW
2658
  pRequest->type = TDMT_MND_REGISTER_INSTANCE;
×
NEW
2659
  pRequest->body.requestMsg = (SDataBuf){.pData = pMsg, .len = msgLen, .handle = NULL};
×
2660

NEW
2661
  SMsgSendInfo *pSend = buildMsgInfoImpl(pRequest);
×
NEW
2662
  if (pSend == NULL) {
×
NEW
2663
    code = terrno != 0 ? terrno : TSDB_CODE_TSC_INTERNAL_ERROR;
×
NEW
2664
    taosMemoryFree(pMsg);
×
NEW
2665
    pRequest->body.requestMsg.pData = NULL;
×
NEW
2666
    goto _cleanup;
×
2667
  }
2668

NEW
2669
  SEpSet epSet = getEpSet_s(&pObj->pAppInfo->mgmtEp);
×
NEW
2670
  code = asyncSendMsgToServer(pObj->pAppInfo->pTransporter, &epSet, NULL, pSend);
×
NEW
2671
  if (code != TSDB_CODE_SUCCESS) {
×
NEW
2672
    destroySendMsgInfo(pSend);
×
NEW
2673
    pRequest->body.requestMsg = (SDataBuf){0};
×
NEW
2674
    goto _cleanup;
×
2675
  }
2676

NEW
2677
  code = tsem_wait(&pRequest->body.rspSem);
×
NEW
2678
  if (code != TSDB_CODE_SUCCESS) {
×
NEW
2679
    code = terrno != 0 ? terrno : code;
×
NEW
2680
    goto _cleanup;
×
2681
  }
2682

NEW
2683
  code = pRequest->code;
×
NEW
2684
  terrno = code;
×
2685

NEW
2686
_cleanup:
×
NEW
2687
  destroyRequest(pRequest);
×
NEW
2688
  return code;
×
2689
}
2690

NEW
2691
static bool instanceRegisterRpcRfp(int32_t code, tmsg_t msgType) {
×
NEW
2692
  if (NEED_REDIRECT_ERROR(code)) {
×
NEW
2693
    return true;
×
NEW
2694
  } else if (code == TSDB_CODE_UTIL_QUEUE_OUT_OF_MEMORY || code == TSDB_CODE_OUT_OF_RPC_MEMORY_QUEUE ||
×
NEW
2695
             code == TSDB_CODE_SYN_WRITE_STALL || code == TSDB_CODE_SYN_PROPOSE_NOT_READY ||
×
2696
             code == TSDB_CODE_SYN_RESTORING) {
NEW
2697
    tscDebug("client msg type %s should retry since %s", TMSG_INFO(msgType), tstrerror(code));
×
NEW
2698
    return true;
×
2699
  } else {
NEW
2700
    return false;
×
2701
  }
2702
}
2703

NEW
2704
int32_t taos_register_instance(const char *id, const char *type, const char *desc, int32_t expire) {
×
NEW
2705
  if (id == NULL || id[0] == 0) {
×
NEW
2706
    return terrno = TSDB_CODE_INVALID_PARA;
×
2707
  }
2708

2709
  // Validate string lengths
NEW
2710
  size_t idLen = strlen(id);
×
NEW
2711
  if (idLen >= TSDB_INSTANCE_ID_LEN) {
×
NEW
2712
    tscError("instance id length %zu exceeds limit %d", idLen, TSDB_INSTANCE_ID_LEN - 1);
×
NEW
2713
    return terrno = TSDB_CODE_INVALID_PARA;
×
2714
  }
2715

NEW
2716
  if (type != NULL && type[0] != 0) {
×
NEW
2717
    size_t typeLen = strlen(type);
×
NEW
2718
    if (typeLen >= TSDB_INSTANCE_TYPE_LEN) {
×
NEW
2719
      tscError("instance type length %zu exceeds limit %d", typeLen, TSDB_INSTANCE_TYPE_LEN - 1);
×
NEW
2720
      return terrno = TSDB_CODE_INVALID_PARA;
×
2721
    }
2722
  }
2723

NEW
2724
  if (desc != NULL && desc[0] != 0) {
×
NEW
2725
    size_t descLen = strlen(desc);
×
NEW
2726
    if (descLen >= TSDB_INSTANCE_DESC_LEN) {
×
NEW
2727
      tscError("instance desc length %zu exceeds limit %d", descLen, TSDB_INSTANCE_DESC_LEN - 1);
×
NEW
2728
      return terrno = TSDB_CODE_INVALID_PARA;
×
2729
    }
2730
  }
2731

NEW
2732
  int32_t code = taos_init();
×
NEW
2733
  if (code != TSDB_CODE_SUCCESS) {
×
NEW
2734
    return code;
×
2735
  }
2736

NEW
2737
  SConfig *pCfg = taosGetCfg();
×
NEW
2738
  if (pCfg == NULL) {
×
NEW
2739
    return terrno = TSDB_CODE_CFG_NOT_FOUND;
×
2740
  }
2741

NEW
2742
  SConfigItem *pFirstEpItem = cfgGetItem(pCfg, "firstEp");
×
NEW
2743
  if (pFirstEpItem == NULL || pFirstEpItem->str == NULL || pFirstEpItem->str[0] == 0) {
×
NEW
2744
    return terrno = TSDB_CODE_CFG_NOT_FOUND;
×
2745
  }
2746

NEW
2747
  SEp firstEp = {0};
×
NEW
2748
  code = taosGetFqdnPortFromEp(pFirstEpItem->str, &firstEp);
×
NEW
2749
  if (code != TSDB_CODE_SUCCESS) {
×
NEW
2750
    return terrno = code;
×
2751
  }
2752

NEW
2753
  void    *clientRpc = NULL;
×
NEW
2754
  SEpSet   epSet = {.inUse = 0, .numOfEps = 1};
×
NEW
2755
  SRpcMsg  rpcMsg = {0};
×
NEW
2756
  SRpcMsg  rpcRsp = {0};
×
NEW
2757
  SRpcInit rpcInit = {0};
×
2758

NEW
2759
  rpcInit.label = "INST";
×
NEW
2760
  rpcInit.numOfThreads = 1;
×
NEW
2761
  rpcInit.cfp = NULL;
×
NEW
2762
  rpcInit.sessions = 16;
×
NEW
2763
  rpcInit.connType = TAOS_CONN_CLIENT;
×
NEW
2764
  rpcInit.idleTime = tsShellActivityTimer * 1000;
×
NEW
2765
  rpcInit.compressSize = tsCompressMsgSize;
×
NEW
2766
  rpcInit.user = TSDB_DEFAULT_USER;
×
2767

NEW
2768
  rpcInit.rfp = instanceRegisterRpcRfp;
×
NEW
2769
  rpcInit.retryMinInterval = tsRedirectPeriod;
×
NEW
2770
  rpcInit.retryStepFactor = tsRedirectFactor;
×
NEW
2771
  rpcInit.retryMaxInterval = tsRedirectMaxPeriod;
×
NEW
2772
  rpcInit.retryMaxTimeout =
×
2773
      tsMaxRetryWaitTime;  // Use a special user for instance registration (can be configured for whitelist)
2774

NEW
2775
  int32_t connLimitNum = tsNumOfRpcSessions / (tsNumOfRpcThreads * 3);
×
NEW
2776
  connLimitNum = TMAX(connLimitNum, 10);
×
NEW
2777
  connLimitNum = TMIN(connLimitNum, 500);
×
NEW
2778
  rpcInit.connLimitNum = connLimitNum;
×
NEW
2779
  rpcInit.timeToGetConn = tsTimeToGetAvailableConn;
×
NEW
2780
  rpcInit.readTimeout = tsReadTimeout;
×
NEW
2781
  rpcInit.ipv6 = tsEnableIpv6;
×
NEW
2782
  rpcInit.enableSSL = tsEnableTLS;
×
2783

NEW
2784
  memcpy(rpcInit.caPath, tsTLSCaPath, strlen(tsTLSCaPath));
×
NEW
2785
  memcpy(rpcInit.certPath, tsTLSSvrCertPath, strlen(tsTLSSvrCertPath));
×
NEW
2786
  memcpy(rpcInit.keyPath, tsTLSSvrKeyPath, strlen(tsTLSSvrKeyPath));
×
NEW
2787
  memcpy(rpcInit.cliCertPath, tsTLSCliCertPath, strlen(tsTLSCliCertPath));
×
NEW
2788
  memcpy(rpcInit.cliKeyPath, tsTLSCliKeyPath, strlen(tsTLSCliKeyPath));
×
2789

NEW
2790
  code = taosVersionStrToInt(td_version, &rpcInit.compatibilityVer);
×
NEW
2791
  if (code != TSDB_CODE_SUCCESS) {
×
NEW
2792
    tscError("failed to convert taos version from str to int, errcode:%s", terrstr(code));
×
NEW
2793
    return code;
×
2794
  }
2795

NEW
2796
  clientRpc = rpcOpen(&rpcInit);
×
NEW
2797
  if (clientRpc == NULL) {
×
NEW
2798
    code = terrno;
×
NEW
2799
    tscError("failed to init instance register client since %s", tstrerror(code));
×
NEW
2800
    return code;
×
2801
  }
2802

2803
  // Prepare epSet
NEW
2804
  tstrncpy(epSet.eps[0].fqdn, firstEp.fqdn, TSDB_FQDN_LEN);
×
NEW
2805
  epSet.eps[0].port = firstEp.port;
×
2806

2807
  // Prepare request
NEW
2808
  SInstanceRegisterReq req = {0};
×
NEW
2809
  tstrncpy(req.id, id, sizeof(req.id));
×
NEW
2810
  if (type != NULL && type[0] != 0) {
×
NEW
2811
    tstrncpy(req.type, type, sizeof(req.type));
×
2812
  }
NEW
2813
  if (desc != NULL && desc[0] != 0) {
×
NEW
2814
    tstrncpy(req.desc, desc, sizeof(req.desc));
×
2815
  }
NEW
2816
  req.expire = expire;
×
2817

NEW
2818
  int32_t contLen = tSerializeSInstanceRegisterReq(NULL, 0, &req);
×
NEW
2819
  if (contLen <= 0) {
×
NEW
2820
    code = terrno != 0 ? terrno : TSDB_CODE_TSC_INTERNAL_ERROR;
×
NEW
2821
    rpcClose(clientRpc);
×
NEW
2822
    return code;
×
2823
  }
2824

NEW
2825
  void *pCont = rpcMallocCont(contLen);
×
NEW
2826
  if (pCont == NULL) {
×
NEW
2827
    code = terrno != 0 ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
NEW
2828
    rpcClose(clientRpc);
×
NEW
2829
    return code;
×
2830
  }
2831

NEW
2832
  if (tSerializeSInstanceRegisterReq(pCont, contLen, &req) < 0) {
×
NEW
2833
    code = terrno != 0 ? terrno : TSDB_CODE_TSC_INTERNAL_ERROR;
×
NEW
2834
    rpcFreeCont(pCont);
×
NEW
2835
    rpcClose(clientRpc);
×
NEW
2836
    return code;
×
2837
  }
2838

NEW
2839
  rpcMsg.pCont = pCont;
×
NEW
2840
  rpcMsg.contLen = contLen;
×
NEW
2841
  rpcMsg.msgType = TDMT_MND_REGISTER_INSTANCE;
×
NEW
2842
  rpcMsg.info.ahandle = (void *)0x9528;  // Different magic number from server status
×
NEW
2843
  rpcMsg.info.notFreeAhandle = 1;
×
2844

NEW
2845
  code = rpcSendRecv(clientRpc, &epSet, &rpcMsg, &rpcRsp);
×
NEW
2846
  if (TSDB_CODE_SUCCESS != code) {
×
NEW
2847
    tscError("failed to send instance register req since %s", tstrerror(code));
×
2848
    // rpcSendRecv failed, pCont may not be freed, but check _RETURN1 path
2849
    // In error path, rpcSendRecv may free pCont, but we free it here to be safe
NEW
2850
    rpcClose(clientRpc);
×
NEW
2851
    return code;
×
2852
  }
2853

NEW
2854
  if (rpcRsp.code != 0) {
×
NEW
2855
    code = rpcRsp.code;
×
NEW
2856
    tscError("instance register failed, code:%s", tstrerror(code));
×
2857
  } else {
NEW
2858
    code = TSDB_CODE_SUCCESS;
×
2859
  }
2860

NEW
2861
  if (rpcRsp.pCont != NULL) {
×
NEW
2862
    rpcFreeCont(rpcRsp.pCont);
×
2863
  }
NEW
2864
  rpcClose(clientRpc);
×
2865

NEW
2866
  terrno = code;
×
NEW
2867
  return code;
×
2868
}
2869

NEW
2870
int32_t taos_list_instances(const char *filter_type, char ***pList, int32_t *pCount) {
×
NEW
2871
  if (pList == NULL || pCount == NULL) {
×
NEW
2872
    return TSDB_CODE_INVALID_PARA;
×
2873
  }
2874

NEW
2875
  int32_t code = taos_init();
×
NEW
2876
  if (code != TSDB_CODE_SUCCESS) {
×
NEW
2877
    terrno = code;
×
NEW
2878
    return code;
×
2879
  }
2880

NEW
2881
  SConfig *pCfg = taosGetCfg();
×
NEW
2882
  if (pCfg == NULL) {
×
NEW
2883
    terrno = TSDB_CODE_CFG_NOT_FOUND;
×
NEW
2884
    return TSDB_CODE_CFG_NOT_FOUND;
×
2885
  }
2886

NEW
2887
  SConfigItem *pFirstEpItem = cfgGetItem(pCfg, "firstEp");
×
NEW
2888
  if (pFirstEpItem == NULL || pFirstEpItem->str == NULL || pFirstEpItem->str[0] == 0) {
×
NEW
2889
    terrno = TSDB_CODE_CFG_NOT_FOUND;
×
NEW
2890
    return TSDB_CODE_CFG_NOT_FOUND;
×
2891
  }
2892

NEW
2893
  SEp firstEp = {0};
×
NEW
2894
  code = taosGetFqdnPortFromEp(pFirstEpItem->str, &firstEp);
×
NEW
2895
  if (code != TSDB_CODE_SUCCESS) {
×
NEW
2896
    terrno = code;
×
NEW
2897
    return code;
×
2898
  }
2899

2900
  // Initialize RPC connection (similar to taos_register_instance)
NEW
2901
  void    *clientRpc = NULL;
×
NEW
2902
  SEpSet   epSet = {.inUse = 0, .numOfEps = 1};
×
NEW
2903
  SRpcMsg  rpcMsg = {0};
×
NEW
2904
  SRpcMsg  rpcRsp = {0};
×
NEW
2905
  SRpcInit rpcInit = {0};
×
2906

NEW
2907
  rpcInit.label = "LIST";
×
NEW
2908
  rpcInit.numOfThreads = 1;
×
NEW
2909
  rpcInit.cfp = NULL;
×
NEW
2910
  rpcInit.sessions = 16;
×
NEW
2911
  rpcInit.connType = TAOS_CONN_CLIENT;
×
NEW
2912
  rpcInit.idleTime = tsShellActivityTimer * 1000;
×
NEW
2913
  rpcInit.compressSize = tsCompressMsgSize;
×
NEW
2914
  rpcInit.user = TSDB_DEFAULT_USER;
×
2915

NEW
2916
  rpcInit.rfp = instanceRegisterRpcRfp;
×
NEW
2917
  rpcInit.retryMinInterval = tsRedirectPeriod;
×
NEW
2918
  rpcInit.retryStepFactor = tsRedirectFactor;
×
NEW
2919
  rpcInit.retryMaxInterval = tsRedirectMaxPeriod;
×
NEW
2920
  rpcInit.retryMaxTimeout =
×
2921
      tsMaxRetryWaitTime;  // Use a special user for instance registration (can be configured for whitelist)
2922

NEW
2923
  int32_t connLimitNum = tsNumOfRpcSessions / (tsNumOfRpcThreads * 3);
×
NEW
2924
  connLimitNum = TMAX(connLimitNum, 10);
×
NEW
2925
  connLimitNum = TMIN(connLimitNum, 500);
×
NEW
2926
  rpcInit.connLimitNum = connLimitNum;
×
NEW
2927
  rpcInit.timeToGetConn = tsTimeToGetAvailableConn;
×
NEW
2928
  rpcInit.readTimeout = tsReadTimeout;
×
NEW
2929
  rpcInit.ipv6 = tsEnableIpv6;
×
NEW
2930
  rpcInit.enableSSL = tsEnableTLS;
×
2931

NEW
2932
  memcpy(rpcInit.caPath, tsTLSCaPath, strlen(tsTLSCaPath));
×
NEW
2933
  memcpy(rpcInit.certPath, tsTLSSvrCertPath, strlen(tsTLSSvrCertPath));
×
NEW
2934
  memcpy(rpcInit.keyPath, tsTLSSvrKeyPath, strlen(tsTLSSvrKeyPath));
×
NEW
2935
  memcpy(rpcInit.cliCertPath, tsTLSCliCertPath, strlen(tsTLSCliCertPath));
×
NEW
2936
  memcpy(rpcInit.cliKeyPath, tsTLSCliKeyPath, strlen(tsTLSCliKeyPath));
×
2937

NEW
2938
  code = taosVersionStrToInt(td_version, &rpcInit.compatibilityVer);
×
NEW
2939
  if (code != TSDB_CODE_SUCCESS) {
×
NEW
2940
    tscError("failed to convert taos version from str to int, errcode:%s", terrstr(code));
×
NEW
2941
    return code;
×
2942
  }
2943

NEW
2944
  clientRpc = rpcOpen(&rpcInit);
×
NEW
2945
  if (clientRpc == NULL) {
×
NEW
2946
    code = terrno;
×
NEW
2947
    tscError("failed to init instance list client since %s", tstrerror(code));
×
NEW
2948
    terrno = code;
×
NEW
2949
    return code;
×
2950
  }
2951

NEW
2952
  tstrncpy(epSet.eps[0].fqdn, firstEp.fqdn, TSDB_FQDN_LEN);
×
NEW
2953
  epSet.eps[0].port = firstEp.port;
×
NEW
2954
  SInstanceListReq req = {0};
×
NEW
2955
  if (filter_type != NULL && filter_type[0] != 0) {
×
NEW
2956
    tstrncpy(req.filter_type, filter_type, sizeof(req.filter_type));
×
2957
  }
2958

2959
  // Serialize request to get required length
NEW
2960
  int32_t contLen = tSerializeSInstanceListReq(NULL, 0, &req);
×
NEW
2961
  if (contLen <= 0) {
×
NEW
2962
    code = terrno != 0 ? terrno : TSDB_CODE_TSC_INTERNAL_ERROR;
×
NEW
2963
    rpcClose(clientRpc);
×
NEW
2964
    terrno = code;
×
NEW
2965
    return code;
×
2966
  }
2967

2968
  // Allocate RPC message buffer (includes message header overhead)
NEW
2969
  void *pCont = rpcMallocCont(contLen);
×
NEW
2970
  if (pCont == NULL) {
×
NEW
2971
    code = terrno != 0 ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
NEW
2972
    rpcClose(clientRpc);
×
NEW
2973
    terrno = code;
×
NEW
2974
    return code;
×
2975
  }
2976

2977
  // Serialize request into the content part (after message header)
NEW
2978
  if (tSerializeSInstanceListReq(pCont, contLen, &req) < 0) {
×
NEW
2979
    code = terrno != 0 ? terrno : TSDB_CODE_TSC_INTERNAL_ERROR;
×
NEW
2980
    rpcFreeCont(pCont);
×
NEW
2981
    rpcClose(clientRpc);
×
NEW
2982
    terrno = code;
×
NEW
2983
    return code;
×
2984
  }
2985

NEW
2986
  rpcMsg.pCont = pCont;
×
NEW
2987
  rpcMsg.contLen = contLen;
×
NEW
2988
  rpcMsg.msgType = TDMT_MND_LIST_INSTANCES;
×
NEW
2989
  rpcMsg.info.ahandle = (void *)0x9529;  // Different magic number from register
×
NEW
2990
  rpcMsg.info.notFreeAhandle = 1;
×
2991

NEW
2992
  code = rpcSendRecv(clientRpc, &epSet, &rpcMsg, &rpcRsp);
×
NEW
2993
  if (TSDB_CODE_SUCCESS != code) {
×
NEW
2994
    tscError("failed to send instance list req since %s", tstrerror(code));
×
NEW
2995
    rpcFreeCont(pCont);
×
NEW
2996
    rpcClose(clientRpc);
×
NEW
2997
    terrno = code;
×
NEW
2998
    return code;
×
2999
  }
3000

3001
  // Check response - rpcRsp.code contains the result code from mnode
NEW
3002
  if (rpcRsp.code != 0) {
×
NEW
3003
    code = rpcRsp.code;
×
NEW
3004
    tscError("instance list failed, code:%s", tstrerror(code));
×
NEW
3005
    if (rpcRsp.pCont != NULL) {
×
NEW
3006
      rpcFreeCont(rpcRsp.pCont);
×
3007
    }
NEW
3008
    rpcClose(clientRpc);
×
NEW
3009
    terrno = code;
×
NEW
3010
    return code;
×
3011
  }
3012

3013
  // Deserialize response
NEW
3014
  if (rpcRsp.pCont != NULL && rpcRsp.contLen > 0) {
×
NEW
3015
    SInstanceListRsp rsp = {0};
×
NEW
3016
    code = tDeserializeSInstanceListRsp(rpcRsp.pCont, rpcRsp.contLen, &rsp);
×
NEW
3017
    if (code != TSDB_CODE_SUCCESS) {
×
NEW
3018
      tscError("failed to deserialize instance list rsp, code:%s", tstrerror(code));
×
NEW
3019
      if (rsp.ids != NULL) {
×
NEW
3020
        for (int32_t i = 0; i < rsp.count; i++) {
×
NEW
3021
          if (rsp.ids[i] != NULL) {
×
NEW
3022
            taosMemoryFree(rsp.ids[i]);
×
3023
          }
3024
        }
NEW
3025
        taosMemoryFree(rsp.ids);
×
NEW
3026
        rsp.ids = NULL;
×
3027
      }
NEW
3028
      rsp.count = 0;
×
NEW
3029
      rpcFreeCont(rpcRsp.pCont);
×
NEW
3030
      rpcClose(clientRpc);
×
NEW
3031
      terrno = code;
×
NEW
3032
      return code;
×
3033
    }
NEW
3034
    *pList = rsp.ids;
×
NEW
3035
    *pCount = rsp.count;
×
3036
  } else {
NEW
3037
    *pList = NULL;
×
NEW
3038
    *pCount = 0;
×
3039
  }
3040

NEW
3041
  if (rpcRsp.pCont != NULL) {
×
NEW
3042
    rpcFreeCont(rpcRsp.pCont);
×
3043
  }
NEW
3044
  rpcClose(clientRpc);
×
3045

NEW
3046
  return TSDB_CODE_SUCCESS;
×
3047
}
3048

NEW
3049
void taos_free_instances(char ***pList, int32_t count) {
×
NEW
3050
  if (pList == NULL || *pList == NULL || count <= 0) {
×
NEW
3051
    return;
×
3052
  }
3053

3054
  // Free each string in the array
NEW
3055
  for (int32_t i = 0; i < count; i++) {
×
NEW
3056
    if ((*pList)[i] != NULL) {
×
NEW
3057
      taosMemoryFree((*pList)[i]);
×
NEW
3058
      (*pList)[i] = NULL;
×
3059
    }
3060
  }
3061

3062
  // Free the array itself
NEW
3063
  taosMemoryFree(*pList);
×
NEW
3064
  *pList = NULL;
×
3065
}
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