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

taosdata / TDengine / #3660

15 Mar 2025 09:06AM UTC coverage: 62.039% (-1.3%) from 63.314%
#3660

push

travis-ci

web-flow
feat(stream): support stream processing for virtual tables (#30144)

* enh: add client processing

* enh: add mnode vtables processing

* enh: add mnode vtable processing

* enh: add normal child vtable support

* fix: compile issues

* fix: compile issues

* fix: create stream issues

* fix: multi stream scan issue

* fix: remove debug info

* fix: agg task and task level issues

* fix: correct task output type

* fix: split vtablescan from agg

* fix: memory leak issues

* fix: add limitations

* Update 09-error-code.md

* Update 09-error-code.md

* fix: remove usless case

* feat(stream): extract original table data in source scan task

Implemented functionality in the source task to extract data
corresponding to the virtual table from the original table using WAL.
The extracted data is then sent to the downstream merge task for further
processing.

* feat(stream): multi-way merge using loser tree in virtual merge task

Implemented multi-way merge in the merge task using a loser tree to
combine data from multiple original table into a single virtual table.
The merged virtual table data is then pushed downstream for further
processing.  Introduced memory limit handling during the merge process
with configurable behavior when the memory limit is reached.

* fix(test): remove useless cases

---------

Co-authored-by: dapan1121 <wpan@taosdata.com>
Co-authored-by: Pan Wei <72057773+dapan1121@users.noreply.github.com>

154078 of 317582 branches covered (48.52%)

Branch coverage included in aggregate %.

313 of 2391 new or added lines in 34 files covered. (13.09%)

26134 existing lines in 205 files now uncovered.

240261 of 318051 relevant lines covered (75.54%)

16655189.27 hits per line

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

204
  if (option == TSDB_OPTION_CONNECTION_USER_IP || option == TSDB_OPTION_CONNECTION_CLEAR) {
34✔
205
    if (val != NULL) {
7✔
206
      pObj->optionInfo.userIp = taosInetAddr(val);
5✔
207
      if (pObj->optionInfo.userIp == INADDR_NONE) {
5✔
208
        code = TSDB_CODE_INVALID_PARA;
3✔
209
        goto END;
3✔
210
      }
211
    } else {
212
      pObj->optionInfo.userIp = INADDR_NONE;
2✔
213
    }
214
  }
215

216
END:
27✔
217
  releaseTscObj(*(int64_t *)taos);
36✔
218
  return terrno = code;
36✔
219
}
220

221
int taos_options_connection(TAOS *taos, TSDB_OPTION_CONNECTION option, const void *arg, ...) {
38✔
222
  return setConnectionOption(taos, option, (const char *)arg);
38✔
223
}
224

225
// this function may be called by user or system, or by both simultaneously.
226
void taos_cleanup(void) {
15,737✔
227
  tscDebug("start to cleanup client environment");
15,737✔
228
  if (atomic_val_compare_exchange_32(&sentinel, TSC_VAR_NOT_RELEASE, TSC_VAR_RELEASED) != TSC_VAR_NOT_RELEASE) {
15,737✔
229
    return;
18✔
230
  }
231

232
  monitorClose();
15,719✔
233
  tscStopCrashReport();
15,719✔
234

235
  hbMgrCleanUp();
15,719✔
236

237
  catalogDestroy();
15,719✔
238
  schedulerDestroy();
15,719✔
239

240
  fmFuncMgtDestroy();
15,719✔
241
  qCleanupKeywordsTable();
15,719✔
242

243
  if (TSDB_CODE_SUCCESS != cleanupTaskQueue()) {
15,719!
244
    tscWarn("failed to cleanup task queue");
×
245
  }
246

247
#if !defined(WINDOWS) && !defined(TD_ASTRA)
248
  tzCleanup();
15,719✔
249
#endif
250
  tmqMgmtClose();
15,719✔
251

252
  int32_t id = clientReqRefPool;
15,719✔
253
  clientReqRefPool = -1;
15,719✔
254
  taosCloseRef(id);
15,719✔
255

256
  id = clientConnRefPool;
15,719✔
257
  clientConnRefPool = -1;
15,719✔
258
  taosCloseRef(id);
15,719✔
259

260
  nodesDestroyAllocatorSet();
15,719✔
261
  cleanupAppInfo();
15,719✔
262
  rpcCleanup();
15,719✔
263
  tscDebug("rpc cleanup");
15,719✔
264

265
  taosConvDestroy();
15,719✔
266
  DestroyRegexCache();
15,719✔
267
#ifdef TAOSD_INTEGRATED
268
  shellStopDaemon();
269
#endif
270
  tscInfo("all local resources released");
15,719!
271
  taosCleanupCfg();
15,719✔
272
#ifndef TAOSD_INTEGRATED
273
  taosCloseLog();
15,719✔
274
#endif
275
}
276

277
static setConfRet taos_set_config_imp(const char *config) {
51✔
278
  setConfRet ret = {SET_CONF_RET_SUCC, {0}};
51✔
279
  // TODO: need re-implementation
280
  return ret;
51✔
281
}
282

283
setConfRet taos_set_config(const char *config) {
51✔
284
  // TODO  pthread_mutex_lock(&setConfMutex);
285
  setConfRet ret = taos_set_config_imp(config);
51✔
286
  //  pthread_mutex_unlock(&setConfMutex);
287
  return ret;
51✔
288
}
289

290
TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port) {
27,524✔
291
  tscInfo("try to connect to %s:%u, user:%s db:%s", ip, port, user, db);
27,524✔
292
  if (user == NULL) {
27,525!
293
    user = TSDB_DEFAULT_USER;
×
294
  }
295

296
  if (pass == NULL) {
27,525!
297
    pass = TSDB_DEFAULT_PASS;
×
298
  }
299

300
  STscObj *pObj = NULL;
27,525✔
301
  int32_t  code = taos_connect_internal(ip, user, pass, NULL, db, port, CONN_TYPE__QUERY, &pObj);
27,525✔
302
  if (TSDB_CODE_SUCCESS == code) {
27,524✔
303
    int64_t *rid = taosMemoryCalloc(1, sizeof(int64_t));
27,484!
304
    if (NULL == rid) {
27,484!
305
      tscError("out of memory when taos connect to %s:%u, user:%s db:%s", ip, port, user, db);
×
306
      return NULL;
×
307
    }
308
    *rid = pObj->id;
27,484✔
309
    return (TAOS *)rid;
27,484✔
310
  } else {
311
    terrno = code;
40✔
312
  }
313

314
  return NULL;
40✔
315
}
316

317
int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type) {
150✔
318
  if (taos == NULL) {
150!
319
    terrno = TSDB_CODE_INVALID_PARA;
×
320
    return terrno;
×
321
  }
322

323
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
150✔
324
  if (NULL == pObj) {
150!
325
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
326
    tscError("invalid parameter for %s", __func__);
×
327
    return terrno;
×
328
  }
329

330
  switch (type) {
150!
331
    case TAOS_NOTIFY_PASSVER: {
40✔
332
      TSC_ERR_RET(taosThreadMutexLock(&pObj->mutex));
40!
333
      pObj->passInfo.fp = fp;
40✔
334
      pObj->passInfo.param = param;
40✔
335
      TSC_ERR_RET(taosThreadMutexUnlock(&pObj->mutex));
40!
336
      break;
40✔
337
    }
338
    case TAOS_NOTIFY_WHITELIST_VER: {
10✔
339
      TSC_ERR_RET(taosThreadMutexLock(&pObj->mutex));
10!
340
      pObj->whiteListInfo.fp = fp;
10✔
341
      pObj->whiteListInfo.param = param;
10✔
342
      TSC_ERR_RET(taosThreadMutexUnlock(&pObj->mutex));
10!
343
      break;
10✔
344
    }
345
    case TAOS_NOTIFY_USER_DROPPED: {
100✔
346
      TSC_ERR_RET(taosThreadMutexLock(&pObj->mutex));
100!
347
      pObj->userDroppedInfo.fp = fp;
100✔
348
      pObj->userDroppedInfo.param = param;
100✔
349
      TSC_ERR_RET(taosThreadMutexUnlock(&pObj->mutex));
100!
350
      break;
100✔
351
    }
352
    default: {
×
353
      terrno = TSDB_CODE_INVALID_PARA;
×
354
      releaseTscObj(*(int64_t *)taos);
×
355
      return terrno;
×
356
    }
357
  }
358

359
  releaseTscObj(*(int64_t *)taos);
150✔
360
  return 0;
150✔
361
}
362

363
typedef struct SFetchWhiteListInfo {
364
  int64_t                     connId;
365
  __taos_async_whitelist_fn_t userCbFn;
366
  void                       *userParam;
367
} SFetchWhiteListInfo;
368

369
int32_t fetchWhiteListCallbackFn(void *param, SDataBuf *pMsg, int32_t code) {
10✔
370
  SFetchWhiteListInfo *pInfo = (SFetchWhiteListInfo *)param;
10✔
371
  TAOS                *taos = &pInfo->connId;
10✔
372
  if (code != TSDB_CODE_SUCCESS) {
10!
373
    pInfo->userCbFn(pInfo->userParam, code, taos, 0, NULL);
×
374
    taosMemoryFree(pMsg->pData);
×
375
    taosMemoryFree(pMsg->pEpSet);
×
376
    taosMemoryFree(pInfo);
×
377
    return code;
×
378
  }
379

380
  SGetUserWhiteListRsp wlRsp;
381
  if (TSDB_CODE_SUCCESS != tDeserializeSGetUserWhiteListRsp(pMsg->pData, pMsg->len, &wlRsp)) {
10!
382
    taosMemoryFree(pMsg->pData);
×
383
    taosMemoryFree(pMsg->pEpSet);
×
384
    taosMemoryFree(pInfo);
×
385
    tFreeSGetUserWhiteListRsp(&wlRsp);
×
386
    return terrno;
×
387
  }
388

389
  uint64_t *pWhiteLists = taosMemoryMalloc(wlRsp.numWhiteLists * sizeof(uint64_t));
10!
390
  if (pWhiteLists == NULL) {
10!
391
    taosMemoryFree(pMsg->pData);
×
392
    taosMemoryFree(pMsg->pEpSet);
×
393
    taosMemoryFree(pInfo);
×
394
    tFreeSGetUserWhiteListRsp(&wlRsp);
×
395
    return terrno;
×
396
  }
397

398
  for (int i = 0; i < wlRsp.numWhiteLists; ++i) {
20✔
399
    pWhiteLists[i] = ((uint64_t)wlRsp.pWhiteLists[i].mask << 32) | wlRsp.pWhiteLists[i].ip;
10✔
400
  }
401

402
  pInfo->userCbFn(pInfo->userParam, code, taos, wlRsp.numWhiteLists, pWhiteLists);
10✔
403

404
  taosMemoryFree(pWhiteLists);
10!
405
  taosMemoryFree(pMsg->pData);
10!
406
  taosMemoryFree(pMsg->pEpSet);
10!
407
  taosMemoryFree(pInfo);
10!
408
  tFreeSGetUserWhiteListRsp(&wlRsp);
10✔
409
  return code;
10✔
410
}
411

412
void taos_fetch_whitelist_a(TAOS *taos, __taos_async_whitelist_fn_t fp, void *param) {
10✔
413
  if (NULL == taos) {
10!
414
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
415
    return;
×
416
  }
417

418
  int64_t connId = *(int64_t *)taos;
10✔
419

420
  STscObj *pTsc = acquireTscObj(connId);
10✔
421
  if (NULL == pTsc) {
10!
422
    fp(param, TSDB_CODE_TSC_DISCONNECTED, taos, 0, NULL);
×
423
    return;
×
424
  }
425

426
  SGetUserWhiteListReq req;
427
  (void)memcpy(req.user, pTsc->user, TSDB_USER_LEN);
10✔
428
  int32_t msgLen = tSerializeSGetUserWhiteListReq(NULL, 0, &req);
10✔
429
  if (msgLen < 0) {
10!
430
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
431
    releaseTscObj(connId);
×
432
    return;
×
433
  }
434

435
  void *pReq = taosMemoryMalloc(msgLen);
10!
436
  if (pReq == NULL) {
10!
437
    fp(param, terrno, taos, 0, NULL);
×
438
    releaseTscObj(connId);
×
439
    return;
×
440
  }
441

442
  if (tSerializeSGetUserWhiteListReq(pReq, msgLen, &req) < 0) {
10!
443
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
444
    taosMemoryFree(pReq);
×
445
    releaseTscObj(connId);
×
446
    return;
×
447
  }
448

449
  SFetchWhiteListInfo *pParam = taosMemoryMalloc(sizeof(SFetchWhiteListInfo));
10!
450
  if (pParam == NULL) {
10!
451
    fp(param, terrno, taos, 0, NULL);
×
452
    taosMemoryFree(pReq);
×
453
    releaseTscObj(connId);
×
454
    return;
×
455
  }
456

457
  pParam->connId = connId;
10✔
458
  pParam->userCbFn = fp;
10✔
459
  pParam->userParam = param;
10✔
460
  SMsgSendInfo *pSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
10!
461
  if (pSendInfo == NULL) {
10!
462
    fp(param, terrno, taos, 0, NULL);
×
463
    taosMemoryFree(pParam);
×
464
    taosMemoryFree(pReq);
×
465
    releaseTscObj(connId);
×
466
    return;
×
467
  }
468

469
  pSendInfo->msgInfo = (SDataBuf){.pData = pReq, .len = msgLen, .handle = NULL};
10✔
470
  pSendInfo->requestId = generateRequestId();
10✔
471
  pSendInfo->requestObjRefId = 0;
10✔
472
  pSendInfo->param = pParam;
10✔
473
  pSendInfo->fp = fetchWhiteListCallbackFn;
10✔
474
  pSendInfo->msgType = TDMT_MND_GET_USER_WHITELIST;
10✔
475

476
  SEpSet epSet = getEpSet_s(&pTsc->pAppInfo->mgmtEp);
10✔
477
  if (TSDB_CODE_SUCCESS != asyncSendMsgToServer(pTsc->pAppInfo->pTransporter, &epSet, NULL, pSendInfo)) {
10!
478
    tscWarn("failed to async send msg to server");
×
479
  }
480
  releaseTscObj(connId);
10✔
481
  return;
10✔
482
}
483

