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

taosdata / TDengine / #4829

30 Oct 2025 09:25AM UTC coverage: 49.734% (-11.3%) from 61.071%
#4829

push

travis-ci

web-flow
Merge pull request #33435 from taosdata/3.0

merge 3.0

123072 of 323930 branches covered (37.99%)

Branch coverage included in aggregate %.

7 of 25 new or added lines in 3 files covered. (28.0%)

35232 existing lines in 327 files now uncovered.

172062 of 269495 relevant lines covered (63.85%)

70709785.06 hits per line

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

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

16
#include "catalog.h"
17
#include "clientInt.h"
18
#include "clientLog.h"
19
#include "clientMonitor.h"
20
#include "clientStmt.h"
21
#include "clientStmt2.h"
22
#include "functionMgt.h"
23
#include "os.h"
24
#include "query.h"
25
#include "scheduler.h"
26
#include "tcompare.h"
27
#include "tconv.h"
28
#include "tdatablock.h"
29
#include "tglobal.h"
30
#include "tmsg.h"
31
#include "tref.h"
32
#include "trpc.h"
33
#include "version.h"
34

35
#define TSC_VAR_NOT_RELEASE 1
36
#define TSC_VAR_RELEASED    0
37

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

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

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

51
  for (int i = 1; atomic_val_compare_exchange_32(&lock, 0, 1) != 0; ++i) {
73,402,836✔
52
    if (i % 1000 == 0) {
72,953,300✔
53
      (void)sched_yield();
74,760✔
54
    }
55
  }
56

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

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

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

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

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

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

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

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

UNCOV
124
END:
×
UNCOV
125
  return tz;
×
126
}
127
#endif
128

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

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

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

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

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

UNCOV
156
  if (option == TSDB_OPTION_CONNECTION_CLEAR) {
×
UNCOV
157
    val = NULL;
×
158
  }
159

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

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

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

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

UNCOV
233
END:
×
UNCOV
234
  releaseTscObj(*(int64_t *)taos);
×
UNCOV
235
  return terrno = code;
×
236
}
237

UNCOV
238
int taos_options_connection(TAOS *taos, TSDB_OPTION_CONNECTION option, const void *arg, ...) {
×
UNCOV
239
  return setConnectionOption(taos, option, (const char *)arg);
×
240
}
241

242
// this function may be called by user or system, or by both simultaneously.
243
void taos_cleanup(void) {
1,354,540✔
244
  tscInfo("start to cleanup client environment");
1,354,540!
245
  if (atomic_val_compare_exchange_32(&sentinel, TSC_VAR_NOT_RELEASE, TSC_VAR_RELEASED) != TSC_VAR_NOT_RELEASE) {
1,354,540✔
246
    return;
707✔
247
  }
248

249
  monitorClose();
1,353,833✔
250
  tscStopCrashReport();
1,353,833✔
251

252
  hbMgrCleanUp();
1,353,833✔
253

254
  catalogDestroy();
1,353,833✔
255
  schedulerDestroy();
1,353,833✔
256

257
  fmFuncMgtDestroy();
1,353,833✔
258
  qCleanupKeywordsTable();
1,353,833✔
259

260
#if !defined(WINDOWS) && !defined(TD_ASTRA)
261
  tzCleanup();
1,353,833✔
262
#endif
263
  tmqMgmtClose();
1,353,833✔
264

265
  int32_t id = clientReqRefPool;
1,353,833✔
266
  clientReqRefPool = -1;
1,353,833✔
267
  taosCloseRef(id);
1,353,833✔
268

269
  id = clientConnRefPool;
1,353,833✔
270
  clientConnRefPool = -1;
1,353,833✔
271
  taosCloseRef(id);
1,353,833✔
272

273
  nodesDestroyAllocatorSet();
1,353,833✔
274
  cleanupAppInfo();
1,353,833✔
275
  rpcCleanup();
1,353,833✔
276
  tscDebug("rpc cleanup");
1,353,833✔
277

278
  if (TSDB_CODE_SUCCESS != cleanupTaskQueue()) {
1,353,833!
279
    tscWarn("failed to cleanup task queue");
×
280
  }
281

282
  taosConvDestroy();
1,353,833✔
283
  DestroyRegexCache();
1,353,833✔
284
#ifdef TAOSD_INTEGRATED
285
  shellStopDaemon();
286
#endif
287
  tscInfo("all local resources released");
1,353,833!
288
  taosCleanupCfg();
1,353,833✔
289
#ifndef TAOSD_INTEGRATED
290
  taosCloseLog();
1,353,833✔
291
#endif
292
}
293

UNCOV
294
static setConfRet taos_set_config_imp(const char *config) {
×
UNCOV
295
  setConfRet ret = {SET_CONF_RET_SUCC, {0}};
×
296
  // TODO: need re-implementation
UNCOV
297
  return ret;
×
298
}
299

UNCOV
300
setConfRet taos_set_config(const char *config) {
×
301
  // TODO  pthread_mutex_lock(&setConfMutex);
UNCOV
302
  setConfRet ret = taos_set_config_imp(config);
×
303
  //  pthread_mutex_unlock(&setConfMutex);
UNCOV
304
  return ret;
×
305
}
306

307
TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port) {
1,752,898✔
308
  tscInfo("try to connect to %s:%u, user:%s db:%s", ip, port, user, db);
1,752,898!
309
  if (user == NULL) {
1,752,898✔
310
    user = TSDB_DEFAULT_USER;
72,049✔
311
  }
312

313
  if (pass == NULL) {
1,752,898✔
314
    pass = TSDB_DEFAULT_PASS;
72,049✔
315
  }
316

317
  STscObj *pObj = NULL;
1,752,898✔
318
  int32_t  code = taos_connect_internal(ip, user, pass, NULL, db, port, CONN_TYPE__QUERY, &pObj);
1,752,898✔
319
  if (TSDB_CODE_SUCCESS == code) {
1,752,650✔
320
    int64_t *rid = taosMemoryCalloc(1, sizeof(int64_t));
1,752,542!
321
    if (NULL == rid) {
1,752,542!
322
      tscError("out of memory when taos connect to %s:%u, user:%s db:%s", ip, port, user, db);
×
323
      return NULL;
×
324
    }
325
    *rid = pObj->id;
1,752,542✔
326
    return (TAOS *)rid;
1,752,542✔
327
  } else {
328
    terrno = code;
108✔
329
  }
330

331
  return NULL;
108✔
332
}
333

334
int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type) {
1,960✔
335
  if (taos == NULL) {
1,960!
336
    terrno = TSDB_CODE_INVALID_PARA;
×
337
    return terrno;
×
338
  }
339

340
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
1,960✔
341
  if (NULL == pObj) {
1,960!
342
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
343
    tscError("invalid parameter for %s", __func__);
×
344
    return terrno;
×
345
  }
346

347
  switch (type) {
1,960!
348
    case TAOS_NOTIFY_PASSVER: {
560✔
349
      TSC_ERR_RET(taosThreadMutexLock(&pObj->mutex));
560!
350
      pObj->passInfo.fp = fp;
560✔
351
      pObj->passInfo.param = param;
560✔
352
      TSC_ERR_RET(taosThreadMutexUnlock(&pObj->mutex));
560!
353
      break;
560✔
354
    }
355
    case TAOS_NOTIFY_WHITELIST_VER: {
×
356
      TSC_ERR_RET(taosThreadMutexLock(&pObj->mutex));
×
357
      pObj->whiteListInfo.fp = fp;
×
358
      pObj->whiteListInfo.param = param;
×
359
      TSC_ERR_RET(taosThreadMutexUnlock(&pObj->mutex));
×
360
      break;
×
361
    }
362
    case TAOS_NOTIFY_USER_DROPPED: {
1,400✔
363
      TSC_ERR_RET(taosThreadMutexLock(&pObj->mutex));
1,400!
364
      pObj->userDroppedInfo.fp = fp;
1,400✔
365
      pObj->userDroppedInfo.param = param;
1,400✔
366
      TSC_ERR_RET(taosThreadMutexUnlock(&pObj->mutex));
1,400!
367
      break;
1,400✔
368
    }
369
    default: {
×
370
      terrno = TSDB_CODE_INVALID_PARA;
×
371
      releaseTscObj(*(int64_t *)taos);
×
372
      return terrno;
×
373
    }
374
  }
375

376
  releaseTscObj(*(int64_t *)taos);
1,960✔
377
  return 0;
1,960✔
378
}
379

380
typedef struct SFetchWhiteListInfo {
381
  int64_t                     connId;
382
  __taos_async_whitelist_fn_t userCbFn;
383
  void                       *userParam;
384
} SFetchWhiteListInfo;
385

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

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

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

415
  for (int i = 0; i < wlRsp.numWhiteLists; ++i) {
×
416
    pWhiteLists[i] = ((uint64_t)wlRsp.pWhiteLists[i].mask << 32) | wlRsp.pWhiteLists[i].ip;
×
417
  }
418

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

421
  taosMemoryFree(pWhiteLists);
×
422
  taosMemoryFree(pMsg->pData);
×
423
  taosMemoryFree(pMsg->pEpSet);
×
424
  taosMemoryFree(pInfo);
×
425
  tFreeSGetUserWhiteListRsp(&wlRsp);
×
426
  return code;
×
427
}
428

429
void taos_fetch_whitelist_a(TAOS *taos, __taos_async_whitelist_fn_t fp, void *param) {
×
430
  if (NULL == taos) {
×
431
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
432
    return;
×
433
  }
434

435
  int64_t connId = *(int64_t *)taos;
×
436

437
  STscObj *pTsc = acquireTscObj(connId);
×
438
  if (NULL == pTsc) {
×
439
    fp(param, TSDB_CODE_TSC_DISCONNECTED, taos, 0, NULL);
×
440
    return;
×
441
  }
442

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

452
  void *pReq = taosMemoryMalloc(msgLen);
×
453
  if (pReq == NULL) {
×
454
    fp(param, terrno, taos, 0, NULL);
×
455
    releaseTscObj(connId);
×
456
    return;
×
457
  }
458

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

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

474
  pParam->connId = connId;
×
475
  pParam->userCbFn = fp;
×
476

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

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

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

502
typedef struct SFetchWhiteListDualStackInfo {
503
  int64_t connId;
504
  void   *userParam;
505

506
  __taos_async_whitelist_dual_stack_fn_t userCbFn;
507
} SFetchWhiteListDualStackInfo;
508

509
int32_t fetchWhiteListDualStackCallbackFn(void *param, SDataBuf *pMsg, int32_t code) {
×
510
  int32_t lino = 0;
×
511
  char  **pWhiteLists = NULL;
×
512

513
  SGetUserWhiteListRsp wlRsp = {0};
×
514

515
  SFetchWhiteListDualStackInfo *pInfo = (SFetchWhiteListDualStackInfo *)param;
×
516
  TAOS *taos = &pInfo->connId;
×
517

518
  if (code != TSDB_CODE_SUCCESS) {
×
519
    pInfo->userCbFn(pInfo->userParam, code, taos, 0, NULL);
×
520
    TAOS_CHECK_GOTO(code, &lino, _error);
×
521
  }
522

523
  if ((code = tDeserializeSGetUserWhiteListDualRsp(pMsg->pData, pMsg->len, &wlRsp)) != TSDB_CODE_SUCCESS) {
×
524
    TAOS_CHECK_GOTO(code, &lino, _error);
×
525
  }
526

527
  pWhiteLists = taosMemoryMalloc(wlRsp.numWhiteLists * sizeof(char *));
×
528
  if (pWhiteLists == NULL) {
×
529
    code = terrno;
×
530
    TAOS_CHECK_GOTO(code, &lino, _error);
×
531
  }
532

533
  for (int32_t i = 0; i < wlRsp.numWhiteLists; i++) {
×
534
    SIpRange *pIpRange = &wlRsp.pWhiteListsDual[i];
×
535
    SIpAddr   ipAddr = {0};
×
536

537
    code = tIpUintToStr(pIpRange, &ipAddr);
×
538
    TAOS_CHECK_GOTO(code, &lino, _error);
×
539

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

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

577
  STscObj *pTsc = acquireTscObj(connId);
×
578
  if (NULL == pTsc) {
×
579
    fp(param, TSDB_CODE_TSC_DISCONNECTED, taos, 0, NULL);
×
580
    return;
×
581
  }
582

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

592
  void *pReq = taosMemoryMalloc(msgLen);
×
593
  if (pReq == NULL) {
×
594
    fp(param, terrno, taos, 0, NULL);
×
595
    releaseTscObj(connId);
×
596
    return;
×
597
  }
598

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

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

614
  pParam->connId = connId;
×
615
  pParam->userCbFn = fp;
×
616
  pParam->userParam = param;
×
617

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

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

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

642
void taos_close_internal(void *taos) {
1,765,714✔
643
  if (taos == NULL) {
1,765,714!
644
    return;
×
645
  }
646

647
  STscObj *pTscObj = (STscObj *)taos;
1,765,714✔
648
  tscDebug("conn:0x%" PRIx64 ", try to close connection, numOfReq:%d", pTscObj->id, pTscObj->numOfReqs);
1,765,714✔
649

650
  if (TSDB_CODE_SUCCESS != taosRemoveRef(clientConnRefPool, pTscObj->id)) {
1,765,714!
651
    tscError("conn:0x%" PRIx64 ", failed to remove ref from conn pool", pTscObj->id);
×
652
  }
653
}
654

655
void taos_close(TAOS *taos) {
1,752,169✔
656
  if (taos == NULL) {
1,752,169!
UNCOV
657
    return;
×
658
  }
659

660
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
1,752,169✔
661
  if (NULL == pObj) {
1,752,417!
662
    taosMemoryFree(taos);
×
663
    return;
×
664
  }
665

666
  taos_close_internal(pObj);
1,752,417✔
667
  releaseTscObj(*(int64_t *)taos);
1,752,169✔
668
  taosMemoryFree(taos);
1,752,670!
669
}
670

671
int taos_errno(TAOS_RES *res) {
216,121,782✔
672
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
216,121,782✔
673
    return terrno;
1,107✔
674
  }
675

676
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
216,121,735✔
677
    return 0;
159,514✔
678
  }
679

680
  return ((SRequestObj *)res)->code;
215,962,571✔
681
}
682

683
const char *taos_errstr(TAOS_RES *res) {
2,897,389✔
684
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
2,897,389!
685
    return (const char *)tstrerror(terrno);
176✔
686
  }
687

688
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
2,897,213!
689
    return "success";
×
690
  }
