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

taosdata / TDengine / #3616

19 Feb 2025 11:22AM UTC coverage: 63.315% (+0.4%) from 62.953%
#3616

push

travis-ci

web-flow
Merge pull request #29823 from taosdata/feat/TS-5928

fix:[TS-5928]add consumer parameters

148228 of 300186 branches covered (49.38%)

Branch coverage included in aggregate %.

232358 of 300909 relevant lines covered (77.22%)

17990742.15 hits per line

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

60.25
/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
static int32_t sentinel = TSC_VAR_NOT_RELEASE;
39
static int32_t createParseContext(const SRequestObj *pRequest, SParseContext **pCxt, SSqlCallbackWrapper *pWrapper);
40

41
int taos_options(TSDB_OPTION option, const void *arg, ...) {
2,371✔
42
  if (arg == NULL) {
2,371!
43
    return TSDB_CODE_INVALID_PARA;
×
44
  }
45
  static int32_t lock = 0;
46

47
  for (int i = 1; atomic_val_compare_exchange_32(&lock, 0, 1) != 0; ++i) {
2,371!
48
    if (i % 1000 == 0) {
×
49
      (void)sched_yield();
×
50
    }
51
  }
52

53
  int ret = taos_options_imp(option, (const char *)arg);
2,371✔
54
  atomic_store_32(&lock, 0);
2,371✔
55
  return ret;
2,371✔
56
}
57

58
#ifndef WINDOWS
59
static void freeTz(void *p) {
10✔
60
  timezone_t tz = *(timezone_t *)p;
10✔
61
  tzfree(tz);
10✔
62
}
10✔
63

64
int32_t tzInit() {
3,335✔
65
  pTimezoneMap = taosHashInit(0, MurmurHash3_32, false, HASH_ENTRY_LOCK);
3,335✔
66
  if (pTimezoneMap == NULL) {
3,335!
67
    return terrno;
×
68
  }
69
  taosHashSetFreeFp(pTimezoneMap, freeTz);
3,335✔
70

71
  pTimezoneNameMap = taosHashInit(0, taosIntHash_64, false, HASH_ENTRY_LOCK);
3,335✔
72
  if (pTimezoneNameMap == NULL) {
3,335!
73
    return terrno;
×
74
  }
75
  return 0;
3,335✔
76
}
77

78
void tzCleanup() {
3,335✔
79
  taosHashCleanup(pTimezoneMap);
3,335✔
80
  taosHashCleanup(pTimezoneNameMap);
3,335✔
81
}
3,335✔
82

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

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

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

120
END:
10✔
121
  return tz;
17✔
122
}
123
#endif
124

125
static int32_t setConnectionOption(TAOS *taos, TSDB_OPTION_CONNECTION option, const char *val) {
38✔
126
  if (taos == NULL) {
38✔
127
    return terrno = TSDB_CODE_INVALID_PARA;
1✔
128
  }
129

130
#ifdef WINDOWS
131
  if (option == TSDB_OPTION_CONNECTION_TIMEZONE) {
132
    return terrno = TSDB_CODE_NOT_SUPPORTTED_IN_WINDOWS;
133
  }
134
#endif
135

136
  if (option < TSDB_OPTION_CONNECTION_CLEAR || option >= TSDB_MAX_OPTIONS_CONNECTION) {
37!
137
    return terrno = TSDB_CODE_INVALID_PARA;
1✔
138
  }
139

140
  int32_t code = taos_init();
36✔
141
  // initialize global config
142
  if (code != 0) {
36!
143
    return terrno = code;
×
144
  }
145

146
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
36✔
147
  if (NULL == pObj) {
36!
148
    tscError("invalid parameter for %s", __func__);
×
149
    return terrno;
×
150
  }
151

152
  if (option == TSDB_OPTION_CONNECTION_CLEAR) {
36✔
153
    val = NULL;
1✔
154
  }
155

156
  if (option == TSDB_OPTION_CONNECTION_CHARSET || option == TSDB_OPTION_CONNECTION_CLEAR) {
36✔
157
    if (val != NULL) {
8✔
158
      if (!taosValidateEncodec(val)) {
5✔
159
        code = terrno;
1✔
160
        goto END;
1✔
161
      }
162
      void *tmp = taosConvInit(val);
4✔
163
      if (tmp == NULL) {
4✔
164
        code = terrno;
1✔
165
        goto END;
1✔
166
      }
167
      pObj->optionInfo.charsetCxt = tmp;
3✔
168
    } else {
169
      pObj->optionInfo.charsetCxt = NULL;
3✔
170
    }
171
  }
172

173
  if (option == TSDB_OPTION_CONNECTION_TIMEZONE || option == TSDB_OPTION_CONNECTION_CLEAR) {
34✔
174
#ifndef WINDOWS
175
    if (val != NULL) {
19✔
176
      if (val[0] == 0) {
17✔
177
        val = "UTC";
1✔
178
      }
179
      timezone_t tz = setConnnectionTz(val);
17✔
180
      if (tz == NULL) {
17!
181
        code = terrno;
×
182
        goto END;
×
183
      }
184
      pObj->optionInfo.timezone = tz;
17✔
185
    } else {
186
      pObj->optionInfo.timezone = NULL;
2✔
187
    }
188
#endif
189
  }
190

191
  if (option == TSDB_OPTION_CONNECTION_USER_APP || option == TSDB_OPTION_CONNECTION_CLEAR) {
34✔
192
    if (val != NULL) {
5✔
193
      tstrncpy(pObj->optionInfo.userApp, val, sizeof(pObj->optionInfo.userApp));
3✔
194
    } else {
195
      pObj->optionInfo.userApp[0] = 0;
2✔
196
    }
197
  }
198

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

211
END:
27✔
212
  releaseTscObj(*(int64_t *)taos);
36✔
213
  return terrno = code;
36✔
214
}
215

216
int taos_options_connection(TAOS *taos, TSDB_OPTION_CONNECTION option, const void *arg, ...) {
38✔
217
  return setConnectionOption(taos, option, (const char *)arg);
38✔
218
}
219

220
// this function may be called by user or system, or by both simultaneously.
221
void taos_cleanup(void) {
3,351✔
222
  tscDebug("start to cleanup client environment");
3,351✔
223
  if (atomic_val_compare_exchange_32(&sentinel, TSC_VAR_NOT_RELEASE, TSC_VAR_RELEASED) != TSC_VAR_NOT_RELEASE) {
3,351✔
224
    return;
16✔
225
  }
226

227
  monitorClose();
3,335✔
228
  tscStopCrashReport();
3,335✔
229

230
  hbMgrCleanUp();
3,335✔
231

232
  catalogDestroy();
3,335✔
233
  schedulerDestroy();
3,335✔
234

235
  fmFuncMgtDestroy();
3,335✔
236
  qCleanupKeywordsTable();
3,335✔
237

238
  if (TSDB_CODE_SUCCESS != cleanupTaskQueue()) {
3,335!
239
    tscWarn("failed to cleanup task queue");
×
240
  }
241

242
#ifndef WINDOWS
243
  tzCleanup();
3,335✔
244
#endif
245
  tmqMgmtClose();
3,335✔
246

247
  int32_t id = clientReqRefPool;
3,335✔
248
  clientReqRefPool = -1;
3,335✔
249
  taosCloseRef(id);
3,335✔
250

251
  id = clientConnRefPool;
3,335✔
252
  clientConnRefPool = -1;
3,335✔
253
  taosCloseRef(id);
3,335✔
254

255
  nodesDestroyAllocatorSet();
3,335✔
256
  cleanupAppInfo();
3,335✔
257
  rpcCleanup();
3,335✔
258
  tscDebug("rpc cleanup");
3,335✔
259

260
  taosConvDestroy();
3,335✔
261
  DestroyRegexCache();
3,335✔
262

263
  tscInfo("all local resources released");
3,335!
264
  taosCleanupCfg();
3,335✔
265
  taosCloseLog();
3,335✔
266
}
267

268
static setConfRet taos_set_config_imp(const char *config) {
×
269
  setConfRet ret = {SET_CONF_RET_SUCC, {0}};
×
270
  // TODO: need re-implementation
271
  return ret;
×
272
}
273

274
setConfRet taos_set_config(const char *config) {
×
275
  // TODO  pthread_mutex_lock(&setConfMutex);
276
  setConfRet ret = taos_set_config_imp(config);
×
277
  //  pthread_mutex_unlock(&setConfMutex);
278
  return ret;
×
279
}
280

281
TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port) {
14,895✔
282
  tscDebug("try to connect to %s:%u, user:%s db:%s", ip, port, user, db);
14,895✔
283
  if (user == NULL) {
14,897!
284
    user = TSDB_DEFAULT_USER;
×
285
  }
286

287
  if (pass == NULL) {
14,897!
288
    pass = TSDB_DEFAULT_PASS;
×
289
  }
290

291
  STscObj *pObj = NULL;
14,897✔
292
  int32_t  code = taos_connect_internal(ip, user, pass, NULL, db, port, CONN_TYPE__QUERY, &pObj);
14,897✔
293
  if (TSDB_CODE_SUCCESS == code) {
14,897✔
294
    int64_t *rid = taosMemoryCalloc(1, sizeof(int64_t));
14,859!
295
    if (NULL == rid) {
14,859!
296
      tscError("out of memory when taos connect to %s:%u, user:%s db:%s", ip, port, user, db);
×
297
      return NULL;
×
298
    }
299
    *rid = pObj->id;
14,859✔
300
    return (TAOS *)rid;
14,859✔
301
  } else {
302
    terrno = code;
38✔
303
  }
304

305
  return NULL;
38✔
306
}
307

308
int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type) {
220✔
309
  if (taos == NULL) {
220!
310
    terrno = TSDB_CODE_INVALID_PARA;
×
311
    return terrno;
×
312
  }
313

314
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
220✔
315
  if (NULL == pObj) {
220!
316
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
317
    tscError("invalid parameter for %s", __func__);
×
318
    return terrno;
×
319
  }
320

321
  switch (type) {
220!
322
    case TAOS_NOTIFY_PASSVER: {
60✔
323
      TSC_ERR_RET(taosThreadMutexLock(&pObj->mutex));
60!
324
      pObj->passInfo.fp = fp;
60✔
325
      pObj->passInfo.param = param;
60✔
326
      TSC_ERR_RET(taosThreadMutexUnlock(&pObj->mutex));
60!
327
      break;
60✔
328
    }
329
    case TAOS_NOTIFY_WHITELIST_VER: {
10✔
330
      TSC_ERR_RET(taosThreadMutexLock(&pObj->mutex));
10!
331
      pObj->whiteListInfo.fp = fp;
10✔
332
      pObj->whiteListInfo.param = param;
10✔
333
      TSC_ERR_RET(taosThreadMutexUnlock(&pObj->mutex));
10!
334
      break;
10✔
335
    }
336
    case TAOS_NOTIFY_USER_DROPPED: {
150✔
337
      TSC_ERR_RET(taosThreadMutexLock(&pObj->mutex));
150!
338
      pObj->userDroppedInfo.fp = fp;
150✔
339
      pObj->userDroppedInfo.param = param;
150✔
340
      TSC_ERR_RET(taosThreadMutexUnlock(&pObj->mutex));
150!
341
      break;
150✔
342
    }
343
    default: {
×
344
      terrno = TSDB_CODE_INVALID_PARA;
×
345
      releaseTscObj(*(int64_t *)taos);
×
346
      return terrno;
×
347
    }
348
  }
349

350
  releaseTscObj(*(int64_t *)taos);
220✔
351
  return 0;
220✔
352
}
353

354
typedef struct SFetchWhiteListInfo {
355
  int64_t                     connId;
356
  __taos_async_whitelist_fn_t userCbFn;
357
  void                       *userParam;
358
} SFetchWhiteListInfo;
359

360
int32_t fetchWhiteListCallbackFn(void *param, SDataBuf *pMsg, int32_t code) {
10✔
361
  SFetchWhiteListInfo *pInfo = (SFetchWhiteListInfo *)param;
10✔
362
  TAOS                *taos = &pInfo->connId;
10✔
363
  if (code != TSDB_CODE_SUCCESS) {
10!
364
    pInfo->userCbFn(pInfo->userParam, code, taos, 0, NULL);
×
365
    taosMemoryFree(pMsg->pData);
×
366
    taosMemoryFree(pMsg->pEpSet);
×
367
    taosMemoryFree(pInfo);
×
368
    return code;
×
369
  }
370

371
  SGetUserWhiteListRsp wlRsp;
372
  if (TSDB_CODE_SUCCESS != tDeserializeSGetUserWhiteListRsp(pMsg->pData, pMsg->len, &wlRsp)) {
10!
373
    taosMemoryFree(pMsg->pData);
×
374
    taosMemoryFree(pMsg->pEpSet);
×
375
    taosMemoryFree(pInfo);
×
376
    tFreeSGetUserWhiteListRsp(&wlRsp);
×
377
    return terrno;
×
378
  }
379

380
  uint64_t *pWhiteLists = taosMemoryMalloc(wlRsp.numWhiteLists * sizeof(uint64_t));
10!
381
  if (pWhiteLists == NULL) {
10!
382
    taosMemoryFree(pMsg->pData);
×
383
    taosMemoryFree(pMsg->pEpSet);
×
384
    taosMemoryFree(pInfo);
×
385
    tFreeSGetUserWhiteListRsp(&wlRsp);
×
386
    return terrno;
×
387
  }
388

389
  for (int i = 0; i < wlRsp.numWhiteLists; ++i) {
20✔
390
    pWhiteLists[i] = ((uint64_t)wlRsp.pWhiteLists[i].mask << 32) | wlRsp.pWhiteLists[i].ip;
10✔
391
  }
392

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

395
  taosMemoryFree(pWhiteLists);
10!
396
  taosMemoryFree(pMsg->pData);
10!
397
  taosMemoryFree(pMsg->pEpSet);
10!
398
  taosMemoryFree(pInfo);
10!
399
  tFreeSGetUserWhiteListRsp(&wlRsp);
10✔
400
  return code;
10✔
401
}
402