484
void taos_close_internal(void *taos) {
27,924✔
485
  if (taos == NULL) {
27,924!
486
    return;
×
487
  }
488

489
  STscObj *pTscObj = (STscObj *)taos;
27,924✔
490
  tscDebug("connObj:0x%" PRIx64 ", try to close connection, numOfReq:%d", pTscObj->id, pTscObj->numOfReqs);
27,924✔
491

492
  if (TSDB_CODE_SUCCESS != taosRemoveRef(clientConnRefPool, pTscObj->id)) {
27,924!
493
    tscError("connObj:0x%" PRIx64 ", failed to remove ref from conn pool", pTscObj->id);
×
494
  }
495
}
496

497
void taos_close(TAOS *taos) {
28,361✔
498
  if (taos == NULL) {
28,361✔
499
    return;
896✔
500
  }
501

502
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
27,465✔
503
  if (NULL == pObj) {
27,465!
504
    taosMemoryFree(taos);
×
505
    return;
×
506
  }
507

508
  taos_close_internal(pObj);
27,465✔
509
  releaseTscObj(*(int64_t *)taos);
27,465✔
510
  taosMemoryFree(taos);
27,465!
511
}
512

513
int taos_errno(TAOS_RES *res) {
12,179,600✔
514
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
12,179,600!
515
    return terrno;
×
516
  }
517

518
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
12,189,695!
519
    return 0;
×
520
  }
521

522
  return ((SRequestObj *)res)->code;
12,189,933✔
523
}
524

525
const char *taos_errstr(TAOS_RES *res) {
88,141✔
526
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
88,141!
527
    return (const char *)tstrerror(terrno);
106✔
528
  }
529

530
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
88,035!
531
    return "success";
×
532
  }
533

534
  SRequestObj *pRequest = (SRequestObj *)res;
88,035✔
535
  if (NULL != pRequest->msgBuf && (strlen(pRequest->msgBuf) > 0 || pRequest->code == TSDB_CODE_RPC_FQDN_ERROR)) {
88,035!
536
    return pRequest->msgBuf;
78,137✔
537
  } else {
538
    return (const char *)tstrerror(pRequest->code);
9,898✔
539
  }
540
}
541

542
void taos_free_result(TAOS_RES *res) {
10,881,688✔
543
  if (NULL == res) {
10,881,688✔
544
    return;
21,059✔
545
  }
546

547
  tscTrace("res:%p, will be freed", res);
10,860,629✔
548

549
  if (TD_RES_QUERY(res)) {
10,868,854✔
550
    SRequestObj *pRequest = (SRequestObj *)res;
10,755,020✔
551
    tscDebug("QID:0x%" PRIx64 ", call taos_free_result to free query", pRequest->requestId);
10,755,020✔
552
    destroyRequest(pRequest);
10,755,020✔
553
    return;
10,752,667✔
554
  }
555

556
  SMqRspObj *pRsp = (SMqRspObj *)res;
113,834✔
557
  if (TD_RES_TMQ(res)) {
113,834✔
558
    tDeleteMqDataRsp(&pRsp->dataRsp);
113,560✔
559
    doFreeReqResultInfo(&pRsp->resInfo);
113,560✔
560
  } else if (TD_RES_TMQ_METADATA(res)) {
274✔
561
    tDeleteSTaosxRsp(&pRsp->dataRsp);
12✔
562
    doFreeReqResultInfo(&pRsp->resInfo);
12✔
563
  } else if (TD_RES_TMQ_META(res)) {
262✔
564
    tDeleteMqMetaRsp(&pRsp->metaRsp);
227✔
565
  } else if (TD_RES_TMQ_BATCH_META(res)) {
35✔
566
    tDeleteMqBatchMetaRsp(&pRsp->batchMetaRsp);
18✔
567
  } else if (TD_RES_TMQ_RAW(res)) {
17!
568
    tDeleteMqRawDataRsp(&pRsp->dataRsp);
17✔
569
  }
570
  taosMemoryFree(pRsp);
113,832!
571
}
572

573
void taos_kill_query(TAOS *taos) {
10✔
574
  if (NULL == taos) {
10✔
575
    return;
5✔
576
  }
577

578
  int64_t  rid = *(int64_t *)taos;
5✔
579
  STscObj *pTscObj = acquireTscObj(rid);
5✔
580
  if (pTscObj) {
5!
581
    stopAllRequests(pTscObj->pRequests);
5✔
582
  }
583
  releaseTscObj(rid);
5✔
584
}
585

586
int taos_field_count(TAOS_RES *res) {
55,051,464✔
587
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
55,051,464!
588
    return 0;
×
589
  }
590

591
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
55,051,590✔
592
  return pResInfo->numOfCols;
55,051,590✔
593
}
594

595
int taos_num_fields(TAOS_RES *res) { return taos_field_count(res); }
35,730,571✔
596

597
TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) {
16,672,233✔
598
  if (taos_num_fields(res) == 0 || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
16,672,233!
599
    return NULL;
132,554✔
600
  }
601

602
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
16,539,499✔
603
  return pResInfo->userFields;
16,539,499✔
604
}
605

606
TAOS_RES *taos_query(TAOS *taos, const char *sql) { return taosQueryImpl(taos, sql, false, TD_REQ_FROM_APP); }
10,720,114✔
607
TAOS_RES *taos_query_with_reqid(TAOS *taos, const char *sql, int64_t reqid) {
1✔
608
  return taosQueryImplWithReqid(taos, sql, false, reqid);
1✔
609
}
610

UNCOV
611
TAOS_FIELD_E *taos_fetch_fields_e(TAOS_RES *res) {
×
UNCOV
612
  if (taos_num_fields(res) == 0 || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
×
613
    return NULL;
×
614
  }
UNCOV
615
  SReqResultInfo* pResInfo = tscGetCurResInfo(res);
×
UNCOV
616
  return pResInfo->fields;
×
617
}
618

619
TAOS_ROW taos_fetch_row(TAOS_RES *res) {
31,602,718✔
620
  if (res == NULL) {
31,602,718!
UNCOV
621
    return NULL;
×
622
  }
623

624
  if (TD_RES_QUERY(res)) {
31,602,718✔
625
    SRequestObj *pRequest = (SRequestObj *)res;
16,251,222✔
626
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
16,251,222!
627
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0 || pRequest->killed) {
16,251,059!
628
      return NULL;
97✔
629
    }
630

631
    if (pRequest->inCallback) {
16,249,309✔
632
      tscError("can not call taos_fetch_row before query callback ends.");
1!
633
      terrno = TSDB_CODE_TSC_INVALID_OPERATION;
1✔
634
      return NULL;
1✔
635
    }
636

637
    return doAsyncFetchRows(pRequest, true, true);
16,249,308✔
638
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
15,351,496!
639
    SMqRspObj      *msg = ((SMqRspObj *)res);
15,351,496✔
640
    SReqResultInfo *pResultInfo = NULL;
15,351,496✔
641
    if (msg->resIter == -1) {
15,351,496✔
642
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
113,015!
UNCOV
643
        return NULL;
×
644
      }
645
    } else {
646
      pResultInfo = tmqGetCurResInfo(res);
15,238,481✔
647
    }
648

649
    if (pResultInfo->current < pResultInfo->numOfRows) {
15,351,493✔
650
      doSetOneRowPtr(pResultInfo, false);
15,021,557✔
651
      pResultInfo->current += 1;
15,020,758✔
652
      return pResultInfo->row;
15,020,758✔
653
    } else {
654
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
329,936✔
655
        return NULL;
113,010✔
656
      }
657

658
      doSetOneRowPtr(pResultInfo, false);
216,956✔
659
      pResultInfo->current += 1;
216,952✔
660
      return pResultInfo->row;
216,952✔
661
    }
UNCOV
662
  } else if (TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
×
UNCOV
663
    return NULL;
×
664
  } else {
UNCOV
665
    tscError("invalid result passed to taos_fetch_row");
×
UNCOV
666
    terrno = TSDB_CODE_TMQ_INVALID_DATA;
×
UNCOV
667
    return NULL;
×
668
  }
669
}
670

671
int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
15,250,563✔
672
  return taos_print_row_with_size(str, INT32_MAX, row, fields, num_fields);
15,250,563✔
673
}
674
int taos_print_row_with_size(char *str, uint32_t size, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
15,250,506✔
675
  int32_t len = 0;
15,250,506✔
676
  for (int i = 0; i < num_fields; ++i) {
91,248,495✔
677
    if (i > 0 && len < size - 1) {
75,996,849!
678
      str[len++] = ' ';
60,760,039✔
679
    }
680

681
    if (row[i] == NULL) {
75,996,849✔
682
      len += tsnprintf(str + len, size - len, "%s", TSDB_DATA_NULL_STR);
261,962✔
683
      continue;
261,983✔
684
    }
685

686
    switch (fields[i].type) {
75,734,887!
687
      case TSDB_DATA_TYPE_TINYINT:
301✔
688
        len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
301✔
689
        break;
301✔
690

691
      case TSDB_DATA_TYPE_UTINYINT:
300✔
692
        len += tsnprintf(str + len, size - len, "%u", *((uint8_t *)row[i]));
300✔
693
        break;
300✔
694

695
      case TSDB_DATA_TYPE_SMALLINT:
301✔
696
        len += tsnprintf(str + len, size - len, "%d", *((int16_t *)row[i]));
301✔
697
        break;
301✔
698

699
      case TSDB_DATA_TYPE_USMALLINT:
300✔
700
        len += tsnprintf(str + len, size - len, "%u", *((uint16_t *)row[i]));
300✔
701
        break;
300✔
702

703
      case TSDB_DATA_TYPE_INT:
16,269,546✔
704
        len += tsnprintf(str + len, size - len, "%d", *((int32_t *)row[i]));
16,269,546✔
705
        break;
16,269,558✔
706

707
      case TSDB_DATA_TYPE_UINT:
300✔
708
        len += tsnprintf(str + len, size - len, "%u", *((uint32_t *)row[i]));
300✔
709
        break;
300✔
710

711
      case TSDB_DATA_TYPE_BIGINT:
13,853,637✔
712
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
13,853,637✔
713
        break;
13,854,415✔
714

715
      case TSDB_DATA_TYPE_UBIGINT:
300✔
716
        len += tsnprintf(str + len, size - len, "%" PRIu64, *((uint64_t *)row[i]));
300✔
717
        break;
300✔
718

719
      case TSDB_DATA_TYPE_FLOAT: {
1,642✔
720
        float fv = 0;
1,642✔
721
        fv = GET_FLOAT_VAL(row[i]);
1,642✔
722
        len += snprintf(str + len, size - len, "%.*g", FLT_DIG, fv);
1,642✔
723
      } break;
1,642✔
724

725
      case TSDB_DATA_TYPE_DOUBLE: {
8,024,805✔
726
        double dv = 0;
8,024,805✔
727
        dv = GET_DOUBLE_VAL(row[i]);
8,024,805✔
728
        len += snprintf(str + len, size - len, "%.*g", DBL_DIG, dv);
8,024,805✔
729
      } break;
8,024,805✔
730

731
      case TSDB_DATA_TYPE_VARBINARY: {
200✔
732
        void    *data = NULL;
200✔
733
        uint32_t tmp = 0;
200✔
734
        int32_t  charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
200✔
735
        if (taosAscii2Hex(row[i], charLen, &data, &tmp) < 0) {
200!
UNCOV
736
          break;
×
737
        }
738
        uint32_t copyLen = TMIN(size - len - 1, tmp);
200✔
739
        (void)memcpy(str + len, data, copyLen);
200✔
740
        len += copyLen;
200✔
741
        taosMemoryFree(data);
200!
742
      } break;
200✔
743
      case TSDB_DATA_TYPE_BINARY:
16,903,328✔
744
      case TSDB_DATA_TYPE_NCHAR:
745
      case TSDB_DATA_TYPE_GEOMETRY: {
746
        int32_t charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
16,903,328✔
747
        if (fields[i].type == TSDB_DATA_TYPE_BINARY || fields[i].type == TSDB_DATA_TYPE_VARBINARY ||
16,903,328✔
748
            fields[i].type == TSDB_DATA_TYPE_GEOMETRY) {
5,437,183✔
749
          if (charLen > fields[i].bytes || charLen < 0) {
11,466,334!
UNCOV
750
            tscError("taos_print_row error binary. charLen:%d, fields[i].bytes:%d", charLen, fields[i].bytes);
×
UNCOV
751
            break;
×
752
          }
753
        } else {
754
          if (charLen > fields[i].bytes * TSDB_NCHAR_SIZE || charLen < 0) {
5,436,994!
755
            tscError("taos_print_row error. charLen:%d, fields[i].bytes:%d", charLen, fields[i].bytes);
3,823!
UNCOV
756
            break;
×
757
          }
758
        }
759

760
        uint32_t copyLen = TMIN(size - len - 1, charLen);
16,901,095✔
761
        (void)memcpy(str + len, row[i], copyLen);
16,901,095✔
762
        len += copyLen;
16,901,095✔
763
      } break;
16,901,095✔
764

765
      case TSDB_DATA_TYPE_TIMESTAMP:
20,713,058✔
766
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
20,713,058✔
767
        break;
20,715,620✔
768

769
      case TSDB_DATA_TYPE_BOOL:
300✔
770
        len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
300✔
771
        break;
300✔
UNCOV
772
      case TSDB_DATA_TYPE_DECIMAL64:
×
773
      case TSDB_DATA_TYPE_DECIMAL: {
UNCOV
774
        uint32_t decimalLen = strlen(row[i]);
×
UNCOV
775
        uint32_t copyLen = TMIN(size - len - 1, decimalLen);
×
UNCOV
776
        (void)memcpy(str + len, row[i], copyLen);
×
UNCOV
777
        len += copyLen;
×
UNCOV
778
      } break;
×
UNCOV
779
      default:
×
780
        break;
×
781
    }
782

783
    if (len >= size - 1) {
75,736,006!
UNCOV
784
      break;
×
785
    }
786
  }
787
  if (len < size) {
15,251,646✔
788
    str[len] = 0;
15,249,564✔
789
  }
790

791
  return len;
15,251,646✔
792
}
793