691

692
  SRequestObj *pRequest = (SRequestObj *)res;
2,897,213✔
693
  if (NULL != pRequest->msgBuf && (strlen(pRequest->msgBuf) > 0 || pRequest->code == TSDB_CODE_RPC_FQDN_ERROR)) {
2,897,213!
694
    return pRequest->msgBuf;
2,174,281✔
695
  } else {
696
    return (const char *)tstrerror(pRequest->code);
722,932✔
697
  }
698
}
699

700
void taos_free_result(TAOS_RES *res) {
170,697,446✔
701
  if (NULL == res) {
170,697,446✔
702
    return;
119,078✔
703
  }
704

705
  tscTrace("res:%p, will be freed", res);
170,578,368✔
706

707
  if (TD_RES_QUERY(res)) {
170,578,368✔
708
    SRequestObj *pRequest = (SRequestObj *)res;
169,513,370✔
709
    tscDebug("QID:0x%" PRIx64 ", call taos_free_result to free query, res:%p", pRequest->requestId, res);
169,513,370✔
710
    destroyRequest(pRequest);
169,513,564✔
711
    return;
169,511,024✔
712
  }
713

714
  SMqRspObj *pRsp = (SMqRspObj *)res;
1,065,257✔
715
  if (TD_RES_TMQ(res)) {
1,065,257✔
716
    tDeleteMqDataRsp(&pRsp->dataRsp);
1,066,361✔
717
    doFreeReqResultInfo(&pRsp->resInfo);
1,066,361✔
718
  } else if (TD_RES_TMQ_METADATA(res)) {
708✔
719
    tDeleteSTaosxRsp(&pRsp->dataRsp);
178✔
720
    doFreeReqResultInfo(&pRsp->resInfo);
178✔
721
  } else if (TD_RES_TMQ_META(res)) {
530✔
722
    tDeleteMqMetaRsp(&pRsp->metaRsp);
178✔
723
  } else if (TD_RES_TMQ_BATCH_META(res)) {
352!
724
    tDeleteMqBatchMetaRsp(&pRsp->batchMetaRsp);
352✔
725
  } else if (TD_RES_TMQ_RAW(res)) {
×
726
    tDeleteMqRawDataRsp(&pRsp->dataRsp);
×
727
  }
728
  taosMemoryFree(pRsp);
1,067,069!
729
}
730

UNCOV
731
void taos_kill_query(TAOS *taos) {
×
UNCOV
732
  if (NULL == taos) {
×
UNCOV
733
    return;
×
734
  }
735

UNCOV
736
  int64_t  rid = *(int64_t *)taos;
×
UNCOV
737
  STscObj *pTscObj = acquireTscObj(rid);
×
UNCOV
738
  if (pTscObj) {
×
UNCOV
739
    stopAllRequests(pTscObj->pRequests);
×
740
  }
UNCOV
741
  releaseTscObj(rid);
×
742
}
743

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

749
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
2,147,483,647✔
750
  return pResInfo->numOfCols;
2,147,483,647✔
751
}
752

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

755
TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) {
1,107,747,857✔
756
  if (taos_num_fields(res) == 0 || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
1,107,747,857!
757
    return NULL;
315,752✔
758
  }
759

760
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
1,107,431,425✔
761
  return pResInfo->userFields;
1,107,431,425✔
762
}
763

764
TAOS_RES *taos_query(TAOS *taos, const char *sql) { return taosQueryImpl(taos, sql, false, TD_REQ_FROM_APP); }
169,216,698✔
765
TAOS_RES *taos_query_with_reqid(TAOS *taos, const char *sql, int64_t reqid) {
20✔
766
  return taosQueryImplWithReqid(taos, sql, false, reqid);
20✔
767
}
768

769
TAOS_FIELD_E *taos_fetch_fields_e(TAOS_RES *res) {
267✔
770
  if (taos_num_fields(res) == 0 || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
267!
771
    return NULL;
×
772
  }
773
  SReqResultInfo* pResInfo = tscGetCurResInfo(res);
267✔
774
  return pResInfo->fields;
267✔
775
}
776

777
TAOS_ROW taos_fetch_row(TAOS_RES *res) {
2,147,483,647✔
778
  if (res == NULL) {
2,147,483,647!
779
    return NULL;
×
780
  }
781

782
  if (TD_RES_QUERY(res)) {
2,147,483,647✔
783
    SRequestObj *pRequest = (SRequestObj *)res;
1,102,267,943✔
784
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
1,102,267,943!
785
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0 || pRequest->killed) {
1,102,270,446!
UNCOV
786
      return NULL;
×
787
    }
788

789
    if (pRequest->inCallback) {
1,102,269,455!
UNCOV
790
      tscError("can not call taos_fetch_row before query callback ends.");
×
UNCOV
791
      terrno = TSDB_CODE_TSC_INVALID_OPERATION;
×
UNCOV
792
      return NULL;
×
793
    }
794

795
    return doAsyncFetchRows(pRequest, true, true);
1,102,270,705✔
796
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
1,082,053,661!
797
    SMqRspObj      *msg = ((SMqRspObj *)res);
1,082,043,480✔
798
    SReqResultInfo *pResultInfo = NULL;
1,082,043,480✔
799
    if (msg->resIter == -1) {
1,082,054,094✔
800
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
906,695!
801
        return NULL;
×
802
      }
803
    } else {
804
      pResultInfo = tmqGetCurResInfo(res);
1,081,147,216✔
805
    }
806

807
    if (pResultInfo->current < pResultInfo->numOfRows) {
1,082,053,911✔
808
      doSetOneRowPtr(pResultInfo);
1,071,053,365✔
809
      pResultInfo->current += 1;
1,071,036,628✔
810
      return pResultInfo->row;
1,071,036,628✔
811
    } else {
812
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
11,000,729✔
813
        return NULL;
906,695✔
814
      }
815

816
      doSetOneRowPtr(pResultInfo);
10,091,596✔
817
      pResultInfo->current += 1;
10,091,596✔
818
      return pResultInfo->row;
10,091,596✔
819
    }
820
  } else if (TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
×
821
    return NULL;
×
822
  } else {
823
    tscError("invalid result passed to taos_fetch_row");
×
824
    terrno = TSDB_CODE_TMQ_INVALID_DATA;
×
825
    return NULL;
×
826
  }
827
}
828

829
int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
1,081,105,693✔
830
  return taos_print_row_with_size(str, INT32_MAX, row, fields, num_fields);