403
void taos_fetch_whitelist_a(TAOS *taos, __taos_async_whitelist_fn_t fp, void *param) {
10✔
404
  if (NULL == taos) {
10!
405
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
406
    return;
×
407
  }
408

409
  int64_t connId = *(int64_t *)taos;
10✔
410

411
  STscObj *pTsc = acquireTscObj(connId);
10✔
412
  if (NULL == pTsc) {
10!
413
    fp(param, TSDB_CODE_TSC_DISCONNECTED, taos, 0, NULL);
×
414
    return;
×
415
  }
416

417
  SGetUserWhiteListReq req;
418
  (void)memcpy(req.user, pTsc->user, TSDB_USER_LEN);
10✔
419
  int32_t msgLen = tSerializeSGetUserWhiteListReq(NULL, 0, &req);
10✔
420
  if (msgLen < 0) {
10!
421
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
422
    releaseTscObj(connId);
×
423
    return;
×
424
  }
425

426
  void *pReq = taosMemoryMalloc(msgLen);
10!
427
  if (pReq == NULL) {
10!
428
    fp(param, terrno, taos, 0, NULL);
×
429
    releaseTscObj(connId);
×
430
    return;
×
431
  }
432

433
  if (tSerializeSGetUserWhiteListReq(pReq, msgLen, &req) < 0) {
10!
434
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
435
    taosMemoryFree(pReq);
×
436
    releaseTscObj(connId);
×
437
    return;
×
438
  }
439

440
  SFetchWhiteListInfo *pParam = taosMemoryMalloc(sizeof(SFetchWhiteListInfo));
10!
441
  if (pParam == NULL) {
10!
442
    fp(param, terrno, taos, 0, NULL);
×
443
    taosMemoryFree(pReq);
×
444
    releaseTscObj(connId);
×
445
    return;
×
446
  }
447

448
  pParam->connId = connId;
10✔
449
  pParam->userCbFn = fp;
10✔
450
  pParam->userParam = param;
10✔
451
  SMsgSendInfo *pSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
10!
452
  if (pSendInfo == NULL) {
10!
453
    fp(param, terrno, taos, 0, NULL);
×
454
    taosMemoryFree(pParam);
×
455
    taosMemoryFree(pReq);
×
456
    releaseTscObj(connId);
×
457
    return;
×
458
  }
459

460
  pSendInfo->msgInfo = (SDataBuf){.pData = pReq, .len = msgLen, .handle = NULL};
10✔
461
  pSendInfo->requestId = generateRequestId();
10✔
462
  pSendInfo->requestObjRefId = 0;
10✔
463
  pSendInfo->param = pParam;
10✔
464
  pSendInfo->fp = fetchWhiteListCallbackFn;
10✔
465
  pSendInfo->msgType = TDMT_MND_GET_USER_WHITELIST;
10✔
466

467
  SEpSet epSet = getEpSet_s(&pTsc->pAppInfo->mgmtEp);
10✔
468
  if (TSDB_CODE_SUCCESS != asyncSendMsgToServer(pTsc->pAppInfo->pTransporter, &epSet, NULL, pSendInfo)) {
10!
469
    tscWarn("failed to async send msg to server");
×
470
  }
471
  releaseTscObj(connId);
10✔
472
  return;
10✔
473
}
474

475
void taos_close_internal(void *taos) {
15,307✔
476
  if (taos == NULL) {
15,307!
477
    return;
×
478
  }
479

480
  STscObj *pTscObj = (STscObj *)taos;
15,307✔
481
  tscDebug("0x%" PRIx64 " try to close connection, numOfReq:%d", pTscObj->id, pTscObj->numOfReqs);
15,307✔
482

483
  if (TSDB_CODE_SUCCESS != taosRemoveRef(clientConnRefPool, pTscObj->id)) {
15,307!
484
    tscError("0x%" PRIx64 " failed to remove ref from conn pool", pTscObj->id);
×
485
  }
486
}
487

488
void taos_close(TAOS *taos) {
15,739✔
489
  if (taos == NULL) {
15,739✔
490
    return;
887✔
491
  }
492

493
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
14,852✔
494
  if (NULL == pObj) {
14,853!
495
    taosMemoryFree(taos);
×
496
    return;
×
497
  }
498

499
  taos_close_internal(pObj);
14,853✔
500
  releaseTscObj(*(int64_t *)taos);
14,852✔
501
  taosMemoryFree(taos);
14,853!
502
}
503

504
int taos_errno(TAOS_RES *res) {
12,184,927✔
505
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
12,184,927!
506
    return terrno;
×
507
  }
508

509
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
12,192,805!
510
    return 0;
141✔
511
  }
512

513
  return ((SRequestObj *)res)->code;
12,192,664✔
514
}
515

516
const char *taos_errstr(TAOS_RES *res) {
93,340✔
517
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
93,340!
518
    return (const char *)tstrerror(terrno);
103✔
519
  }
520

521
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
93,237!
522
    return "success";
×
523
  }
524

525
  SRequestObj *pRequest = (SRequestObj *)res;
93,237✔
526
  if (NULL != pRequest->msgBuf && (strlen(pRequest->msgBuf) > 0 || pRequest->code == TSDB_CODE_RPC_FQDN_ERROR)) {
93,237!
527
    return pRequest->msgBuf;
84,639✔
528
  } else {
529
    return (const char *)tstrerror(pRequest->code);
8,598✔
530
  }
531
}
532

533
void taos_free_result(TAOS_RES *res) {
10,857,759✔
534
  if (NULL == res) {
10,857,759✔
535
    return;
2,120✔
536
  }
537

538
  tscDebug("taos free res %p", res);
10,855,639✔
539

540
  if (TD_RES_QUERY(res)) {
10,862,381✔
541
    SRequestObj *pRequest = (SRequestObj *)res;
10,832,326✔
542
    tscDebug("0x%" PRIx64 " taos_free_result start to free query", pRequest->requestId);
10,832,326✔
543
    destroyRequest(pRequest);
10,832,326✔
544
    return;
10,826,827✔
545
  }
546
  SMqRspObj *pRsp = (SMqRspObj *)res;
30,055✔
547
  if (TD_RES_TMQ(res)) {
30,055✔
548
    tDeleteMqDataRsp(&pRsp->dataRsp);
29,710✔
549
    doFreeReqResultInfo(&pRsp->resInfo);
29,710✔
550
  } else if (TD_RES_TMQ_METADATA(res)) {
345✔
551
    tDeleteSTaosxRsp(&pRsp->dataRsp);
76✔
552
    doFreeReqResultInfo(&pRsp->resInfo);
76✔
553
  } else if (TD_RES_TMQ_META(res)) {
269✔
554
    tDeleteMqMetaRsp(&pRsp->metaRsp);
233✔
555
  } else if (TD_RES_TMQ_BATCH_META(res)) {
36✔
556
    tDeleteMqBatchMetaRsp(&pRsp->batchMetaRsp);
18✔
557
  } else if (TD_RES_TMQ_RAW(res)) {
18!
558
    tDeleteMqRawDataRsp(&pRsp->dataRsp);
18✔
559
  }
560
  taosMemoryFree(pRsp);
30,055!
561
}
562

563
void taos_kill_query(TAOS *taos) {
10✔
564
  if (NULL == taos) {
10✔
565
    return;
5✔
566
  }
567

568
  int64_t  rid = *(int64_t *)taos;
5✔
569
  STscObj *pTscObj = acquireTscObj(rid);
5✔
570
  if (pTscObj) {
5!
571
    stopAllRequests(pTscObj->pRequests);
5✔
572
  }
573
  releaseTscObj(rid);
5✔
574
}
575

576
int taos_field_count(TAOS_RES *res) {
68,202,858✔
577
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
68,202,858!
578
    return 0;
×
579
  }
580

581
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
68,202,968✔
582
  return pResInfo->numOfCols;
68,202,968✔
583
}
584

585
int taos_num_fields(TAOS_RES *res) { return taos_field_count(res); }
48,670,608✔
586

587
TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) {
16,896,779✔
588
  if (taos_num_fields(res) == 0 || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
16,896,779!
589
    return NULL;
132,645✔
590
  }
591

592
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
16,763,994✔
593
  return pResInfo->userFields;
16,763,994✔
594
}
595

596
TAOS_RES *taos_query(TAOS *taos, const char *sql) { return taosQueryImpl(taos, sql, false, TD_REQ_FROM_APP); }
10,711,721✔
597
TAOS_RES *taos_query_with_reqid(TAOS *taos, const char *sql, int64_t reqid) {
×
598
  return taosQueryImplWithReqid(taos, sql, false, reqid);
×
599
}
600

601
TAOS_ROW taos_fetch_row(TAOS_RES *res) {
44,316,921✔
602
  if (res == NULL) {
44,316,921!
603
    return NULL;
×
604
  }
605

606
  if (TD_RES_QUERY(res)) {
44,316,921✔
607
    SRequestObj *pRequest = (SRequestObj *)res;
28,857,731✔
608
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
28,857,731!
609
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0 || pRequest->killed) {
28,857,492✔
610
      return NULL;
321✔
611
    }
612

613
    if (pRequest->inCallback) {
28,856,071!
614
      tscError("can not call taos_fetch_row before query callback ends.");
×
615
      terrno = TSDB_CODE_TSC_INVALID_OPERATION;
×
616
      return NULL;
×
617
    }
618

619
    return doAsyncFetchRows(pRequest, true, true);
28,856,071✔
620
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
15,459,190!
621
    SMqRspObj      *msg = ((SMqRspObj *)res);
15,459,190✔
622
    SReqResultInfo *pResultInfo = NULL;
15,459,190✔
623
    if (msg->resIter == -1) {
15,459,190✔
624
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
29,027!
625
        return NULL;
×
626
      }
627
    } else {
628
      pResultInfo = tmqGetCurResInfo(res);
15,430,163✔
629
    }
630

631
    if (pResultInfo->current < pResultInfo->numOfRows) {
15,459,190✔
632
      doSetOneRowPtr(pResultInfo);
15,125,938✔
633
      pResultInfo->current += 1;
15,125,320✔
634
      return pResultInfo->row;
15,125,320✔
635
    } else {
636
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
333,252✔
637
        return NULL;
29,022✔
638
      }
639

640
      doSetOneRowPtr(pResultInfo);
304,399✔
641
      pResultInfo->current += 1;
304,377✔
642
      return pResultInfo->row;
304,377✔
643
    }
644
  } else if (TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
×
645
    return NULL;
×
646
  } else {
647
    tscError("invalid result passed to taos_fetch_row");
×
648
    terrno = TSDB_CODE_TMQ_INVALID_DATA;
×
649
    return NULL;
×
650
  }
651
}
652

653
int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
15,515,292✔
654
  return taos_print_row_with_size(str, INT32_MAX, row, fields, num_fields);