794
int *taos_fetch_lengths(TAOS_RES *res) {
29,138,891✔
795
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
29,138,891!
UNCOV
796
    return NULL;
×
797
  }
798

799
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
29,138,983✔
800
  return pResInfo->length;
29,138,983✔
801
}
802

803
TAOS_ROW *taos_result_block(TAOS_RES *res) {
×
804
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
×
805
    terrno = TSDB_CODE_INVALID_PARA;
×
806
    return NULL;
×
807
  }
808

809
  if (taos_is_update_query(res)) {
×
810
    return NULL;
×
811
  }
812

813
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
×
814
  return &pResInfo->row;
×
815
}
816

817
// todo intergrate with tDataTypes
818
const char *taos_data_type(int type) {
×
819
  switch (type) {
×
820
    case TSDB_DATA_TYPE_NULL:
×
821
      return "TSDB_DATA_TYPE_NULL";
×
UNCOV
822
    case TSDB_DATA_TYPE_BOOL:
×
823
      return "TSDB_DATA_TYPE_BOOL";
×
824
    case TSDB_DATA_TYPE_TINYINT:
×
825
      return "TSDB_DATA_TYPE_TINYINT";
×
826
    case TSDB_DATA_TYPE_SMALLINT:
×
827
      return "TSDB_DATA_TYPE_SMALLINT";
×
828
    case TSDB_DATA_TYPE_INT:
×
829
      return "TSDB_DATA_TYPE_INT";
×
830
    case TSDB_DATA_TYPE_BIGINT:
×
831
      return "TSDB_DATA_TYPE_BIGINT";
×
832
    case TSDB_DATA_TYPE_FLOAT:
×
833
      return "TSDB_DATA_TYPE_FLOAT";
×
834
    case TSDB_DATA_TYPE_DOUBLE:
×
835
      return "TSDB_DATA_TYPE_DOUBLE";
×
836
    case TSDB_DATA_TYPE_VARCHAR:
×
837
      return "TSDB_DATA_TYPE_VARCHAR";
×
838
      //    case TSDB_DATA_TYPE_BINARY:          return "TSDB_DATA_TYPE_VARCHAR";
839
    case TSDB_DATA_TYPE_TIMESTAMP:
×
840
      return "TSDB_DATA_TYPE_TIMESTAMP";
×
841
    case TSDB_DATA_TYPE_NCHAR:
×
842
      return "TSDB_DATA_TYPE_NCHAR";
×
843
    case TSDB_DATA_TYPE_JSON:
×
844
      return "TSDB_DATA_TYPE_JSON";
×
845
    case TSDB_DATA_TYPE_GEOMETRY:
×
846
      return "TSDB_DATA_TYPE_GEOMETRY";
×
847
    case TSDB_DATA_TYPE_UTINYINT:
×
848
      return "TSDB_DATA_TYPE_UTINYINT";
×
UNCOV
849
    case TSDB_DATA_TYPE_USMALLINT:
×
UNCOV
850
      return "TSDB_DATA_TYPE_USMALLINT";
×
UNCOV
851
    case TSDB_DATA_TYPE_UINT:
×
UNCOV
852
      return "TSDB_DATA_TYPE_UINT";
×
UNCOV
853
    case TSDB_DATA_TYPE_UBIGINT:
×
UNCOV
854
      return "TSDB_DATA_TYPE_UBIGINT";
×
UNCOV
855
    case TSDB_DATA_TYPE_VARBINARY:
×
UNCOV
856
      return "TSDB_DATA_TYPE_VARBINARY";
×
UNCOV
857
    case TSDB_DATA_TYPE_DECIMAL:
×
858
      return "TSDB_DATA_TYPE_DECIMAL";
×
UNCOV
859
    case TSDB_DATA_TYPE_BLOB:
×
UNCOV
860
      return "TSDB_DATA_TYPE_BLOB";
×
UNCOV
861
    case TSDB_DATA_TYPE_MEDIUMBLOB:
×
UNCOV
862
      return "TSDB_DATA_TYPE_MEDIUMBLOB";
×
UNCOV
863
    default:
×
UNCOV
864
      return "UNKNOWN";
×
865
  }
866
}
867

868
const char *taos_get_client_info() { return td_version; }
15,720✔
869

870
// return int32_t
871
int taos_affected_rows(TAOS_RES *res) {
1,554,695✔
872
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
1,554,695!
873
      TD_RES_TMQ_BATCH_META(res)) {
1,554,708!
UNCOV
874
    return 0;
×
875
  }
876

877
  SRequestObj    *pRequest = (SRequestObj *)res;
1,554,709✔
878
  SReqResultInfo *pResInfo = &pRequest->body.resInfo;
1,554,709✔
879
  return (int)pResInfo->numOfRows;
1,554,709✔
880
}
881

882
// return int64_t
883
int64_t taos_affected_rows64(TAOS_RES *res) {
125,396✔
884
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
125,396!
885
      TD_RES_TMQ_BATCH_META(res)) {
125,396!
UNCOV
886
    return 0;
×
887
  }
888

889
  SRequestObj    *pRequest = (SRequestObj *)res;
125,396✔
890
  SReqResultInfo *pResInfo = &pRequest->body.resInfo;
125,396✔
891
  return pResInfo->numOfRows;
125,396✔
892
}
893

894
int taos_result_precision(TAOS_RES *res) {
16,238,967✔
895
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
16,238,967!
896
    return TSDB_TIME_PRECISION_MILLI;
×
897
  }
898

899
  if (TD_RES_QUERY(res)) {
16,238,992✔
900
    SRequestObj *pRequest = (SRequestObj *)res;
998,806✔
901
    return pRequest->body.resInfo.precision;
998,806✔
902
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
15,240,186!
903
    SReqResultInfo *info = tmqGetCurResInfo(res);
15,240,186✔
904
    return info->precision;
15,240,186✔
905
  }
UNCOV
906
  return TSDB_TIME_PRECISION_MILLI;
×
907
}
908

909
int taos_select_db(TAOS *taos, const char *db) {
403✔
910
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
403✔
911
  if (pObj == NULL) {
403!
UNCOV
912
    releaseTscObj(*(int64_t *)taos);
×
UNCOV
913
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
UNCOV
914
    return TSDB_CODE_TSC_DISCONNECTED;
×
915
  }
916

917
  if (db == NULL || strlen(db) == 0) {
403!
UNCOV
918
    releaseTscObj(*(int64_t *)taos);
×
UNCOV
919
    tscError("invalid parameter for %s", db == NULL ? "db is NULL" : "db is empty");
×
UNCOV
920
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
UNCOV
921
    return terrno;
×
922
  }
923

924
  char sql[256] = {0};
403✔
925
  (void)snprintf(sql, tListLen(sql), "use %s", db);
403✔
926

927
  TAOS_RES *pRequest = taos_query(taos, sql);
403✔
928
  int32_t   code = taos_errno(pRequest);
403✔
929

930
  taos_free_result(pRequest);
403✔
931
  releaseTscObj(*(int64_t *)taos);
403✔
932
  return code;
403✔
933
}
934

935
void taos_stop_query(TAOS_RES *res) {
10,773,837✔
936
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
10,773,837!
937
      TD_RES_TMQ_BATCH_META(res)) {
10,784,996!
UNCOV
938
    return;
×
939
  }
940

941
  stopAllQueries((SRequestObj *)res);
10,785,419✔
942
}
943

944
bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) {
303,734,205✔
945
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
303,734,205!
UNCOV
946
    return true;
×
947
  }
948
  SReqResultInfo *pResultInfo = tscGetCurResInfo(res);
303,734,296✔
949
  if (col >= pResultInfo->numOfCols || col < 0 || row >= pResultInfo->numOfRows || row < 0) {
303,734,296✔
950
    return true;
7✔
951
  }
952

953
  SResultColumn *pCol = &pResultInfo->pCol[col];
303,734,289✔
954
  if (IS_VAR_DATA_TYPE(pResultInfo->fields[col].type)) {
303,734,289!
955
    return (pCol->offset[row] == -1);
×
956
  } else {
957
    return colDataIsNull_f(pCol->nullbitmap, row);
303,734,297✔
958
  }
959
}
960

961
bool taos_is_update_query(TAOS_RES *res) { return taos_num_fields(res) == 0; }
13,165✔
962

963
int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
1,251,807✔
964
  int32_t numOfRows = 0;
1,251,807✔
965
  /*int32_t code = */ terrno = taos_fetch_block_s(res, &numOfRows, rows);
1,251,807✔
966
  return numOfRows;
1,251,806✔
967
}
968

969
int taos_fetch_block_s(TAOS_RES *res, int *numOfRows, TAOS_ROW *rows) {
1,251,807✔
970
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
1,251,807!
UNCOV
971
    return 0;
×
972
  }
973

974
  if (TD_RES_QUERY(res)) {
1,251,807✔
975
    SRequestObj *pRequest = (SRequestObj *)res;
1,247,810✔
976

977
    (*rows) = NULL;
1,247,810✔
978
    (*numOfRows) = 0;
1,247,810✔
979

980
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
1,247,810!
981
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
1,245,333!
982
      return pRequest->code;
6,063✔
983
    }
984

985
    (void)doAsyncFetchRows(pRequest, false, true);
1,241,747✔
986

987
    // TODO refactor
988
    SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
1,241,747✔
989
    pResultInfo->current = pResultInfo->numOfRows;
1,241,747✔
990

991
    (*rows) = pResultInfo->row;
1,241,747✔
992
    (*numOfRows) = pResultInfo->numOfRows;
1,241,747✔
993
    return pRequest->code;
1,241,747✔
994
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
3,997!
995
    SReqResultInfo *pResultInfo = NULL;
3,997✔
996
    int32_t         code = tmqGetNextResInfo(res, true, &pResultInfo);
3,997✔
997
    if (code != 0) return code;
3,997✔
998

999
    pResultInfo->current = pResultInfo->numOfRows;
3,570✔
1000
    (*rows) = pResultInfo->row;
3,570✔
1001
    (*numOfRows) = pResultInfo->numOfRows;
3,570✔
1002
    return 0;
3,570✔
1003
  } else {
UNCOV
1004
    tscError("taos_fetch_block_s invalid res type");
×
UNCOV
1005
    return TSDB_CODE_TMQ_INVALID_DATA;
×
1006
  }
1007
}
1008

1009
int taos_fetch_raw_block(TAOS_RES *res, int *numOfRows, void **pData) {
1,788✔
1010
  *numOfRows = 0;
1,788✔
1011
  *pData = NULL;
1,788✔
1012

1013
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
1,788!
UNCOV
1014
    return 0;
×
1015
  }
1016

1017
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
1,788!
1018
    SReqResultInfo *pResultInfo = NULL;
674✔
1019
    int32_t         code = tmqGetNextResInfo(res, false, &pResultInfo);
674✔
1020
    if (code != 0) {
674✔
1021
      (*numOfRows) = 0;
53✔
1022
      return 0;
53✔
1023
    }
1024

1025
    pResultInfo->current = pResultInfo->numOfRows;
621✔
1026
    (*numOfRows) = pResultInfo->numOfRows;
621✔
1027
    (*pData) = (void *)pResultInfo->pData;
621✔
1028
    return 0;
621✔
1029
  }
1030

1031
  SRequestObj *pRequest = (SRequestObj *)res;
1,114✔
1032

1033
  if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
1,114!
1034
      pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