1,081,105,693✔
831
}
832
int taos_print_row_with_size(char *str, uint32_t size, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
1,081,103,579✔
833
  int32_t len = 0;
1,081,103,579✔
834
  for (int i = 0; i < num_fields; ++i) {
2,147,483,647✔
835
    if (i > 0 && len < size - 1) {
2,147,483,647!
836
      str[len++] = ' ';
2,147,483,647✔
837
    }
838

839
    if (row[i] == NULL) {
2,147,483,647✔
840
      len += tsnprintf(str + len, size - len, "%s", TSDB_DATA_NULL_STR);
4,146,215✔
841
      continue;
4,146,215✔
842
    }
843

844
    switch (fields[i].type) {
2,147,483,647!
845
      case TSDB_DATA_TYPE_TINYINT:
560,800✔
846
        len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
560,800✔
847
        break;
560,800✔
848

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

853
      case TSDB_DATA_TYPE_SMALLINT:
560,800✔
854
        len += tsnprintf(str + len, size - len, "%d", *((int16_t *)row[i]));
560,800✔
855
        break;
560,800✔
856

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

861
      case TSDB_DATA_TYPE_INT:
1,153,891,902✔
862
        len += tsnprintf(str + len, size - len, "%d", *((int32_t *)row[i]));
1,153,891,902✔
863
        break;
1,153,951,184✔
864

865
      case TSDB_DATA_TYPE_UINT:
560,800✔
866
        len += tsnprintf(str + len, size - len, "%u", *((uint32_t *)row[i]));
560,800✔
867
        break;
560,800✔
868

869
      case TSDB_DATA_TYPE_BIGINT:
1,260,598,095✔
870
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
1,260,598,095✔
871
        break;
1,260,599,925✔
872

873
      case TSDB_DATA_TYPE_UBIGINT:
560,800✔
874
        len += tsnprintf(str + len, size - len, "%" PRIu64, *((uint64_t *)row[i]));
560,800✔
875
        break;
560,800✔
876

877
      case TSDB_DATA_TYPE_FLOAT: {
46,328,661✔
878
        float fv = 0;
46,328,661✔
879
        fv = GET_FLOAT_VAL(row[i]);
46,328,661✔
880
        len += snprintf(str + len, size - len, "%.*g", FLT_DIG, fv);
46,328,661✔
881
      } break;
46,328,661✔
882

883
      case TSDB_DATA_TYPE_DOUBLE: {
582,586,669✔
884
        double dv = 0;
582,586,669✔
885
        dv = GET_DOUBLE_VAL(row[i]);
582,586,669✔
886
        len += snprintf(str + len, size - len, "%.*g", DBL_DIG, dv);
582,586,486✔
887
      } break;
582,585,022✔
888

889
      case TSDB_DATA_TYPE_VARBINARY: {
561,264✔
890
        void    *data = NULL;
561,264✔
891
        uint32_t tmp = 0;
561,264✔
892
        int32_t  charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
561,264✔
893
        if (taosAscii2Hex(row[i], charLen, &data, &tmp) < 0) {
561,264!
894
          break;
×
895
        }
896
        uint32_t copyLen = TMIN(size - len - 1, tmp);
561,264✔
897
        (void)memcpy(str + len, data, copyLen);
561,264!
898
        len += copyLen;
561,264✔
899
        taosMemoryFree(data);
561,264!
900
      } break;
561,264✔
901
      case TSDB_DATA_TYPE_BINARY:
1,329,947,072✔
902
      case TSDB_DATA_TYPE_NCHAR:
903
      case TSDB_DATA_TYPE_GEOMETRY: {
904
        int32_t charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
1,329,947,072✔
905
        if (fields[i].type == TSDB_DATA_TYPE_BINARY || fields[i].type == TSDB_DATA_TYPE_VARBINARY ||
1,329,947,621!
906
            fields[i].type == TSDB_DATA_TYPE_GEOMETRY) {
566,911,738✔
907
          if (charLen > fields[i].bytes || charLen < 0) {
763,602,905✔
908
            tscError("taos_print_row error binary. charLen:%d, fields[i].bytes:%d", charLen, fields[i].bytes);
732!
909
            break;
×
910
          }
911
        } else {
912
          if (charLen > fields[i].bytes * TSDB_NCHAR_SIZE || charLen < 0) {
566,350,572!
913
            tscError("taos_print_row error. charLen:%d, fields[i].bytes:%d", charLen, fields[i].bytes);
3,933!
914
            break;
×
915
          }
916
        }
917

918
        uint32_t copyLen = TMIN(size - len - 1, charLen);
1,329,977,089✔
919
        (void)memcpy(str + len, row[i], copyLen);
1,329,977,089!
920
        len += copyLen;
1,329,954,031✔
921
      } break;
1,329,954,031✔
922
      case TSDB_DATA_TYPE_BLOB:
×
923
      case TSDB_DATA_TYPE_MEDIUMBLOB: {
924
        void    *data = NULL;
×
925
        uint32_t tmp = 0;
×
926
        int32_t  charLen = blobDataLen((char *)row[i] - BLOBSTR_HEADER_SIZE);
×
927
        if (taosAscii2Hex(row[i], charLen, &data, &tmp) < 0) {
×
928
          break;
×
929
        }
930

931
        uint32_t copyLen = TMIN(size - len - 1, tmp);
×
932
        (void)memcpy(str + len, data, copyLen);
×
933
        len += copyLen;
×
934

935
        taosMemoryFree(data);
×
936
      } break;
×
937

938
      case TSDB_DATA_TYPE_TIMESTAMP:
1,436,504,072✔
939
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
1,436,504,072✔
940
        break;
1,436,481,707✔
941

942
      case TSDB_DATA_TYPE_BOOL:
560,800✔
943
        len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
560,800✔
944
        break;
230,485✔
945
      case TSDB_DATA_TYPE_DECIMAL64:
×
946
      case TSDB_DATA_TYPE_DECIMAL: {
947
        uint32_t decimalLen = strlen(row[i]);
×
948
        uint32_t copyLen = TMIN(size - len - 1, decimalLen);
×
949
        (void)memcpy(str + len, row[i], copyLen);
×
950
        len += copyLen;
×
951
      } break;
×
952
      default:
×
953
        break;
×
954
    }
955

956
    if (len >= size - 1) {
2,147,483,647!
957
      break;
×
958
    }
959
  }
960
  if (len < size) {
1,081,131,351✔
961
    str[len] = 0;
1,081,133,545✔
962
  }
963

964
  return len;
1,081,134,462✔
965
}
966

967
int *taos_fetch_lengths(TAOS_RES *res) {
2,147,483,647✔
968
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
2,147,483,647!
UNCOV
969
    return NULL;
×
970
  }
971

972
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
2,147,483,647✔
973
  return pResInfo->length;
2,147,483,647✔
974
}
975

976
TAOS_ROW *taos_result_block(TAOS_RES *res) {
×
977
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
×
978
    terrno = TSDB_CODE_INVALID_PARA;
×
979
    return NULL;
×
980
  }
981

982
  if (taos_is_update_query(res)) {
×
983
    return NULL;
×
984
  }
985

986
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
×
987
  return &pResInfo->row;
×
988
}
989

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

1041
const char *taos_get_client_info() { return td_version; }
1,240,618✔
1042

1043
// return int32_t
1044
int taos_affected_rows(TAOS_RES *res) {
122,407,090✔
1045
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
122,407,090!
1046
      TD_RES_TMQ_BATCH_META(res)) {
122,407,391✔
1047
    return 0;
×
1048
  }
1049

1050
  SRequestObj    *pRequest = (SRequestObj *)res;
122,407,138✔
1051
  SReqResultInfo *pResInfo = &pRequest->body.resInfo;
122,407,138✔
1052
  return (int)pResInfo->numOfRows;
122,407,654✔
1053
}
1054

1055
// return int64_t
1056
int64_t taos_affected_rows64(TAOS_RES *res) {
98,196✔
1057
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
98,196!
1058
      TD_RES_TMQ_BATCH_META(res)) {
98,196!
1059
    return 0;
×
1060
  }
1061

1062
  SRequestObj    *pRequest = (SRequestObj *)res;
98,196✔
1063
  SReqResultInfo *pResInfo = &pRequest->body.resInfo;
98,196✔
1064
  return pResInfo->numOfRows;
98,196✔
1065
}
1066

1067
int taos_result_precision(TAOS_RES *res) {
1,087,402,747✔
1068
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
1,087,402,747!
1069
    return TSDB_TIME_PRECISION_MILLI;
×
1070
  }
1071

1072
  if (TD_RES_QUERY(res)) {
1,087,402,930✔
1073
    SRequestObj *pRequest = (SRequestObj *)res;
28,604,090✔
1074
    return pRequest->body.resInfo.precision;
28,604,090✔
1075
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
1,058,798,840!
1076
    SReqResultInfo *info = tmqGetCurResInfo(res);
1,058,747,783✔
1077
    return info->precision;
1,058,747,783✔
1078
  }
1079
  return TSDB_TIME_PRECISION_MILLI;
×
1080
}
1081

1082
int taos_select_db(TAOS *taos, const char *db) {
18,572✔
1083
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
18,572✔
1084
  if (pObj == NULL) {
18,572!
1085
    releaseTscObj(*(int64_t *)taos);
×
1086
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1087
    return TSDB_CODE_TSC_DISCONNECTED;
×
1088
  }
1089

1090
  if (db == NULL || strlen(db) == 0) {
18,572!
1091
    releaseTscObj(*(int64_t *)taos);
×
1092
    tscError("invalid parameter for %s", db == NULL ? "db is NULL" : "db is empty");
×
1093
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1094
    return terrno;
×
1095
  }
1096

1097
  char sql[256] = {0};
18,572✔
1098
  (void)snprintf(sql, tListLen(sql), "use %s", db);
18,572!
1099

1100
  TAOS_RES *pRequest = taos_query(taos, sql);
18,572✔
1101
  int32_t   code = taos_errno(pRequest);
18,843✔
1102

1103
  taos_free_result(pRequest);
18,843✔
1104
  releaseTscObj(*(int64_t *)taos);
18,843✔
1105
  return code;
18,843✔
1106
}
1107

1108
void taos_stop_query(TAOS_RES *res) {
171,427,204✔
1109
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
171,427,204!
1110
      TD_RES_TMQ_BATCH_META(res)) {
171,428,899✔
1111
    return;
×
1112
  }
1113

1114
  stopAllQueries((SRequestObj *)res);
171,426,547✔
1115
}
1116

1117
bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) {
×
1118
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
×
1119
    return true;
×
1120
  }
1121
  SReqResultInfo *pResultInfo = tscGetCurResInfo(res);
×
1122
  if (col >= pResultInfo->numOfCols || col < 0 || row >= pResultInfo->numOfRows || row < 0) {
×
1123
    return true;
×
1124
  }
1125

1126
  SResultColumn *pCol = &pResultInfo->pCol[col];
×
1127
  if (IS_VAR_DATA_TYPE(pResultInfo->fields[col].type)) {
×
1128
    return (pCol->offset[row] == -1);
×
1129
  } else {
1130
    return colDataIsNull_f(pCol, row);
×
1131
  }
1132
}
1133

UNCOV
1134
bool taos_is_update_query(TAOS_RES *res) { return taos_num_fields(res) == 0; }
×
1135

1136
int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
44,235,132✔
1137
  int32_t numOfRows = 0;
44,235,132✔
1138
  /*int32_t code = */ terrno = taos_fetch_block_s(res, &numOfRows, rows);
44,235,132✔
1139
  return numOfRows;
44,235,132✔
1140
}
1141

1142
int taos_fetch_block_s(TAOS_RES *res, int *numOfRows, TAOS_ROW *rows) {
44,235,132✔
1143
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
44,235,132!
1144
    return 0;
×
1145
  }
1146

1147
  if (TD_RES_QUERY(res)) {
44,235,132✔
1148
    SRequestObj *pRequest = (SRequestObj *)res;
43,143,760✔
1149

1150
    (*rows) = NULL;
43,143,760✔
1151
    (*numOfRows) = 0;
43,143,760✔
1152

1153
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
43,143,760!
1154
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
43,114,086!
1155
      return pRequest->code;
139,831✔
1156
    }
1157

1158
    (void)doAsyncFetchRows(pRequest, false, true);
43,003,929✔
1159

1160
    // TODO refactor
1161
    SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
43,003,397✔
1162
    pResultInfo->current = pResultInfo->numOfRows;
43,003,929✔
1163

1164
    (*rows) = pResultInfo->row;
43,003,929✔
1165
    (*numOfRows) = pResultInfo->numOfRows;
43,003,929✔
1166
    return pRequest->code;
43,003,929✔
1167
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
1,091,372!
1168
    SReqResultInfo *pResultInfo = NULL;
1,091,372✔
1169
    int32_t         code = tmqGetNextResInfo(res, true, &pResultInfo);
1,091,372✔
1170
    if (code != 0) return code;
1,091,372✔
1171

1172
    pResultInfo->current = pResultInfo->numOfRows;
931,882✔
1173
    (*rows) = pResultInfo->row;
931,564✔
1174
    (*numOfRows) = pResultInfo->numOfRows;
931,564✔
1175
    return 0;
931,882✔
1176
  } else {
1177
    tscError("taos_fetch_block_s invalid res type");
×
1178
    return TSDB_CODE_TMQ_INVALID_DATA;
×
1179
  }
1180
}
1181

UNCOV
1182
int taos_fetch_raw_block(TAOS_RES *res, int *numOfRows, void **pData) {
×
UNCOV
1183
  *numOfRows = 0;
×
UNCOV
1184
  *pData = NULL;
×
1185

UNCOV
1186
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
×
1187
    return 0;
×
1188
  }
1189

UNCOV
1190
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
×
UNCOV
1191
    SReqResultInfo *pResultInfo = NULL;
×
UNCOV
1192
    int32_t         code = tmqGetNextResInfo(res, false, &pResultInfo);
×
UNCOV
1193
    if (code != 0) {
×
UNCOV
1194
      (*numOfRows) = 0;
×
UNCOV
1195
      return 0;
×
1196
    }
1197

UNCOV
1198
    pResultInfo->current = pResultInfo->numOfRows;
×
UNCOV
1199
    (*numOfRows) = pResultInfo->numOfRows;
×
UNCOV
1200
    (*pData) = (void *)pResultInfo->pData;
×
UNCOV
1201
    return 0;
×
1202
  }
1203

UNCOV
1204
  SRequestObj *pRequest = (SRequestObj *)res;
×
1205

UNCOV
1206
  if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
×
UNCOV
1207
      pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
×
1208
    return pRequest->code;
×
1209
  }
1210

UNCOV
1211
  (void)doAsyncFetchRows(pRequest, false, false);
×
1212

UNCOV
1213
  SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
×
1214

UNCOV
1215
  pResultInfo->current = pResultInfo->numOfRows;
×
UNCOV
1216
  (*numOfRows) = pResultInfo->numOfRows;