15,515,292✔
655
}
656
int taos_print_row_with_size(char *str, uint32_t size, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
15,515,235✔
657
  int32_t len = 0;
15,515,235✔
658
  for (int i = 0; i < num_fields; ++i) {
92,873,007✔
659
    if (i > 0 && len < size - 1) {
77,349,275!
660
      str[len++] = ' ';
61,867,033✔
661
    }
662

663
    if (row[i] == NULL) {
77,349,275✔
664
      len += tsnprintf(str + len, size - len, "%s", TSDB_DATA_NULL_STR);
543,348✔
665
      continue;
543,347✔
666
    }
667

668
    switch (fields[i].type) {
76,805,927!
669
      case TSDB_DATA_TYPE_TINYINT:
28,405✔
670
        len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
28,405✔
671
        break;
28,405✔
672

673
      case TSDB_DATA_TYPE_UTINYINT:
27,528✔
674
        len += tsnprintf(str + len, size - len, "%u", *((uint8_t *)row[i]));
27,528✔
675
        break;
27,528✔
676

677
      case TSDB_DATA_TYPE_SMALLINT:
26,491✔
678
        len += tsnprintf(str + len, size - len, "%d", *((int16_t *)row[i]));
26,491✔
679
        break;
26,491✔
680

681
      case TSDB_DATA_TYPE_USMALLINT:
26,228✔
682
        len += tsnprintf(str + len, size - len, "%u", *((uint16_t *)row[i]));
26,228✔
683
        break;
26,228✔
684

685
      case TSDB_DATA_TYPE_INT:
16,421,814✔
686
        len += tsnprintf(str + len, size - len, "%d", *((int32_t *)row[i]));
16,421,814✔
687
        break;
16,423,115✔
688

689
      case TSDB_DATA_TYPE_UINT:
26,248✔
690
        len += tsnprintf(str + len, size - len, "%u", *((uint32_t *)row[i]));
26,248✔
691
        break;
26,248✔
692

693
      case TSDB_DATA_TYPE_BIGINT:
13,982,342✔
694
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
13,982,342✔
695
        break;
13,983,155✔
696

697
      case TSDB_DATA_TYPE_UBIGINT:
25,828✔
698
        len += tsnprintf(str + len, size - len, "%" PRIu64, *((uint64_t *)row[i]));
25,828✔
699
        break;
25,828✔
700

701
      case TSDB_DATA_TYPE_FLOAT: {
28,730✔
702
        float fv = 0;
28,730✔
703
        fv = GET_FLOAT_VAL(row[i]);
28,730✔
704
        len += snprintf(str + len, size - len, "%.*g", FLT_DIG, fv);
28,730✔
705
      } break;
28,730✔
706

707
      case TSDB_DATA_TYPE_DOUBLE: {
8,051,420✔
708
        double dv = 0;
8,051,420✔
709
        dv = GET_DOUBLE_VAL(row[i]);
8,051,420✔
710
        len += snprintf(str + len, size - len, "%.*g", DBL_DIG, dv);
8,051,420✔
711
      } break;
8,051,420✔
712

713
      case TSDB_DATA_TYPE_VARBINARY: {
2✔
714
        void    *data = NULL;
2✔
715
        uint32_t tmp = 0;
2✔
716
        int32_t  charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
2✔
717
        if (taosAscii2Hex(row[i], charLen, &data, &tmp) < 0) {
2!
718
          break;
×
719
        }
720
        uint32_t copyLen = TMIN(size - len - 1, tmp);
2✔
721
        (void)memcpy(str + len, data, copyLen);
2✔
722
        len += copyLen;
2✔
723
        taosMemoryFree(data);
2!
724
      } break;
2✔
725
      case TSDB_DATA_TYPE_BINARY:
17,105,651✔
726
      case TSDB_DATA_TYPE_NCHAR:
727
      case TSDB_DATA_TYPE_GEOMETRY: {
728
        int32_t charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
17,105,651✔
729
        if (fields[i].type == TSDB_DATA_TYPE_BINARY || fields[i].type == TSDB_DATA_TYPE_VARBINARY ||
17,105,651!
730
            fields[i].type == TSDB_DATA_TYPE_GEOMETRY) {
5,457,701✔
731
          if (charLen > fields[i].bytes || charLen < 0) {
11,648,017!
732
            tscError("taos_print_row error binary. charLen:%d, fields[i].bytes:%d", charLen, fields[i].bytes);
×
733
            break;
×
734
          }
735
        } else {
736
          if (charLen > fields[i].bytes * TSDB_NCHAR_SIZE || charLen < 0) {
5,457,634!
737
            tscError("taos_print_row error. charLen:%d, fields[i].bytes:%d", charLen, fields[i].bytes);
1,997!
738
            break;
×
739
          }
740
        }
741

742
        uint32_t copyLen = TMIN(size - len - 1, charLen);
17,104,798✔
743
        (void)memcpy(str + len, row[i], copyLen);
17,104,798✔
744
        len += copyLen;
17,104,798✔
745
      } break;
17,104,798✔
746

747
      case TSDB_DATA_TYPE_TIMESTAMP:
21,028,432✔
748
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
21,028,432✔
749
        break;
21,035,669✔
750

751
      case TSDB_DATA_TYPE_BOOL:
82,178✔
752
        len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
82,178✔
753
      default:
26,808✔
754
        break;
26,808✔
755
    }
756

757
    if (len >= size - 1) {
76,814,425!
758
      break;
×
759
    }
760
  }
761
  if (len < size) {
15,523,732✔
762
    str[len] = 0;
15,514,396✔
763
  }
764

765
  return len;
15,523,732✔
766
}
767

768
int *taos_fetch_lengths(TAOS_RES *res) {
19,942,322✔
769
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
19,942,322!
770
    return NULL;
×
771
  }
772

773
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
19,942,453✔
774
  return pResInfo->length;
19,942,453✔
775
}
776

777
TAOS_ROW *taos_result_block(TAOS_RES *res) {
×
778
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
×
779
    terrno = TSDB_CODE_INVALID_PARA;
×
780
    return NULL;
×
781
  }
782

783
  if (taos_is_update_query(res)) {
×
784
    return NULL;
×
785
  }
786

787
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
×
788
  return &pResInfo->row;
×
789
}
790

791
// todo intergrate with tDataTypes
792
const char *taos_data_type(int type) {
×
793
  switch (type) {
×
794
    case TSDB_DATA_TYPE_NULL:
×
795
      return "TSDB_DATA_TYPE_NULL";
×
796
    case TSDB_DATA_TYPE_BOOL:
×
797
      return "TSDB_DATA_TYPE_BOOL";
×
798
    case TSDB_DATA_TYPE_TINYINT:
×
799
      return "TSDB_DATA_TYPE_TINYINT";
×
800
    case TSDB_DATA_TYPE_SMALLINT:
×
801
      return "TSDB_DATA_TYPE_SMALLINT";
×
802
    case TSDB_DATA_TYPE_INT:
×
803
      return "TSDB_DATA_TYPE_INT";
×
804
    case TSDB_DATA_TYPE_BIGINT:
×
805
      return "TSDB_DATA_TYPE_BIGINT";
×
806
    case TSDB_DATA_TYPE_FLOAT:
×
807
      return "TSDB_DATA_TYPE_FLOAT";
×
808
    case TSDB_DATA_TYPE_DOUBLE:
×
809
      return "TSDB_DATA_TYPE_DOUBLE";
×
810
    case TSDB_DATA_TYPE_VARCHAR:
×
811
      return "TSDB_DATA_TYPE_VARCHAR";
×
812
      //    case TSDB_DATA_TYPE_BINARY:          return "TSDB_DATA_TYPE_VARCHAR";
813
    case TSDB_DATA_TYPE_TIMESTAMP:
×
814
      return "TSDB_DATA_TYPE_TIMESTAMP";
×
815
    case TSDB_DATA_TYPE_NCHAR:
×
816
      return "TSDB_DATA_TYPE_NCHAR";
×
817
    case TSDB_DATA_TYPE_JSON:
×
818
      return "TSDB_DATA_TYPE_JSON";
×
819
    case TSDB_DATA_TYPE_GEOMETRY:
×
820
      return "TSDB_DATA_TYPE_GEOMETRY";
×
821
    case TSDB_DATA_TYPE_UTINYINT:
×
822
      return "TSDB_DATA_TYPE_UTINYINT";
×
823
    case TSDB_DATA_TYPE_USMALLINT:
×
824
      return "TSDB_DATA_TYPE_USMALLINT";
×
825
    case TSDB_DATA_TYPE_UINT:
×
826
      return "TSDB_DATA_TYPE_UINT";
×
827
    case TSDB_DATA_TYPE_UBIGINT:
×
828
      return "TSDB_DATA_TYPE_UBIGINT";
×
829
    case TSDB_DATA_TYPE_VARBINARY:
×
830
      return "TSDB_DATA_TYPE_VARBINARY";
×
831
    case TSDB_DATA_TYPE_DECIMAL:
×
832
      return "TSDB_DATA_TYPE_DECIMAL";
×
833
    case TSDB_DATA_TYPE_BLOB:
×
834
      return "TSDB_DATA_TYPE_BLOB";
×
835
    case TSDB_DATA_TYPE_MEDIUMBLOB:
×
836
      return "TSDB_DATA_TYPE_MEDIUMBLOB";
×
837
    default:
×
838
      return "UNKNOWN";
×
839
  }
840
}
841

842
const char *taos_get_client_info() { return td_version; }
3,738✔
843

844
// return int32_t
845
int taos_affected_rows(TAOS_RES *res) {
1,597,491✔
846
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
1,597,491!
847
      TD_RES_TMQ_BATCH_META(res)) {
1,597,492!
848
    return 0;
×
849
  }
850

851
  SRequestObj    *pRequest = (SRequestObj *)res;
1,597,494✔
852
  SReqResultInfo *pResInfo = &pRequest->body.resInfo;
1,597,494✔
853
  return (int)pResInfo->numOfRows;
1,597,494✔
854
}
855

856
// return int64_t
857
int64_t taos_affected_rows64(TAOS_RES *res) {
125,124✔
858
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
125,124!
859
      TD_RES_TMQ_BATCH_META(res)) {
125,124!
860
    return 0;
×
861
  }
862

863
  SRequestObj    *pRequest = (SRequestObj *)res;
125,124✔
864
  SReqResultInfo *pResInfo = &pRequest->body.resInfo;
125,124✔
865
  return pResInfo->numOfRows;
125,124✔
866
}
867

868
int taos_result_precision(TAOS_RES *res) {
16,429,173✔
869
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
16,429,173!
870
    return TSDB_TIME_PRECISION_MILLI;
×
871
  }
872

873
  if (TD_RES_QUERY(res)) {
16,429,238✔
874
    SRequestObj *pRequest = (SRequestObj *)res;
997,484✔
875
    return pRequest->body.resInfo.precision;
997,484✔
876
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
15,431,754!
877
    SReqResultInfo *info = tmqGetCurResInfo(res);
15,431,754✔
878
    return info->precision;
15,431,754✔
879
  }
880
  return TSDB_TIME_PRECISION_MILLI;
×
881
}
882

883
int taos_select_db(TAOS *taos, const char *db) {
372✔
884
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
372✔
885
  if (pObj == NULL) {
372!
886
    releaseTscObj(*(int64_t *)taos);
×
887
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
888
    return TSDB_CODE_TSC_DISCONNECTED;
×
889
  }
890

891
  if (db == NULL || strlen(db) == 0) {
372!
892
    releaseTscObj(*(int64_t *)taos);
×
893
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
894
    return terrno;
×
895
  }
896

897
  char sql[256] = {0};
372✔
898
  (void)snprintf(sql, tListLen(sql), "use %s", db);
372✔
899

900
  TAOS_RES *pRequest = taos_query(taos, sql);
372✔
901
  int32_t   code = taos_errno(pRequest);
372✔
902

903
  taos_free_result(pRequest);
372✔
904
  releaseTscObj(*(int64_t *)taos);
372✔
905
  return code;
372✔
906
}
907

908
void taos_stop_query(TAOS_RES *res) {
10,842,284✔
909
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
10,842,284!
910
      TD_RES_TMQ_BATCH_META(res)) {
10,850,876!
911
    return;
×
912
  }
913

914
  stopAllQueries((SRequestObj *)res);
10,851,422✔
915
}
916

917
bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) {
312,941,248✔
918
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
312,941,248!
919
    return true;
×
920
  }
921
  SReqResultInfo *pResultInfo = tscGetCurResInfo(res);
312,941,281✔
922
  if (col >= pResultInfo->numOfCols || col < 0 || row >= pResultInfo->numOfRows || row < 0) {
312,941,281!
923
    return true;
×
924
  }
925

926
  SResultColumn *pCol = &pResultInfo->pCol[col];
312,941,295✔
927
  if (IS_VAR_DATA_TYPE(pResultInfo->fields[col].type)) {
312,941,295✔
928
    return (pCol->offset[row] == -1);
31✔
929
  } else {
930
    return colDataIsNull_f(pCol->nullbitmap, row);
312,941,264✔
931
  }
932
}
933

934
bool taos_is_update_query(TAOS_RES *res) { return taos_num_fields(res) == 0; }
×
935

936
int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
1,277,255✔
937
  int32_t numOfRows = 0;
1,277,255✔
938
  /*int32_t code = */ terrno = taos_fetch_block_s(res, &numOfRows, rows);
1,277,255✔
939
  return numOfRows;
1,277,255✔
940
}
941

942
int taos_fetch_block_s(TAOS_RES *res, int *numOfRows, TAOS_ROW *rows) {
1,277,255✔
943
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
1,277,255!
944
    return 0;
×
945
  }
946

947
  if (TD_RES_QUERY(res)) {
1,277,255✔
948
    SRequestObj *pRequest = (SRequestObj *)res;
1,273,345✔
949

950
    (*rows) = NULL;
1,273,345✔
951
    (*numOfRows) = 0;
1,273,345✔
952

953
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
1,273,345!
954
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
1,270,847!
955
      return pRequest->code;
6,269✔
956
    }
957

958
    (void)doAsyncFetchRows(pRequest, false, true);
1,267,076✔
959

960
    // TODO refactor
961
    SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
1,267,075✔
962
    pResultInfo->current = pResultInfo->numOfRows;
1,267,075✔
963

964
    (*rows) = pResultInfo->row;
1,267,075✔
965
    (*numOfRows) = pResultInfo->numOfRows;
1,267,075✔
966
    return pRequest->code;
1,267,075✔
967
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
3,910!
968
    SReqResultInfo *pResultInfo = NULL;
3,910✔
969
    int32_t         code = tmqGetNextResInfo(res, true, &pResultInfo);
3,910✔
970
    if (code != 0) return code;
3,910✔
971

972
    pResultInfo->current = pResultInfo->numOfRows;