1,110!
1035
    return pRequest->code;
4✔
1036
  }
1037

1038
  (void)doAsyncFetchRows(pRequest, false, false);
1,110✔
1039

1040
  SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
1,110✔
1041

1042
  pResultInfo->current = pResultInfo->numOfRows;
1,110✔
1043
  (*numOfRows) = pResultInfo->numOfRows;
1,110✔
1044
  (*pData) = (void *)pResultInfo->pData;
1,110✔
1045

1046
  return pRequest->code;
1,110✔
1047
}
1048

1049
int *taos_get_column_data_offset(TAOS_RES *res, int columnIndex) {
514,045✔
1050
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
514,045!
UNCOV
1051
    return 0;
×
1052
  }
1053

1054
  int32_t numOfFields = taos_num_fields(res);
514,045✔
1055
  if (columnIndex < 0 || columnIndex >= numOfFields || numOfFields == 0) {
514,045!
UNCOV
1056
    return 0;
×
1057
  }
1058

1059
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
514,045✔
1060
  TAOS_FIELD     *pField = &pResInfo->userFields[columnIndex];
514,045✔
1061
  if (!IS_VAR_DATA_TYPE(pField->type)) {
514,045!
UNCOV
1062
    return 0;
×
1063
  }
1064

1065
  return pResInfo->pCol[columnIndex].offset;
514,045✔
1066
}
1067

1068
int taos_is_null_by_column(TAOS_RES *res, int columnIndex, bool result[], int *rows) {
×
UNCOV
1069
  if (res == NULL || result == NULL || rows == NULL || *rows <= 0 || columnIndex < 0 || TD_RES_TMQ_META(res) ||
×
1070
      TD_RES_TMQ_RAW(res) || TD_RES_TMQ_BATCH_META(res)) {
×
1071
    return TSDB_CODE_INVALID_PARA;
×
1072
  }
1073

UNCOV
1074
  int32_t numOfFields = taos_num_fields(res);
×
1075
  if (columnIndex >= numOfFields || numOfFields == 0) {
×
UNCOV
1076
    return TSDB_CODE_INVALID_PARA;
×
1077
  }
1078

1079
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
×
1080
  TAOS_FIELD     *pField = &pResInfo->userFields[columnIndex];
×
1081
  SResultColumn  *pCol = &pResInfo->pCol[columnIndex];
×
1082

1083
  if (*rows > pResInfo->numOfRows) {
×
UNCOV
1084
    *rows = pResInfo->numOfRows;
×
1085
  }
UNCOV
1086
  if (IS_VAR_DATA_TYPE(pField->type)) {
×
1087
    for (int i = 0; i < *rows; i++) {
×
UNCOV
1088
      if (pCol->offset[i] == -1) {
×
UNCOV
1089
        result[i] = true;
×
1090
      } else {
1091
        result[i] = false;
×
1092
      }
1093
    }
1094
  } else {
1095
    for (int i = 0; i < *rows; i++) {
×
1096
      if (colDataIsNull_f(pCol->nullbitmap, i)) {
×
UNCOV
1097
        result[i] = true;
×
1098
      } else {
1099
        result[i] = false;
×
1100
      }
1101
    }
1102
  }
1103
  return 0;
×
1104
}
1105

1106
int taos_validate_sql(TAOS *taos, const char *sql) {
×
UNCOV
1107
  TAOS_RES *pObj = taosQueryImpl(taos, sql, true, TD_REQ_FROM_APP);
×
1108

UNCOV
1109
  int code = taos_errno(pObj);
×
1110

UNCOV
1111
  taos_free_result(pObj);
×
UNCOV
1112
  return code;
×
1113
}
1114

1115
void taos_reset_current_db(TAOS *taos) {
×
UNCOV
1116
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
×
UNCOV
1117
  if (pTscObj == NULL) {
×
UNCOV
1118
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
UNCOV
1119
    return;
×
1120
  }
1121

UNCOV
1122
  resetConnectDB(pTscObj);
×
1123

UNCOV
1124
  releaseTscObj(*(int64_t *)taos);
×
1125
}
1126

1127
const char *taos_get_server_info(TAOS *taos) {
124✔
1128
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
124✔
1129
  if (pTscObj == NULL) {
124!
UNCOV
1130
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
UNCOV
1131
    return NULL;
×
1132
  }
1133

1134
  releaseTscObj(*(int64_t *)taos);
124✔
1135

1136
  return pTscObj->sDetailVer;
124✔
1137
}
1138

1139
int taos_get_current_db(TAOS *taos, char *database, int len, int *required) {
4✔
1140
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
4✔
1141
  if (pTscObj == NULL) {
4!
UNCOV
1142
    return TSDB_CODE_TSC_DISCONNECTED;
×
1143
  }
1144

1145
  int code = TSDB_CODE_SUCCESS;
4✔
1146
  (void)taosThreadMutexLock(&pTscObj->mutex);
4✔
1147
  if (database == NULL || len <= 0) {
4!
1148
    if (required != NULL) *required = strlen(pTscObj->db) + 1;
2✔
1149
    TSC_ERR_JRET(TSDB_CODE_INVALID_PARA);
2!
1150
  } else if (len < strlen(pTscObj->db) + 1) {
2✔
1151
    tstrncpy(database, pTscObj->db, len);
1✔
1152
    if (required) *required = strlen(pTscObj->db) + 1;
1!
1153
    TSC_ERR_JRET(TSDB_CODE_INVALID_PARA);
1!
1154
  } else {
1155
    tstrncpy(database, pTscObj->db, len);
1✔
1156
    code = 0;
1✔
1157
  }
1158
_return:
4✔
1159
  (void)taosThreadMutexUnlock(&pTscObj->mutex);
4✔
1160
  releaseTscObj(*(int64_t *)taos);
4✔
1161
  return code;
4✔
1162
}
1163

1164
void destorySqlCallbackWrapper(SSqlCallbackWrapper *pWrapper) {
21,495,180✔
1165
  if (NULL == pWrapper) {
21,495,180✔
1166
    return;
10,786,988✔
1167
  }
1168
  destoryCatalogReq(pWrapper->pCatalogReq);
10,708,192✔
1169
  taosMemoryFree(pWrapper->pCatalogReq);
10,726,270!
1170
  qDestroyParseContext(pWrapper->pParseCtx);
10,737,287✔
1171
  taosMemoryFree(pWrapper);
10,737,221!
1172
}
1173

1174
void destroyCtxInRequest(SRequestObj *pRequest) {
14,427✔
1175
  schedulerFreeJob(&pRequest->body.queryJob, 0);
14,427✔
1176
  qDestroyQuery(pRequest->pQuery);
14,427✔
1177
  pRequest->pQuery = NULL;
14,427✔
1178
  destorySqlCallbackWrapper(pRequest->pWrapper);
14,427✔
1179
  pRequest->pWrapper = NULL;
14,427✔
1180
}
14,427✔
1181

1182
static void doAsyncQueryFromAnalyse(SMetaData *pResultMeta, void *param, int32_t code) {
1,154,244✔
1183
  SSqlCallbackWrapper *pWrapper = (SSqlCallbackWrapper *)param;
1,154,244✔
1184
  SRequestObj         *pRequest = pWrapper->pRequest;
1,154,244✔
1185
  SQuery              *pQuery = pRequest->pQuery;
1,154,244✔
1186

1187
  qDebug("req:0x%" PRIx64 ", start to semantic analysis, QID:0x%" PRIx64, pRequest->self, pRequest->requestId);
1,154,244✔
1188

1189
  int64_t analyseStart = taosGetTimestampUs();
1,154,244✔
1190
  pRequest->metric.ctgCostUs = analyseStart - pRequest->metric.ctgStart;
1,154,244✔
1191
  pWrapper->pParseCtx->parseOnly = pRequest->parseOnly;
1,154,244✔
1192

1193
  if (TSDB_CODE_SUCCESS == code) {
1,154,244✔
1194
    code = qAnalyseSqlSemantic(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
1,154,231✔
1195
  }
1196

1197
  pRequest->metric.analyseCostUs += taosGetTimestampUs() - analyseStart;
1,154,180✔
1198

1199
  if (pRequest->parseOnly) {
1,154,180✔
1200
    (void)memcpy(&pRequest->parseMeta, pResultMeta, sizeof(*pResultMeta));
620✔
1201
    (void)memset(pResultMeta, 0, sizeof(*pResultMeta));
620✔
1202
  }
1203

1204
  handleQueryAnslyseRes(pWrapper, pResultMeta, code);
1,154,180✔
1205
}
1,154,163✔
1206

1207
int32_t cloneCatalogReq(SCatalogReq **ppTarget, SCatalogReq *pSrc) {
514✔
1208
  int32_t      code = TSDB_CODE_SUCCESS;
514✔
1209
  SCatalogReq *pTarget = taosMemoryCalloc(1, sizeof(SCatalogReq));
514!
1210
  if (pTarget == NULL) {
514!
UNCOV
1211
    code = terrno;
×
1212
  } else {
1213
    pTarget->pDbVgroup = taosArrayDup(pSrc->pDbVgroup, NULL);
514✔
1214
    pTarget->pDbCfg = taosArrayDup(pSrc->pDbCfg, NULL);
514✔
1215
    pTarget->pDbInfo = taosArrayDup(pSrc->pDbInfo, NULL);
514✔
1216
    pTarget->pTableMeta = taosArrayDup(pSrc->pTableMeta, NULL);
514✔
1217
    pTarget->pTableHash = taosArrayDup(pSrc->pTableHash, NULL);
514✔
1218
    pTarget->pUdf = taosArrayDup(pSrc->pUdf, NULL);
514✔
1219
    pTarget->pIndex = taosArrayDup(pSrc->pIndex, NULL);
514✔
1220
    pTarget->pUser = taosArrayDup(pSrc->pUser, NULL);
514✔
1221
    pTarget->pTableIndex = taosArrayDup(pSrc->pTableIndex, NULL);
514✔
1222
    pTarget->pTableCfg = taosArrayDup(pSrc->pTableCfg, NULL);
514✔
1223
    pTarget->pTableTag = taosArrayDup(pSrc->pTableTag, NULL);
514✔
1224
    pTarget->pView = taosArrayDup(pSrc->pView, NULL);
514✔
1225
    pTarget->pTableTSMAs = taosArrayDup(pSrc->pTableTSMAs, NULL);
514✔
1226
    pTarget->pTSMAs = taosArrayDup(pSrc->pTSMAs, NULL);
514✔
1227
    pTarget->qNodeRequired = pSrc->qNodeRequired;
514✔
1228
    pTarget->dNodeRequired = pSrc->dNodeRequired;
514✔
1229
    pTarget->svrVerRequired = pSrc->svrVerRequired;
514✔
1230
    pTarget->forceUpdate = pSrc->forceUpdate;
514✔
1231
    pTarget->cloned = true;
514✔
1232

1233
    *ppTarget = pTarget;
514✔
1234
  }
1235

1236
  return code;
514✔
1237
}
1238

1239
void handleSubQueryFromAnalyse(SSqlCallbackWrapper *pWrapper, SMetaData *pResultMeta, SNode *pRoot) {
514✔
1240
  SRequestObj         *pNewRequest = NULL;
514✔
1241
  SSqlCallbackWrapper *pNewWrapper = NULL;
514✔
1242
  int32_t              code = buildPreviousRequest(pWrapper->pRequest, pWrapper->pRequest->sqlstr, &pNewRequest);
514✔
1243
  if (code) {
514!
UNCOV
1244
    handleQueryAnslyseRes(pWrapper, pResultMeta, code);
×
UNCOV
1245
    return;
×
1246
  }
1247

1248
  pNewRequest->pQuery = NULL;
514✔
1249
  code = nodesMakeNode(QUERY_NODE_QUERY, (SNode **)&pNewRequest->pQuery);
514✔
1250
  if (pNewRequest->pQuery) {
514!
1251
    pNewRequest->pQuery->pRoot = pRoot;
514✔
1252
    pRoot = NULL;
514✔
1253
    pNewRequest->pQuery->execStage = QUERY_EXEC_STAGE_ANALYSE;
514✔
1254
  }
1255
  if (TSDB_CODE_SUCCESS == code) {
514!
1256
    code = prepareAndParseSqlSyntax(&pNewWrapper, pNewRequest, false);
514✔
1257
  }
1258
  if (TSDB_CODE_SUCCESS == code) {
514!
1259
    code = cloneCatalogReq(&pNewWrapper->pCatalogReq, pWrapper->pCatalogReq);
514✔
1260
  }
1261
  if (TSDB_CODE_SUCCESS == code) {
514!
1262
    doAsyncQueryFromAnalyse(pResultMeta, pNewWrapper, code);
514✔
1263
    nodesDestroyNode(pRoot);
514✔
1264
  } else {
UNCOV
1265
    handleQueryAnslyseRes(pWrapper, pResultMeta, code);
×
UNCOV
1266
    return;
×
1267
  }
1268
}
1269

1270
void handleQueryAnslyseRes(SSqlCallbackWrapper *pWrapper, SMetaData *pResultMeta, int32_t code) {
1,154,652✔
1271
  SRequestObj *pRequest = pWrapper->pRequest;
1,154,652✔
1272
  SQuery      *pQuery = pRequest->pQuery;
1,154,652✔
1273

1274
  if (code == TSDB_CODE_SUCCESS && pQuery->pPrevRoot) {
1,154,652✔
1275
    SNode *prevRoot = pQuery->pPrevRoot;
514✔
1276
    pQuery->pPrevRoot = NULL;
514✔
1277
    handleSubQueryFromAnalyse(pWrapper, pResultMeta, prevRoot);
514✔
1278
    return;
514✔
1279
  }
1280

1281
  if (code == TSDB_CODE_SUCCESS) {
1,154,138✔
1282
    pRequest->stableQuery = pQuery->stableQuery;
1,082,500✔
1283
    if (pQuery->pRoot) {
1,082,500✔
1284
      pRequest->stmtType = pQuery->pRoot->type;
1,082,492✔
1285
    }
1286

1287
    if (pQuery->haveResultSet) {
1,082,500✔
1288
      code = setResSchemaInfo(&pRequest->body.resInfo, pQuery->pResSchema, pQuery->numOfResCols, pQuery->pResExtSchema, pRequest->isStmtBind);
886,180✔
1289
      setResPrecision(&pRequest->body.resInfo, pQuery->precision);
886,167✔
1290
    }
1291
  }
1292

1293
  if (code == TSDB_CODE_SUCCESS) {
1,154,131✔
1294
    TSWAP(pRequest->dbList, (pQuery)->pDbList);
1,082,429✔
1295
    TSWAP(pRequest->tableList, (pQuery)->pTableList);
1,082,429✔
1296
    TSWAP(pRequest->targetTableList, (pQuery)->pTargetTableList);
1,082,429✔
1297

1298
    launchAsyncQuery(pRequest, pQuery, pResultMeta, pWrapper);
1,082,429✔
1299
  } else {
1300
    destorySqlCallbackWrapper(pWrapper);
71,702✔
1301
    pRequest->pWrapper = NULL;
71,702✔
1302
    qDestroyQuery(pRequest->pQuery);
71,702✔
1303
    pRequest->pQuery = NULL;
71,702✔
1304

1305
    if (NEED_CLIENT_HANDLE_ERROR(code)) {
71,702!
1306
      tscDebug("req:0x%" PRIx64 ", client retry to handle the error, code:%d - %s, tryCount:%d, QID:0x%" PRIx64,
14,158✔
1307
               pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId);
1308
      restartAsyncQuery(pRequest, code);
14,158✔
1309
      return;
14,158✔
1310
    }
1311

1312
    // return to app directly
1313
    tscError("req:0x%" PRIx64 ", error occurs, code:%s, return to user app, QID:0x%" PRIx64, pRequest->self, tstrerror(code),
57,544!
1314
             pRequest->requestId);
1315
    pRequest->code = code;
57,544✔
1316
    returnToUser(pRequest);
57,544✔
1317
  }
1318
}
1319

1320
static int32_t getAllMetaAsync(SSqlCallbackWrapper *pWrapper, catalogCallback fp) {
1,221,682✔
1321
  SRequestConnInfo conn = {.pTrans = pWrapper->pParseCtx->pTransporter,
1,221,682✔
1322
                           .requestId = pWrapper->pParseCtx->requestId,
1,221,682✔
1323
                           .requestObjRefId = pWrapper->pParseCtx->requestRid,
1,221,682✔
1324
                           .mgmtEps = pWrapper->pParseCtx->mgmtEpSet};
1,221,682✔
1325

1326
  pWrapper->pRequest->metric.ctgStart = taosGetTimestampUs();
1,221,682✔
1327

1328
  return catalogAsyncGetAllMeta(pWrapper->pParseCtx->pCatalog, &conn, pWrapper->pCatalogReq, fp, pWrapper,
2,443,475✔
1329
                                &pWrapper->pRequest->body.queryJob);
1,221,763✔
1330
}
1331

1332
static void doAsyncQueryFromParse(SMetaData *pResultMeta, void *param, int32_t code);
1333

1334
static int32_t phaseAsyncQuery(SSqlCallbackWrapper *pWrapper) {
10,719,563✔
1335
  int32_t code = TSDB_CODE_SUCCESS;
10,719,563✔
1336
  switch (pWrapper->pRequest->pQuery->execStage) {
10,719,563!
1337
    case QUERY_EXEC_STAGE_PARSE: {
68,044✔
1338
      // continue parse after get metadata
1339
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromParse);
68,044✔
1340
      break;
68,044✔
1341
    }
1342
    case QUERY_EXEC_STAGE_ANALYSE: {
1,153,693✔
1343
      // analysis after get metadata
1344
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromAnalyse);
1,153,693✔
1345
      break;
1,153,687✔
1346
    }
1347
    case QUERY_EXEC_STAGE_SCHEDULE: {
9,516,323✔
1348
      launchAsyncQuery(pWrapper->pRequest, pWrapper->pRequest->pQuery, NULL, pWrapper);
9,516,323✔
1349
      break;
9,517,442✔
1350
    }
UNCOV
1351
    default:
×
UNCOV
1352
      break;
×
1353
  }