×
UNCOV
1217
  (*pData) = (void *)pResultInfo->pData;
×
1218

UNCOV
1219
  return pRequest->code;
×
1220
}
1221

1222
int *taos_get_column_data_offset(TAOS_RES *res, int columnIndex) {
25,493,025✔
1223
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
25,493,025!
1224
    return 0;
×
1225
  }
1226

1227
  int32_t numOfFields = taos_num_fields(res);
25,493,025✔
1228
  if (columnIndex < 0 || columnIndex >= numOfFields || numOfFields == 0) {
25,493,025!
1229
    return 0;
×
1230
  }
1231

1232
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
25,493,025✔
1233
  TAOS_FIELD     *pField = &pResInfo->userFields[columnIndex];
25,493,025✔
1234
  if (!IS_VAR_DATA_TYPE(pField->type)) {
25,493,025!
1235
    return 0;
×
1236
  }
1237

1238
  return pResInfo->pCol[columnIndex].offset;
25,493,025✔
1239
}
1240

1241
int taos_is_null_by_column(TAOS_RES *res, int columnIndex, bool result[], int *rows) {
73,992,437✔
1242
  if (res == NULL || result == NULL || rows == NULL || *rows <= 0 || columnIndex < 0 || TD_RES_TMQ_META(res) ||
73,992,437!
1243
      TD_RES_TMQ_RAW(res) || TD_RES_TMQ_BATCH_META(res)) {
73,992,437!
1244
    return TSDB_CODE_INVALID_PARA;
×
1245
  }
1246

1247
  int32_t numOfFields = taos_num_fields(res);
73,992,437✔
1248
  if (columnIndex >= numOfFields || numOfFields == 0) {
73,992,437!
1249
    return TSDB_CODE_INVALID_PARA;
×
1250
  }
1251

1252
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
73,992,437✔
1253
  TAOS_FIELD     *pField = &pResInfo->userFields[columnIndex];
73,992,437✔
1254
  SResultColumn  *pCol = &pResInfo->pCol[columnIndex];
73,992,437✔
1255

1256
  if (*rows > pResInfo->numOfRows) {
73,992,437!
1257
    *rows = pResInfo->numOfRows;
×
1258
  }
1259
  if (IS_VAR_DATA_TYPE(pField->type)) {
73,992,437!
1260
    for (int i = 0; i < *rows; i++) {
×
1261
      if (pCol->offset[i] == -1) {
×
1262
        result[i] = true;
×
1263
      } else {
1264
        result[i] = false;
×
1265
      }
1266
    }
1267
  } else {
1268
    for (int i = 0; i < *rows; i++) {
2,147,483,647✔
1269
      if (colDataIsNull_f(pCol, i)) {
2,147,483,647!
1270
        result[i] = true;
2,147,483,647✔
1271
      } else {
1272
        result[i] = false;
2,147,483,647✔
1273
      }
1274
    }
1275
  }
1276
  return 0;
73,992,437✔
1277
}
1278

1279
int taos_validate_sql(TAOS *taos, const char *sql) {
×
1280
  TAOS_RES *pObj = taosQueryImpl(taos, sql, true, TD_REQ_FROM_APP);
×
1281

1282
  int code = taos_errno(pObj);
×
1283

1284
  taos_free_result(pObj);
×
1285
  return code;
×
1286
}
1287

1288
void taos_reset_current_db(TAOS *taos) {
×
1289
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
×
1290
  if (pTscObj == NULL) {
×
1291
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1292
    return;
×
1293
  }
1294

1295
  resetConnectDB(pTscObj);
×
1296

1297
  releaseTscObj(*(int64_t *)taos);
×
1298
}
1299

1300
const char *taos_get_server_info(TAOS *taos) {
8,310✔
1301
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
8,310✔
1302
  if (pTscObj == NULL) {
8,310!
1303
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1304
    return NULL;
×
1305
  }
1306

1307
  releaseTscObj(*(int64_t *)taos);
8,310✔
1308

1309
  return pTscObj->sDetailVer;
8,310✔
1310
}
1311

UNCOV
1312
int taos_get_current_db(TAOS *taos, char *database, int len, int *required) {
×
UNCOV
1313
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
×
UNCOV
1314
  if (pTscObj == NULL) {
×
1315
    return TSDB_CODE_TSC_DISCONNECTED;
×
1316
  }
1317

UNCOV
1318
  int code = TSDB_CODE_SUCCESS;
×
UNCOV
1319
  (void)taosThreadMutexLock(&pTscObj->mutex);
×
UNCOV
1320
  if (database == NULL || len <= 0) {
×
UNCOV
1321
    if (required != NULL) *required = strlen(pTscObj->db) + 1;
×
UNCOV
1322
    TSC_ERR_JRET(TSDB_CODE_INVALID_PARA);
×
UNCOV
1323
  } else if (len < strlen(pTscObj->db) + 1) {
×
UNCOV
1324
    tstrncpy(database, pTscObj->db, len);
×
UNCOV
1325
    if (required) *required = strlen(pTscObj->db) + 1;
×
UNCOV
1326
    TSC_ERR_JRET(TSDB_CODE_INVALID_PARA);
×
1327
  } else {
UNCOV
1328
    tstrncpy(database, pTscObj->db, len);
×
UNCOV
1329
    code = 0;
×
1330
  }
UNCOV
1331
_return:
×
UNCOV
1332
  (void)taosThreadMutexUnlock(&pTscObj->mutex);
×
UNCOV
1333
  releaseTscObj(*(int64_t *)taos);
×
UNCOV
1334
  return code;
×
1335
}
1336

1337
void destorySqlCallbackWrapper(SSqlCallbackWrapper *pWrapper) {
341,983,768✔
1338
  if (NULL == pWrapper) {
341,983,768✔
1339
    return;
172,217,175✔
1340
  }
1341
  destoryCatalogReq(pWrapper->pCatalogReq);
169,766,593✔
1342
  taosMemoryFree(pWrapper->pCatalogReq);
169,760,148!
1343
  qDestroyParseContext(pWrapper->pParseCtx);
169,758,775✔
1344
  taosMemoryFree(pWrapper);
169,755,195!
1345
}
1346

1347
void destroyCtxInRequest(SRequestObj *pRequest) {
793,502✔
1348
  schedulerFreeJob(&pRequest->body.queryJob, 0);
793,502✔
1349
  qDestroyQuery(pRequest->pQuery);
793,502✔
1350
  pRequest->pQuery = NULL;
793,502✔
1351
  destorySqlCallbackWrapper(pRequest->pWrapper);
793,502✔
1352
  pRequest->pWrapper = NULL;
793,502✔
1353
}
793,502✔
1354

1355
static void doAsyncQueryFromAnalyse(SMetaData *pResultMeta, void *param, int32_t code) {
42,086,857✔
1356
  SSqlCallbackWrapper *pWrapper = (SSqlCallbackWrapper *)param;
42,086,857✔
1357
  SRequestObj         *pRequest = pWrapper->pRequest;
42,086,857✔
1358
  SQuery              *pQuery = pRequest->pQuery;
42,086,857✔
1359

1360
  qDebug("req:0x%" PRIx64 ", start to semantic analysis, QID:0x%" PRIx64, pRequest->self, pRequest->requestId);
42,086,542✔
1361

1362
  int64_t analyseStart = taosGetTimestampUs();
42,086,833✔
1363
  pRequest->metric.ctgCostUs = analyseStart - pRequest->metric.ctgStart;
42,086,833✔
1364
  pWrapper->pParseCtx->parseOnly = pRequest->parseOnly;
42,086,833!
1365

1366
  if (TSDB_CODE_SUCCESS == code) {
42,086,518!
1367
    code = qAnalyseSqlSemantic(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
42,086,518✔
1368
  }
1369

1370
  pRequest->metric.analyseCostUs += taosGetTimestampUs() - analyseStart;
42,080,043✔
1371

1372
  if (pRequest->parseOnly) {
42,082,662!
1373
    (void)memcpy(&pRequest->parseMeta, pResultMeta, sizeof(*pResultMeta));
628!
1374
    (void)memset(pResultMeta, 0, sizeof(*pResultMeta));
628!
1375
  }
1376

1377
  handleQueryAnslyseRes(pWrapper, pResultMeta, code);
42,081,697✔
1378
}
42,083,340✔
1379

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

1407
    *ppTarget = pTarget;
×
1408
  }
1409

1410
  return code;
×
1411
}
1412

1413
void handleSubQueryFromAnalyse(SSqlCallbackWrapper *pWrapper, SMetaData *pResultMeta, SNode *pRoot) {
×
1414
  SRequestObj         *pNewRequest = NULL;
×
1415
  SSqlCallbackWrapper *pNewWrapper = NULL;
×
1416
  int32_t              code = buildPreviousRequest(pWrapper->pRequest, pWrapper->pRequest->sqlstr, &pNewRequest);
×
1417
  if (code) {
×
1418
    handleQueryAnslyseRes(pWrapper, pResultMeta, code);
×
1419
    return;
×
1420
  }
1421

1422
  pNewRequest->pQuery = NULL;
×
1423
  code = nodesMakeNode(QUERY_NODE_QUERY, (SNode **)&pNewRequest->pQuery);
×
1424
  if (pNewRequest->pQuery) {
×
1425
    pNewRequest->pQuery->pRoot = pRoot;
×
1426
    pRoot = NULL;
×
1427
    pNewRequest->pQuery->execStage = QUERY_EXEC_STAGE_ANALYSE;
×
1428
  }
1429
  if (TSDB_CODE_SUCCESS == code) {
×
1430
    code = prepareAndParseSqlSyntax(&pNewWrapper, pNewRequest, false);
×
1431
  }
1432
  if (TSDB_CODE_SUCCESS == code) {
×
1433
    code = cloneCatalogReq(&pNewWrapper->pCatalogReq, pWrapper->pCatalogReq);
×
1434
  }
1435
  if (TSDB_CODE_SUCCESS == code) {
×
1436
    doAsyncQueryFromAnalyse(pResultMeta, pNewWrapper, code);
×
1437
    nodesDestroyNode(pRoot);
×
1438
  } else {
1439
    handleQueryAnslyseRes(pWrapper, pResultMeta, code);
×
1440
    return;
×
1441
  }
1442
}
1443

1444
void handleQueryAnslyseRes(SSqlCallbackWrapper *pWrapper, SMetaData *pResultMeta, int32_t code) {
42,081,152✔
1445
  SRequestObj *pRequest = pWrapper->pRequest;
42,081,152✔
1446
  SQuery      *pQuery = pRequest->pQuery;
42,082,886✔
1447

1448
  if (code == TSDB_CODE_SUCCESS && pQuery->pPrevRoot) {
42,079,532!
1449
    SNode *prevRoot = pQuery->pPrevRoot;
×
1450
    pQuery->pPrevRoot = NULL;
×
1451
    handleSubQueryFromAnalyse(pWrapper, pResultMeta, prevRoot);
×
1452
    return;
×
1453
  }
1454

1455
  if (code == TSDB_CODE_SUCCESS) {
42,084,715✔
1456
    pRequest->stableQuery = pQuery->stableQuery;
39,606,796!
1457
    if (pQuery->pRoot) {
39,612,562✔
1458
      pRequest->stmtType = pQuery->pRoot->type;
39,608,334✔
1459
    }
1460

1461
    if (pQuery->haveResultSet) {
39,610,608✔
1462
      code = setResSchemaInfo(&pRequest->body.resInfo, pQuery->pResSchema, pQuery->numOfResCols, pQuery->pResExtSchema,
22,792,570✔
1463
                              pRequest->stmtBindVersion > 0);
22,792,054✔
1464
      setResPrecision(&pRequest->body.resInfo, pQuery->precision);
22,792,565✔
1465
    }
1466
  }
1467

1468
  if (code == TSDB_CODE_SUCCESS) {
42,081,145✔
1469
    TSWAP(pRequest->dbList, (pQuery)->pDbList);
39,609,355✔
1470
    TSWAP(pRequest->tableList, (pQuery)->pTableList);
39,600,081✔
1471
    TSWAP(pRequest->targetTableList, (pQuery)->pTargetTableList);
39,609,425✔
1472

1473
    launchAsyncQuery(pRequest, pQuery, pResultMeta, pWrapper);
39,604,467✔
1474
  } else {
1475
    destorySqlCallbackWrapper(pWrapper);
2,471,790✔
1476
    pRequest->pWrapper = NULL;
2,471,790✔
1477
    qDestroyQuery(pRequest->pQuery);
2,471,790✔
1478
    pRequest->pQuery = NULL;
2,471,790✔
1479

1480
    if (NEED_CLIENT_HANDLE_ERROR(code) && pRequest->stmtBindVersion == 0) {
2,471,790!
1481
      tscDebug("req:0x%" PRIx64 ", client retry to handle the error, code:%d - %s, tryCount:%d, QID:0x%" PRIx64,
789,684✔
1482
               pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId);
1483
      restartAsyncQuery(pRequest, code);
789,684✔
1484
      return;
789,684✔
1485
    }
1486

1487
    // return to app directly
1488
    tscError("req:0x%" PRIx64 ", error occurs, code:%s, return to user app, QID:0x%" PRIx64, pRequest->self, tstrerror(code),
1,682,106!
1489
             pRequest->requestId);
1490
    pRequest->code = code;
1,682,106✔
1491
    returnToUser(pRequest);
1,682,106✔
1492
  }
1493
}
1494