3,234✔
973
    (*rows) = pResultInfo->row;
3,234✔
974
    (*numOfRows) = pResultInfo->numOfRows;
3,234✔
975
    return 0;
3,234✔
976
  } else {
977
    tscError("taos_fetch_block_s invalid res type");
×
978
    return TSDB_CODE_TMQ_INVALID_DATA;
×
979
  }
980
}
981

982
int taos_fetch_raw_block(TAOS_RES *res, int *numOfRows, void **pData) {
8✔
983
  *numOfRows = 0;
8✔
984
  *pData = NULL;
8✔
985

986
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
8!
987
    return 0;
×
988
  }
989

990
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
8!
991
    SReqResultInfo *pResultInfo = NULL;
×
992
    int32_t         code = tmqGetNextResInfo(res, false, &pResultInfo);
×
993
    if (code != 0) {
×
994
      (*numOfRows) = 0;
×
995
      return 0;
×
996
    }
997

998
    pResultInfo->current = pResultInfo->numOfRows;
×
999
    (*numOfRows) = pResultInfo->numOfRows;
×
1000
    (*pData) = (void *)pResultInfo->pData;
×
1001
    return 0;
×
1002
  }
1003

1004
  SRequestObj *pRequest = (SRequestObj *)res;
8✔
1005

1006
  if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
8!
1007
      pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
8!
1008
    return pRequest->code;
×
1009
  }
1010

1011
  (void)doAsyncFetchRows(pRequest, false, false);
8✔
1012

1013
  SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
8✔
1014

1015
  pResultInfo->current = pResultInfo->numOfRows;
8✔
1016
  (*numOfRows) = pResultInfo->numOfRows;
8✔
1017
  (*pData) = (void *)pResultInfo->pData;
8✔
1018

1019
  return pRequest->code;
8✔
1020
}
1021

1022
int *taos_get_column_data_offset(TAOS_RES *res, int columnIndex) {
526,957✔
1023
  if (res == NULL || TD_RES_TMQ_RAW(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
526,957!
1024
    return 0;
×
1025
  }
1026

1027
  int32_t numOfFields = taos_num_fields(res);
526,957✔
1028
  if (columnIndex < 0 || columnIndex >= numOfFields || numOfFields == 0) {
526,957!
1029
    return 0;
×
1030
  }
1031

1032
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
526,957✔
1033
  TAOS_FIELD     *pField = &pResInfo->userFields[columnIndex];
526,957✔
1034
  if (!IS_VAR_DATA_TYPE(pField->type)) {
526,957!
1035
    return 0;
×
1036
  }
1037

1038
  return pResInfo->pCol[columnIndex].offset;
526,957✔
1039
}
1040

1041
int taos_is_null_by_column(TAOS_RES *res, int columnIndex, bool result[], int *rows) {
×
1042
  if (res == NULL || result == NULL || rows == NULL || *rows <= 0 || columnIndex < 0 || TD_RES_TMQ_META(res) ||
×
1043
      TD_RES_TMQ_RAW(res) || TD_RES_TMQ_BATCH_META(res)) {
×
1044
    return TSDB_CODE_INVALID_PARA;
×
1045
  }
1046

1047
  int32_t numOfFields = taos_num_fields(res);
×
1048
  if (columnIndex >= numOfFields || numOfFields == 0) {
×
1049
    return TSDB_CODE_INVALID_PARA;
×
1050
  }
1051

1052
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
×
1053
  TAOS_FIELD     *pField = &pResInfo->userFields[columnIndex];
×
1054
  SResultColumn  *pCol = &pResInfo->pCol[columnIndex];
×
1055

1056
  if (*rows > pResInfo->numOfRows) {
×
1057
    *rows = pResInfo->numOfRows;
×
1058
  }
1059
  if (IS_VAR_DATA_TYPE(pField->type)) {
×
1060
    for (int i = 0; i < *rows; i++) {
×
1061
      if (pCol->offset[i] == -1) {
×
1062
        result[i] = true;
×
1063
      } else {
1064
        result[i] = false;
×
1065
      }
1066
    }
1067
  } else {
1068
    for (int i = 0; i < *rows; i++) {
×
1069
      if (colDataIsNull_f(pCol->nullbitmap, i)) {
×
1070
        result[i] = true;
×
1071
      } else {
1072
        result[i] = false;
×
1073
      }
1074
    }
1075
  }
1076
  return 0;
×
1077
}
1078

1079
int taos_validate_sql(TAOS *taos, const char *sql) {
×
1080
  TAOS_RES *pObj = taosQueryImpl(taos, sql, true, TD_REQ_FROM_APP);
×
1081

1082
  int code = taos_errno(pObj);
×
1083

1084
  taos_free_result(pObj);
×
1085
  return code;
×
1086
}
1087

1088
void taos_reset_current_db(TAOS *taos) {
×
1089
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
×
1090
  if (pTscObj == NULL) {
×
1091
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1092
    return;
×
1093
  }
1094

1095
  resetConnectDB(pTscObj);
×
1096

1097
  releaseTscObj(*(int64_t *)taos);
×
1098
}
1099

1100
const char *taos_get_server_info(TAOS *taos) {
93✔
1101
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
93✔
1102
  if (pTscObj == NULL) {
93!
1103
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1104
    return NULL;
×
1105
  }
1106

1107
  releaseTscObj(*(int64_t *)taos);
93✔
1108

1109
  return pTscObj->sDetailVer;
93✔
1110
}
1111

1112
int taos_get_current_db(TAOS *taos, char *database, int len, int *required) {
4✔
1113
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
4✔
1114
  if (pTscObj == NULL) {
4!
1115
    return TSDB_CODE_TSC_DISCONNECTED;
×
1116
  }
1117

1118
  int code = TSDB_CODE_SUCCESS;
4✔
1119
  (void)taosThreadMutexLock(&pTscObj->mutex);
4✔
1120
  if (database == NULL || len <= 0) {
4!
1121
    if (required != NULL) *required = strlen(pTscObj->db) + 1;
2✔
1122
    TSC_ERR_JRET(TSDB_CODE_INVALID_PARA);
2!
1123
  } else if (len < strlen(pTscObj->db) + 1) {
2✔
1124
    tstrncpy(database, pTscObj->db, len);
1✔
1125
    if (required) *required = strlen(pTscObj->db) + 1;
1!
1126
    TSC_ERR_JRET(TSDB_CODE_INVALID_PARA);
1!
1127
  } else {
1128
    tstrncpy(database, pTscObj->db, len);
1✔
1129
    code = 0;
1✔
1130
  }
1131
_return:
4✔
1132
  (void)taosThreadMutexUnlock(&pTscObj->mutex);
4✔
1133
  releaseTscObj(*(int64_t *)taos);
4✔
1134
  return code;
4✔
1135
}
1136

1137
void destorySqlCallbackWrapper(SSqlCallbackWrapper *pWrapper) {
21,547,984✔
1138
  if (NULL == pWrapper) {
21,547,984✔
1139
    return;
10,848,352✔
1140
  }
1141
  destoryCatalogReq(pWrapper->pCatalogReq);
10,699,632✔
1142
  taosMemoryFree(pWrapper->pCatalogReq);
10,719,137!
1143
  qDestroyParseContext(pWrapper->pParseCtx);
10,738,415✔
1144
  taosMemoryFree(pWrapper);
10,736,983!
1145
}
1146

1147
void destroyCtxInRequest(SRequestObj *pRequest) {
16,587✔
1148
  schedulerFreeJob(&pRequest->body.queryJob, 0);
16,587✔
1149
  qDestroyQuery(pRequest->pQuery);
16,587✔
1150
  pRequest->pQuery = NULL;
16,587✔
1151
  destorySqlCallbackWrapper(pRequest->pWrapper);
16,587✔
1152
  pRequest->pWrapper = NULL;
16,587✔
1153
}
16,587✔
1154

1155
static void doAsyncQueryFromAnalyse(SMetaData *pResultMeta, void *param, int32_t code) {
1,190,992✔
1156
  SSqlCallbackWrapper *pWrapper = (SSqlCallbackWrapper *)param;
1,190,992✔
1157
  SRequestObj         *pRequest = pWrapper->pRequest;
1,190,992✔
1158
  SQuery              *pQuery = pRequest->pQuery;
1,190,992✔
1159

1160
  qDebug("0x%" PRIx64 " start to semantic analysis,QID:0x%" PRIx64, pRequest->self, pRequest->requestId);
1,190,992✔
1161

1162
  int64_t analyseStart = taosGetTimestampUs();
1,190,992✔
1163
  pRequest->metric.ctgCostUs = analyseStart - pRequest->metric.ctgStart;
1,190,992✔
1164
  pWrapper->pParseCtx->parseOnly = pRequest->parseOnly;
1,190,992✔
1165

1166
  if (TSDB_CODE_SUCCESS == code) {
1,190,992✔
1167
    code = qAnalyseSqlSemantic(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
1,190,989✔
1168
  }
1169

1170
  pRequest->metric.analyseCostUs += taosGetTimestampUs() - analyseStart;
1,190,954✔
1171

1172
  if (pRequest->parseOnly) {
1,190,954✔
1173
    (void)memcpy(&pRequest->parseMeta, pResultMeta, sizeof(*pResultMeta));
624✔
1174
    (void)memset(pResultMeta, 0, sizeof(*pResultMeta));
624✔
1175
  }
1176

1177
  handleQueryAnslyseRes(pWrapper, pResultMeta, code);
1,190,954✔
1178
}
1,190,911✔
1179

1180
int32_t cloneCatalogReq(SCatalogReq **ppTarget, SCatalogReq *pSrc) {
524✔
1181
  int32_t      code = TSDB_CODE_SUCCESS;
524✔
1182
  SCatalogReq *pTarget = taosMemoryCalloc(1, sizeof(SCatalogReq));
524!
1183
  if (pTarget == NULL) {
524!
1184
    code = terrno;
×
1185
  } else {
1186
    pTarget->pDbVgroup = taosArrayDup(pSrc->pDbVgroup, NULL);
524✔
1187
    pTarget->pDbCfg = taosArrayDup(pSrc->pDbCfg, NULL);
524✔
1188
    pTarget->pDbInfo = taosArrayDup(pSrc->pDbInfo, NULL);
524✔
1189
    pTarget->pTableMeta = taosArrayDup(pSrc->pTableMeta, NULL);
524✔
1190
    pTarget->pTableHash = taosArrayDup(pSrc->pTableHash, NULL);
524✔
1191
    pTarget->pUdf = taosArrayDup(pSrc->pUdf, NULL);
524✔
1192
    pTarget->pIndex = taosArrayDup(pSrc->pIndex, NULL);
524✔
1193
    pTarget->pUser = taosArrayDup(pSrc->pUser, NULL);
524✔
1194
    pTarget->pTableIndex = taosArrayDup(pSrc->pTableIndex, NULL);
524✔
1195
    pTarget->pTableCfg = taosArrayDup(pSrc->pTableCfg, NULL);
524✔
1196
    pTarget->pTableTag = taosArrayDup(pSrc->pTableTag, NULL);
524✔
1197
    pTarget->pView = taosArrayDup(pSrc->pView, NULL);
524✔
1198
    pTarget->pTableTSMAs = taosArrayDup(pSrc->pTableTSMAs, NULL);
524✔
1199
    pTarget->pTSMAs = taosArrayDup(pSrc->pTSMAs, NULL);
524✔
1200
    pTarget->qNodeRequired = pSrc->qNodeRequired;
524✔
1201
    pTarget->dNodeRequired = pSrc->dNodeRequired;
524✔
1202
    pTarget->svrVerRequired = pSrc->svrVerRequired;
524✔
1203
    pTarget->forceUpdate = pSrc->forceUpdate;
524✔
1204
    pTarget->cloned = true;
524✔
1205

1206
    *ppTarget = pTarget;
524✔
1207
  }
1208

1209
  return code;
524✔
1210
}
1211

1212
void handleSubQueryFromAnalyse(SSqlCallbackWrapper *pWrapper, SMetaData *pResultMeta, SNode *pRoot) {
524✔
1213
  SRequestObj         *pNewRequest = NULL;
524✔
1214
  SSqlCallbackWrapper *pNewWrapper = NULL;
524✔
1215
  int32_t              code = buildPreviousRequest(pWrapper->pRequest, pWrapper->pRequest->sqlstr, &pNewRequest);
524✔
1216
  if (code) {
524!
1217
    handleQueryAnslyseRes(pWrapper, pResultMeta, code);
×
1218
    return;
×
1219
  }
1220

1221
  pNewRequest->pQuery = NULL;
524✔
1222
  code = nodesMakeNode(QUERY_NODE_QUERY, (SNode **)&pNewRequest->pQuery);
524✔
1223
  if (pNewRequest->pQuery) {
524!
1224
    pNewRequest->pQuery->pRoot = pRoot;
524✔
1225
    pRoot = NULL;
524✔
1226
    pNewRequest->pQuery->execStage = QUERY_EXEC_STAGE_ANALYSE;
524✔
1227
  }
1228
  if (TSDB_CODE_SUCCESS == code) {
524!
1229
    code = prepareAndParseSqlSyntax(&pNewWrapper, pNewRequest, false);
524✔
1230
  }
1231
  if (TSDB_CODE_SUCCESS == code) {
524!
1232
    code = cloneCatalogReq(&pNewWrapper->pCatalogReq, pWrapper->pCatalogReq);
524✔
1233
  }
1234
  if (TSDB_CODE_SUCCESS == code) {
524!
1235
    doAsyncQueryFromAnalyse(pResultMeta, pNewWrapper, code);
524✔
1236
    nodesDestroyNode(pRoot);
524✔
1237
  } else {
1238
    handleQueryAnslyseRes(pWrapper, pResultMeta, code);
×
1239
    return;
×
1240
  }
1241
}
1242

1243
void handleQueryAnslyseRes(SSqlCallbackWrapper *pWrapper, SMetaData *pResultMeta, int32_t code) {
1,191,435✔
1244
  SRequestObj *pRequest = pWrapper->pRequest;
1,191,435✔
1245
  SQuery      *pQuery = pRequest->pQuery;
1,191,435✔
1246

1247
  if (code == TSDB_CODE_SUCCESS && pQuery->pPrevRoot) {
1,191,435✔
1248
    SNode *prevRoot = pQuery->pPrevRoot;
524✔
1249
    pQuery->pPrevRoot = NULL;
524✔
1250
    handleSubQueryFromAnalyse(pWrapper, pResultMeta, prevRoot);
524✔
1251
    return;
524✔
1252
  }
1253

1254
  if (code == TSDB_CODE_SUCCESS) {
1,190,911✔
1255
    pRequest->stableQuery = pQuery->stableQuery;
1,111,837✔
1256
    if (pQuery->pRoot) {
1,111,837!
1257
      pRequest->stmtType = pQuery->pRoot->type;
1,111,843✔
1258
    }
1259

1260
    if (pQuery->haveResultSet) {
1,111,837✔
1261
      code = setResSchemaInfo(&pRequest->body.resInfo, pQuery->pResSchema, pQuery->numOfResCols);
909,724✔
1262
      setResPrecision(&pRequest->body.resInfo, pQuery->precision);
909,722✔
1263
    }
1264
  }
1265

1266
  if (code == TSDB_CODE_SUCCESS) {
1,190,930✔
1267
    TSWAP(pRequest->dbList, (pQuery)->pDbList);
1,111,811✔
1268
    TSWAP(pRequest->tableList, (pQuery)->pTableList);
1,111,811✔
1269
    TSWAP(pRequest->targetTableList, (pQuery)->pTargetTableList);
1,111,811✔
1270

1271
    launchAsyncQuery(pRequest, pQuery, pResultMeta, pWrapper);
1,111,811✔
1272
  } else {
1273
    destorySqlCallbackWrapper(pWrapper);
79,119✔
1274
    pRequest->pWrapper = NULL;
79,119✔
1275
    qDestroyQuery(pRequest->pQuery);
79,119✔
1276
    pRequest->pQuery = NULL;
79,119✔
1277

1278
    if (NEED_CLIENT_HANDLE_ERROR(code)) {
79,119!
1279
      tscDebug("0x%" PRIx64 " client retry to handle the error, code:%d - %s, tryCount:%d,QID:0x%" PRIx64,
16,278✔
1280
               pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId);
1281
      restartAsyncQuery(pRequest, code);
16,278✔
1282
      return;
16,278✔
1283
    }
1284

1285
    // return to app directly
1286
    tscError("0x%" PRIx64 " error occurs, code:%s, return to user app,QID:0x%" PRIx64, pRequest->self, tstrerror(code),
62,841!
1287
             pRequest->requestId);
1288
    pRequest->code = code;
62,841✔
1289
    returnToUser(pRequest);
62,841✔
1290
  }
1291
}
1292

1293
static int32_t getAllMetaAsync(SSqlCallbackWrapper *pWrapper, catalogCallback fp) {
1,233,432✔
1294
  SRequestConnInfo conn = {.pTrans = pWrapper->pParseCtx->pTransporter,
1,233,432✔
1295
                           .requestId = pWrapper->pParseCtx->requestId,
1,233,432✔
1296
                           .requestObjRefId = pWrapper->pParseCtx->requestRid,
1,233,432✔
1297
                           .mgmtEps = pWrapper->pParseCtx->mgmtEpSet};
1,233,432✔
1298

1299
  pWrapper->pRequest->metric.ctgStart = taosGetTimestampUs();
1,233,432✔
1300

1301
  return catalogAsyncGetAllMeta(pWrapper->pParseCtx->pCatalog, &conn, pWrapper->pCatalogReq, fp, pWrapper,
2,466,980✔
1302
                                &pWrapper->pRequest->body.queryJob);
1,233,500✔
1303
}
1304

1305
static void doAsyncQueryFromParse(SMetaData *pResultMeta, void *param, int32_t code);
1306

1307
static int32_t phaseAsyncQuery(SSqlCallbackWrapper *pWrapper) {
10,669,244✔
1308
  int32_t code = TSDB_CODE_SUCCESS;
10,669,244✔
1309
  switch (pWrapper->pRequest->pQuery->execStage) {
10,669,244!
1310
    case QUERY_EXEC_STAGE_PARSE: {
43,043✔
1311
      // continue parse after get metadata
1312
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromParse);
43,043✔
1313
      break;
43,043✔
1314
    }
1315
    case QUERY_EXEC_STAGE_ANALYSE: {
1,190,436✔
1316
      // analysis after get metadata
1317
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromAnalyse);
1,190,436✔
1318
      break;
1,190,430✔
1319
    }
1320
    case QUERY_EXEC_STAGE_SCHEDULE: {
9,453,196✔
1321
      launchAsyncQuery(pWrapper->pRequest, pWrapper->pRequest->pQuery, NULL, pWrapper);
9,453,196✔
1322
      break;
9,464,660✔
1323
    }
1324
    default:
×
1325
      break;
×
1326
  }
1327
  return code;
10,680,702✔
1328
}
1329