1354
  return code;
10,720,676✔
1355
}
1356

1357
static void doAsyncQueryFromParse(SMetaData *pResultMeta, void *param, int32_t code) {
68,046✔
1358
  SSqlCallbackWrapper *pWrapper = (SSqlCallbackWrapper *)param;
68,046✔
1359
  SRequestObj         *pRequest = pWrapper->pRequest;
68,046✔
1360
  SQuery              *pQuery = pRequest->pQuery;
68,046✔
1361

1362
  pRequest->metric.ctgCostUs += taosGetTimestampUs() - pRequest->metric.ctgStart;
68,046✔
1363
  qDebug("req:0x%" PRIx64 ", start to continue parse, QID:0x%" PRIx64 ", code:%s", pRequest->self, pRequest->requestId,
68,046✔
1364
         tstrerror(code));
1365

1366
  if (code == TSDB_CODE_SUCCESS) {
68,045✔
1367
    // pWrapper->pCatalogReq->forceUpdate = false;
1368
    code = qContinueParseSql(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
67,782✔
1369
  }
1370

1371
  if (TSDB_CODE_SUCCESS == code) {
68,042✔
1372
    code = phaseAsyncQuery(pWrapper);
66,494✔
1373
  }
1374

1375
  if (TSDB_CODE_SUCCESS != code) {
68,040✔
1376
    tscError("req:0x%" PRIx64 ", error happens, code:%d - %s, QID:0x%" PRIx64, pWrapper->pRequest->self, code,
1,549!
1377
             tstrerror(code), pWrapper->pRequest->requestId);
1378
    destorySqlCallbackWrapper(pWrapper);
1,549✔
1379
    pRequest->pWrapper = NULL;
1,549✔
1380
    terrno = code;
1,549✔
1381
    pRequest->code = code;
1,549✔
1382
    doRequestCallback(pRequest, code);
1,549✔
1383
  }
1384
}
68,040✔
1385

UNCOV
1386
void continueInsertFromCsv(SSqlCallbackWrapper *pWrapper, SRequestObj *pRequest) {
×
UNCOV
1387
  int32_t code = qParseSqlSyntax(pWrapper->pParseCtx, &pRequest->pQuery, pWrapper->pCatalogReq);
×
UNCOV
1388
  if (TSDB_CODE_SUCCESS == code) {
×
UNCOV
1389
    code = phaseAsyncQuery(pWrapper);
×
1390
  }
1391

UNCOV
1392
  if (TSDB_CODE_SUCCESS != code) {
×
UNCOV
1393
    tscError("req:0x%" PRIx64 ", error happens, code:%d - %s, QID:0x%" PRIx64, pWrapper->pRequest->self, code,
×
1394
             tstrerror(code), pWrapper->pRequest->requestId);
1395
    destorySqlCallbackWrapper(pWrapper);
×
1396
    pRequest->pWrapper = NULL;
×
1397
    terrno = code;
×
UNCOV
1398
    pRequest->code = code;
×
UNCOV
1399
    doRequestCallback(pRequest, code);
×
1400
  }
UNCOV
1401
}
×
1402

1403
void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param) {
517✔
1404
  int64_t connId = *(int64_t *)taos;
517✔
1405
  tscDebug("taos_query_a start with sql:%s", sql);
517✔
1406
  taosAsyncQueryImpl(connId, sql, fp, param, false, TD_REQ_FROM_APP);
517✔
1407
  tscDebug("taos_query_a end with sql:%s", sql);
517✔
1408
}
517✔
1409

UNCOV
1410
void taos_query_a_with_reqid(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param, int64_t reqid) {
×
UNCOV
1411
  int64_t connId = *(int64_t *)taos;
×
UNCOV
1412
  taosAsyncQueryImplWithReqid(connId, sql, fp, param, false, reqid);
×
UNCOV
1413
}
×
1414

1415
int32_t createParseContext(const SRequestObj *pRequest, SParseContext **pCxt, SSqlCallbackWrapper *pWrapper) {
10,720,206✔
1416
  const STscObj *pTscObj = pRequest->pTscObj;
10,720,206✔
1417

1418
  *pCxt = taosMemoryCalloc(1, sizeof(SParseContext));
10,720,206!
1419
  if (*pCxt == NULL) {
10,728,386!
UNCOV
1420
    return terrno;
×
1421
  }
1422

1423
  **pCxt = (SParseContext){.requestId = pRequest->requestId,
10,728,386✔
1424
                           .requestRid = pRequest->self,
10,728,386✔
1425
                           .acctId = pTscObj->acctId,
10,728,386✔
1426
                           .db = pRequest->pDb,
10,728,386✔
1427
                           .topicQuery = false,
1428
                           .pSql = pRequest->sqlstr,
10,728,386✔
1429
                           .sqlLen = pRequest->sqlLen,
10,728,386✔
1430
                           .pMsg = pRequest->msgBuf,
10,728,386✔
1431
                           .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE,
1432
                           .pTransporter = pTscObj->pAppInfo->pTransporter,
10,728,386✔
1433
                           .pStmtCb = NULL,
1434
                           .pUser = pTscObj->user,
10,728,386✔
1435
                           .pEffectiveUser = pRequest->effectiveUser,
10,728,386✔
1436
                           .isSuperUser = (0 == strcmp(pTscObj->user, TSDB_DEFAULT_USER)),
10,728,386✔
1437
                           .enableSysInfo = pTscObj->sysInfo,
10,728,386✔
1438
                           .async = true,
1439
                           .svrVer = pTscObj->sVer,
10,728,386✔
1440
                           .nodeOffline = (pTscObj->pAppInfo->onlineDnodes < pTscObj->pAppInfo->totalDnodes),
10,728,386✔
1441
                           .allocatorId = pRequest->allocatorRefId,
10,728,386✔
1442
                           .parseSqlFp = clientParseSql,
1443
                           .parseSqlParam = pWrapper,
1444
                           .setQueryFp = setQueryRequest,
1445
                           .timezone = pTscObj->optionInfo.timezone,
10,728,386✔
1446
                           .charsetCxt = pTscObj->optionInfo.charsetCxt,
10,728,386✔
1447
                           .streamRunHistory = pRequest->streamRunHistory};
10,728,386✔
1448
  int8_t biMode = atomic_load_8(&((STscObj *)pTscObj)->biMode);
10,728,386✔
1449
  (*pCxt)->biMode = biMode;
10,717,087✔
1450
  return TSDB_CODE_SUCCESS;
10,717,087✔
1451
}
1452

1453
int32_t prepareAndParseSqlSyntax(SSqlCallbackWrapper **ppWrapper, SRequestObj *pRequest, bool updateMetaForce) {
10,718,138✔
1454
  int32_t              code = TSDB_CODE_SUCCESS;
10,718,138✔
1455
  STscObj             *pTscObj = pRequest->pTscObj;
10,718,138✔
1456
  SSqlCallbackWrapper *pWrapper = taosMemoryCalloc(1, sizeof(SSqlCallbackWrapper));
10,718,138!
1457
  if (pWrapper == NULL) {
10,729,990!
UNCOV
1458
    code = terrno;
×
1459
  } else {
1460
    pWrapper->pRequest = pRequest;
10,729,990✔
1461
    pRequest->pWrapper = pWrapper;
10,729,990✔
1462
    *ppWrapper = pWrapper;
10,729,990✔
1463
  }
1464

1465
  if (TSDB_CODE_SUCCESS == code) {
10,729,990!
1466
    code = createParseContext(pRequest, &pWrapper->pParseCtx, pWrapper);
10,731,649✔
1467
  }
1468

1469
  if (TSDB_CODE_SUCCESS == code) {
10,715,017!
1470
    pWrapper->pParseCtx->mgmtEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
10,717,250✔
1471
    code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pWrapper->pParseCtx->pCatalog);
10,736,848✔
1472
  }
1473

1474
  if (TSDB_CODE_SUCCESS == code && NULL == pRequest->pQuery) {
10,746,260!
1475
    int64_t syntaxStart = taosGetTimestampUs();
10,718,727✔
1476

1477
    pWrapper->pCatalogReq = taosMemoryCalloc(1, sizeof(SCatalogReq));
10,718,727!
1478
    if (pWrapper->pCatalogReq == NULL) {
10,727,814!
UNCOV
1479
      code = terrno;
×
1480
    } else {
1481
      pWrapper->pCatalogReq->forceUpdate = updateMetaForce;
10,727,814✔
1482
      TSC_ERR_RET(qnodeRequired(pRequest, &pWrapper->pCatalogReq->qNodeRequired));
10,727,814!
1483
      code = qParseSqlSyntax(pWrapper->pParseCtx, &pRequest->pQuery, pWrapper->pCatalogReq);
10,724,559✔
1484
    }
1485

1486
    pRequest->metric.parseCostUs += taosGetTimestampUs() - syntaxStart;
10,675,804✔
1487
  }