1495
static int32_t getAllMetaAsync(SSqlCallbackWrapper *pWrapper, catalogCallback fp) {
42,983,700✔
1496
  SRequestConnInfo conn = {.pTrans = pWrapper->pParseCtx->pTransporter,
85,686,884✔
1497
                           .requestId = pWrapper->pParseCtx->requestId,
42,983,700✔
1498
                           .requestObjRefId = pWrapper->pParseCtx->requestRid,
42,985,354✔
1499
                           .mgmtEps = pWrapper->pParseCtx->mgmtEpSet};
42,983,323✔
1500

1501
  pWrapper->pRequest->metric.ctgStart = taosGetTimestampUs();
85,687,451✔
1502

1503
  return catalogAsyncGetAllMeta(pWrapper->pParseCtx->pCatalog, &conn, pWrapper->pCatalogReq, fp, pWrapper,
43,262,491✔
1504
                                &pWrapper->pRequest->body.queryJob);
42,980,796✔
1505
}
1506

1507
static void doAsyncQueryFromParse(SMetaData *pResultMeta, void *param, int32_t code);
1508

1509
static int32_t phaseAsyncQuery(SSqlCallbackWrapper *pWrapper) {
169,928,421✔
1510
  int32_t code = TSDB_CODE_SUCCESS;
169,928,421✔
1511
  switch (pWrapper->pRequest->pQuery->execStage) {
169,928,421!
1512
    case QUERY_EXEC_STAGE_PARSE: {
902,950✔
1513
      // continue parse after get metadata
1514
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromParse);
902,950✔
1515
      break;
902,950✔
1516
    }
1517
    case QUERY_EXEC_STAGE_ANALYSE: {
42,082,389✔
1518
      // analysis after get metadata
1519
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromAnalyse);
42,082,389✔
1520
      break;
42,080,215✔
1521
    }
1522
    case QUERY_EXEC_STAGE_SCHEDULE: {
126,951,326✔
1523
      launchAsyncQuery(pWrapper->pRequest, pWrapper->pRequest->pQuery, NULL, pWrapper);
126,951,326✔
1524
      break;
126,952,794✔
1525
    }
1526
    default:
×
1527
      break;
×
1528
  }
1529
  return code;
169,935,959✔
1530
}
1531

1532
static void doAsyncQueryFromParse(SMetaData *pResultMeta, void *param, int32_t code) {
902,950✔
1533
  SSqlCallbackWrapper *pWrapper = (SSqlCallbackWrapper *)param;
902,950✔
1534
  SRequestObj         *pRequest = pWrapper->pRequest;
902,950✔
1535
  SQuery              *pQuery = pRequest->pQuery;
902,950✔
1536

1537
  pRequest->metric.ctgCostUs += taosGetTimestampUs() - pRequest->metric.ctgStart;
902,950✔
1538
  qDebug("req:0x%" PRIx64 ", continue parse query, QID:0x%" PRIx64 ", code:%s", pRequest->self, pRequest->requestId,
902,950✔
1539
         tstrerror(code));
1540

1541
  if (code == TSDB_CODE_SUCCESS) {
902,950✔
1542
    // pWrapper->pCatalogReq->forceUpdate = false;
1543
    code = qContinueParseSql(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
877,852✔
1544
  }
1545

1546
  if (TSDB_CODE_SUCCESS == code) {
902,950✔
1547
    code = phaseAsyncQuery(pWrapper);
715,117✔
1548
  }
1549

1550
  if (TSDB_CODE_SUCCESS != code) {
902,950✔
1551
    tscError("req:0x%" PRIx64 ", error happens, code:%d - %s, QID:0x%" PRIx64, pWrapper->pRequest->self, code,
187,833!
1552
             tstrerror(code), pWrapper->pRequest->requestId);
1553
    destorySqlCallbackWrapper(pWrapper);
187,833✔
1554
    pRequest->pWrapper = NULL;
187,833✔
1555
    terrno = code;
187,833✔
1556
    pRequest->code = code;
187,833✔
1557
    doRequestCallback(pRequest, code);
187,833✔
1558
  }
1559
}
902,950✔
1560

UNCOV
1561
void continueInsertFromCsv(SSqlCallbackWrapper *pWrapper, SRequestObj *pRequest) {
×
UNCOV
1562
  int32_t code = qParseSqlSyntax(pWrapper->pParseCtx, &pRequest->pQuery, pWrapper->pCatalogReq);
×
UNCOV
1563
  if (TSDB_CODE_SUCCESS == code) {
×
UNCOV
1564
    code = phaseAsyncQuery(pWrapper);
×
1565
  }
1566

UNCOV
1567
  if (TSDB_CODE_SUCCESS != code) {
×
1568
    tscError("req:0x%" PRIx64 ", error happens, code:%d - %s, QID:0x%" PRIx64, pWrapper->pRequest->self, code,
×
1569
             tstrerror(code), pWrapper->pRequest->requestId);
1570
    destorySqlCallbackWrapper(pWrapper);
×
1571
    pRequest->pWrapper = NULL;
×
1572
    terrno = code;
×
1573
    pRequest->code = code;
×
1574
    doRequestCallback(pRequest, code);
×
1575
  }
UNCOV
1576
}
×
1577

1578
void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param) {
17,835✔
1579
  int64_t connId = *(int64_t *)taos;
17,835✔
1580
  taosAsyncQueryImpl(connId, sql, fp, param, false, TD_REQ_FROM_APP);
17,835✔
1581
}
17,835✔
1582

1583
void taos_query_a_with_reqid(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param, int64_t reqid) {
×
1584
  int64_t connId = *(int64_t *)taos;
×
1585
  taosAsyncQueryImplWithReqid(connId, sql, fp, param, false, reqid);
×
1586
}
×
1587

1588
int32_t createParseContext(const SRequestObj *pRequest, SParseContext **pCxt, SSqlCallbackWrapper *pWrapper) {
169,765,433✔
1589
  const STscObj *pTscObj = pRequest->pTscObj;
169,765,433✔
1590

1591
  *pCxt = taosMemoryCalloc(1, sizeof(SParseContext));
169,771,036!
1592
  if (*pCxt == NULL) {
169,762,227!
1593
    return terrno;
×
1594
  }
1595

1596
  **pCxt = (SParseContext){.requestId = pRequest->requestId,
338,967,028✔
1597
                           .requestRid = pRequest->self,
169,767,117✔
1598
                           .acctId = pTscObj->acctId,
169,767,107✔
1599
                           .db = pRequest->pDb,
169,767,998✔
1600
                           .topicQuery = false,
1601
                           .pSql = pRequest->sqlstr,
169,771,506✔
1602
                           .sqlLen = pRequest->sqlLen,
169,771,821✔
1603
                           .pMsg = pRequest->msgBuf,
169,772,712✔
1604
                           .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE,
1605
                           .pTransporter = pTscObj->pAppInfo->pTransporter,
169,769,427✔
1606
                           .pStmtCb = NULL,
1607
                           .pUser = pTscObj->user,
169,771,165✔
1608
                           .pEffectiveUser = pRequest->effectiveUser,
169,771,757✔
1609
                           .isSuperUser = (0 == strcmp(pTscObj->user, TSDB_DEFAULT_USER)),
169,770,794!
1610
                           .enableSysInfo = pTscObj->sysInfo,
169,770,356✔
1611
                           .async = true,
1612
                           .svrVer = pTscObj->sVer,
169,768,059✔
1613
                           .nodeOffline = (pTscObj->pAppInfo->onlineDnodes < pTscObj->pAppInfo->totalDnodes),
169,769,561✔
1614
                           .allocatorId = pRequest->allocatorRefId,
169,769,552✔
1615
                           .parseSqlFp = clientParseSql,
1616
                           .parseSqlParam = pWrapper,
1617
                           .setQueryFp = setQueryRequest,
1618
                           .timezone = pTscObj->optionInfo.timezone,
169,767,515✔
1619
                           .charsetCxt = pTscObj->optionInfo.charsetCxt};
169,766,591✔
1620
  int8_t biMode = atomic_load_8(&((STscObj *)pTscObj)->biMode);
169,766,118✔
1621
  (*pCxt)->biMode = biMode;
169,763,421✔
1622
  return TSDB_CODE_SUCCESS;
169,768,778✔
1623
}
1624

1625
int32_t prepareAndParseSqlSyntax(SSqlCallbackWrapper **ppWrapper, SRequestObj *pRequest, bool updateMetaForce) {
169,766,939✔
1626
  int32_t              code = TSDB_CODE_SUCCESS;
169,766,939✔
1627
  STscObj             *pTscObj = pRequest->pTscObj;
169,766,939✔
1628
  SSqlCallbackWrapper *pWrapper = taosMemoryCalloc(1, sizeof(SSqlCallbackWrapper));
169,769,354!
1629
  if (pWrapper == NULL) {
169,765,694!
1630
    code = terrno;
×
1631
  } else {
1632
    pWrapper->pRequest = pRequest;
169,765,694✔
1633
    pRequest->pWrapper = pWrapper;
169,767,892✔
1634
    *ppWrapper = pWrapper;
169,767,651✔
1635
  }
1636

1637
  if (TSDB_CODE_SUCCESS == code) {
169,767,718✔
1638
    code = createParseContext(pRequest, &pWrapper->pParseCtx, pWrapper);
169,766,872✔
1639
  }
1640

1641
  if (TSDB_CODE_SUCCESS == code) {
169,764,553!
1642
    pWrapper->pParseCtx->mgmtEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
169,764,553✔
1643
    code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pWrapper->pParseCtx->pCatalog);
169,772,345✔
1644
  }
1645

1646
  if (TSDB_CODE_SUCCESS == code && NULL == pRequest->pQuery) {
169,766,834!
1647
    int64_t syntaxStart = taosGetTimestampUs();
169,770,829✔
1648

1649
    pWrapper->pCatalogReq = taosMemoryCalloc(1, sizeof(SCatalogReq));
169,770,829!
1650
    if (pWrapper->pCatalogReq == NULL) {
169,761,346!
1651
      code = terrno;
×
1652
    } else {
1653
      pWrapper->pCatalogReq->forceUpdate = updateMetaForce;
169,763,307✔
1654
      TSC_ERR_RET(qnodeRequired(pRequest, &pWrapper->pCatalogReq->qNodeRequired));
169,766,348!
1655
      code = qParseSqlSyntax(pWrapper->pParseCtx, &pRequest->pQuery, pWrapper->pCatalogReq);
169,769,028✔
1656
    }
1657

1658
    pRequest->metric.parseCostUs += taosGetTimestampUs() - syntaxStart;
169,765,171✔
1659
  }