1330
static void doAsyncQueryFromParse(SMetaData *pResultMeta, void *param, int32_t code) {
43,046✔
1331
  SSqlCallbackWrapper *pWrapper = (SSqlCallbackWrapper *)param;
43,046✔
1332
  SRequestObj         *pRequest = pWrapper->pRequest;
43,046✔
1333
  SQuery              *pQuery = pRequest->pQuery;
43,046✔
1334

1335
  pRequest->metric.ctgCostUs += taosGetTimestampUs() - pRequest->metric.ctgStart;
43,046✔
1336
  qDebug("0x%" PRIx64 " start to continue parse,QID:0x%" PRIx64 ", code:%s", pRequest->self, pRequest->requestId,
43,046✔
1337
         tstrerror(code));
1338

1339
  if (code == TSDB_CODE_SUCCESS) {
43,046✔
1340
    // pWrapper->pCatalogReq->forceUpdate = false;
1341
    code = qContinueParseSql(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
42,796✔
1342
  }
1343

1344
  if (TSDB_CODE_SUCCESS == code) {
43,044✔
1345
    code = phaseAsyncQuery(pWrapper);
42,142✔
1346
  }
1347

1348
  if (TSDB_CODE_SUCCESS != code) {
43,043✔
1349
    tscError("0x%" PRIx64 " error happens, code:%d - %s,QID:0x%" PRIx64, pWrapper->pRequest->self, code,
902!
1350
             tstrerror(code), pWrapper->pRequest->requestId);
1351
    destorySqlCallbackWrapper(pWrapper);
902✔
1352
    pRequest->pWrapper = NULL;
902✔
1353
    terrno = code;
902✔
1354
    pRequest->code = code;
902✔
1355
    doRequestCallback(pRequest, code);
902✔
1356
  }
1357
}
43,043✔
1358

1359
void continueInsertFromCsv(SSqlCallbackWrapper *pWrapper, SRequestObj *pRequest) {
×
1360
  int32_t code = qParseSqlSyntax(pWrapper->pParseCtx, &pRequest->pQuery, pWrapper->pCatalogReq);
×
1361
  if (TSDB_CODE_SUCCESS == code) {
×
1362
    code = phaseAsyncQuery(pWrapper);
×
1363
  }
1364

1365
  if (TSDB_CODE_SUCCESS != code) {
×
1366
    tscError("0x%" PRIx64 " error happens, code:%d - %s,QID:0x%" PRIx64, pWrapper->pRequest->self, code,
×
1367
             tstrerror(code), pWrapper->pRequest->requestId);
1368
    destorySqlCallbackWrapper(pWrapper);
×
1369
    pRequest->pWrapper = NULL;
×
1370
    terrno = code;
×
1371
    pRequest->code = code;
×
1372
    doRequestCallback(pRequest, code);
×
1373
  }
1374
}
×
1375

1376
void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param) {
516✔
1377
  int64_t connId = *(int64_t *)taos;
516✔
1378
  tscDebug("taos_query_a start with sql:%s", sql);
516✔
1379
  taosAsyncQueryImpl(connId, sql, fp, param, false, TD_REQ_FROM_APP);
516✔
1380
  tscDebug("taos_query_a end with sql:%s", sql);
516✔
1381
}
516✔
1382

1383
void taos_query_a_with_reqid(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param, int64_t reqid) {
×
1384
  int64_t connId = *(int64_t *)taos;
×
1385
  taosAsyncQueryImplWithReqid(connId, sql, fp, param, false, reqid);
×
1386
}
×
1387

1388
int32_t createParseContext(const SRequestObj *pRequest, SParseContext **pCxt, SSqlCallbackWrapper *pWrapper) {
10,722,590✔
1389
  const STscObj *pTscObj = pRequest->pTscObj;
10,722,590✔
1390

1391
  *pCxt = taosMemoryCalloc(1, sizeof(SParseContext));
10,722,590!
1392
  if (*pCxt == NULL) {
10,722,844!
1393
    return terrno;
×
1394
  }
1395

1396
  **pCxt = (SParseContext){.requestId = pRequest->requestId,
10,722,844✔
1397
                           .requestRid = pRequest->self,
10,722,844✔
1398
                           .acctId = pTscObj->acctId,
10,722,844✔
1399
                           .db = pRequest->pDb,
10,722,844✔
1400
                           .topicQuery = false,
1401
                           .pSql = pRequest->sqlstr,
10,722,844✔
1402
                           .sqlLen = pRequest->sqlLen,
10,722,844✔
1403
                           .pMsg = pRequest->msgBuf,
10,722,844✔
1404
                           .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE,
1405
                           .pTransporter = pTscObj->pAppInfo->pTransporter,
10,722,844✔
1406
                           .pStmtCb = NULL,
1407
                           .pUser = pTscObj->user,
10,722,844✔
1408
                           .pEffectiveUser = pRequest->effectiveUser,
10,722,844✔
1409
                           .isSuperUser = (0 == strcmp(pTscObj->user, TSDB_DEFAULT_USER)),
10,722,844✔
1410
                           .enableSysInfo = pTscObj->sysInfo,
10,722,844✔
1411
                           .async = true,
1412
                           .svrVer = pTscObj->sVer,
10,722,844✔
1413
                           .nodeOffline = (pTscObj->pAppInfo->onlineDnodes < pTscObj->pAppInfo->totalDnodes),
10,722,844✔
1414
                           .allocatorId = pRequest->allocatorRefId,
10,722,844✔
1415
                           .parseSqlFp = clientParseSql,
1416
                           .parseSqlParam = pWrapper,
1417
                           .setQueryFp = setQueryRequest,
1418
                           .timezone = pTscObj->optionInfo.timezone,
10,722,844✔
1419
                           .charsetCxt = pTscObj->optionInfo.charsetCxt};
10,722,844✔
1420
  int8_t biMode = atomic_load_8(&((STscObj *)pTscObj)->biMode);
10,722,844✔
1421
  (*pCxt)->biMode = biMode;
10,682,370✔
1422
  return TSDB_CODE_SUCCESS;
10,682,370✔
1423
}
1424

1425
int32_t prepareAndParseSqlSyntax(SSqlCallbackWrapper **ppWrapper, SRequestObj *pRequest, bool updateMetaForce) {
10,712,751✔
1426
  int32_t              code = TSDB_CODE_SUCCESS;
10,712,751✔
1427
  STscObj             *pTscObj = pRequest->pTscObj;
10,712,751✔
1428
  SSqlCallbackWrapper *pWrapper = taosMemoryCalloc(1, sizeof(SSqlCallbackWrapper));
10,712,751!
1429
  if (pWrapper == NULL) {
10,731,098!
1430
    code = terrno;
×
1431
  } else {
1432
    pWrapper->pRequest = pRequest;
10,731,098✔
1433
    pRequest->pWrapper = pWrapper;
10,731,098✔
1434
    *ppWrapper = pWrapper;
10,731,098✔
1435
  }
1436

1437
  if (TSDB_CODE_SUCCESS == code) {
10,731,098!
1438
    code = createParseContext(pRequest, &pWrapper->pParseCtx, pWrapper);
10,732,169✔
1439
  }
1440

1441
  if (TSDB_CODE_SUCCESS == code) {
10,680,890!
1442
    pWrapper->pParseCtx->mgmtEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
10,682,161✔
1443
    code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pWrapper->pParseCtx->pCatalog);
10,740,612✔
1444
  }
1445