1488

1489
  return code;
10,696,801✔
1490
}
1491

1492
void doAsyncQuery(SRequestObj *pRequest, bool updateMetaForce) {
10,723,401✔
1493
  SSqlCallbackWrapper *pWrapper = NULL;
10,723,401✔
1494
  int32_t              code = TSDB_CODE_SUCCESS;
10,723,401✔
1495

1496
  if (pRequest->retry++ > REQUEST_TOTAL_EXEC_TIMES) {
10,723,401✔
1497
    code = pRequest->prevCode;
4,720✔
1498
    terrno = code;
4,720✔
1499
    pRequest->code = code;
4,720✔
1500
    tscDebug("req:0x%" PRIx64 ", call sync query cb with code:%s", pRequest->self, tstrerror(code));
4,720✔
1501
    doRequestCallback(pRequest, code);
4,720✔
1502
    return;
4,735✔
1503
  }
1504

1505
  if (TSDB_CODE_SUCCESS == code) {
10,718,681✔
1506
    code = prepareAndParseSqlSyntax(&pWrapper, pRequest, updateMetaForce);
10,717,628✔
1507
  }
1508

1509
  if (TSDB_CODE_SUCCESS == code) {
10,681,914✔
1510
    pRequest->stmtType = pRequest->pQuery->pRoot->type;
10,666,890✔
1511
    code = phaseAsyncQuery(pWrapper);
10,666,890✔
1512
  }
1513

1514
  if (TSDB_CODE_SUCCESS != code) {
10,684,224✔
1515
    tscError("req:0x%" PRIx64 ", error happens, code:%d - %s, QID:0x%" PRIx64, pRequest->self, code, tstrerror(code),
25,985!
1516
             pRequest->requestId);
1517
    destorySqlCallbackWrapper(pWrapper);
25,986✔
1518
    pRequest->pWrapper = NULL;
25,987✔
1519
    qDestroyQuery(pRequest->pQuery);
25,987✔
1520
    pRequest->pQuery = NULL;
25,987✔
1521

1522
    if (NEED_CLIENT_HANDLE_ERROR(code)) {
25,987!
1523
      tscDebug("req:0x%" PRIx64 ", client retry to handle the error, code:%d - %s, tryCount:%d, QID:0x%" PRIx64,
15!
1524
               pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId);
1525
      code = refreshMeta(pRequest->pTscObj, pRequest);
15✔
1526
      if (code != 0) {
15!
1527
        tscWarn("req:0x%" PRIx64 ", refresh meta failed, code:%d - %s, QID:0x%" PRIx64, pRequest->self, code, tstrerror(code),
15!
1528
                pRequest->requestId);
1529
      }
1530
      pRequest->prevCode = code;
15✔
1531
      doAsyncQuery(pRequest, true);
15✔
1532
      return;
15✔
1533
    }
1534

1535
    terrno = code;
25,972✔
1536
    pRequest->code = code;
25,972✔
1537
    doRequestCallback(pRequest, code);
25,972✔
1538
  }
1539
}
1540

1541
void restartAsyncQuery(SRequestObj *pRequest, int32_t code) {
14,427✔
1542
  tscInfo("restart request:%s p:%p", pRequest->sqlstr, pRequest);
14,427!
1543
  SRequestObj *pUserReq = pRequest;
14,427✔
1544
  (void)acquireRequest(pRequest->self);
14,427✔
1545
  while (pUserReq) {
14,451!
1546
    if (pUserReq->self == pUserReq->relation.userRefId || pUserReq->relation.userRefId == 0) {
14,451!
1547
      break;
1548
    } else {
1549
      int64_t nextRefId = pUserReq->relation.nextRefId;
24✔
1550
      (void)releaseRequest(pUserReq->self);
24✔
1551
      if (nextRefId) {
24!
1552
        pUserReq = acquireRequest(nextRefId);
24✔
1553
      }
1554
    }
1555
  }
1556
  bool hasSubRequest = pUserReq != pRequest || pRequest->relation.prevRefId != 0;
14,427!
1557
  if (pUserReq) {
14,427!
1558
    destroyCtxInRequest(pUserReq);
14,427✔
1559
    pUserReq->prevCode = code;
14,427✔
1560
    (void)memset(&pUserReq->relation, 0, sizeof(pUserReq->relation));
14,427✔
1561
  } else {
UNCOV
1562
    tscError("User req is missing");
×
UNCOV
1563
    (void)removeFromMostPrevReq(pRequest);
×
UNCOV
1564
    return;
×
1565
  }
1566
  if (hasSubRequest)
14,427✔
1567
    (void)removeFromMostPrevReq(pRequest);
24✔
1568
  else
1569
    (void)releaseRequest(pUserReq->self);
14,403✔
1570
  doAsyncQuery(pUserReq, true);
14,427✔
1571
}
1572

1573
typedef struct SAsyncFetchParam {
1574
  SRequestObj      *pReq;
1575
  __taos_async_fn_t fp;
1576
  void             *param;
1577
} SAsyncFetchParam;
1578

1579
static int32_t doAsyncFetch(void *pParam) {
934,540✔
1580
  SAsyncFetchParam *param = pParam;
934,540✔
1581
  taosAsyncFetchImpl(param->pReq, param->fp, param->param);
934,540✔
1582
  taosMemoryFree(param);
934,533!
1583
  return TSDB_CODE_SUCCESS;
934,537✔
1584
}
1585

1586
void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
934,513✔
1587
  if (res == NULL || fp == NULL) {
934,513!
UNCOV
1588
    tscError("taos_fetch_rows_a invalid paras");
×
1589
    return;
×
1590
  }
1591
  if (!TD_RES_QUERY(res)) {
934,530!
UNCOV
1592
    tscError("taos_fetch_rows_a res is NULL");
×
UNCOV
1593
    fp(param, res, TSDB_CODE_APP_ERROR);
×
UNCOV
1594
    return;
×
1595
  }
1596

1597
  SRequestObj *pRequest = res;
934,530✔
1598
  if (TSDB_SQL_RETRIEVE_EMPTY_RESULT == pRequest->type) {
934,530✔
1599
    fp(param, res, 0);
5✔
1600
    return;
5✔
1601
  }
1602

1603
  SAsyncFetchParam *pParam = taosMemoryCalloc(1, sizeof(SAsyncFetchParam));
934,525!
1604
  if (!pParam) {
934,531!
1605
    fp(param, res, terrno);
×
1606
    return;
×
1607
  }
1608
  pParam->pReq = pRequest;
934,531✔
1609
  pParam->fp = fp;
934,531✔
1610
  pParam->param = param;
934,531✔
1611
  int32_t code = taosAsyncExec(doAsyncFetch, pParam, NULL);
934,531✔
1612
  if (TSDB_CODE_SUCCESS != code) {
934,538!
UNCOV
1613
    taosMemoryFree(pParam);
×
UNCOV
1614
    fp(param, res, code);
×
UNCOV
1615
    return;
×
1616
  }
1617
}
1618

1619
void taos_fetch_raw_block_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
4✔
1620
  if (res == NULL || fp == NULL) {
4!
UNCOV
1621
    tscError("taos_fetch_raw_block_a invalid paras");
×
1622
    return;
×
1623
  }
1624
  if (!TD_RES_QUERY(res)) {
4!
1625
    tscError("taos_fetch_raw_block_a res is NULL");
×
UNCOV
1626
    return;
×
1627
  }
1628
  SRequestObj    *pRequest = res;
4✔
1629
  SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
4✔
1630

1631
  // set the current block is all consumed
1632
  pResultInfo->convertUcs4 = false;
4✔
1633

1634
  // it is a local executed query, no need to do async fetch
1635
  taos_fetch_rows_a(pRequest, fp, param);
4✔
1636
}
1637

1638
const void *taos_get_raw_block(TAOS_RES *res) {
×
1639
  if (res == NULL) {
×
UNCOV
1640
    tscError("taos_get_raw_block invalid paras");
×
UNCOV
1641
    return NULL;
×
1642
  }
1643
  if (!TD_RES_QUERY(res)) {
×
1644
    tscError("taos_get_raw_block res is NULL");
×
1645
    return NULL;
×
1646
  }
UNCOV
1647
  SRequestObj *pRequest = res;
×
1648

UNCOV
1649
  return pRequest->body.resInfo.pData;
×
1650
}
1651