1660

1661
  return code;
169,770,807✔
1662
}
1663

1664
void doAsyncQuery(SRequestObj *pRequest, bool updateMetaForce) {
170,030,919✔
1665
  SSqlCallbackWrapper *pWrapper = NULL;
170,030,919✔
1666
  int32_t              code = TSDB_CODE_SUCCESS;
170,033,877✔
1667

1668
  if (pRequest->retry++ > REQUEST_TOTAL_EXEC_TIMES) {
170,033,877✔
1669
    code = pRequest->prevCode;
263,759✔
1670
    terrno = code;
263,759✔
1671
    pRequest->code = code;
263,759✔
1672
    tscDebug("req:0x%" PRIx64 ", call sync query cb with code:%s", pRequest->self, tstrerror(code));
263,759✔
1673
    doRequestCallback(pRequest, code);
263,759✔
1674
    return;
263,759✔
1675
  }
1676

1677
  if (TSDB_CODE_SUCCESS == code) {
169,765,588✔
1678
    code = prepareAndParseSqlSyntax(&pWrapper, pRequest, updateMetaForce);
169,765,411✔
1679
  }
1680

1681
  if (TSDB_CODE_SUCCESS == code) {
169,757,679✔
1682
    pRequest->stmtType = pRequest->pQuery->pRoot->type;
169,215,885✔
1683
    code = phaseAsyncQuery(pWrapper);
169,224,405✔
1684
  }
1685

1686
  if (TSDB_CODE_SUCCESS != code) {
169,763,649✔
1687
    if (NULL != pRequest->msgBuf && strlen(pRequest->msgBuf) > 0) {
543,928!
1688
      tscError("req:0x%" PRIx64 ", error happens, code:%d - %s, QID:0x%" PRIx64, pRequest->self, code, pRequest->msgBuf,
538,204!
1689
               pRequest->requestId);
1690
    } else {
1691
      tscError("req:0x%" PRIx64 ", error happens, code:%d - %s, QID:0x%" PRIx64, pRequest->self, code, tstrerror(code),
5,724!
1692
               pRequest->requestId);
1693
    }
1694

1695
    destorySqlCallbackWrapper(pWrapper);
543,928✔
1696
    pRequest->pWrapper = NULL;
543,928✔
1697
    qDestroyQuery(pRequest->pQuery);
543,928✔
1698
    pRequest->pQuery = NULL;
543,928✔
1699

1700
    if (NEED_CLIENT_HANDLE_ERROR(code) && pRequest->stmtBindVersion == 0) {
543,928!
UNCOV
1701
      tscDebug("req:0x%" PRIx64 ", client retry to handle the error, code:%d - %s, tryCount:%d, QID:0x%" PRIx64,
×
1702
               pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId);
UNCOV
1703
      code = refreshMeta(pRequest->pTscObj, pRequest);
×
UNCOV
1704
      if (code != 0) {
×
UNCOV
1705
        tscWarn("req:0x%" PRIx64 ", refresh meta failed, code:%d - %s, QID:0x%" PRIx64, pRequest->self, code, tstrerror(code),
×
1706
                pRequest->requestId);
1707
      }
UNCOV
1708
      pRequest->prevCode = code;
×
UNCOV
1709
      doAsyncQuery(pRequest, true);
×
UNCOV
1710
      return;
×
1711
    }
1712

1713
    terrno = code;
543,928✔
1714
    pRequest->code = code;
543,928✔
1715
    doRequestCallback(pRequest, code);
543,928✔
1716
  }
1717
}
1718

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

1751
typedef struct SAsyncFetchParam {
1752
  SRequestObj      *pReq;
1753
  __taos_async_fn_t fp;
1754
  void             *param;
1755
} SAsyncFetchParam;
1756

1757
static int32_t doAsyncFetch(void *pParam) {
33,432,288✔
1758
  SAsyncFetchParam *param = pParam;
33,432,288✔
1759
  taosAsyncFetchImpl(param->pReq, param->fp, param->param);
33,432,288✔
1760
  taosMemoryFree(param);
33,432,288!
1761
  return TSDB_CODE_SUCCESS;
33,432,288✔
1762
}
1763

1764
void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
33,432,288✔
1765
  if (res == NULL || fp == NULL) {
33,432,288!
1766
    tscError("taos_fetch_rows_a invalid paras");
×
1767
    return;
×
1768
  }
1769
  if (!TD_RES_QUERY(res)) {
33,432,288!
1770
    tscError("taos_fetch_rows_a res is NULL");
×
1771
    fp(param, res, TSDB_CODE_APP_ERROR);
×
1772
    return;
×
1773
  }
1774

1775
  SRequestObj *pRequest = res;
33,432,288✔
1776
  if (TSDB_SQL_RETRIEVE_EMPTY_RESULT == pRequest->type) {
33,432,288!
UNCOV
1777
    fp(param, res, 0);
×
UNCOV
1778
    return;
×
1779
  }
1780

1781
  SAsyncFetchParam *pParam = taosMemoryCalloc(1, sizeof(SAsyncFetchParam));
33,432,288!
1782
  if (!pParam) {
33,432,288!
1783
    fp(param, res, terrno);
×
1784
    return;
×
1785
  }
1786
  pParam->pReq = pRequest;
33,432,288✔
1787
  pParam->fp = fp;
33,432,288✔
1788
  pParam->param = param;
33,432,288✔
1789
  int32_t code = taosAsyncExec(doAsyncFetch, pParam, NULL);
33,432,288✔
1790
  if (TSDB_CODE_SUCCESS != code) {
33,432,288!
1791
    taosMemoryFree(pParam);
×
1792
    fp(param, res, code);
×
1793
    return;
×
1794
  }
1795
}
1796

UNCOV
1797
void taos_fetch_raw_block_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
×
UNCOV
1798
  if (res == NULL || fp == NULL) {
×
1799
    tscError("taos_fetch_raw_block_a invalid paras");
×
1800
    return;
×
1801
  }
UNCOV
1802
  if (!TD_RES_QUERY(res)) {
×
1803
    tscError("taos_fetch_raw_block_a res is NULL");
×
1804
    return;
×
1805
  }
UNCOV
1806
  SRequestObj    *pRequest = res;
×
UNCOV
1807
  SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
×
1808

1809
  // set the current block is all consumed
UNCOV
1810
  pResultInfo->convertUcs4 = false;
×
1811

1812
  // it is a local executed query, no need to do async fetch
UNCOV
1813
  taos_fetch_rows_a(pRequest, fp, param);
×
1814
}
1815

UNCOV
1816
const void *taos_get_raw_block(TAOS_RES *res) {
×
UNCOV
1817
  if (res == NULL) {
×
1818
    tscError("taos_get_raw_block invalid paras");
×
1819
    return NULL;
×
1820
  }
UNCOV
1821
  if (!TD_RES_QUERY(res)) {
×
1822
    tscError("taos_get_raw_block res is NULL");
×
1823
    return NULL;
×
1824
  }
UNCOV
1825
  SRequestObj *pRequest = res;
×
1826

UNCOV
1827
  return pRequest->body.resInfo.pData;
×
1828
}
1829