1446
  if (TSDB_CODE_SUCCESS == code && NULL == pRequest->pQuery) {
10,714,227✔
1447
    int64_t syntaxStart = taosGetTimestampUs();
10,701,158✔
1448

1449
    pWrapper->pCatalogReq = taosMemoryCalloc(1, sizeof(SCatalogReq));
10,701,158!
1450
    if (pWrapper->pCatalogReq == NULL) {
10,731,953!
1451
      code = terrno;
×
1452
    } else {
1453
      pWrapper->pCatalogReq->forceUpdate = updateMetaForce;
10,731,953✔
1454
      TSC_ERR_RET(qnodeRequired(pRequest, &pWrapper->pCatalogReq->qNodeRequired));
10,731,953!
1455
      code = qParseSqlSyntax(pWrapper->pParseCtx, &pRequest->pQuery, pWrapper->pCatalogReq);
10,729,710✔
1456
    }
1457

1458
    pRequest->metric.parseCostUs += taosGetTimestampUs() - syntaxStart;
10,645,304✔
1459
  }
1460

1461
  return code;
10,659,281✔
1462
}
1463

1464
void doAsyncQuery(SRequestObj *pRequest, bool updateMetaForce) {
10,718,970✔
1465
  SSqlCallbackWrapper *pWrapper = NULL;
10,718,970✔
1466
  int32_t              code = TSDB_CODE_SUCCESS;
10,718,970✔
1467

1468
  if (pRequest->retry++ > REQUEST_TOTAL_EXEC_TIMES) {
10,718,970✔
1469
    code = pRequest->prevCode;
5,427✔
1470
    terrno = code;
5,427✔
1471
    pRequest->code = code;
5,427✔
1472
    tscDebug("call sync query cb with code: %s", tstrerror(code));
5,427✔
1473
    doRequestCallback(pRequest, code);
5,427✔
1474
    return;
5,539✔
1475
  }
1476

1477
  if (TSDB_CODE_SUCCESS == code) {
10,713,543!
1478
    code = prepareAndParseSqlSyntax(&pWrapper, pRequest, updateMetaForce);
10,718,451✔
1479
  }
1480

1481
  if (TSDB_CODE_SUCCESS == code) {
10,653,721✔
1482
    pRequest->stmtType = pRequest->pQuery->pRoot->type;
10,639,810✔
1483
    code = phaseAsyncQuery(pWrapper);
10,639,810✔
1484
  }
1485

1486
  if (TSDB_CODE_SUCCESS != code) {
10,672,135✔
1487
    tscError("0x%" PRIx64 " error happens, code:%d - %s,QID:0x%" PRIx64, pRequest->self, code, tstrerror(code),
27,112!
1488
             pRequest->requestId);
1489
    destorySqlCallbackWrapper(pWrapper);
27,112✔
1490
    pRequest->pWrapper = NULL;
27,112✔
1491
    qDestroyQuery(pRequest->pQuery);
27,112✔
1492
    pRequest->pQuery = NULL;
27,112✔
1493

1494
    if (NEED_CLIENT_HANDLE_ERROR(code)) {
27,112!
1495
      tscDebug("0x%" PRIx64 " client retry to handle the error, code:%d - %s, tryCount:%d,QID:0x%" PRIx64,
112!
1496
               pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId);
1497
      code = refreshMeta(pRequest->pTscObj, pRequest);
112✔
1498
      if (code != 0) {
112!
1499
        tscWarn("0x%" PRIx64 " refresh meta failed, code:%d - %s,QID:0x%" PRIx64, pRequest->self, code, tstrerror(code),
112!
1500
                pRequest->requestId);
1501
      }
1502
      pRequest->prevCode = code;
112✔
1503
      doAsyncQuery(pRequest, true);
112✔
1504
      return;
112✔
1505
    }
1506

1507
    terrno = code;
27,000✔
1508
    pRequest->code = code;
27,000✔
1509
    doRequestCallback(pRequest, code);
27,000✔
1510
  }
1511
}
1512

1513
void restartAsyncQuery(SRequestObj *pRequest, int32_t code) {
16,587✔
1514
  tscInfo("restart request: %s p: %p", pRequest->sqlstr, pRequest);
16,587!
1515
  SRequestObj *pUserReq = pRequest;
16,587✔
1516
  (void)acquireRequest(pRequest->self);
16,587✔
1517
  while (pUserReq) {
16,610!
1518
    if (pUserReq->self == pUserReq->relation.userRefId || pUserReq->relation.userRefId == 0) {
16,610!
1519
      break;
1520
    } else {
1521
      int64_t nextRefId = pUserReq->relation.nextRefId;
23✔
1522
      (void)releaseRequest(pUserReq->self);
23✔
1523
      if (nextRefId) {
23!
1524
        pUserReq = acquireRequest(nextRefId);
23✔
1525
      }
1526
    }
1527
  }
1528
  bool hasSubRequest = pUserReq != pRequest || pRequest->relation.prevRefId != 0;
16,587!
1529
  if (pUserReq) {
16,587!
1530
    destroyCtxInRequest(pUserReq);
16,587✔
1531
    pUserReq->prevCode = code;
16,587✔
1532
    (void)memset(&pUserReq->relation, 0, sizeof(pUserReq->relation));
16,587✔
1533
  } else {
1534
    tscError("User req is missing");
×
1535
    (void)removeFromMostPrevReq(pRequest);
×
1536
    return;
×
1537
  }
1538
  if (hasSubRequest)
16,587✔
1539
    (void)removeFromMostPrevReq(pRequest);
23✔
1540
  else
1541
    (void)releaseRequest(pUserReq->self);
16,564✔
1542
  doAsyncQuery(pUserReq, true);
16,587✔
1543
}
1544

1545
typedef struct SAsyncFetchParam {
1546
  SRequestObj      *pReq;
1547
  __taos_async_fn_t fp;
1548
  void             *param;
1549
} SAsyncFetchParam;
1550

1551
static int32_t doAsyncFetch(void *pParam) {
987,264✔
1552
  SAsyncFetchParam *param = pParam;
987,264✔
1553
  taosAsyncFetchImpl(param->pReq, param->fp, param->param);
987,264✔
1554
  taosMemoryFree(param);
987,259!
1555
  return TSDB_CODE_SUCCESS;
987,261✔
1556
}
1557

1558
void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
987,260✔
1559
  if (res == NULL || fp == NULL) {
987,260!
1560
    tscError("taos_fetch_rows_a invalid paras");
×
1561
    return;
×
1562
  }
1563
  if (!TD_RES_QUERY(res)) {
987,267!
1564
    tscError("taos_fetch_rows_a res is NULL");
×
1565
    fp(param, res, TSDB_CODE_APP_ERROR);
×
1566
    return;
×
1567
  }
1568

1569
  SRequestObj *pRequest = res;
987,267✔
1570
  if (TSDB_SQL_RETRIEVE_EMPTY_RESULT == pRequest->type) {
987,267✔
1571
    fp(param, res, 0);
10✔
1572
    return;
10✔
1573
  }
1574

1575
  SAsyncFetchParam *pParam = taosMemoryCalloc(1, sizeof(SAsyncFetchParam));
987,257!
1576
  if (!pParam) {
987,258!
1577
    fp(param, res, terrno);
×
1578
    return;
×
1579
  }
1580
  pParam->pReq = pRequest;
987,258✔
1581
  pParam->fp = fp;
987,258✔
1582
  pParam->param = param;
987,258✔
1583
  int32_t code = taosAsyncExec(doAsyncFetch, pParam, NULL);
987,258✔
1584
  if (TSDB_CODE_SUCCESS != code) {
987,260!
1585
    taosMemoryFree(pParam);
×
1586
    fp(param, res, code);
×
1587
    return;
×
1588
  }
1589
}
1590

1591
void taos_fetch_raw_block_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
×
1592
  if (res == NULL || fp == NULL) {
×
1593
    tscError("taos_fetch_raw_block_a invalid paras");
×
1594
    return;
×
1595
  }
1596
  if (!TD_RES_QUERY(res)) {
×
1597
    tscError("taos_fetch_raw_block_a res is NULL");
×
1598
    return;
×
1599
  }
1600
  SRequestObj    *pRequest = res;
×
1601
  SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
×
1602

1603
  // set the current block is all consumed
1604
  pResultInfo->convertUcs4 = false;
×
1605

1606
  // it is a local executed query, no need to do async fetch
1607
  taos_fetch_rows_a(pRequest, fp, param);
×
1608
}
1609

1610
const void *taos_get_raw_block(TAOS_RES *res) {
×
1611
  if (res == NULL) {
×
1612
    tscError("taos_get_raw_block invalid paras");
×
1613
    return NULL;
×
1614
  }
1615
  if (!TD_RES_QUERY(res)) {
×
1616
    tscError("taos_get_raw_block res is NULL");
×
1617
    return NULL;
×
1618
  }
1619
  SRequestObj *pRequest = res;
×
1620

1621
  return pRequest->body.resInfo.pData;
×
1622
}
1623