1652
int taos_get_db_route_info(TAOS *taos, const char *db, TAOS_DB_ROUTE_INFO *dbInfo) {
2✔
1653
  if (NULL == taos) {
2!
1654
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
UNCOV
1655
    return terrno;
×
1656
  }
1657

1658
  if (NULL == db || NULL == dbInfo) {
2!
UNCOV
1659
    tscError("invalid input param, db:%p, dbInfo:%p", db, dbInfo);
×
UNCOV
1660
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1661
    return terrno;
×
1662
  }
1663

1664
  int64_t      connId = *(int64_t *)taos;
2✔
1665
  SRequestObj *pRequest = NULL;
2✔
1666
  char        *sql = "taos_get_db_route_info";
2✔
1667
  int32_t      code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
2✔
1668
  if (code != TSDB_CODE_SUCCESS) {
2!
UNCOV
1669
    terrno = code;
×
UNCOV
1670
    return terrno;
×
1671
  }
1672

1673
  STscObj  *pTscObj = pRequest->pTscObj;
2✔
1674
  SCatalog *pCtg = NULL;
2✔
1675
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
2✔
1676
  if (code != TSDB_CODE_SUCCESS) {
2!
UNCOV
1677
    goto _return;
×
1678
  }
1679

1680
  SRequestConnInfo conn = {
2✔
1681
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
2✔
1682

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

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

1688
  code = catalogGetDBVgInfo(pCtg, &conn, dbFName, dbInfo);
2✔
1689
  if (code) {
2!
UNCOV
1690
    goto _return;
×
1691
  }
1692

1693
_return:
2✔
1694

1695
  terrno = code;
2✔
1696

1697
  destroyRequest(pRequest);
2✔
1698
  return code;
2✔
1699
}
1700

1701
int taos_get_table_vgId(TAOS *taos, const char *db, const char *table, int *vgId) {
200✔
1702
  if (NULL == taos) {
200!
UNCOV
1703
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
UNCOV
1704
    return terrno;
×
1705
  }
1706

1707
  if (NULL == db || NULL == table || NULL == vgId) {
200!
UNCOV
1708
    tscError("invalid input param, db:%p, table:%p, vgId:%p", db, table, vgId);
×
UNCOV
1709
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
UNCOV
1710
    return terrno;
×
1711
  }
1712

1713
  int64_t      connId = *(int64_t *)taos;
200✔
1714
  SRequestObj *pRequest = NULL;
200✔
1715
  char        *sql = "taos_get_table_vgId";
200✔
1716
  int32_t      code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
200✔
1717
  if (code != TSDB_CODE_SUCCESS) {
200!
UNCOV
1718
    return terrno;
×
1719
  }
1720

1721
  pRequest->syncQuery = true;
200✔
1722

1723
  STscObj  *pTscObj = pRequest->pTscObj;
200✔
1724
  SCatalog *pCtg = NULL;
200✔
1725
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
200✔
1726
  if (code != TSDB_CODE_SUCCESS) {
200!
UNCOV
1727
    goto _return;
×
1728
  }
1729

1730
  SRequestConnInfo conn = {
200✔
1731
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
200✔
1732

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

1735
  SName tableName = {0};
200✔
1736
  toName(pTscObj->acctId, db, table, &tableName);
200✔
1737

1738
  SVgroupInfo vgInfo;
1739
  code = catalogGetTableHashVgroup(pCtg, &conn, &tableName, &vgInfo);
200✔
1740
  if (code) {
200!
1741
    goto _return;
×
1742
  }
1743

1744
  *vgId = vgInfo.vgId;
200✔
1745

1746
_return:
200✔
1747

1748
  terrno = code;
200✔
1749

1750
  destroyRequest(pRequest);
200✔
1751
  return code;
200✔
1752
}
1753

1754
int taos_get_tables_vgId(TAOS *taos, const char *db, const char *table[], int tableNum, int *vgId) {
1✔
1755
  if (NULL == taos) {
1!
UNCOV
1756
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
UNCOV
1757
    return terrno;
×
1758
  }
1759

1760
  if (NULL == db || NULL == table || NULL == vgId || tableNum <= 0) {
1!
UNCOV
1761
    tscError("invalid input param, db:%p, table:%p, vgId:%p, tbNum:%d", db, table, vgId, tableNum);
×
UNCOV
1762
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
UNCOV
1763
    return terrno;
×
1764
  }
1765

1766
  int64_t      connId = *(int64_t *)taos;
1✔
1767
  SRequestObj *pRequest = NULL;
1✔
1768
  char        *sql = "taos_get_table_vgId";
1✔
1769
  int32_t      code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
1✔
1770
  if (code != TSDB_CODE_SUCCESS) {
1!
UNCOV
1771
    return terrno;
×
1772
  }
1773

1774
  pRequest->syncQuery = true;
1✔
1775

1776
  STscObj  *pTscObj = pRequest->pTscObj;
1✔
1777
  SCatalog *pCtg = NULL;
1✔
1778
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
1✔
1779
  if (code != TSDB_CODE_SUCCESS) {
1!
UNCOV
1780
    goto _return;
×
1781
  }
1782

1783
  SRequestConnInfo conn = {
1✔
1784
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
1✔
1785

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

1788
  code = catalogGetTablesHashVgId(pCtg, &conn, pTscObj->acctId, db, table, tableNum, vgId);
1✔
1789
  if (code) {
1!
UNCOV
1790
    goto _return;
×
1791
  }
1792

1793
_return:
1✔
1794

1795
  terrno = code;
1✔
1796

1797
  destroyRequest(pRequest);
1✔
1798
  return code;
1✔
1799
}
1800

1801
int taos_load_table_info(TAOS *taos, const char *tableNameList) {
3✔
1802
  if (NULL == taos) {
3!
1803
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
UNCOV
1804
    return terrno;
×
1805
  }
1806

1807
  int64_t       connId = *(int64_t *)taos;
3✔
1808
  const int32_t MAX_TABLE_NAME_LENGTH = 12 * 1024 * 1024;  // 12MB list
3✔
1809
  int32_t       code = 0;
3✔
1810
  SRequestObj  *pRequest = NULL;
3✔
1811
  SCatalogReq   catalogReq = {0};
3✔
1812

1813
  if (NULL == tableNameList) {
3!
UNCOV
1814
    return TSDB_CODE_SUCCESS;
×
1815
  }
1816

1817
  int32_t length = (int32_t)strlen(tableNameList);
3✔
1818
  if (0 == length) {
3!
UNCOV
1819
    return TSDB_CODE_SUCCESS;
×
1820
  } else if (length > MAX_TABLE_NAME_LENGTH) {
3!
1821
    tscError("tableNameList too long, length:%d, maximum allowed:%d", length, MAX_TABLE_NAME_LENGTH);
×
UNCOV
1822
    return TSDB_CODE_TSC_INVALID_OPERATION;
×
1823
  }
1824

1825
  char *sql = "taos_load_table_info";
3✔
1826
  code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
3✔
1827
  if (code != TSDB_CODE_SUCCESS) {
3!
UNCOV
1828
    terrno = code;
×
UNCOV
1829
    goto _return;
×
1830
  }
1831

1832
  pRequest->syncQuery = true;
3✔
1833

1834
  STscObj *pTscObj = pRequest->pTscObj;
3✔
1835
  code = transferTableNameList(tableNameList, pTscObj->acctId, pTscObj->db, &catalogReq.pTableMeta);
3✔
1836
  if (code) {
3!
1837
    goto _return;
×
1838
  }
1839

1840
  SCatalog *pCtg = NULL;
3✔
1841
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
3✔
1842
  if (code != TSDB_CODE_SUCCESS) {
3!
1843
    goto _return;
×
1844
  }
1845

1846
  SRequestConnInfo conn = {
3✔
1847
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
3✔
1848

1849
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
3✔
1850

1851
  code = catalogAsyncGetAllMeta(pCtg, &conn, &catalogReq, syncCatalogFn, pRequest->body.interParam, NULL);
3✔
1852
  if (code) {
3!
UNCOV
1853
    goto _return;
×
1854
  }
1855

1856
  SSyncQueryParam *pParam = pRequest->body.interParam;
3✔
1857
  code = tsem_wait(&pParam->sem);
3✔
1858
  if (code) {
3!
UNCOV
1859
    tscError("tsem wait failed, code:%d - %s", code, tstrerror(code));
×
UNCOV
1860
    goto _return;
×
1861
  }
1862
_return:
3✔
1863
  destoryCatalogReq(&catalogReq);
3✔
1864
  destroyRequest(pRequest);
3✔
1865
  return code;
3✔
1866
}
1867

1868
TAOS_STMT *taos_stmt_init(TAOS *taos) {
491✔
1869
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
491✔
1870
  if (NULL == pObj) {
491!
1871
    tscError("invalid parameter for %s", __FUNCTION__);
×
1872
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1873
    return NULL;
×
1874
  }
1875

1876
  TAOS_STMT *pStmt = stmtInit(pObj, 0, NULL);
491✔
1877
  if (NULL == pStmt) {
491!
1878
    tscError("stmt init failed, errcode:%s", terrstr());
×
1879
  }
1880
  releaseTscObj(*(int64_t *)taos);
491✔
1881

1882
  return pStmt;
491✔
1883
}
1884

UNCOV
1885
TAOS_STMT *taos_stmt_init_with_reqid(TAOS *taos, int64_t reqid) {
×
UNCOV
1886
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
×
UNCOV
1887
  if (NULL == pObj) {
×
UNCOV
1888
    tscError("invalid parameter for %s", __FUNCTION__);
×
1889
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1890
    return NULL;
×
1891
  }
1892

UNCOV
1893
  TAOS_STMT *pStmt = stmtInit(pObj, reqid, NULL);
×
UNCOV
1894
  if (NULL == pStmt) {
×
UNCOV
1895
    tscError("stmt init failed, errcode:%s", terrstr());
×
1896
  }
UNCOV
1897
  releaseTscObj(*(int64_t *)taos);
×
1898

UNCOV
1899
  return pStmt;
×
1900
}
1901

1902
TAOS_STMT *taos_stmt_init_with_options(TAOS *taos, TAOS_STMT_OPTIONS *options) {
76✔
1903
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
76✔
1904
  if (NULL == pObj) {
76!
1905
    tscError("invalid parameter for %s", __FUNCTION__);
×
1906
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1907
    return NULL;
×
1908
  }
1909

1910
  TAOS_STMT *pStmt = stmtInit(pObj, options->reqId, options);
76✔
1911
  if (NULL == pStmt) {
76!
UNCOV
1912
    tscError("stmt init failed, errcode:%s", terrstr());
×
1913
  }
1914
  releaseTscObj(*(int64_t *)taos);
76✔
1915

1916
  return pStmt;
76✔
1917
}
1918

1919
int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length) {
10,561✔
1920
  if (stmt == NULL || sql == NULL) {
10,561!
UNCOV
1921
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
1922
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
1923
    return terrno;
×
1924
  }
1925

1926
  return stmtPrepare(stmt, sql, length);
10,563✔
1927
}
1928

1929
int taos_stmt_set_tbname_tags(TAOS_STMT *stmt, const char *name, TAOS_MULTI_BIND *tags) {
70✔
1930
  if (stmt == NULL || name == NULL) {
70!
UNCOV
1931
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
1932
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
1933
    return terrno;
×
1934
  }
1935

1936
  int32_t code = stmtSetTbName(stmt, name);
70✔
1937
  if (code) {
70✔
1938
    return code;
8✔
1939
  }
1940

1941
  if (tags) {
62!
1942
    return stmtSetTbTags(stmt, tags);
62✔
1943
  }
1944

1945
  return TSDB_CODE_SUCCESS;
×
1946
}
1947

1948
int taos_stmt_set_tbname(TAOS_STMT *stmt, const char *name) {
64,633✔
1949
  if (stmt == NULL || name == NULL) {
64,633!
UNCOV
1950
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
1951
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
1952
    return terrno;
×
1953
  }
1954

1955
  return stmtSetTbName(stmt, name);
64,678✔
1956
}
1957

1958
int taos_stmt_set_tags(TAOS_STMT *stmt, TAOS_MULTI_BIND *tags) {
4✔
1959
  if (stmt == NULL || tags == NULL) {
4!
UNCOV
1960
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
1961
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
1962
    return terrno;
×
1963
  }
1964

1965
  return stmtSetTbTags(stmt, tags);
4✔
1966
}
1967

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

1970
int taos_stmt_get_tag_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields) {
2✔
1971
  if (stmt == NULL || NULL == fieldNum) {
2!
UNCOV
1972
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
1973
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
1974
    return terrno;
×
1975
  }
1976

1977
  return stmtGetTagFields(stmt, fieldNum, fields);
2✔
1978
}
1979

1980
int taos_stmt_get_col_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields) {
151✔
1981
  if (stmt == NULL || NULL == fieldNum) {
151!
UNCOV
1982
    tscError("NULL parameter for %s", __FUNCTION__);
×
1983
    terrno = TSDB_CODE_INVALID_PARA;
×
1984
    return terrno;
×
1985
  }
1986

1987
  return stmtGetColFields(stmt, fieldNum, fields);
151✔
1988
}
1989

1990
// let stmt to reclaim TAOS_FIELD_E that was allocated by `taos_stmt_get_tag_fields`/`taos_stmt_get_col_fields`
1991
void taos_stmt_reclaim_fields(TAOS_STMT *stmt, TAOS_FIELD_E *fields) {
×
1992
  (void)stmt;
UNCOV
1993
  if (!fields) return;
×
UNCOV
1994
  taosMemoryFree(fields);
×
1995
}
1996

1997
int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
91✔
1998
  if (stmt == NULL || bind == NULL) {
91!
1999
    tscError("NULL parameter for %s", __FUNCTION__);
×
2000
    terrno = TSDB_CODE_INVALID_PARA;
×
2001
    return terrno;
×
2002
  }
2003

2004
  if (bind->num > 1) {
91!
2005
    tscError("invalid bind number %d for %s", bind->num, __FUNCTION__);
×
2006
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
2007
    return terrno;
×
2008
  }
2009

2010
  return stmtBindBatch(stmt, bind, -1);
91✔
2011
}
2012

2013
int taos_stmt_bind_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
1,033,793✔
2014
  if (stmt == NULL || bind == NULL) {
1,033,793!
UNCOV
2015
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2016
    terrno = TSDB_CODE_INVALID_PARA;
×
2017
    return terrno;
×
2018
  }
2019

2020
  if (bind->num <= 0 || bind->num > INT16_MAX) {
1,048,754!
UNCOV
2021
    tscError("invalid bind num %d", bind->num);
×
UNCOV
2022
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
UNCOV
2023
    return terrno;
×
2024
  }
2025

2026
  int32_t insert = 0;
1,049,685✔
2027
  int32_t code = stmtIsInsert(stmt, &insert);
1,049,685✔
2028
  if (TSDB_CODE_SUCCESS != code) {
1,061,008!
2029
    tscError("stmt insert failed, errcode:%s", tstrerror(code));
×
UNCOV
2030
    return code;
×
2031
  }
2032
  if (0 == insert && bind->num > 1) {
1,061,008!
2033
    tscError("only one row data allowed for query");
×
2034
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
2035
    return terrno;
×
2036
  }
2037

2038
  return stmtBindBatch(stmt, bind, -1);
1,061,008✔
2039
}
2040

2041
int taos_stmt_bind_single_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int colIdx) {
732✔
2042
  if (stmt == NULL || bind == NULL) {
732!
UNCOV
2043
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2044
    terrno = TSDB_CODE_INVALID_PARA;
×
2045
    return terrno;
×
2046
  }
2047

2048
  if (colIdx < 0) {
732!
UNCOV
2049
    tscError("invalid bind column idx %d", colIdx);
×
UNCOV
2050
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2051
    return terrno;
×
2052
  }
2053

2054
  int32_t insert = 0;
732✔
2055
  int32_t code = stmtIsInsert(stmt, &insert);
732✔
2056
  if (TSDB_CODE_SUCCESS != code) {
732!
2057
    tscError("stmt insert failed, errcode:%s", tstrerror(code));
×
UNCOV
2058
    return code;
×
2059
  }
2060
  if (0 == insert && bind->num > 1) {
732!
UNCOV
2061
    tscError("only one row data allowed for query");
×
UNCOV
2062
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
UNCOV
2063
    return terrno;
×
2064
  }
2065

2066
  return stmtBindBatch(stmt, bind, colIdx);
732✔
2067
}
2068

2069
int taos_stmt_add_batch(TAOS_STMT *stmt) {
993,936✔
2070
  if (stmt == NULL) {
993,936!
UNCOV
2071
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2072
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2073
    return terrno;
×
2074
  }
2075

2076
  return stmtAddBatch(stmt);
993,936✔
2077
}
2078

2079
int taos_stmt_execute(TAOS_STMT *stmt) {
32,714✔
2080
  if (stmt == NULL) {
32,714!
UNCOV
2081
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2082
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2083
    return terrno;
×
2084
  }
2085

2086
  return stmtExec(stmt);
32,714✔
2087
}
2088

2089
int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert) {
6✔
2090
  if (stmt == NULL || insert == NULL) {
6!
UNCOV
2091
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2092
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2093
    return terrno;
×
2094
  }
2095

2096
  return stmtIsInsert(stmt, insert);
6✔
2097
}
2098

UNCOV
2099
int taos_stmt_num_params(TAOS_STMT *stmt, int *nums) {
×
UNCOV
2100
  if (stmt == NULL || nums == NULL) {
×
UNCOV
2101
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2102
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2103
    return terrno;
×
2104
  }
2105

2106
  return stmtGetParamNum(stmt, nums);
×
2107
}
2108