1830
int taos_get_db_route_info(TAOS *taos, const char *db, TAOS_DB_ROUTE_INFO *dbInfo) {
×
1831
  if (NULL == taos) {
×
1832
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1833
    return terrno;
×
1834
  }
1835

1836
  if (NULL == db || NULL == dbInfo) {
×
1837
    tscError("invalid input param, db:%p, dbInfo:%p", db, dbInfo);
×
1838
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1839
    return terrno;
×
1840
  }
1841

1842
  int64_t      connId = *(int64_t *)taos;
×
1843
  SRequestObj *pRequest = NULL;
×
1844
  char        *sql = "taos_get_db_route_info";
×
1845
  int32_t      code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
×
1846
  if (code != TSDB_CODE_SUCCESS) {
×
1847
    terrno = code;
×
1848
    return terrno;
×
1849
  }
1850

1851
  STscObj  *pTscObj = pRequest->pTscObj;
×
1852
  SCatalog *pCtg = NULL;
×
1853
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
×
1854
  if (code != TSDB_CODE_SUCCESS) {
×
1855
    goto _return;
×
1856
  }
1857

1858
  SRequestConnInfo conn = {
×
1859
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
×
1860

1861
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
×
1862

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

1866
  code = catalogGetDBVgInfo(pCtg, &conn, dbFName, dbInfo);
×
1867
  if (code) {
×
1868
    goto _return;
×
1869
  }
1870

1871
_return:
×
1872

1873
  terrno = code;
×
1874

1875
  destroyRequest(pRequest);
×
1876
  return code;
×
1877
}
1878

1879
int taos_get_table_vgId(TAOS *taos, const char *db, const char *table, int *vgId) {
×
1880
  if (NULL == taos) {
×
1881
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1882
    return terrno;
×
1883
  }
1884

1885
  if (NULL == db || NULL == table || NULL == vgId) {
×
1886
    tscError("invalid input param, db:%p, table:%p, vgId:%p", db, table, vgId);
×
1887
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1888
    return terrno;
×
1889
  }
1890

1891
  int64_t      connId = *(int64_t *)taos;
×
1892
  SRequestObj *pRequest = NULL;
×
1893
  char        *sql = "taos_get_table_vgId";
×
1894
  int32_t      code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
×
1895
  if (code != TSDB_CODE_SUCCESS) {
×
1896
    return terrno;
×
1897
  }
1898

1899
  pRequest->syncQuery = true;
×
1900

1901
  STscObj  *pTscObj = pRequest->pTscObj;
×
1902
  SCatalog *pCtg = NULL;
×
1903
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
×
1904
  if (code != TSDB_CODE_SUCCESS) {
×
1905
    goto _return;
×
1906
  }
1907

1908
  SRequestConnInfo conn = {
×
1909
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
×
1910

1911
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
×
1912

1913
  SName tableName = {0};
×
1914
  toName(pTscObj->acctId, db, table, &tableName);
×
1915

1916
  SVgroupInfo vgInfo;
×
1917
  code = catalogGetTableHashVgroup(pCtg, &conn, &tableName, &vgInfo);
×
1918
  if (code) {
×
1919
    goto _return;
×
1920
  }
1921

1922
  *vgId = vgInfo.vgId;
×
1923

1924
_return:
×
1925

1926
  terrno = code;
×
1927

1928
  destroyRequest(pRequest);
×
1929
  return code;
×
1930
}
1931

1932
int taos_get_tables_vgId(TAOS *taos, const char *db, const char *table[], int tableNum, int *vgId) {
×
1933
  if (NULL == taos) {
×
1934
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1935
    return terrno;
×
1936
  }
1937

1938
  if (NULL == db || NULL == table || NULL == vgId || tableNum <= 0) {
×
1939
    tscError("invalid input param, db:%p, table:%p, vgId:%p, tbNum:%d", db, table, vgId, tableNum);
×
1940
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1941
    return terrno;
×
1942
  }
1943

1944
  int64_t      connId = *(int64_t *)taos;
×
1945
  SRequestObj *pRequest = NULL;
×
1946
  char        *sql = "taos_get_table_vgId";
×
1947
  int32_t      code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
×
1948
  if (code != TSDB_CODE_SUCCESS) {
×
1949
    return terrno;
×
1950
  }
1951

1952
  pRequest->syncQuery = true;
×
1953

1954
  STscObj  *pTscObj = pRequest->pTscObj;
×
1955
  SCatalog *pCtg = NULL;
×
1956
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
×
1957
  if (code != TSDB_CODE_SUCCESS) {
×
1958
    goto _return;
×
1959
  }
1960

1961
  SRequestConnInfo conn = {
×
1962
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
×
1963

1964
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
×
1965

1966
  code = catalogGetTablesHashVgId(pCtg, &conn, pTscObj->acctId, db, table, tableNum, vgId);
×
1967
  if (code) {
×
1968
    goto _return;
×
1969
  }
1970

1971
_return:
×
1972

1973
  terrno = code;
×
1974

1975
  destroyRequest(pRequest);
×
1976
  return code;
×
1977
}
1978

UNCOV
1979
int taos_load_table_info(TAOS *taos, const char *tableNameList) {
×
UNCOV
1980
  if (NULL == taos) {
×
1981
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1982
    return terrno;
×
1983
  }
1984

UNCOV
1985
  int64_t       connId = *(int64_t *)taos;
×
UNCOV
1986
  const int32_t MAX_TABLE_NAME_LENGTH = 12 * 1024 * 1024;  // 12MB list
×
UNCOV
1987
  int32_t       code = 0;
×
UNCOV
1988
  SRequestObj  *pRequest = NULL;
×
UNCOV
1989
  SCatalogReq   catalogReq = {0};
×
1990

UNCOV
1991
  if (NULL == tableNameList) {
×
1992
    return TSDB_CODE_SUCCESS;
×
1993
  }
1994

UNCOV
1995
  int32_t length = (int32_t)strlen(tableNameList);
×
UNCOV
1996
  if (0 == length) {
×
1997
    return TSDB_CODE_SUCCESS;
×
UNCOV
1998
  } else if (length > MAX_TABLE_NAME_LENGTH) {
×
1999
    tscError("tableNameList too long, length:%d, maximum allowed:%d", length, MAX_TABLE_NAME_LENGTH);
×
2000
    return TSDB_CODE_TSC_INVALID_OPERATION;
×
2001
  }
2002

UNCOV
2003
  char *sql = "taos_load_table_info";
×
UNCOV
2004
  code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
×
UNCOV
2005
  if (code != TSDB_CODE_SUCCESS) {
×
2006
    terrno = code;
×
2007
    goto _return;
×
2008
  }
2009

UNCOV
2010
  pRequest->syncQuery = true;
×
2011

UNCOV
2012
  STscObj *pTscObj = pRequest->pTscObj;
×
UNCOV
2013
  code = transferTableNameList(tableNameList, pTscObj->acctId, pTscObj->db, &catalogReq.pTableMeta);
×
UNCOV
2014
  if (code) {
×
2015
    goto _return;
×
2016
  }
2017

UNCOV
2018
  SCatalog *pCtg = NULL;
×
UNCOV
2019
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
×
UNCOV
2020
  if (code != TSDB_CODE_SUCCESS) {
×
2021
    goto _return;
×
2022
  }
2023

UNCOV
2024
  SRequestConnInfo conn = {
×
UNCOV
2025
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
×
2026

UNCOV
2027
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
×
2028

UNCOV
2029
  code = catalogAsyncGetAllMeta(pCtg, &conn, &catalogReq, syncCatalogFn, pRequest->body.interParam, NULL);
×
UNCOV
2030
  if (code) {
×
2031
    goto _return;
×
2032
  }
2033

UNCOV
2034
  SSyncQueryParam *pParam = pRequest->body.interParam;
×
UNCOV
2035
  code = tsem_wait(&pParam->sem);
×
UNCOV
2036
  if (code) {
×
2037
    tscError("tsem wait failed, code:%d - %s", code, tstrerror(code));
×
2038
    goto _return;
×
2039
  }
UNCOV
2040
_return:
×
UNCOV
2041
  destoryCatalogReq(&catalogReq);
×
UNCOV
2042
  destroyRequest(pRequest);
×
UNCOV
2043
  return code;
×
2044
}
2045

2046
TAOS_STMT *taos_stmt_init(TAOS *taos) {
59,167✔
2047
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
59,167✔
2048
  if (NULL == pObj) {
59,919!
2049
    tscError("invalid parameter for %s", __FUNCTION__);
×
2050
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
2051
    return NULL;
×
2052
  }
2053

2054
  TAOS_STMT *pStmt = stmtInit(pObj, 0, NULL);
59,919✔
2055
  if (NULL == pStmt) {
59,919!
2056
    tscError("stmt init failed, errcode:%s", terrstr());
×
2057
  }
2058
  releaseTscObj(*(int64_t *)taos);
59,919✔
2059

2060
  return pStmt;
59,919✔
2061
}
2062

2063
TAOS_STMT *taos_stmt_init_with_reqid(TAOS *taos, int64_t reqid) {
×
2064
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
×
2065
  if (NULL == pObj) {
×
2066
    tscError("invalid parameter for %s", __FUNCTION__);
×
2067
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
2068
    return NULL;
×
2069
  }
2070

2071
  TAOS_STMT *pStmt = stmtInit(pObj, reqid, NULL);
×
2072
  if (NULL == pStmt) {
×
2073
    tscError("stmt init failed, errcode:%s", terrstr());
×
2074
  }
2075
  releaseTscObj(*(int64_t *)taos);
×
2076

2077
  return pStmt;
×
2078
}
2079

2080
TAOS_STMT *taos_stmt_init_with_options(TAOS *taos, TAOS_STMT_OPTIONS *options) {
3,693✔
2081
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
3,693✔
2082
  if (NULL == pObj) {
3,693!
2083
    tscError("invalid parameter for %s", __FUNCTION__);
×
2084
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
2085
    return NULL;
×
2086
  }
2087

2088
  TAOS_STMT *pStmt = stmtInit(pObj, options->reqId, options);
3,693✔
2089
  if (NULL == pStmt) {
3,422!
2090
    tscError("stmt init failed, errcode:%s", terrstr());
×
2091
  }
2092
  releaseTscObj(*(int64_t *)taos);
3,422✔
2093

2094
  return pStmt;
3,693✔
2095
}
2096

2097
int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length) {
63,612✔
2098
  if (stmt == NULL || sql == NULL) {
63,612!
2099
    tscError("NULL parameter for %s", __FUNCTION__);
248!
2100
    terrno = TSDB_CODE_INVALID_PARA;
248✔
2101
    return terrno;
×
2102
  }
2103

2104
  return stmtPrepare(stmt, sql, length);
63,364✔
2105
}
2106

2107
int taos_stmt_set_tbname_tags(TAOS_STMT *stmt, const char *name, TAOS_MULTI_BIND *tags) {
408✔
2108
  if (stmt == NULL || name == NULL) {
408!
2109
    tscError("NULL parameter for %s", __FUNCTION__);
×
2110
    terrno = TSDB_CODE_INVALID_PARA;
×
2111
    return terrno;
×
2112
  }
2113

2114
  int32_t code = stmtSetTbName(stmt, name);
408✔
2115
  if (code) {
408!
UNCOV
2116
    return code;
×
2117
  }
2118

2119
  if (tags) {
408!
2120
    return stmtSetTbTags(stmt, tags);
408✔
2121
  }
2122

2123
  return TSDB_CODE_SUCCESS;
×
2124
}
2125

2126
int taos_stmt_set_tbname(TAOS_STMT *stmt, const char *name) {
90,244✔
2127
  if (stmt == NULL || name == NULL) {
90,244!
2128
    tscError("NULL parameter for %s", __FUNCTION__);
×
2129
    terrno = TSDB_CODE_INVALID_PARA;
×
2130
    return terrno;
×
2131
  }
2132

2133
  return stmtSetTbName(stmt, name);
90,268✔
2134
}
2135

UNCOV
2136
int taos_stmt_set_tags(TAOS_STMT *stmt, TAOS_MULTI_BIND *tags) {
×
UNCOV
2137
  if (stmt == NULL || tags == NULL) {
×
2138
    tscError("NULL parameter for %s", __FUNCTION__);
×
2139
    terrno = TSDB_CODE_INVALID_PARA;
×
2140
    return terrno;
×
2141
  }
2142

UNCOV
2143
  return stmtSetTbTags(stmt, tags);
×
2144
}
2145

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

UNCOV
2148
int taos_stmt_get_tag_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields) {
×
UNCOV
2149
  if (stmt == NULL || NULL == fieldNum) {
×
2150
    tscError("NULL parameter for %s", __FUNCTION__);
×
2151
    terrno = TSDB_CODE_INVALID_PARA;
×
2152
    return terrno;
×
2153
  }
2154

UNCOV
2155
  return stmtGetTagFields(stmt, fieldNum, fields);
×
2156
}
2157

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

UNCOV
2165
  return stmtGetColFields(stmt, fieldNum, fields);
×
2166
}
2167

2168
// let stmt to reclaim TAOS_FIELD_E that was allocated by `taos_stmt_get_tag_fields`/`taos_stmt_get_col_fields`
2169
void taos_stmt_reclaim_fields(TAOS_STMT *stmt, TAOS_FIELD_E *fields) {
×
2170
  (void)stmt;
2171
  if (!fields) return;
×
2172
  taosMemoryFree(fields);
×
2173
}
2174

2175
int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
3,348✔
2176
  if (stmt == NULL || bind == NULL) {
3,348!
2177
    tscError("NULL parameter for %s", __FUNCTION__);
×
2178
    terrno = TSDB_CODE_INVALID_PARA;
×
2179
    return terrno;
×
2180
  }
2181

2182
  if (bind->num > 1) {
3,348!
UNCOV
2183
    tscError("invalid bind number %d for %s", bind->num, __FUNCTION__);
×
UNCOV
2184
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
UNCOV
2185
    return terrno;
×
2186
  }
2187

2188
  return stmtBindBatch(stmt, bind, -1);
3,348✔
2189
}
2190

2191
int taos_stmt_bind_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
17,325,106✔
2192
  if (stmt == NULL || bind == NULL) {
17,325,106!
2193
    tscError("NULL parameter for %s", __FUNCTION__);
×
2194
    terrno = TSDB_CODE_INVALID_PARA;
×
2195
    return terrno;
×
2196
  }
2197

2198
  if (bind->num <= 0 || bind->num > INT16_MAX) {
17,369,637!
UNCOV
2199
    tscError("invalid bind num %d", bind->num);
×
UNCOV
2200
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
2201
    return terrno;
×
2202
  }
2203

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

2216
  return stmtBindBatch(stmt, bind, -1);
17,140,320✔
2217
}
2218

UNCOV
2219
int taos_stmt_bind_single_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int colIdx) {
×
UNCOV
2220
  if (stmt == NULL || bind == NULL) {
×
2221
    tscError("NULL parameter for %s", __FUNCTION__);
×
2222
    terrno = TSDB_CODE_INVALID_PARA;
×
2223
    return terrno;
×
2224
  }
2225

UNCOV
2226
  if (colIdx < 0) {
×
2227
    tscError("invalid bind column idx %d", colIdx);
×
2228
    terrno = TSDB_CODE_INVALID_PARA;
×
2229
    return terrno;
×
2230
  }
2231

UNCOV
2232
  int32_t insert = 0;
×
UNCOV
2233
  int32_t code = stmtIsInsert(stmt, &insert);
×
UNCOV
2234
  if (TSDB_CODE_SUCCESS != code) {
×
2235
    tscError("stmt insert failed, errcode:%s", tstrerror(code));
×
2236
    return code;
×
2237
  }
UNCOV
2238
  if (0 == insert && bind->num > 1) {
×
2239
    tscError("only one row data allowed for query");
×
2240
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
2241
    return terrno;
×
2242
  }
2243

UNCOV
2244
  return stmtBindBatch(stmt, bind, colIdx);
×
2245
}
2246

2247
int taos_stmt_add_batch(TAOS_STMT *stmt) {
17,178,182✔
2248
  if (stmt == NULL) {
17,178,182!
2249
    tscError("NULL parameter for %s", __FUNCTION__);
×
2250
    terrno = TSDB_CODE_INVALID_PARA;
×
2251
    return terrno;
×
2252
  }
2253

2254
  return stmtAddBatch(stmt);
17,178,182✔
2255
}
2256

2257
int taos_stmt_execute(TAOS_STMT *stmt) {
147,411✔
2258
  if (stmt == NULL) {
147,411!
2259
    tscError("NULL parameter for %s", __FUNCTION__);
×
2260
    terrno = TSDB_CODE_INVALID_PARA;
×
2261
    return terrno;
×
2262
  }
2263

2264
  return stmtExec(stmt);
147,411✔
2265
}
2266