1624
int taos_get_db_route_info(TAOS *taos, const char *db, TAOS_DB_ROUTE_INFO *dbInfo) {
2✔
1625
  if (NULL == taos) {
2!
1626
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1627
    return terrno;
×
1628
  }
1629

1630
  if (NULL == db || NULL == dbInfo) {
2!
1631
    tscError("invalid input param, db:%p, dbInfo:%p", db, dbInfo);
×
1632
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1633
    return terrno;
×
1634
  }
1635

1636
  int64_t      connId = *(int64_t *)taos;
2✔
1637
  SRequestObj *pRequest = NULL;
2✔
1638
  char        *sql = "taos_get_db_route_info";
2✔
1639
  int32_t      code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
2✔
1640
  if (code != TSDB_CODE_SUCCESS) {
2!
1641
    terrno = code;
×
1642
    return terrno;
×
1643
  }
1644

1645
  STscObj  *pTscObj = pRequest->pTscObj;
2✔
1646
  SCatalog *pCtg = NULL;
2✔
1647
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
2✔
1648
  if (code != TSDB_CODE_SUCCESS) {
2!
1649
    goto _return;
×
1650
  }
1651

1652
  SRequestConnInfo conn = {
2✔
1653
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
2✔
1654

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

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

1660
  code = catalogGetDBVgInfo(pCtg, &conn, dbFName, dbInfo);
2✔
1661
  if (code) {
2!
1662
    goto _return;
×
1663
  }
1664

1665
_return:
2✔
1666

1667
  terrno = code;
2✔
1668

1669
  destroyRequest(pRequest);
2✔
1670
  return code;
2✔
1671
}
1672

1673
int taos_get_table_vgId(TAOS *taos, const char *db, const char *table, int *vgId) {
200✔
1674
  if (NULL == taos) {
200!
1675
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1676
    return terrno;
×
1677
  }
1678

1679
  if (NULL == db || NULL == table || NULL == vgId) {
200!
1680
    tscError("invalid input param, db:%p, table:%p, vgId:%p", db, table, vgId);
×
1681
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1682
    return terrno;
×
1683
  }
1684

1685
  int64_t      connId = *(int64_t *)taos;
200✔
1686
  SRequestObj *pRequest = NULL;
200✔
1687
  char        *sql = "taos_get_table_vgId";
200✔
1688
  int32_t      code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
200✔
1689
  if (code != TSDB_CODE_SUCCESS) {
200!
1690
    return terrno;
×
1691
  }
1692

1693
  pRequest->syncQuery = true;
200✔
1694

1695
  STscObj  *pTscObj = pRequest->pTscObj;
200✔
1696
  SCatalog *pCtg = NULL;
200✔
1697
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
200✔
1698
  if (code != TSDB_CODE_SUCCESS) {
200!
1699
    goto _return;
×
1700
  }
1701

1702
  SRequestConnInfo conn = {
200✔
1703
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
200✔
1704

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

1707
  SName tableName = {0};
200✔
1708
  toName(pTscObj->acctId, db, table, &tableName);
200✔
1709

1710
  SVgroupInfo vgInfo;
1711
  code = catalogGetTableHashVgroup(pCtg, &conn, &tableName, &vgInfo);
200✔
1712
  if (code) {
200!
1713
    goto _return;
×
1714
  }
1715

1716
  *vgId = vgInfo.vgId;
200✔
1717

1718
_return:
200✔
1719

1720
  terrno = code;
200✔
1721

1722
  destroyRequest(pRequest);
200✔
1723
  return code;
200✔
1724
}
1725

1726
int taos_get_tables_vgId(TAOS *taos, const char *db, const char *table[], int tableNum, int *vgId) {
1✔
1727
  if (NULL == taos) {
1!
1728
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1729
    return terrno;
×
1730
  }
1731

1732
  if (NULL == db || NULL == table || NULL == vgId || tableNum <= 0) {
1!
1733
    tscError("invalid input param, db:%p, table:%p, vgId:%p, tbNum:%d", db, table, vgId, tableNum);
×
1734
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1735
    return terrno;
×
1736
  }
1737

1738
  int64_t      connId = *(int64_t *)taos;
1✔
1739
  SRequestObj *pRequest = NULL;
1✔
1740
  char        *sql = "taos_get_table_vgId";
1✔
1741
  int32_t      code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
1✔
1742
  if (code != TSDB_CODE_SUCCESS) {
1!
1743
    return terrno;
×
1744
  }
1745

1746
  pRequest->syncQuery = true;
1✔
1747

1748
  STscObj  *pTscObj = pRequest->pTscObj;
1✔
1749
  SCatalog *pCtg = NULL;
1✔
1750
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
1✔
1751
  if (code != TSDB_CODE_SUCCESS) {
1!
1752
    goto _return;
×
1753
  }
1754

1755
  SRequestConnInfo conn = {
1✔
1756
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
1✔
1757

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

1760
  code = catalogGetTablesHashVgId(pCtg, &conn, pTscObj->acctId, db, table, tableNum, vgId);
1✔
1761
  if (code) {
1!
1762
    goto _return;
×
1763
  }
1764

1765
_return:
1✔
1766

1767
  terrno = code;
1✔
1768

1769
  destroyRequest(pRequest);
1✔
1770
  return code;
1✔
1771
}
1772

1773
int taos_load_table_info(TAOS *taos, const char *tableNameList) {
3✔
1774
  if (NULL == taos) {
3!
1775
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1776
    return terrno;
×
1777
  }
1778

1779
  int64_t       connId = *(int64_t *)taos;
3✔
1780
  const int32_t MAX_TABLE_NAME_LENGTH = 12 * 1024 * 1024;  // 12MB list
3✔
1781
  int32_t       code = 0;
3✔
1782
  SRequestObj  *pRequest = NULL;
3✔
1783
  SCatalogReq   catalogReq = {0};
3✔
1784

1785
  if (NULL == tableNameList) {
3!
1786
    return TSDB_CODE_SUCCESS;
×
1787
  }
1788

1789
  int32_t length = (int32_t)strlen(tableNameList);
3✔
1790
  if (0 == length) {
3!
1791
    return TSDB_CODE_SUCCESS;
×
1792
  } else if (length > MAX_TABLE_NAME_LENGTH) {
3!
1793
    tscError("tableNameList too long, length:%d, maximum allowed:%d", length, MAX_TABLE_NAME_LENGTH);
×
1794
    return TSDB_CODE_TSC_INVALID_OPERATION;
×
1795
  }
1796

1797
  char *sql = "taos_load_table_info";
3✔
1798
  code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
3✔
1799
  if (code != TSDB_CODE_SUCCESS) {
3!
1800
    terrno = code;
×
1801
    goto _return;
×
1802
  }
1803

1804
  pRequest->syncQuery = true;
3✔
1805

1806
  STscObj *pTscObj = pRequest->pTscObj;
3✔
1807
  code = transferTableNameList(tableNameList, pTscObj->acctId, pTscObj->db, &catalogReq.pTableMeta);
3✔
1808
  if (code) {
3!
1809
    goto _return;
×
1810
  }
1811

1812
  SCatalog *pCtg = NULL;
3✔
1813
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
3✔
1814
  if (code != TSDB_CODE_SUCCESS) {
3!
1815
    goto _return;
×
1816
  }
1817

1818
  SRequestConnInfo conn = {
3✔
1819
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
3✔
1820

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

1823
  code = catalogAsyncGetAllMeta(pCtg, &conn, &catalogReq, syncCatalogFn, pRequest->body.interParam, NULL);
3✔
1824
  if (code) {
3!
1825
    goto _return;
×
1826
  }
1827

1828
  SSyncQueryParam *pParam = pRequest->body.interParam;
3✔
1829
  code = tsem_wait(&pParam->sem);
3✔
1830
  if (code) {
3!
1831
    tscError("tsem wait failed, code:%d - %s", code, tstrerror(code));
×
1832
    goto _return;
×
1833
  }
1834
_return:
3✔
1835
  destoryCatalogReq(&catalogReq);
3✔
1836
  destroyRequest(pRequest);
3✔
1837
  return code;
3✔
1838
}
1839

1840
TAOS_STMT *taos_stmt_init(TAOS *taos) {
633✔
1841
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
633✔
1842
  if (NULL == pObj) {
633!
1843
    tscError("invalid parameter for %s", __FUNCTION__);
×
1844
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1845
    return NULL;
×
1846
  }
1847

1848
  TAOS_STMT *pStmt = stmtInit(pObj, 0, NULL);
633✔
1849
  if (NULL == pStmt) {
633!
1850
    tscError("stmt init failed, errcode:%s", terrstr());
×
1851
  }
1852
  releaseTscObj(*(int64_t *)taos);
633✔
1853

1854
  return pStmt;
633✔
1855
}
1856

1857
TAOS_STMT *taos_stmt_init_with_reqid(TAOS *taos, int64_t reqid) {
×
1858
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
×
1859
  if (NULL == pObj) {
×
1860
    tscError("invalid parameter for %s", __FUNCTION__);
×
1861
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1862
    return NULL;
×
1863
  }
1864

1865
  TAOS_STMT *pStmt = stmtInit(pObj, reqid, NULL);
×
1866
  if (NULL == pStmt) {
×
1867
    tscError("stmt init failed, errcode:%s", terrstr());
×
1868
  }
1869
  releaseTscObj(*(int64_t *)taos);
×
1870

1871
  return pStmt;
×
1872
}
1873

1874
TAOS_STMT *taos_stmt_init_with_options(TAOS *taos, TAOS_STMT_OPTIONS *options) {
53✔
1875
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
53✔
1876
  if (NULL == pObj) {
53!
1877
    tscError("invalid parameter for %s", __FUNCTION__);
×
1878
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1879
    return NULL;
×
1880
  }
1881

1882
  TAOS_STMT *pStmt = stmtInit(pObj, options->reqId, options);
53✔
1883
  if (NULL == pStmt) {
53!
1884
    tscError("stmt init failed, errcode:%s", terrstr());
×
1885
  }
1886
  releaseTscObj(*(int64_t *)taos);
53✔
1887

1888
  return pStmt;
53✔
1889
}
1890

1891
int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length) {
1,145✔
1892
  if (stmt == NULL || sql == NULL) {
1,145!
1893
    tscError("NULL parameter for %s", __FUNCTION__);
×
1894
    terrno = TSDB_CODE_INVALID_PARA;
×
1895
    return terrno;
×
1896
  }
1897

1898
  return stmtPrepare(stmt, sql, length);
1,145✔
1899
}
1900

1901
int taos_stmt_set_tbname_tags(TAOS_STMT *stmt, const char *name, TAOS_MULTI_BIND *tags) {
20,030✔
1902
  if (stmt == NULL || name == NULL) {
20,030!
1903
    tscError("NULL parameter for %s", __FUNCTION__);
×
1904
    terrno = TSDB_CODE_INVALID_PARA;
×
1905
    return terrno;
×
1906
  }
1907

1908
  int32_t code = stmtSetTbName(stmt, name);
20,030✔
1909
  if (code) {
20,030!
1910
    return code;
×
1911
  }
1912

1913
  if (tags) {
20,030!
1914
    return stmtSetTbTags(stmt, tags);
20,030✔
1915
  }
1916

1917
  return TSDB_CODE_SUCCESS;
×
1918
}
1919

1920
int taos_stmt_set_tbname(TAOS_STMT *stmt, const char *name) {
106,690✔
1921
  if (stmt == NULL || name == NULL) {
106,690!
1922
    tscError("NULL parameter for %s", __FUNCTION__);
×
1923
    terrno = TSDB_CODE_INVALID_PARA;
×
1924
    return terrno;
×
1925
  }
1926

1927
  return stmtSetTbName(stmt, name);
106,699✔
1928
}
1929

1930
int taos_stmt_set_tags(TAOS_STMT *stmt, TAOS_MULTI_BIND *tags) {
20,104✔
1931
  if (stmt == NULL || tags == NULL) {
20,104!
1932
    tscError("NULL parameter for %s", __FUNCTION__);
×
1933
    terrno = TSDB_CODE_INVALID_PARA;
×
1934
    return terrno;
×
1935
  }
1936

1937
  return stmtSetTbTags(stmt, tags);
20,104✔
1938
}
1939

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

1942
int taos_stmt_get_tag_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields) {
20,104✔
1943
  if (stmt == NULL || NULL == fieldNum) {
20,104!
1944
    tscError("NULL parameter for %s", __FUNCTION__);
×
1945
    terrno = TSDB_CODE_INVALID_PARA;
×
1946
    return terrno;
×
1947
  }
1948

1949
  return stmtGetTagFields(stmt, fieldNum, fields);
20,104✔
1950
}
1951

1952
int taos_stmt_get_col_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields) {
268,568✔
1953
  if (stmt == NULL || NULL == fieldNum) {
268,568!
1954
    tscError("NULL parameter for %s", __FUNCTION__);
×
1955
    terrno = TSDB_CODE_INVALID_PARA;
×
1956
    return terrno;
×
1957
  }
1958

1959
  return stmtGetColFields(stmt, fieldNum, fields);
268,568✔
1960
}
1961

1962
// let stmt to reclaim TAOS_FIELD_E that was allocated by `taos_stmt_get_tag_fields`/`taos_stmt_get_col_fields`
1963
void taos_stmt_reclaim_fields(TAOS_STMT *stmt, TAOS_FIELD_E *fields) {
×
1964
  (void)stmt;
1965
  if (!fields) return;
×
1966
  taosMemoryFree(fields);
×
1967
}
1968

1969
int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
13,915✔
1970
  if (stmt == NULL || bind == NULL) {
13,915!
1971
    tscError("NULL parameter for %s", __FUNCTION__);
×
1972
    terrno = TSDB_CODE_INVALID_PARA;
×
1973
    return terrno;
×
1974
  }
1975

1976
  if (bind->num > 1) {
13,915!
1977
    tscError("invalid bind number %d for %s", bind->num, __FUNCTION__);
×
1978
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
1979
    return terrno;
×
1980
  }
1981

1982
  return stmtBindBatch(stmt, bind, -1);
13,915✔
1983
}
1984

1985
int taos_stmt_bind_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
1,191,505✔
1986
  if (stmt == NULL || bind == NULL) {
1,191,505!
1987
    tscError("NULL parameter for %s", __FUNCTION__);
×
1988
    terrno = TSDB_CODE_INVALID_PARA;
×
1989
    return terrno;
×
1990
  }
1991

1992
  if (bind->num <= 0 || bind->num > INT16_MAX) {
1,192,103!
1993
    tscError("invalid bind num %d", bind->num);
122!
1994
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
122✔
1995
    return terrno;
×
1996
  }
1997

1998
  int32_t insert = 0;
1,191,981✔
1999
  int32_t code = stmtIsInsert(stmt, &insert);
1,191,981✔
2000
  if (TSDB_CODE_SUCCESS != code) {
1,190,748!
2001
    tscError("stmt insert failed, errcode:%s", tstrerror(code));
×
2002
    return code;
×
2003
  }
2004
  if (0 == insert && bind->num > 1) {
1,190,748!
2005
    tscError("only one row data allowed for query");
×
2006
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
2007
    return terrno;
×
2008
  }
2009

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

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

2020
  if (colIdx < 0) {
1,102,302!
2021
    tscError("invalid bind column idx %d", colIdx);
×
2022
    terrno = TSDB_CODE_INVALID_PARA;
×
2023
    return terrno;
×
2024
  }
2025

2026
  int32_t insert = 0;
1,102,302✔
2027
  int32_t code = stmtIsInsert(stmt, &insert);
1,102,302✔
2028
  if (TSDB_CODE_SUCCESS != code) {
1,102,302!
2029
    tscError("stmt insert failed, errcode:%s", tstrerror(code));
×
2030
    return code;
×
2031
  }
2032
  if (0 == insert && bind->num > 1) {
1,102,302!
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, colIdx);
1,102,302✔
2039
}
2040

2041
int taos_stmt_add_batch(TAOS_STMT *stmt) {
1,258,183✔
2042
  if (stmt == NULL) {
1,258,183!
2043
    tscError("NULL parameter for %s", __FUNCTION__);
×
2044
    terrno = TSDB_CODE_INVALID_PARA;
×
2045
    return terrno;
×
2046
  }
2047

2048
  return stmtAddBatch(stmt);
1,258,183✔
2049
}
2050

2051
int taos_stmt_execute(TAOS_STMT *stmt) {
115,405✔
2052
  if (stmt == NULL) {
115,405!
2053
    tscError("NULL parameter for %s", __FUNCTION__);
×
2054
    terrno = TSDB_CODE_INVALID_PARA;
×
2055
    return terrno;
×
2056
  }
2057

2058
  return stmtExec(stmt);
115,405✔
2059
}
2060

2061
int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert) {
23,084✔
2062
  if (stmt == NULL || insert == NULL) {
23,084!
2063
    tscError("NULL parameter for %s", __FUNCTION__);
×
2064
    terrno = TSDB_CODE_INVALID_PARA;
×
2065
    return terrno;
×
2066
  }
2067

2068
  return stmtIsInsert(stmt, insert);
23,084✔
2069
}
2070

2071
int taos_stmt_num_params(TAOS_STMT *stmt, int *nums) {
1,331✔
2072
  if (stmt == NULL || nums == NULL) {
1,331!
2073
    tscError("NULL parameter for %s", __FUNCTION__);
×
2074
    terrno = TSDB_CODE_INVALID_PARA;
×
2075
    return terrno;
×
2076
  }
2077

2078
  return stmtGetParamNum(stmt, nums);
1,331✔
2079
}
2080

2081
int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) {
2,324,538✔
2082
  if (stmt == NULL || type == NULL || NULL == bytes || idx < 0) {
2,324,538!
2083
    tscError("invalid parameter for %s", __FUNCTION__);
×
2084
    terrno = TSDB_CODE_INVALID_PARA;
×
2085
    return terrno;
×
2086
  }
2087

2088
  return stmtGetParam(stmt, idx, type, bytes);
2,324,538✔
2089
}
2090

2091
TAOS_RES *taos_stmt_use_result(TAOS_STMT *stmt) {
21,804✔
2092
  if (stmt == NULL) {
21,804!
2093
    tscError("NULL parameter for %s", __FUNCTION__);
×
2094
    terrno = TSDB_CODE_INVALID_PARA;
×
2095
    return NULL;
×
2096
  }
2097

2098
  return stmtUseResult(stmt);
21,804✔
2099
}
2100

2101
char *taos_stmt_errstr(TAOS_STMT *stmt) { return (char *)stmtErrstr(stmt); }
4✔
2102

2103
int taos_stmt_affected_rows(TAOS_STMT *stmt) {
297✔
2104
  if (stmt == NULL) {
297!
2105
    tscError("NULL parameter for %s", __FUNCTION__);
×
2106
    terrno = TSDB_CODE_INVALID_PARA;
×
2107
    return 0;
×
2108
  }
2109

2110
  return stmtAffectedRows(stmt);
297✔
2111
}
2112

2113
int taos_stmt_affected_rows_once(TAOS_STMT *stmt) {
28✔
2114
  if (stmt == NULL) {
28!
2115
    tscError("NULL parameter for %s", __FUNCTION__);
×
2116
    terrno = TSDB_CODE_INVALID_PARA;
×
2117
    return 0;
×
2118
  }
2119

2120
  return stmtAffectedRowsOnce(stmt);
28✔
2121
}
2122

2123
int taos_stmt_close(TAOS_STMT *stmt) {
685✔
2124
  if (stmt == NULL) {
685!
2125
    tscError("NULL parameter for %s", __FUNCTION__);
×
2126
    terrno = TSDB_CODE_INVALID_PARA;
×
2127
    return terrno;
×
2128
  }
2129

2130
  return stmtClose(stmt);
685✔
2131
}
2132

2133
TAOS_STMT2 *taos_stmt2_init(TAOS *taos, TAOS_STMT2_OPTION *option) {
77✔
2134
  if (NULL == taos) {
77✔
2135
    tscError("NULL parameter for %s", __FUNCTION__);
1!
2136
    terrno = TSDB_CODE_INVALID_PARA;
1✔
2137
    return NULL;
1✔
2138
  }
2139
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
76✔
2140
  if (NULL == pObj) {
76!
2141
    tscError("invalid parameter for %s", __FUNCTION__);
×
2142
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
2143
    return NULL;
×
2144
  }
2145

2146
  TAOS_STMT2 *pStmt = stmtInit2(pObj, option);
76✔
2147

2148
  releaseTscObj(*(int64_t *)taos);
76✔
2149

2150
  return pStmt;
76✔
2151
}
2152

2153
int taos_stmt2_prepare(TAOS_STMT2 *stmt, const char *sql, unsigned long length) {
77✔
2154
  if (stmt == NULL || sql == NULL) {
77!
2155
    tscError("NULL parameter for %s", __FUNCTION__);
1!
2156
    terrno = TSDB_CODE_INVALID_PARA;
1✔
2157
    return terrno;
1✔
2158
  }
2159

2160
  return stmtPrepare2(stmt, sql, length);
76✔
2161
}
2162

2163
int taos_stmt2_bind_param(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx) {
94✔
2164
  if (stmt == NULL) {
94!
2165
    tscError("NULL parameter for %s", __FUNCTION__);
×
2166
    terrno = TSDB_CODE_INVALID_PARA;
×
2167
    return terrno;
×
2168
  }
2169

2170
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
94✔
2171
  if( atomic_load_8((int8_t*)&pStmt->asyncBindParam.asyncBindNum)>1) {
94!
2172
    tscError("async bind param is still working, please try again later");
×
2173
    return TSDB_CODE_TSC_STMT_API_ERROR;
×
2174
  }
2175

2176
  if (pStmt->options.asyncExecFn && !pStmt->execSemWaited) {
94✔
2177
    if (tsem_wait(&pStmt->asyncExecSem) != 0) {
16!
2178
      tscError("wait asyncExecSem failed");
×
2179
    }
2180
    pStmt->execSemWaited = true;
16✔
2181
  }
2182

2183
  SSHashObj *hashTbnames = tSimpleHashInit(100, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR));
94✔
2184
  if (NULL == hashTbnames) {
94!
2185
    tscError("stmt2 bind failed: %s", tstrerror(terrno));
×
2186
    return terrno;
×
2187
  }
2188

2189
  int32_t code = TSDB_CODE_SUCCESS;
94✔
2190
  for (int i = 0; i < bindv->count; ++i) {
259✔
2191
    if (bindv->tbnames && bindv->tbnames[i]) {
168!
2192
      if (pStmt->sql.stbInterlaceMode) {
156✔
2193
        if (tSimpleHashGet(hashTbnames, bindv->tbnames[i], strlen(bindv->tbnames[i])) != NULL) {
52!
2194
          code = terrno = TSDB_CODE_PAR_TBNAME_DUPLICATED;
×
2195
          tscError("stmt2 bind failed: %s %s", tstrerror(terrno), bindv->tbnames[i]);
×
2196
          goto out;
×
2197
        }
2198

2199
        code = tSimpleHashPut(hashTbnames, bindv->tbnames[i], strlen(bindv->tbnames[i]), NULL, 0);
52✔
2200
        if (code) {
52!
2201
          goto out;
×
2202
        }
2203
      }
2204

2205
      code = stmtSetTbName2(stmt, bindv->tbnames[i]);
156✔
2206
      if (code) {
156!
2207
        goto out;
×
2208
      }
2209
    }
2210

2211
    if (bindv->tags && bindv->tags[i]) {
168!
2212
      code = stmtSetTbTags2(stmt, bindv->tags[i]);
64✔
2213
      if (code) {
64!
2214
        goto out;
×
2215
      }
2216
    } else if (pStmt->bInfo.tbType == TSDB_CHILD_TABLE && pStmt->sql.autoCreateTbl) {
104✔
2217
      code = stmtSetTbTags2(stmt, NULL);
34✔
2218
      if (code) {
34!
2219
        return code;
×
2220
      }
2221
    }
2222

2223
    if (bindv->bind_cols && bindv->bind_cols[i]) {
168!
2224
      TAOS_STMT2_BIND *bind = bindv->bind_cols[i];
168✔
2225

2226
      if (bind->num <= 0 || bind->num > INT16_MAX) {
168!
2227
        tscError("invalid bind num %d", bind->num);
×
2228
        code = terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
2229
        goto out;
2✔
2230
      }
2231

2232
      int32_t insert = 0;
168✔
2233
      (void)stmtIsInsert2(stmt, &insert);
168✔
2234
      if (0 == insert && bind->num > 1) {
168✔
2235
        tscError("only one row data allowed for query");
1!
2236
        code = terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
1✔
2237
        goto out;
1✔
2238
      }
2239

2240
      code = stmtBindBatch2(stmt, bind, col_idx);
167✔
2241
      if (TSDB_CODE_SUCCESS != code) {
166✔
2242
        goto out;
1✔
2243
      }
2244
    }
2245
  }
2246

2247
out:
91✔
2248
  tSimpleHashCleanup(hashTbnames);
93✔
2249

2250
  return code;
93✔
2251
}
2252

2253
int taos_stmt2_bind_param_a(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx, __taos_async_fn_t fp,
10✔
2254
                            void *param) {
2255
  if (stmt == NULL || bindv == NULL || fp == NULL) {
10!
2256
    terrno = TSDB_CODE_INVALID_PARA;
×
2257
    return terrno;
×
2258
  }
2259

2260
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
10✔
2261
  if (atomic_load_8((int8_t *)&pStmt->asyncBindParam.asyncBindNum) > 0) {
10✔
2262
    tscError("async bind param is still working, please try again later");
1!
2263
    return TSDB_CODE_TSC_STMT_API_ERROR;
1✔
2264
  }
2265

2266
  ThreadArgs *args = (ThreadArgs *)taosMemoryMalloc(sizeof(ThreadArgs));
9!
2267
  args->stmt = stmt;
9✔
2268
  args->bindv = bindv;
9✔
2269
  args->col_idx = col_idx;
9✔
2270
  args->fp = fp;
9✔
2271
  args->param = param;
9✔
2272
  (void)atomic_add_fetch_8(&pStmt->asyncBindParam.asyncBindNum, 1);
9✔
2273
  int code_s = taosStmt2AsyncBind(stmtAsyncBindThreadFunc, (void *)args);
9✔
2274
  if (code_s != TSDB_CODE_SUCCESS) {
9!
2275
    (void)atomic_sub_fetch_8(&pStmt->asyncBindParam.asyncBindNum, 1);
×
2276
    // terrno = TAOS_SYSTEM_ERROR(errno);
2277
  }
2278

2279
  return code_s;
9✔
2280
}
2281

2282
int taos_stmt2_exec(TAOS_STMT2 *stmt, int *affected_rows) {
85✔
2283
  if (stmt == NULL) {
85!
2284
    tscError("NULL parameter for %s", __FUNCTION__);
×
2285
    terrno = TSDB_CODE_INVALID_PARA;
×
2286
    return terrno;
×
2287
  }
2288

2289
  return stmtExec2(stmt, affected_rows);
85✔
2290
}
2291

2292
int taos_stmt2_close(TAOS_STMT2 *stmt) {
75✔
2293
  if (stmt == NULL) {
75!
2294
    tscError("NULL parameter for %s", __FUNCTION__);
×
2295
    terrno = TSDB_CODE_INVALID_PARA;
×
2296
    return terrno;
×
2297
  }
2298

2299
  return stmtClose2(stmt);
75✔
2300
}
2301

2302
int taos_stmt2_is_insert(TAOS_STMT2 *stmt, int *insert) {
×
2303
  if (stmt == NULL || insert == NULL) {
×
2304
    tscError("NULL parameter for %s", __FUNCTION__);
×
2305
    terrno = TSDB_CODE_INVALID_PARA;
×
2306
    return terrno;
×
2307
  }
2308

2309
  return stmtIsInsert2(stmt, insert);
×
2310
}
2311

2312
int taos_stmt2_get_fields(TAOS_STMT2 *stmt, int *count, TAOS_FIELD_ALL **fields) {
44✔
2313
  if (stmt == NULL || count == NULL) {
44!
2314
    tscError("NULL parameter for %s", __FUNCTION__);
1!
2315
    terrno = TSDB_CODE_INVALID_PARA;
1✔
2316
    return terrno;
1✔
2317
  }
2318

2319
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
43✔
2320
  if (pStmt->sql.type == 0) {
43!
2321
    int isInsert = 0;
43✔
2322
    (void)stmtIsInsert2(stmt, &isInsert);
43✔
2323
    if (!isInsert) {
43✔
2324
      pStmt->sql.type = STMT_TYPE_QUERY;
9✔
2325
    }
2326
  }
2327
  if (pStmt->sql.type == STMT_TYPE_QUERY) {
43✔
2328
    return stmtGetParamNum2(stmt, count);
9✔
2329
  }
2330

2331
  return stmtGetStbColFields2(stmt, count, fields);
34✔
2332
}
2333

2334
DLL_EXPORT void taos_stmt2_free_fields(TAOS_STMT2 *stmt, TAOS_FIELD_ALL *fields) {
42✔
2335
  (void)stmt;
2336
  if (!fields) return;
42✔
2337
  taosMemoryFree(fields);
22!
2338
}
2339

2340
TAOS_RES *taos_stmt2_result(TAOS_STMT2 *stmt) {
3✔
2341
  if (stmt == NULL) {
3!
2342
    tscError("NULL parameter for %s", __FUNCTION__);
×
2343
    terrno = TSDB_CODE_INVALID_PARA;
×
2344
    return NULL;
×
2345
  }
2346

2347
  return stmtUseResult2(stmt);
3✔
2348
}
2349

2350
char *taos_stmt2_error(TAOS_STMT2 *stmt) { return (char *)stmtErrstr2(stmt); }
3✔
2351

2352
int taos_set_conn_mode(TAOS *taos, int mode, int value) {
4✔
2353
  if (taos == NULL) {
4!
2354
    terrno = TSDB_CODE_INVALID_PARA;
×
2355
    return terrno;
×
2356
  }
2357

2358
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
4✔
2359
  if (NULL == pObj) {
4!
2360
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
2361
    tscError("invalid parameter for %s", __func__);
×
2362
    return terrno;
×
2363
  }
2364
  switch (mode) {
4!
2365
    case TAOS_CONN_MODE_BI:
4✔
2366
      atomic_store_8(&pObj->biMode, value);
4✔
2367
      break;
4✔
2368
    default:
×
2369
      tscError("not supported mode.");
×
2370
      return TSDB_CODE_INVALID_PARA;
×
2371
  }
2372
  return 0;
4✔
2373
}
2374

2375
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