2109
int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) {
902✔
2110
  if (stmt == NULL || type == NULL || NULL == bytes || idx < 0) {
902!
UNCOV
2111
    tscError("invalid parameter for %s", __FUNCTION__);
×
UNCOV
2112
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2113
    return terrno;
×
2114
  }
2115

2116
  return stmtGetParam(stmt, idx, type, bytes);
902✔
2117
}
2118

2119
TAOS_RES *taos_stmt_use_result(TAOS_STMT *stmt) {
2✔
2120
  if (stmt == NULL) {
2!
UNCOV
2121
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2122
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2123
    return NULL;
×
2124
  }
2125

2126
  return stmtUseResult(stmt);
2✔
2127
}
2128

2129
char *taos_stmt_errstr(TAOS_STMT *stmt) { return (char *)stmtErrstr(stmt); }
184✔
2130

2131
int taos_stmt_affected_rows(TAOS_STMT *stmt) {
6✔
2132
  if (stmt == NULL) {
6!
UNCOV
2133
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2134
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2135
    return 0;
×
2136
  }
2137

2138
  return stmtAffectedRows(stmt);
6✔
2139
}
2140

2141
int taos_stmt_affected_rows_once(TAOS_STMT *stmt) {
28✔
2142
  if (stmt == NULL) {
28!
UNCOV
2143
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2144
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2145
    return 0;
×
2146
  }
2147

2148
  return stmtAffectedRowsOnce(stmt);
28✔
2149
}
2150

2151
int taos_stmt_close(TAOS_STMT *stmt) {
557✔
2152
  if (stmt == NULL) {
557!
2153
    tscError("NULL parameter for %s", __FUNCTION__);
×
2154
    terrno = TSDB_CODE_INVALID_PARA;
×
2155
    return terrno;
×
2156
  }
2157

2158
  return stmtClose(stmt);
557✔
2159
}
2160

2161
TAOS_STMT2 *taos_stmt2_init(TAOS *taos, TAOS_STMT2_OPTION *option) {
24✔
2162
  if (NULL == taos) {
24!
UNCOV
2163
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2164
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2165
    return NULL;
×
2166
  }
2167
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
24✔
2168
  if (NULL == pObj) {
24!
2169
    tscError("invalid parameter for %s", __FUNCTION__);
×
UNCOV
2170
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
UNCOV
2171
    return NULL;
×
2172
  }
2173

2174
  TAOS_STMT2 *pStmt = stmtInit2(pObj, option);
24✔
2175

2176
  releaseTscObj(*(int64_t *)taos);
24✔
2177

2178
  return pStmt;
24✔
2179
}
2180

2181
int taos_stmt2_prepare(TAOS_STMT2 *stmt, const char *sql, unsigned long length) {
24✔
2182
  if (stmt == NULL || sql == NULL) {
24!
UNCOV
2183
    tscError("NULL parameter for %s", __FUNCTION__);
×
2184
    terrno = TSDB_CODE_INVALID_PARA;
×
2185
    return terrno;
×
2186
  }
2187

2188
  return stmtPrepare2(stmt, sql, length);
24✔
2189
}
2190

2191
int taos_stmt2_bind_param(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx) {
253✔
2192
  if (stmt == NULL) {
253!
UNCOV
2193
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2194
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2195
    return terrno;
×
2196
  }
2197

2198
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
253✔
2199
  if (atomic_load_8((int8_t *)&pStmt->asyncBindParam.asyncBindNum) > 1) {
253!
UNCOV
2200
    tscError("async bind param is still working, please try again later");
×
UNCOV
2201
    return TSDB_CODE_TSC_STMT_API_ERROR;
×
2202
  }
2203

2204
  if (pStmt->options.asyncExecFn && !pStmt->execSemWaited) {
253!
UNCOV
2205
    if (tsem_wait(&pStmt->asyncExecSem) != 0) {
×
2206
      tscError("wait asyncExecSem failed");
×
2207
    }
2208
    pStmt->execSemWaited = true;
×
2209
  }
2210

2211
  SSHashObj *hashTbnames = tSimpleHashInit(100, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR));
253✔
2212
  if (NULL == hashTbnames) {
253!
2213
    tscError("stmt2 bind failed, %s", tstrerror(terrno));
×
UNCOV
2214
    return terrno;
×
2215
  }
2216

2217
  int32_t code = TSDB_CODE_SUCCESS;
253✔
2218
  for (int i = 0; i < bindv->count; ++i) {
806✔
2219
    if (bindv->tbnames && bindv->tbnames[i]) {
553!
2220
      if (pStmt->sql.stbInterlaceMode) {
553!
2221
        if (tSimpleHashGet(hashTbnames, bindv->tbnames[i], strlen(bindv->tbnames[i])) != NULL) {
553!
UNCOV
2222
          code = terrno = TSDB_CODE_PAR_TBNAME_DUPLICATED;
×
UNCOV
2223
          tscError("stmt2 bind failed, %s %s", tstrerror(terrno), bindv->tbnames[i]);
×
UNCOV
2224
          goto out;
×
2225
        }
2226

2227
        code = tSimpleHashPut(hashTbnames, bindv->tbnames[i], strlen(bindv->tbnames[i]), NULL, 0);
552✔
2228
        if (code) {
553!
UNCOV
2229
          goto out;
×
2230
        }
2231
      }
2232

2233
      code = stmtSetTbName2(stmt, bindv->tbnames[i]);
553✔
2234
      if (code) {
553!
UNCOV
2235
        goto out;
×
2236
      }
2237
    }
2238

2239
    SVCreateTbReq *pCreateTbReq = NULL;
553✔
2240
    if (bindv->tags && bindv->tags[i]) {
553!
UNCOV
2241
      code = stmtSetTbTags2(stmt, bindv->tags[i], &pCreateTbReq);
×
2242
    } else if (pStmt->sql.autoCreateTbl || pStmt->bInfo.needParse) {
553!
UNCOV
2243
      code = stmtCheckTags2(stmt, &pCreateTbReq);
×
2244
    } else {
2245
      pStmt->sql.autoCreateTbl = false;
553✔
2246
    }
2247

2248
    if (code) {
553!
2249
      goto out;
×
2250
    }
2251

2252
    if (bindv->bind_cols && bindv->bind_cols[i]) {
553!
2253
      TAOS_STMT2_BIND *bind = bindv->bind_cols[i];
553✔
2254

2255
      if (bind->num <= 0 || bind->num > INT16_MAX) {
553!
UNCOV
2256
        tscError("invalid bind num %d", bind->num);
×
UNCOV
2257
        code = terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
UNCOV
2258
        goto out;
×
2259
      }
2260

2261
      int32_t insert = 0;
553✔
2262
      (void)stmtIsInsert2(stmt, &insert);
553✔
2263
      if (0 == insert && bind->num > 1) {
553!
UNCOV
2264
        tscError("only one row data allowed for query");
×
UNCOV
2265
        code = terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
2266
        goto out;
×
2267
      }
2268

2269
      code = stmtBindBatch2(stmt, bind, col_idx, pCreateTbReq);
553✔
2270
      if (TSDB_CODE_SUCCESS != code) {
553!
UNCOV
2271
        goto out;
×
2272
      }
2273
    }
2274
  }
2275

2276
out:
253✔
2277
  tSimpleHashCleanup(hashTbnames);
253✔
2278

2279
  return code;
253✔
2280
}
2281

2282
int taos_stmt2_bind_param_a(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx, __taos_async_fn_t fp,
×
2283
                            void *param) {
2284
  if (stmt == NULL || bindv == NULL || fp == NULL) {
×
2285
    terrno = TSDB_CODE_INVALID_PARA;
×
2286
    return terrno;
×
2287
  }
2288

2289
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
×
2290

2291
  ThreadArgs *args = (ThreadArgs *)taosMemoryMalloc(sizeof(ThreadArgs));
×
2292
  args->stmt = stmt;
×
2293
  args->bindv = bindv;
×
2294
  args->col_idx = col_idx;
×
2295
  args->fp = fp;
×
2296
  args->param = param;
×
2297

UNCOV
2298
  (void)taosThreadMutexLock(&(pStmt->asyncBindParam.mutex));
×
UNCOV
2299
  if (atomic_load_8((int8_t *)&pStmt->asyncBindParam.asyncBindNum) > 0) {
×
2300
    (void)taosThreadMutexUnlock(&(pStmt->asyncBindParam.mutex));
×
UNCOV
2301
    tscError("async bind param is still working, please try again later");
×
UNCOV
2302
    return TSDB_CODE_TSC_STMT_API_ERROR;
×
2303
  }
UNCOV
2304
  (void)atomic_add_fetch_8(&pStmt->asyncBindParam.asyncBindNum, 1);
×
2305
  (void)taosThreadMutexUnlock(&(pStmt->asyncBindParam.mutex));
×
2306

2307
  int code_s = taosStmt2AsyncBind(stmtAsyncBindThreadFunc, (void *)args);
×
UNCOV
2308
  if (code_s != TSDB_CODE_SUCCESS) {
×
UNCOV
2309
    (void)taosThreadMutexLock(&(pStmt->asyncBindParam.mutex));
×
UNCOV
2310
    (void)taosThreadCondSignal(&(pStmt->asyncBindParam.waitCond));
×
UNCOV
2311
    (void)atomic_sub_fetch_8(&pStmt->asyncBindParam.asyncBindNum, 1);
×
UNCOV
2312
    (void)taosThreadMutexUnlock(&(pStmt->asyncBindParam.mutex));
×
UNCOV
2313
    tscError("async bind failed, code:%d , %s", code_s, tstrerror(code_s));
×
2314
  }
2315

2316
  return code_s;
×
2317
}
2318

2319
int taos_stmt2_exec(TAOS_STMT2 *stmt, int *affected_rows) {
253✔
2320
  if (stmt == NULL) {
253!
UNCOV
2321
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2322
    terrno = TSDB_CODE_INVALID_PARA;
×
2323
    return terrno;
×
2324
  }
2325

2326
  return stmtExec2(stmt, affected_rows);
253✔
2327
}
2328

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

2336
  return stmtClose2(stmt);
24✔
2337
}
2338

UNCOV
2339
int taos_stmt2_is_insert(TAOS_STMT2 *stmt, int *insert) {
×
2340
  if (stmt == NULL || insert == NULL) {
×
2341
    tscError("NULL parameter for %s", __FUNCTION__);
×
2342
    terrno = TSDB_CODE_INVALID_PARA;
×
2343
    return terrno;
×
2344
  }
2345

UNCOV
2346
  return stmtIsInsert2(stmt, insert);
×
2347
}
2348

2349
int taos_stmt2_get_fields(TAOS_STMT2 *stmt, int *count, TAOS_FIELD_ALL **fields) {
×
UNCOV
2350
  if (stmt == NULL || count == NULL) {
×
UNCOV
2351
    tscError("NULL parameter for %s", __FUNCTION__);
×
2352
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2353
    return terrno;
×
2354
  }
2355

UNCOV
2356
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
×
2357
  if (pStmt->sql.type == 0) {
×
2358
    int isInsert = 0;
×
UNCOV
2359
    (void)stmtIsInsert2(stmt, &isInsert);
×
UNCOV
2360
    if (!isInsert) {
×
2361
      pStmt->sql.type = STMT_TYPE_QUERY;
×
2362
    }
2363
  }
2364
  if (pStmt->sql.type == STMT_TYPE_QUERY) {
×
2365
    return stmtGetParamNum2(stmt, count);
×
2366
  }
2367

2368
  return stmtGetStbColFields2(stmt, count, fields);
×
2369
}
2370

2371
DLL_EXPORT void taos_stmt2_free_fields(TAOS_STMT2 *stmt, TAOS_FIELD_ALL *fields) {
×
2372
  (void)stmt;
UNCOV
2373
  if (!fields) return;
×
UNCOV
2374
  taosMemoryFree(fields);
×
2375
}
2376

UNCOV
2377
TAOS_RES *taos_stmt2_result(TAOS_STMT2 *stmt) {
×
UNCOV
2378
  if (stmt == NULL) {
×
UNCOV
2379
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2380
    terrno = TSDB_CODE_INVALID_PARA;
×
2381
    return NULL;
×
2382
  }
2383

UNCOV
2384
  return stmtUseResult2(stmt);
×
2385
}
2386

UNCOV
2387
char *taos_stmt2_error(TAOS_STMT2 *stmt) { return (char *)stmtErrstr2(stmt); }
×
2388

2389
int taos_set_conn_mode(TAOS *taos, int mode, int value) {
4✔
2390
  if (taos == NULL) {
4!
2391
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2392
    return terrno;
×
2393
  }
2394

2395
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
4✔
2396
  if (NULL == pObj) {
4!
UNCOV
2397
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
UNCOV
2398
    tscError("invalid parameter for %s", __func__);
×
UNCOV
2399
    return terrno;
×
2400
  }
2401
  switch (mode) {
4!
2402
    case TAOS_CONN_MODE_BI:
4✔
2403
      atomic_store_8(&pObj->biMode, value);
4✔
2404
      break;
4✔
UNCOV
2405
    default:
×
UNCOV
2406
      tscError("not supported mode.");
×
UNCOV
2407
      return TSDB_CODE_INVALID_PARA;
×
2408
  }
2409
  return 0;
4✔
2410
}
2411

UNCOV
2412
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