2267
int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert) {
×
2268
  if (stmt == NULL || insert == NULL) {
×
2269
    tscError("NULL parameter for %s", __FUNCTION__);
×
2270
    terrno = TSDB_CODE_INVALID_PARA;
×
2271
    return terrno;
×
2272
  }
2273

2274
  return stmtIsInsert(stmt, insert);
×
2275
}
2276

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

2284
  return stmtGetParamNum(stmt, nums);
×
2285
}
2286

UNCOV
2287
int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) {
×
UNCOV
2288
  if (stmt == NULL || type == NULL || NULL == bytes || idx < 0) {
×
2289
    tscError("invalid parameter for %s", __FUNCTION__);
×
2290
    terrno = TSDB_CODE_INVALID_PARA;
×
2291
    return terrno;
×
2292
  }
2293

UNCOV
2294
  return stmtGetParam(stmt, idx, type, bytes);
×
2295
}
2296

2297
TAOS_RES *taos_stmt_use_result(TAOS_STMT *stmt) {
464✔
2298
  if (stmt == NULL) {
464!
2299
    tscError("NULL parameter for %s", __FUNCTION__);
×
2300
    terrno = TSDB_CODE_INVALID_PARA;
×
2301
    return NULL;
×
2302
  }
2303

2304
  return stmtUseResult(stmt);
464✔
2305
}
2306

2307
char *taos_stmt_errstr(TAOS_STMT *stmt) { return (char *)stmtErrstr(stmt); }
356✔
2308

UNCOV
2309
int taos_stmt_affected_rows(TAOS_STMT *stmt) {
×
UNCOV
2310
  if (stmt == NULL) {
×
2311
    tscError("NULL parameter for %s", __FUNCTION__);
×
2312
    terrno = TSDB_CODE_INVALID_PARA;
×
2313
    return 0;
×
2314
  }
2315

UNCOV
2316
  return stmtAffectedRows(stmt);
×
2317
}
2318

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

UNCOV
2326
  return stmtAffectedRowsOnce(stmt);
×
2327
}
2328

2329
int taos_stmt_close(TAOS_STMT *stmt) {
62,859✔
2330
  if (stmt == NULL) {
62,859!
2331
    tscError("NULL parameter for %s", __FUNCTION__);
×
2332
    terrno = TSDB_CODE_INVALID_PARA;
×
2333
    return terrno;
×
2334
  }
2335

2336
  return stmtClose(stmt);
62,859✔
2337
}
2338

2339
TAOS_STMT2 *taos_stmt2_init(TAOS *taos, TAOS_STMT2_OPTION *option) {
4,427✔
2340
  if (NULL == taos) {
4,427!
UNCOV
2341
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2342
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2343
    return NULL;
×
2344
  }
2345
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
4,427✔
2346
  if (NULL == pObj) {
4,427!
2347
    tscError("invalid parameter for %s", __FUNCTION__);
×
2348
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
2349
    return NULL;
×
2350
  }
2351

2352
  TAOS_STMT2 *pStmt = stmtInit2(pObj, option);
4,427✔
2353

2354
  releaseTscObj(*(int64_t *)taos);
4,427✔
2355

2356
  return pStmt;
4,427✔
2357
}
2358

2359
int taos_stmt2_prepare(TAOS_STMT2 *stmt, const char *sql, unsigned long length) {
4,427✔
2360
  if (stmt == NULL || sql == NULL) {
4,427!
UNCOV
2361
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2362
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2363
    return terrno;
×
2364
  }
2365

2366
  return stmtPrepare2(stmt, sql, length);
4,427✔
2367
}
2368

2369
int taos_stmt2_bind_param(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx) {
79,667✔
2370
  if (stmt == NULL) {
79,667!
2371
    tscError("NULL parameter for %s", __FUNCTION__);
×
2372
    terrno = TSDB_CODE_INVALID_PARA;
×
2373
    return terrno;
×
2374
  }
2375

2376
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
79,667✔
2377
  STMT2_DLOG_E("start to bind param");
79,667!
2378
  if (atomic_load_8((int8_t *)&pStmt->asyncBindParam.asyncBindNum) > 1) {
79,667!
2379
    STMT2_ELOG_E("async bind param is still working, please try again later");
×
2380
    terrno = TSDB_CODE_TSC_STMT_API_ERROR;
×
2381
    return terrno;
×
2382
  }
2383

2384
  if (pStmt->options.asyncExecFn && !pStmt->execSemWaited) {
80,471!
UNCOV
2385
    if (tsem_wait(&pStmt->asyncExecSem) != 0) {
×
2386
      STMT2_ELOG_E("bind param wait asyncExecSem failed");
×
2387
    }
UNCOV
2388
    pStmt->execSemWaited = true;
×
2389
  }
2390

2391
  int32_t code = TSDB_CODE_SUCCESS;
80,471✔
2392
  for (int i = 0; i < bindv->count; ++i) {
687,045✔
2393
    if (bindv->tbnames && bindv->tbnames[i]) {
606,304!
2394
      code = stmtSetTbName2(stmt, bindv->tbnames[i]);
606,574✔
2395
      if (code) {
606,034!
UNCOV
2396
        terrno = code;
×
UNCOV
2397
        STMT2_ELOG("set tbname failed, code:%s", tstrerror(code));
×
UNCOV
2398
        return terrno;
×
2399
      }
2400
    }
2401

2402
    SVCreateTbReq *pCreateTbReq = NULL;
606,034✔
2403
    if (bindv->tags && bindv->tags[i]) {
606,034!
2404
      code = stmtSetTbTags2(stmt, bindv->tags[i], &pCreateTbReq);
190✔
2405
    } else if (pStmt->bInfo.tbNameFlag & IS_FIXED_TAG) {
606,114!
UNCOV
2406
      code = stmtCheckTags2(stmt, &pCreateTbReq);
×
2407
    } else if (pStmt->sql.autoCreateTbl) {
605,844!
2408
      // if (pStmt->sql.autoCreateTbl) {
2409
      //   pStmt->sql.autoCreateTbl = false;
2410
      //   STMT2_WLOG_E("sql is autoCreateTbl, but no tags");
2411
      // }
UNCOV
2412
      code = stmtSetTbTags2(stmt, NULL, &pCreateTbReq);
×
2413
    }
2414

2415
    if (code) {
605,496!
UNCOV
2416
      terrno = code;
×
UNCOV
2417
      STMT2_ELOG("set tags failed, code:%s", tstrerror(code));
×
UNCOV
2418
      return terrno;
×
2419
    }
2420

2421
    if (bindv->bind_cols && bindv->bind_cols[i]) {
605,496!
2422
      TAOS_STMT2_BIND *bind = bindv->bind_cols[i];
606,304✔
2423

2424
      if (bind->num <= 0 || bind->num > INT16_MAX) {
605,768!
2425
        STMT2_ELOG("bind num:%d must > 0 and < INT16_MAX", bind->num);
268!
2426
        code = terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
268✔
2427
        return terrno;
×
2428
      }
2429

2430
      if (!stmt2IsInsert(stmt) && bind->num > 1) {
606,306!
UNCOV
2431
        STMT2_ELOG_E("only one row data allowed for query");
×
UNCOV
2432
        code = terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
UNCOV
2433
        return terrno;
×
2434
      }
2435

2436
      code = stmtBindBatch2(stmt, bind, col_idx, pCreateTbReq);
606,306✔
2437
      if (TSDB_CODE_SUCCESS != code) {
606,034!
UNCOV
2438
        terrno = code;
×
UNCOV
2439
        STMT2_ELOG("bind batch failed, code:%s", tstrerror(code));
×
UNCOV
2440
        return terrno;
×
2441
      }
2442
    }
2443
  }
2444

2445
  return code;
80,471✔
2446
}
2447

2448
int taos_stmt2_bind_param_a(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx, __taos_async_fn_t fp,
×
2449
                            void *param) {
2450
  if (stmt == NULL || bindv == NULL || fp == NULL) {
×
2451
    terrno = TSDB_CODE_INVALID_PARA;
×
2452
    return terrno;
×
2453
  }
2454

2455
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
×
2456

2457
  ThreadArgs *args = (ThreadArgs *)taosMemoryMalloc(sizeof(ThreadArgs));
×
2458
  args->stmt = stmt;
×
2459
  args->bindv = bindv;
×
2460
  args->col_idx = col_idx;
×
2461
  args->fp = fp;
×
2462
  args->param = param;
×
2463

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

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

2484
  return code_s;
×
2485
}
2486

2487
int taos_stmt2_exec(TAOS_STMT2 *stmt, int *affected_rows) {
80,203✔
2488
  if (stmt == NULL) {
80,203!
2489
    tscError("NULL parameter for %s", __FUNCTION__);
×
2490
    terrno = TSDB_CODE_INVALID_PARA;
×
2491
    return terrno;
×
2492
  }
2493

2494
  return stmtExec2(stmt, affected_rows);
80,203✔
2495
}
2496

2497
int taos_stmt2_close(TAOS_STMT2 *stmt) {
4,427✔
2498
  if (stmt == NULL) {
4,427!
2499
    tscError("NULL parameter for %s", __FUNCTION__);
×
2500
    terrno = TSDB_CODE_INVALID_PARA;
×
2501
    return terrno;
×
2502
  }
2503

2504
  return stmtClose2(stmt);
4,427✔
2505
}
2506

2507
int taos_stmt2_is_insert(TAOS_STMT2 *stmt, int *insert) {
19✔
2508
  if (stmt == NULL || insert == NULL) {
19!
2509
    tscError("NULL parameter for %s", __FUNCTION__);
×
2510
    terrno = TSDB_CODE_INVALID_PARA;
×
2511
    return terrno;
×
2512
  }
2513
  *insert = stmt2IsInsert(stmt);
19✔
2514
  return TSDB_CODE_SUCCESS;
19✔
2515
}
2516

2517
int taos_stmt2_get_fields(TAOS_STMT2 *stmt, int *count, TAOS_FIELD_ALL **fields) {
19✔
2518
  if (stmt == NULL || count == NULL) {
19!
UNCOV
2519
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2520
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2521
    return terrno;
×
2522
  }
2523

2524
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
19✔
2525
  if (STMT_TYPE_INSERT == pStmt->sql.type || STMT_TYPE_MULTI_INSERT == pStmt->sql.type ||
19!
2526
      (pStmt->sql.type == 0 && stmt2IsInsert(stmt))) {
19!
2527
    return stmtGetStbColFields2(stmt, count, fields);
19✔
2528
  }
UNCOV
2529
  if (STMT_TYPE_QUERY == pStmt->sql.type || (pStmt->sql.type == 0 && stmt2IsSelect(stmt))) {
×
UNCOV
2530
    return stmtGetParamNum2(stmt, count);
×
2531
  }
2532

UNCOV
2533
  tscError("Invalid sql for stmt %s", pStmt->sql.sqlStr);
×
UNCOV
2534
  return TSDB_CODE_PAR_SYNTAX_ERROR;
×
2535
}
2536

2537
DLL_EXPORT void taos_stmt2_free_fields(TAOS_STMT2 *stmt, TAOS_FIELD_ALL *fields) {
19✔
2538
  (void)stmt;
2539
  if (!fields) return;
19!
2540
  taosMemoryFree(fields);
19!
2541
}
2542

UNCOV
2543
TAOS_RES *taos_stmt2_result(TAOS_STMT2 *stmt) {
×
UNCOV
2544
  if (stmt == NULL) {
×
2545
    tscError("NULL parameter for %s", __FUNCTION__);
×
2546
    terrno = TSDB_CODE_INVALID_PARA;
×
2547
    return NULL;
×
2548
  }
2549

UNCOV
2550
  return stmtUseResult2(stmt);
×
2551
}
2552

UNCOV
2553
char *taos_stmt2_error(TAOS_STMT2 *stmt) { return (char *)stmtErrstr2(stmt); }
×
2554

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

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

2578
char *getBuildInfo() { return td_buildinfo; }
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc