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

taosdata / TDengine / #3552

11 Dec 2024 06:08AM UTC coverage: 62.526% (+0.7%) from 61.798%
#3552

push

travis-ci

web-flow
Merge pull request #29092 from taosdata/fix/3.0/TD-33146

fix:[TD-33146] stmt_get_tag_fields return error code

124833 of 255773 branches covered (48.81%)

Branch coverage included in aggregate %.

209830 of 279467 relevant lines covered (75.08%)

19111707.6 hits per line

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

43.1
/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 "tdatablock.h"
28
#include "tglobal.h"
29
#include "tmsg.h"
30
#include "tref.h"
31
#include "trpc.h"
32
#include "version.h"
33
#include "tconv.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,081✔
42
  if (arg == NULL) {
2,081!
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) {
70,081✔
48
    if (i % 1000 == 0) {
68,000✔
49
      (void)sched_yield();
68✔
50
    }
51
  }
52

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

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

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

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

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

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

91
  tscDebug("set timezone to %s", val);
×
92
  tz = tzalloc(val);
×
93
  if (tz == NULL) {
×
94
    tscWarn("%s unknown timezone %s change to UTC", __func__, val);
×
95
    tz = tzalloc("UTC");
×
96
    if (tz == NULL) {
×
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));
×
103
  if (code != 0){
×
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();
×
111
  char output[TD_TIMEZONE_LEN] = {0};
×
112
  taosFormatTimezoneStr(tx1, val, tz, output);
×
113
  code = taosHashPut(pTimezoneNameMap, &tz, sizeof(timezone_t), output, strlen(output) + 1);
×
114
  if (code != 0){
×
115
    tscError("failed to put timezone %s to map", val);
×
116
  }
117

118
END:
×
119
  return tz;
×
120
}
121
#endif
122

123
static int32_t setConnectionOption(TAOS *taos, TSDB_OPTION_CONNECTION option, const char* val){
×
124
  if (taos == NULL) {
×
125
    return TSDB_CODE_INVALID_PARA;
×
126
  }
127

128
#ifdef WINDOWS
129
  if (option == TSDB_OPTION_CONNECTION_TIMEZONE){
130
    return TSDB_CODE_NOT_SUPPORTTED_IN_WINDOWS;
131
  }
132
#endif
133

134
  if (option < TSDB_OPTION_CONNECTION_CLEAR || option >= TSDB_MAX_OPTIONS_CONNECTION){
×
135
    return TSDB_CODE_INVALID_PARA;
×
136
  }
137

138
  int32_t code = taos_init();
×
139
  // initialize global config
140
  if (code != 0) {
×
141
    return code;
×
142
  }
143

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

150
  if (option == TSDB_OPTION_CONNECTION_CLEAR){
×
151
    val = NULL;
×
152
  }
153

154
  if (option == TSDB_OPTION_CONNECTION_CHARSET || option == TSDB_OPTION_CONNECTION_CLEAR) {
×
155
    if (val != NULL) {
×
156
      if (!taosValidateEncodec(val)) {
×
157
        code = terrno;
×
158
        goto END;
×
159
      }
160
      void *tmp = taosConvInit(val);
×
161
      if (tmp == NULL) {
×
162
        code = terrno;
×
163
        goto END;
×
164
      }
165
      pObj->optionInfo.charsetCxt = tmp;
×
166
    }else{
167
      pObj->optionInfo.charsetCxt = NULL;
×
168
    }
169
  }
170

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

189
  if (option == TSDB_OPTION_CONNECTION_USER_APP || option == TSDB_OPTION_CONNECTION_CLEAR) {
×
190
    if (val != NULL) {
×
191
      tstrncpy(pObj->optionInfo.userApp, val, sizeof(pObj->optionInfo.userApp));
×
192
    } else {
193
      pObj->optionInfo.userApp[0] = 0;
×
194
    }
195
  }
196

197
  if (option == TSDB_OPTION_CONNECTION_USER_IP || option == TSDB_OPTION_CONNECTION_CLEAR) {
×
198
    if (val != NULL) {
×
199
      pObj->optionInfo.userIp = taosInetAddr(val);
×
200
      if (pObj->optionInfo.userIp == INADDR_NONE){
×
201
        code = TSDB_CODE_INVALID_PARA;
×
202
        goto END;
×
203
      }
204
    } else {
205
      pObj->optionInfo.userIp = INADDR_NONE;
×
206
    }
207
  }
208

209
END:
×
210
  releaseTscObj(*(int64_t *)taos);
×
211
  return code;
×
212
}
213

214
int taos_options_connection(TAOS *taos, TSDB_OPTION_CONNECTION option, const void *arg, ...){
×
215
  return setConnectionOption(taos, option, (const char *)arg);
×
216
}
217

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

225
  monitorClose();
4,162✔
226
  tscStopCrashReport();
4,162✔
227

228
  hbMgrCleanUp();
4,162✔
229

230
  catalogDestroy();
4,162✔
231
  schedulerDestroy();
4,162✔
232

233
  fmFuncMgtDestroy();
4,162✔
234
  qCleanupKeywordsTable();
4,162✔
235

236
  if (TSDB_CODE_SUCCESS != cleanupTaskQueue()) {
4,162!
237
    tscWarn("failed to cleanup task queue");
×
238
  }
239

240
#ifndef WINDOWS
241
  tzCleanup();
4,162✔
242
#endif
243
  tmqMgmtClose();
4,162✔
244

245
  int32_t id = clientReqRefPool;
4,162✔
246
  clientReqRefPool = -1;
4,162✔
247
  taosCloseRef(id);
4,162✔
248

249
  id = clientConnRefPool;
4,162✔
250
  clientConnRefPool = -1;
4,162✔
251
  taosCloseRef(id);
4,162✔
252

253
  nodesDestroyAllocatorSet();
4,162✔
254
  //  cleanupAppInfo();
255
  rpcCleanup();
4,162✔
256
  tscDebug("rpc cleanup");
4,162✔
257

258
  taosConvDestroy();
4,162✔
259
  DestroyRegexCache();
4,162✔
260

261
  tscInfo("all local resources released");
4,162!
262
  taosCleanupCfg();
4,162✔
263
  taosCloseLog();
4,162✔
264
}
265

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

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

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

285
  if (pass == NULL) {
12,736!
286
    pass = TSDB_DEFAULT_PASS;
×
287
  }
288

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

304
  return NULL;
145✔
305
}
306

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

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

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

349
  releaseTscObj(*(int64_t *)taos);
70✔
350
  return 0;
70✔
351
}
352

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

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

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

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

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

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

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

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

408
  int64_t connId = *(int64_t *)taos;
×
409

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

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

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

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

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

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

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

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

474
void taos_close_internal(void *taos) {
13,178✔
475
  if (taos == NULL) {
13,178✔
476
    return;
1✔
477
  }
478

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

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

487
void taos_close(TAOS *taos) {
13,365✔
488
  if (taos == NULL) {
13,365✔
489
    return;
776✔
490
  }
491

492
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
12,589✔
493
  if (NULL == pObj) {
12,589!
494
    taosMemoryFree(taos);
×
495
    return;
×
496
  }
497

498
  taos_close_internal(pObj);
12,589✔
499
  releaseTscObj(*(int64_t *)taos);
12,589✔
500
  taosMemoryFree(taos);
12,589✔
501
}
502

503
int taos_errno(TAOS_RES *res) {
12,652,577✔
504
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
12,652,577!
505
    return terrno;
1✔
506
  }
507

508
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
12,660,033!
509
    return 0;
377✔
510
  }
511

512
  return ((SRequestObj *)res)->code;
12,659,656✔
513
}
514

515
const char *taos_errstr(TAOS_RES *res) {
144,479✔
516
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
144,479!
517
    return (const char *)tstrerror(terrno);
131✔
518
  }
519

520
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
144,348!
521
    return "success";
×
522
  }
523

524
  SRequestObj *pRequest = (SRequestObj *)res;
144,348✔
525
  if (NULL != pRequest->msgBuf && (strlen(pRequest->msgBuf) > 0 || pRequest->code == TSDB_CODE_RPC_FQDN_ERROR)) {
144,348!
526
    return pRequest->msgBuf;
131,327✔
527
  } else {
528
    return (const char *)tstrerror(pRequest->code);
13,021✔
529
  }
530
}
531

532
void taos_free_result(TAOS_RES *res) {
10,960,095✔
533
  if (NULL == res) {
10,960,095✔
534
    return;
89✔
535
  }
536

537
  tscDebug("taos free res %p", res);
10,960,006✔
538

539
  if (TD_RES_QUERY(res)) {
10,966,688✔
540
    SRequestObj *pRequest = (SRequestObj *)res;
10,936,008✔
541
    tscDebug("0x%" PRIx64 " taos_free_result start to free query", pRequest->requestId);
10,936,008✔
542
    destroyRequest(pRequest);
10,936,008✔
543
    return;
10,935,015✔
544
  }
545
  SMqRspObj *pRsp = (SMqRspObj *)res;
30,680✔
546
  if (TD_RES_TMQ(res)) {
30,680✔
547
    tDeleteMqDataRsp(&pRsp->dataRsp);
30,461✔
548
    doFreeReqResultInfo(&pRsp->resInfo);
30,461✔
549
  } else if (TD_RES_TMQ_METADATA(res)) {
219✔
550
    tDeleteSTaosxRsp(&pRsp->dataRsp);
12✔
551
    doFreeReqResultInfo(&pRsp->resInfo);
12✔
552
  } else if (TD_RES_TMQ_META(res)) {
207✔
553
    tDeleteMqMetaRsp(&pRsp->metaRsp);
188✔
554
  } else if (TD_RES_TMQ_BATCH_META(res)) {
19!
555
    tDeleteMqBatchMetaRsp(&pRsp->batchMetaRsp);
19✔
556
  }
557
  taosMemoryFree(pRsp);
30,680✔
558
}
559

560
void taos_kill_query(TAOS *taos) {
11✔
561
  if (NULL == taos) {
11✔
562
    return;
6✔
563
  }
564

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

573
int taos_field_count(TAOS_RES *res) {
45,235,051✔
574
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
45,235,051!
575
    return 0;
×
576
  }
577

578
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
45,235,161✔
579
  return pResInfo->numOfCols;
45,235,161✔
580
}
581

582
int taos_num_fields(TAOS_RES *res) { return taos_field_count(res); }
25,567,409✔
583

584
TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) {
16,386,132✔
585
  if (taos_num_fields(res) == 0 || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
16,386,132!
586
    return NULL;
137,929✔
587
  }
588

589
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
16,248,180✔
590
  return pResInfo->userFields;
16,248,180✔
591
}
592

593
TAOS_RES *taos_query(TAOS *taos, const char *sql) { return taosQueryImpl(taos, sql, false, TD_REQ_FROM_APP); }
10,933,774✔
594
TAOS_RES *taos_query_with_reqid(TAOS *taos, const char *sql, int64_t reqid) {
×
595
  return taosQueryImplWithReqid(taos, sql, false, reqid);
×
596
}
597

598
TAOS_ROW taos_fetch_row(TAOS_RES *res) {
20,594,869✔
599
  if (res == NULL) {
20,594,869!
600
    return NULL;
×
601
  }
602

603
  if (TD_RES_QUERY(res)) {
20,594,869✔
604
    SRequestObj *pRequest = (SRequestObj *)res;
5,692,749✔
605
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
5,692,749!
606
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0 || pRequest->killed) {
5,692,594!
607
      return NULL;
156✔
608
    }
609

610
    if (pRequest->inCallback) {
5,692,591!
611
      tscError("can not call taos_fetch_row before query callback ends.");
×
612
      terrno = TSDB_CODE_TSC_INVALID_OPERATION;
×
613
      return NULL;
×
614
    }
615

616
    return doAsyncFetchRows(pRequest, true, true);
5,692,591✔
617
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
14,902,120!
618
    SMqRspObj      *msg = ((SMqRspObj *)res);
14,902,120✔
619
    SReqResultInfo *pResultInfo = NULL;
14,902,120✔
620
    if (msg->resIter == -1) {
14,902,120✔
621
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
29,782!
622
        return NULL;
×
623
      }
624
    } else {
625
      pResultInfo = tmqGetCurResInfo(res);
14,872,338✔
626
    }
627

628
    if (pResultInfo->current < pResultInfo->numOfRows) {
14,902,120✔
629
      doSetOneRowPtr(pResultInfo);
14,566,820✔
630
      pResultInfo->current += 1;
14,566,363✔
631
      return pResultInfo->row;
14,566,363✔
632
    } else {
633
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
335,300✔
634
        return NULL;
29,777✔
635
      }
636

637
      doSetOneRowPtr(pResultInfo);
305,516✔
638
      pResultInfo->current += 1;
305,490✔
639
      return pResultInfo->row;
305,490✔
640
    }
641
  } else if (TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
×
642
    return NULL;
×
643
  } else {
644
    tscError("invalid result passed to taos_fetch_row");
×
645
    terrno = TSDB_CODE_TSC_INTERNAL_ERROR;
×
646
    return NULL;
×
647
  }
648
}
649

650
int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
14,875,987✔
651
  return taos_print_row_with_size(str, INT32_MAX, row, fields, num_fields);
14,875,987✔
652
}
653
int taos_print_row_with_size(char *str, uint32_t size, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
14,875,894✔
654
  int32_t len = 0;
14,875,894✔
655
  for (int i = 0; i < num_fields; ++i) {
88,380,500✔
656
    if (i > 0 && len < size - 1) {
73,496,279!
657
      str[len++] = ' ';
58,645,775✔
658
    }
659

660
    if (row[i] == NULL) {
73,496,279✔
661
      len += tsnprintf(str + len, size - len, "%s", TSDB_DATA_NULL_STR);
268,592✔
662
      continue;
268,618✔
663
    }
664

665
    switch (fields[i].type) {
73,227,687!
666
      case TSDB_DATA_TYPE_TINYINT:
×
667
        len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
×
668
        break;
×
669

670
      case TSDB_DATA_TYPE_UTINYINT:
×
671
        len += tsnprintf(str + len, size - len, "%u", *((uint8_t *)row[i]));
×
672
        break;
×
673

674
      case TSDB_DATA_TYPE_SMALLINT:
×
675
        len += tsnprintf(str + len, size - len, "%d", *((int16_t *)row[i]));
×
676
        break;
×
677

678
      case TSDB_DATA_TYPE_USMALLINT:
×
679
        len += tsnprintf(str + len, size - len, "%u", *((uint16_t *)row[i]));
×
680
        break;
×
681

682
      case TSDB_DATA_TYPE_INT:
16,047,328✔
683
        len += tsnprintf(str + len, size - len, "%d", *((int32_t *)row[i]));
16,047,328✔
684
        break;
16,049,491✔
685

686
      case TSDB_DATA_TYPE_UINT:
×
687
        len += tsnprintf(str + len, size - len, "%u", *((uint32_t *)row[i]));
×
688
        break;
×
689

690
      case TSDB_DATA_TYPE_BIGINT:
13,402,173✔
691
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
13,402,173✔
692
        break;
13,402,630✔
693

694
      case TSDB_DATA_TYPE_UBIGINT:
×
695
        len += tsnprintf(str + len, size - len, "%" PRIu64, *((uint64_t *)row[i]));
×
696
        break;
×
697

698
      case TSDB_DATA_TYPE_FLOAT: {
1,341✔
699
        float fv = 0;
1,341✔
700
        fv = GET_FLOAT_VAL(row[i]);
1,341✔
701
        len += tsnprintf(str + len, size - len, "%f", fv);
1,341✔
702
      } break;
1,341✔
703

704
      case TSDB_DATA_TYPE_DOUBLE: {
7,660,516✔
705
        double dv = 0;
7,660,516✔
706
        dv = GET_DOUBLE_VAL(row[i]);
7,660,516✔
707
        len += tsnprintf(str + len, size - len, "%lf", dv);
7,660,516✔
708
      } break;
7,660,618✔
709

710
      case TSDB_DATA_TYPE_VARBINARY: {
2✔
711
        void    *data = NULL;
2✔
712
        uint32_t tmp = 0;
2✔
713
        int32_t  charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
2✔
714
        if (taosAscii2Hex(row[i], charLen, &data, &tmp) < 0) {
2!
715
          break;
×
716
        }
717
        uint32_t copyLen = TMIN(size - len - 1, tmp);
2✔
718
        (void)memcpy(str + len, data, copyLen);
2✔
719
        len += copyLen;
2✔
720
        taosMemoryFree(data);
2✔
721
      } break;
2✔
722
      case TSDB_DATA_TYPE_BINARY:
16,142,144✔
723
      case TSDB_DATA_TYPE_NCHAR:
724
      case TSDB_DATA_TYPE_GEOMETRY: {
725
        int32_t charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
16,142,144✔
726
        if (fields[i].type == TSDB_DATA_TYPE_BINARY || fields[i].type == TSDB_DATA_TYPE_VARBINARY ||
16,142,144!
727
            fields[i].type == TSDB_DATA_TYPE_GEOMETRY) {
5,071,889!
728
          if (charLen > fields[i].bytes || charLen < 0) {
11,070,243!
729
            tscError("taos_print_row error binary. charLen:%d, fields[i].bytes:%d", charLen, fields[i].bytes);
×
730
            break;
×
731
          }
732
        } else {
733
          if (charLen > fields[i].bytes * TSDB_NCHAR_SIZE || charLen < 0) {
5,071,901!
734
            tscError("taos_print_row error. charLen:%d, fields[i].bytes:%d", charLen, fields[i].bytes);
4,679!
735
            break;
×
736
          }
737
        }
738

739
        uint32_t copyLen = TMIN(size - len - 1, charLen);
16,139,441✔
740
        (void)memcpy(str + len, row[i], copyLen);
16,139,441✔
741
        len += copyLen;
16,139,441✔
742
      } break;
16,139,441✔
743

744
      case TSDB_DATA_TYPE_TIMESTAMP:
20,034,245✔
745
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
20,034,245✔
746
        break;
20,042,527✔
747

748
      case TSDB_DATA_TYPE_BOOL:
×
749
        len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
×
750
      default:
×
751
        break;
×
752
    }
753

754
    if (len >= size - 1) {
73,235,988!
755
      break;
×
756
    }
757
  }
758
  if (len < size) {
14,884,221✔
759
    str[len] = 0;
14,875,518✔
760
  }
761

762
  return len;
14,884,221✔
763
}
764

765
int *taos_fetch_lengths(TAOS_RES *res) {
18,361,275✔
766
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
18,361,275!
767
    return NULL;
×
768
  }
769

770
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
18,361,406✔
771
  return pResInfo->length;
18,361,406✔
772
}
773

774
TAOS_ROW *taos_result_block(TAOS_RES *res) {
×
775
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
×
776
    terrno = TSDB_CODE_INVALID_PARA;
×
777
    return NULL;
×
778
  }
779

780
  if (taos_is_update_query(res)) {
×
781
    return NULL;
×
782
  }
783

784
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
×
785
  return &pResInfo->row;
×
786
}
787

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

839
const char *taos_get_client_info() { return td_version; }
3,955✔
840

841
// return int32_t
842
int taos_affected_rows(TAOS_RES *res) {
1,678,628✔
843
  if (res == NULL || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
1,678,628!
844
      TD_RES_TMQ_BATCH_META(res)) {
1,678,628!
845
    return 0;
×
846
  }
847

848
  SRequestObj    *pRequest = (SRequestObj *)res;
1,678,628✔
849
  SReqResultInfo *pResInfo = &pRequest->body.resInfo;
1,678,628✔
850
  return (int)pResInfo->numOfRows;
1,678,628✔
851
}
852

853
// return int64_t
854
int64_t taos_affected_rows64(TAOS_RES *res) {
128,082✔
855
  if (res == NULL || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
128,082!
856
      TD_RES_TMQ_BATCH_META(res)) {
128,082!
857
    return 0;
×
858
  }
859

860
  SRequestObj    *pRequest = (SRequestObj *)res;
128,082✔
861
  SReqResultInfo *pResInfo = &pRequest->body.resInfo;
128,082✔
862
  return pResInfo->numOfRows;
128,082✔
863
}
864

865
int taos_result_precision(TAOS_RES *res) {
16,034,871✔
866
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
16,034,871!
867
    return TSDB_TIME_PRECISION_MILLI;
×
868
  }
869

870
  if (TD_RES_QUERY(res)) {
16,034,912✔
871
    SRequestObj *pRequest = (SRequestObj *)res;
1,145,254✔
872
    return pRequest->body.resInfo.precision;
1,145,254✔
873
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
14,889,658!
874
    SReqResultInfo *info = tmqGetCurResInfo(res);
14,889,658✔
875
    return info->precision;
14,889,658✔
876
  }
877
  return TSDB_TIME_PRECISION_MILLI;
×
878
}
879

880
int taos_select_db(TAOS *taos, const char *db) {
3,196✔
881
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
3,196✔
882
  if (pObj == NULL) {
3,197!
883
    releaseTscObj(*(int64_t *)taos);
×
884
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
885
    return TSDB_CODE_TSC_DISCONNECTED;
×
886
  }
887

888
  if (db == NULL || strlen(db) == 0) {
3,197!
889
    releaseTscObj(*(int64_t *)taos);
×
890
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
891
    return terrno;
×
892
  }
893

894
  char sql[256] = {0};
3,197✔
895
  (void)snprintf(sql, tListLen(sql), "use %s", db);
3,197✔
896

897
  TAOS_RES *pRequest = taos_query(taos, sql);
3,197✔
898
  int32_t   code = taos_errno(pRequest);
3,196✔
899

900
  taos_free_result(pRequest);
3,197✔
901
  releaseTscObj(*(int64_t *)taos);
3,197✔
902
  return code;
3,195✔
903
}
904

905
void taos_stop_query(TAOS_RES *res) {
10,942,550✔
906
  if (res == NULL || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
10,942,550!
907
      TD_RES_TMQ_BATCH_META(res)) {
10,950,237!
908
    return;
×
909
  }
910

911
  stopAllQueries((SRequestObj *)res);
10,951,204✔
912
}
913

914
bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) {
423,465,906✔
915
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
423,465,906!
916
    return true;
×
917
  }
918
  SReqResultInfo *pResultInfo = tscGetCurResInfo(res);
423,465,922✔
919
  if (col >= pResultInfo->numOfCols || col < 0 || row >= pResultInfo->numOfRows || row < 0) {
423,465,922!
920
    return true;
×
921
  }
922

923
  SResultColumn *pCol = &pResultInfo->pCol[col];
423,465,926✔
924
  if (IS_VAR_DATA_TYPE(pResultInfo->fields[col].type)) {
423,465,926!
925
    return (pCol->offset[row] == -1);
15✔
926
  } else {
927
    return colDataIsNull_f(pCol->nullbitmap, row);
423,465,911✔
928
  }
929
}
930

931
bool taos_is_update_query(TAOS_RES *res) { return taos_num_fields(res) == 0; }
×
932

933
int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
1,561,736✔
934
  int32_t numOfRows = 0;
1,561,736✔
935
  /*int32_t code = */ terrno = taos_fetch_block_s(res, &numOfRows, rows);
1,561,736✔
936
  return numOfRows;
1,561,736✔
937
}
938

939
int taos_fetch_block_s(TAOS_RES *res, int *numOfRows, TAOS_ROW *rows) {
1,561,736✔
940
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
1,561,736!
941
    return 0;
×
942
  }
943

944
  if (TD_RES_QUERY(res)) {
1,561,736✔
945
    SRequestObj *pRequest = (SRequestObj *)res;
1,540,110✔
946

947
    (*rows) = NULL;
1,540,110✔
948
    (*numOfRows) = 0;
1,540,110✔
949

950
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
1,540,110!
951
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
1,537,598!
952
      return pRequest->code;
7,438✔
953
    }
954

955
    (void)doAsyncFetchRows(pRequest, false, true);
1,532,672✔
956

957
    // TODO refactor
958
    SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
1,532,672✔
959
    pResultInfo->current = pResultInfo->numOfRows;
1,532,672✔
960

961
    (*rows) = pResultInfo->row;
1,532,672✔
962
    (*numOfRows) = pResultInfo->numOfRows;
1,532,672✔
963
    return pRequest->code;
1,532,672✔
964
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
21,626!
965
    SReqResultInfo *pResultInfo = NULL;
21,626✔
966
    int32_t         code = tmqGetNextResInfo(res, true, &pResultInfo);
21,626✔
967
    if (code != 0) return code;
21,626✔
968

969
    pResultInfo->current = pResultInfo->numOfRows;
21,009✔
970
    (*rows) = pResultInfo->row;
21,009✔
971
    (*numOfRows) = pResultInfo->numOfRows;
21,009✔
972
    return 0;
21,009✔
973
  } else {
974
    tscError("taos_fetch_block_s invalid res type");
×
975
    return -1;
×
976
  }
977
}
978

979
int taos_fetch_raw_block(TAOS_RES *res, int *numOfRows, void **pData) {
8✔
980
  *numOfRows = 0;
8✔
981
  *pData = NULL;
8✔
982

983
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
8!
984
    return 0;
×
985
  }
986

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

995
    pResultInfo->current = pResultInfo->numOfRows;
×
996
    (*numOfRows) = pResultInfo->numOfRows;
×
997
    (*pData) = (void *)pResultInfo->pData;
×
998
    return 0;
×
999
  }
1000

1001
  SRequestObj *pRequest = (SRequestObj *)res;
8✔
1002

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

1008
  (void)doAsyncFetchRows(pRequest, false, false);
8✔
1009

1010
  SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
8✔
1011

1012
  pResultInfo->current = pResultInfo->numOfRows;
8✔
1013
  (*numOfRows) = pResultInfo->numOfRows;
8✔
1014
  (*pData) = (void *)pResultInfo->pData;
8✔
1015

1016
  return pRequest->code;
8✔
1017
}
1018

1019
int *taos_get_column_data_offset(TAOS_RES *res, int columnIndex) {
780,491✔
1020
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
780,491!
1021
    return 0;
×
1022
  }
1023

1024
  int32_t numOfFields = taos_num_fields(res);
780,491✔
1025
  if (columnIndex < 0 || columnIndex >= numOfFields || numOfFields == 0) {
780,491!
1026
    return 0;
×
1027
  }
1028

1029
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
780,491✔
1030
  TAOS_FIELD     *pField = &pResInfo->userFields[columnIndex];
780,491✔
1031
  if (!IS_VAR_DATA_TYPE(pField->type)) {
780,491!
1032
    return 0;
×
1033
  }
1034

1035
  return pResInfo->pCol[columnIndex].offset;
780,491✔
1036
}
1037

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

1044
  int32_t numOfFields = taos_num_fields(res);
×
1045
  if (columnIndex >= numOfFields || numOfFields == 0) {
×
1046
    return TSDB_CODE_INVALID_PARA;
×
1047
  }
1048

1049
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
×
1050
  TAOS_FIELD     *pField = &pResInfo->userFields[columnIndex];
×
1051
  SResultColumn  *pCol = &pResInfo->pCol[columnIndex];
×
1052

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

1076
int taos_validate_sql(TAOS *taos, const char *sql) {
×
1077
  TAOS_RES *pObj = taosQueryImpl(taos, sql, true, TD_REQ_FROM_APP);
×
1078

1079
  int code = taos_errno(pObj);
×
1080

1081
  taos_free_result(pObj);
×
1082
  return code;
×
1083
}
1084

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

1092
  resetConnectDB(pTscObj);
×
1093

1094
  releaseTscObj(*(int64_t *)taos);
×
1095
}
1096

1097
const char *taos_get_server_info(TAOS *taos) {
6✔
1098
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
6✔
1099
  if (pTscObj == NULL) {
6!
1100
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1101
    return NULL;
×
1102
  }
1103

1104
  releaseTscObj(*(int64_t *)taos);
6✔
1105

1106
  return pTscObj->sDetailVer;
6✔
1107
}
1108

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

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

1134
void destorySqlCallbackWrapper(SSqlCallbackWrapper *pWrapper) {
21,903,044✔
1135
  if (NULL == pWrapper) {
21,903,044✔
1136
    return;
10,974,910✔
1137
  }
1138
  destoryCatalogReq(pWrapper->pCatalogReq);
10,928,134✔
1139
  taosMemoryFree(pWrapper->pCatalogReq);
10,929,554✔
1140
  qDestroyParseContext(pWrapper->pParseCtx);
10,953,397✔
1141
  taosMemoryFree(pWrapper);
10,949,743✔
1142
}
1143

1144
void destroyCtxInRequest(SRequestObj *pRequest) {
17,343✔
1145
  schedulerFreeJob(&pRequest->body.queryJob, 0);
17,343✔
1146
  qDestroyQuery(pRequest->pQuery);
17,343✔
1147
  pRequest->pQuery = NULL;
17,343✔
1148
  destorySqlCallbackWrapper(pRequest->pWrapper);
17,343✔
1149
  pRequest->pWrapper = NULL;
17,343✔
1150
}
17,343✔
1151

1152
static void doAsyncQueryFromAnalyse(SMetaData *pResultMeta, void *param, int32_t code) {
1,273,793✔
1153
  SSqlCallbackWrapper *pWrapper = (SSqlCallbackWrapper *)param;
1,273,793✔
1154
  SRequestObj         *pRequest = pWrapper->pRequest;
1,273,793✔
1155
  SQuery              *pQuery = pRequest->pQuery;
1,273,793✔
1156

1157
  qDebug("0x%" PRIx64 " start to semantic analysis,QID:0x%" PRIx64, pRequest->self, pRequest->requestId);
1,273,793✔
1158

1159
  int64_t analyseStart = taosGetTimestampUs();
1,273,794✔
1160
  pRequest->metric.ctgCostUs = analyseStart - pRequest->metric.ctgStart;
1,273,794✔
1161
  pWrapper->pParseCtx->parseOnly = pRequest->parseOnly;
1,273,794✔
1162

1163
  if (TSDB_CODE_SUCCESS == code) {
1,273,794✔
1164
    code = qAnalyseSqlSemantic(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
1,273,787✔
1165
  }
1166

1167
  pRequest->metric.analyseCostUs += taosGetTimestampUs() - analyseStart;
1,273,777✔
1168

1169
  if (pRequest->parseOnly) {
1,273,777✔
1170
    (void)memcpy(&pRequest->parseMeta, pResultMeta, sizeof(*pResultMeta));
424✔
1171
    (void)memset(pResultMeta, 0, sizeof(*pResultMeta));
424✔
1172
  }
1173

1174
  handleQueryAnslyseRes(pWrapper, pResultMeta, code);
1,273,777✔
1175
}
1,273,750✔
1176

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

1203
    *ppTarget = pTarget;
519✔
1204
  }
1205

1206
  return code;
519✔
1207
}
1208

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

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

1240
void handleQueryAnslyseRes(SSqlCallbackWrapper *pWrapper, SMetaData *pResultMeta, int32_t code) {
1,274,249✔
1241
  SRequestObj *pRequest = pWrapper->pRequest;
1,274,249✔
1242
  SQuery      *pQuery = pRequest->pQuery;
1,274,249✔
1243

1244
  if (code == TSDB_CODE_SUCCESS && pQuery->pPrevRoot) {
1,274,249✔
1245
    SNode *prevRoot = pQuery->pPrevRoot;
519✔
1246
    pQuery->pPrevRoot = NULL;
519✔
1247
    handleSubQueryFromAnalyse(pWrapper, pResultMeta, prevRoot);
519✔
1248
    return;
519✔
1249
  }
1250

1251
  if (code == TSDB_CODE_SUCCESS) {
1,273,730✔
1252
    pRequest->stableQuery = pQuery->stableQuery;
1,175,944✔
1253
    if (pQuery->pRoot) {
1,175,944!
1254
      pRequest->stmtType = pQuery->pRoot->type;
1,175,947✔
1255
    }
1256

1257
    if (pQuery->haveResultSet) {
1,175,944✔
1258
      code = setResSchemaInfo(&pRequest->body.resInfo, pQuery->pResSchema, pQuery->numOfResCols);
967,245✔
1259
      setResPrecision(&pRequest->body.resInfo, pQuery->precision);
967,243✔
1260
    }
1261
  }
1262

1263
  if (code == TSDB_CODE_SUCCESS) {
1,273,736✔
1264
    TSWAP(pRequest->dbList, (pQuery)->pDbList);
1,175,921✔
1265
    TSWAP(pRequest->tableList, (pQuery)->pTableList);
1,175,921✔
1266
    TSWAP(pRequest->targetTableList, (pQuery)->pTargetTableList);
1,175,921✔
1267

1268
    launchAsyncQuery(pRequest, pQuery, pResultMeta, pWrapper);
1,175,921✔
1269
  } else {
1270
    destorySqlCallbackWrapper(pWrapper);
97,815✔
1271
    pRequest->pWrapper = NULL;
97,815✔
1272
    qDestroyQuery(pRequest->pQuery);
97,815✔
1273
    pRequest->pQuery = NULL;
97,815✔
1274

1275
    if (NEED_CLIENT_HANDLE_ERROR(code)) {
97,815!
1276
      tscDebug("0x%" PRIx64 " client retry to handle the error, code:%d - %s, tryCount:%d,QID:0x%" PRIx64,
16,754✔
1277
               pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId);
1278
      restartAsyncQuery(pRequest, code);
16,754✔
1279
      return;
16,754✔
1280
    }
1281

1282
    // return to app directly
1283
    tscError("0x%" PRIx64 " error occurs, code:%s, return to user app,QID:0x%" PRIx64, pRequest->self, tstrerror(code),
81,061!
1284
             pRequest->requestId);
1285
    pRequest->code = code;
81,061✔
1286
    returnToUser(pRequest);
81,061✔
1287
  }
1288
}
1289

1290
static int32_t getAllMetaAsync(SSqlCallbackWrapper *pWrapper, catalogCallback fp) {
1,306,348✔
1291
  SRequestConnInfo conn = {.pTrans = pWrapper->pParseCtx->pTransporter,
1,306,348✔
1292
                           .requestId = pWrapper->pParseCtx->requestId,
1,306,348✔
1293
                           .requestObjRefId = pWrapper->pParseCtx->requestRid,
1,306,348✔
1294
                           .mgmtEps = pWrapper->pParseCtx->mgmtEpSet};
1,306,348✔
1295

1296
  pWrapper->pRequest->metric.ctgStart = taosGetTimestampUs();
1,306,348✔
1297

1298
  return catalogAsyncGetAllMeta(pWrapper->pParseCtx->pCatalog, &conn, pWrapper->pCatalogReq, fp, pWrapper,
2,612,729✔
1299
                                &pWrapper->pRequest->body.queryJob);
1,306,375✔
1300
}
1301

1302
static void doAsyncQueryFromParse(SMetaData *pResultMeta, void *param, int32_t code);
1303

1304
static int32_t phaseAsyncQuery(SSqlCallbackWrapper *pWrapper) {
10,851,825✔
1305
  int32_t code = TSDB_CODE_SUCCESS;
10,851,825✔
1306
  switch (pWrapper->pRequest->pQuery->execStage) {
10,851,825!
1307
    case QUERY_EXEC_STAGE_PARSE: {
33,111✔
1308
      // continue parse after get metadata
1309
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromParse);
33,111✔
1310
      break;
33,110✔
1311
    }
1312
    case QUERY_EXEC_STAGE_ANALYSE: {
1,273,252✔
1313
      // analysis after get metadata
1314
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromAnalyse);
1,273,252✔
1315
      break;
1,273,246✔
1316
    }
1317
    case QUERY_EXEC_STAGE_SCHEDULE: {
9,559,551✔
1318
      launchAsyncQuery(pWrapper->pRequest, pWrapper->pRequest->pQuery, NULL, pWrapper);
9,559,551✔
1319
      break;
9,571,631✔
1320
    }
1321
    default:
×
1322
      break;
×
1323
  }
1324
  return code;
10,863,898✔
1325
}
1326

1327
static void doAsyncQueryFromParse(SMetaData *pResultMeta, void *param, int32_t code) {
33,117✔
1328
  SSqlCallbackWrapper *pWrapper = (SSqlCallbackWrapper *)param;
33,117✔
1329
  SRequestObj         *pRequest = pWrapper->pRequest;
33,117✔
1330
  SQuery              *pQuery = pRequest->pQuery;
33,117✔
1331

1332
  pRequest->metric.ctgCostUs += taosGetTimestampUs() - pRequest->metric.ctgStart;
33,116✔
1333
  qDebug("0x%" PRIx64 " start to continue parse,QID:0x%" PRIx64 ", code:%s", pRequest->self, pRequest->requestId,
33,116✔
1334
         tstrerror(code));
1335

1336
  if (code == TSDB_CODE_SUCCESS) {
33,116✔
1337
    // pWrapper->pCatalogReq->forceUpdate = false;
1338
    code = qContinueParseSql(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
32,765✔
1339
  }
1340

1341
  if (TSDB_CODE_SUCCESS == code) {
33,115✔
1342
    code = phaseAsyncQuery(pWrapper);
32,015✔
1343
  }
1344

1345
  if (TSDB_CODE_SUCCESS != code) {
33,113✔
1346
    tscError("0x%" PRIx64 " error happens, code:%d - %s,QID:0x%" PRIx64, pWrapper->pRequest->self, code,
1,100!
1347
             tstrerror(code), pWrapper->pRequest->requestId);
1348
    destorySqlCallbackWrapper(pWrapper);
1,100✔
1349
    pRequest->pWrapper = NULL;
1,100✔
1350
    terrno = code;
1,100✔
1351
    pRequest->code = code;
1,100✔
1352
    doRequestCallback(pRequest, code);
1,100✔
1353
  }
1354
}
33,113✔
1355

1356
void continueInsertFromCsv(SSqlCallbackWrapper *pWrapper, SRequestObj *pRequest) {
20✔
1357
  int32_t code = qParseSqlSyntax(pWrapper->pParseCtx, &pRequest->pQuery, pWrapper->pCatalogReq);
20✔
1358
  if (TSDB_CODE_SUCCESS == code) {
20!
1359
    code = phaseAsyncQuery(pWrapper);
20✔
1360
  }
1361

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

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

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

1385
int32_t createParseContext(const SRequestObj *pRequest, SParseContext **pCxt, SSqlCallbackWrapper *pWrapper) {
10,935,567✔
1386
  const STscObj *pTscObj = pRequest->pTscObj;
10,935,567✔
1387

1388
  *pCxt = taosMemoryCalloc(1, sizeof(SParseContext));
10,935,567✔
1389
  if (*pCxt == NULL) {
10,934,265!
1390
    return terrno;
×
1391
  }
1392

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

1422
int32_t prepareAndParseSqlSyntax(SSqlCallbackWrapper **ppWrapper, SRequestObj *pRequest, bool updateMetaForce) {
10,927,356✔
1423
  int32_t              code = TSDB_CODE_SUCCESS;
10,927,356✔
1424
  STscObj             *pTscObj = pRequest->pTscObj;
10,927,356✔
1425
  SSqlCallbackWrapper *pWrapper = taosMemoryCalloc(1, sizeof(SSqlCallbackWrapper));
10,927,356✔
1426
  if (pWrapper == NULL) {
10,945,077!
1427
    code = terrno;
×
1428
  } else {
1429
    pWrapper->pRequest = pRequest;
10,946,412✔
1430
    pRequest->pWrapper = pWrapper;
10,946,412✔
1431
    *ppWrapper = pWrapper;
10,946,412✔
1432
  }
1433

1434
  if (TSDB_CODE_SUCCESS == code) {
10,946,412!
1435
    code = createParseContext(pRequest, &pWrapper->pParseCtx, pWrapper);
10,947,058✔
1436
  }
1437

1438
  if (TSDB_CODE_SUCCESS == code) {
10,884,497!
1439
    pWrapper->pParseCtx->mgmtEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
10,885,345✔
1440
    code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pWrapper->pParseCtx->pCatalog);
10,955,645✔
1441
  }
1442

1443
  if (TSDB_CODE_SUCCESS == code && NULL == pRequest->pQuery) {
10,913,372!
1444
    int64_t syntaxStart = taosGetTimestampUs();
10,908,066✔
1445

1446
    pWrapper->pCatalogReq = taosMemoryCalloc(1, sizeof(SCatalogReq));
10,908,066✔
1447
    if (pWrapper->pCatalogReq == NULL) {
10,945,667!
1448
      code = terrno;
×
1449
    } else {
1450
      pWrapper->pCatalogReq->forceUpdate = updateMetaForce;
10,945,667✔
1451
      TSC_ERR_RET(qnodeRequired(pRequest, &pWrapper->pCatalogReq->qNodeRequired));
10,945,667!
1452
      code = qParseSqlSyntax(pWrapper->pParseCtx, &pRequest->pQuery, pWrapper->pCatalogReq);
10,942,703✔
1453
    }
1454

1455
    pRequest->metric.parseCostUs += taosGetTimestampUs() - syntaxStart;
10,884,778✔
1456
  }
1457

1458
  return code;
10,893,504✔
1459
}
1460

1461
void doAsyncQuery(SRequestObj *pRequest, bool updateMetaForce) {
10,935,467✔
1462
  SSqlCallbackWrapper *pWrapper = NULL;
10,935,467✔
1463
  int32_t              code = TSDB_CODE_SUCCESS;
10,935,467✔
1464

1465
  if (pRequest->retry++ > REQUEST_TOTAL_EXEC_TIMES) {
10,935,467✔
1466
    code = pRequest->prevCode;
5,649✔
1467
    terrno = code;
5,649✔
1468
    pRequest->code = code;
5,649✔
1469
    tscDebug("call sync query cb with code: %s", tstrerror(code));
5,649✔
1470
    doRequestCallback(pRequest, code);
5,649✔
1471
    return;
5,825✔
1472
  }
1473

1474
  if (TSDB_CODE_SUCCESS == code) {
10,929,818✔
1475
    code = prepareAndParseSqlSyntax(&pWrapper, pRequest, updateMetaForce);
10,928,876✔
1476
  }
1477

1478
  if (TSDB_CODE_SUCCESS == code) {
10,872,458✔
1479
    pRequest->stmtType = pRequest->pQuery->pRoot->type;
10,826,663✔
1480
    code = phaseAsyncQuery(pWrapper);
10,826,663✔
1481
  }
1482

1483
  if (TSDB_CODE_SUCCESS != code) {
10,890,680✔
1484
    tscError("0x%" PRIx64 " error happens, code:%d - %s,QID:0x%" PRIx64, pRequest->self, code, tstrerror(code),
56,447!
1485
             pRequest->requestId);
1486
    destorySqlCallbackWrapper(pWrapper);
56,447✔
1487
    pRequest->pWrapper = NULL;
56,447✔
1488
    qDestroyQuery(pRequest->pQuery);
56,447✔
1489
    pRequest->pQuery = NULL;
56,447✔
1490

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

1504
    terrno = code;
56,271✔
1505
    pRequest->code = code;
56,271✔
1506
    doRequestCallback(pRequest, code);
56,271✔
1507
  }
1508
}
1509

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

1542
typedef struct SAsyncFetchParam {
1543
  SRequestObj      *pReq;
1544
  __taos_async_fn_t fp;
1545
  void             *param;
1546
} SAsyncFetchParam;
1547

1548
static int32_t doAsyncFetch(void *pParam) {
1,069,111✔
1549
  SAsyncFetchParam *param = pParam;
1,069,111✔
1550
  taosAsyncFetchImpl(param->pReq, param->fp, param->param);
1,069,111✔
1551
  taosMemoryFree(param);
1,069,108✔
1552
  return TSDB_CODE_SUCCESS;
1,069,112✔
1553
}
1554

1555
void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
1,069,113✔
1556
  if (res == NULL || fp == NULL) {
1,069,113!
1557
    tscError("taos_fetch_rows_a invalid paras");
×
1558
    return;
×
1559
  }
1560
  if (!TD_RES_QUERY(res)) {
1,069,117!
1561
    tscError("taos_fetch_rows_a res is NULL");
×
1562
    fp(param, res, TSDB_CODE_APP_ERROR);
×
1563
    return;
×
1564
  }
1565

1566
  SRequestObj *pRequest = res;
1,069,117✔
1567
  if (TSDB_SQL_RETRIEVE_EMPTY_RESULT == pRequest->type) {
1,069,117✔
1568
    fp(param, res, 0);
5✔
1569
    return;
5✔
1570
  }
1571

1572
  SAsyncFetchParam *pParam = taosMemoryCalloc(1, sizeof(SAsyncFetchParam));
1,069,112✔
1573
  if (!pParam) {
1,069,109!
1574
    fp(param, res, terrno);
×
1575
    return;
×
1576
  }
1577
  pParam->pReq = pRequest;
1,069,109✔
1578
  pParam->fp = fp;
1,069,109✔
1579
  pParam->param = param;
1,069,109✔
1580
  int32_t code = taosAsyncExec(doAsyncFetch, pParam, NULL);
1,069,109✔
1581
  if (TSDB_CODE_SUCCESS != code) {
1,069,112!
1582
    taosMemoryFree(pParam);
×
1583
    fp(param, res, code);
×
1584
    return;
×
1585
  }
1586
}
1587

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

1600
  // set the current block is all consumed
1601
  pResultInfo->convertUcs4 = false;
×
1602

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

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

1618
  return pRequest->body.resInfo.pData;
×
1619
}
1620

1621
int taos_get_db_route_info(TAOS *taos, const char *db, TAOS_DB_ROUTE_INFO *dbInfo) {
×
1622
  if (NULL == taos) {
×
1623
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1624
    return terrno;
×
1625
  }
1626

1627
  if (NULL == db || NULL == dbInfo) {
×
1628
    tscError("invalid input param, db:%p, dbInfo:%p", db, dbInfo);
×
1629
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1630
    return terrno;
×
1631
  }
1632

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

1642
  STscObj  *pTscObj = pRequest->pTscObj;
×
1643
  SCatalog *pCtg = NULL;
×
1644
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
×
1645
  if (code != TSDB_CODE_SUCCESS) {
×
1646
    goto _return;
×
1647
  }
1648

1649
  SRequestConnInfo conn = {
×
1650
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
×
1651

1652
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
×
1653

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

1657
  code = catalogGetDBVgInfo(pCtg, &conn, dbFName, dbInfo);
×
1658
  if (code) {
×
1659
    goto _return;
×
1660
  }
1661

1662
_return:
×
1663

1664
  terrno = code;
×
1665

1666
  destroyRequest(pRequest);
×
1667
  return code;
×
1668
}
1669

1670
int taos_get_table_vgId(TAOS *taos, const char *db, const char *table, int *vgId) {
×
1671
  if (NULL == taos) {
×
1672
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1673
    return terrno;
×
1674
  }
1675

1676
  if (NULL == db || NULL == table || NULL == vgId) {
×
1677
    tscError("invalid input param, db:%p, table:%p, vgId:%p", db, table, vgId);
×
1678
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1679
    return terrno;
×
1680
  }
1681

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

1690
  pRequest->syncQuery = true;
×
1691

1692
  STscObj  *pTscObj = pRequest->pTscObj;
×
1693
  SCatalog *pCtg = NULL;
×
1694
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
×
1695
  if (code != TSDB_CODE_SUCCESS) {
×
1696
    goto _return;
×
1697
  }
1698

1699
  SRequestConnInfo conn = {
×
1700
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
×
1701

1702
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
×
1703

1704
  SName tableName = {0};
×
1705
  toName(pTscObj->acctId, db, table, &tableName);
×
1706

1707
  SVgroupInfo vgInfo;
1708
  code = catalogGetTableHashVgroup(pCtg, &conn, &tableName, &vgInfo);
×
1709
  if (code) {
×
1710
    goto _return;
×
1711
  }
1712

1713
  *vgId = vgInfo.vgId;
×
1714

1715
_return:
×
1716

1717
  terrno = code;
×
1718

1719
  destroyRequest(pRequest);
×
1720
  return code;
×
1721
}
1722

1723
int taos_get_tables_vgId(TAOS *taos, const char *db, const char *table[], int tableNum, int *vgId) {
×
1724
  if (NULL == taos) {
×
1725
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1726
    return terrno;
×
1727
  }
1728

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

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

1743
  pRequest->syncQuery = true;
×
1744

1745
  STscObj  *pTscObj = pRequest->pTscObj;
×
1746
  SCatalog *pCtg = NULL;
×
1747
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
×
1748
  if (code != TSDB_CODE_SUCCESS) {
×
1749
    goto _return;
×
1750
  }
1751

1752
  SRequestConnInfo conn = {
×
1753
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
×
1754

1755
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
×
1756

1757
  code = catalogGetTablesHashVgId(pCtg, &conn, pTscObj->acctId, db, table, tableNum, vgId);
×
1758
  if (code) {
×
1759
    goto _return;
×
1760
  }
1761

1762
_return:
×
1763

1764
  terrno = code;
×
1765

1766
  destroyRequest(pRequest);
×
1767
  return code;
×
1768
}
1769

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

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

1782
  if (NULL == tableNameList) {
3!
1783
    return TSDB_CODE_SUCCESS;
×
1784
  }
1785

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

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

1801
  pRequest->syncQuery = true;
3✔
1802

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

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

1815
  SRequestConnInfo conn = {
3✔
1816
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
3✔
1817

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

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

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

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

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

1851
  return pStmt;
41✔
1852
}
1853

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

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

1868
  return pStmt;
×
1869
}
1870

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

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

1885
  return pStmt;
4✔
1886
}
1887

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

1895
  return stmtPrepare(stmt, sql, length);
53✔
1896
}
1897

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

1905
  int32_t code = stmtSetTbName(stmt, name);
8✔
1906
  if (code) {
8!
1907
    return code;
×
1908
  }
1909

1910
  if (tags) {
8!
1911
    return stmtSetTbTags(stmt, tags);
8✔
1912
  }
1913

1914
  return TSDB_CODE_SUCCESS;
×
1915
}
1916

1917
int taos_stmt_set_tbname(TAOS_STMT *stmt, const char *name) {
48✔
1918
  if (stmt == NULL || name == NULL) {
48!
1919
    tscError("NULL parameter for %s", __FUNCTION__);
×
1920
    terrno = TSDB_CODE_INVALID_PARA;
×
1921
    return terrno;
×
1922
  }
1923

1924
  return stmtSetTbName(stmt, name);
48✔
1925
}
1926

1927
int taos_stmt_set_tags(TAOS_STMT *stmt, TAOS_MULTI_BIND *tags) {
×
1928
  if (stmt == NULL || tags == NULL) {
×
1929
    tscError("NULL parameter for %s", __FUNCTION__);
×
1930
    terrno = TSDB_CODE_INVALID_PARA;
×
1931
    return terrno;
×
1932
  }
1933

1934
  return stmtSetTbTags(stmt, tags);
×
1935
}
1936

1937
int taos_stmt_set_sub_tbname(TAOS_STMT *stmt, const char *name) { return taos_stmt_set_tbname(stmt, name); }
×
1938

1939
int taos_stmt_get_tag_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields) {
×
1940
  if (stmt == NULL || NULL == fieldNum) {
×
1941
    tscError("NULL parameter for %s", __FUNCTION__);
×
1942
    terrno = TSDB_CODE_INVALID_PARA;
×
1943
    return terrno;
×
1944
  }
1945

1946
  return stmtGetTagFields(stmt, fieldNum, fields);
×
1947
}
1948

1949
int taos_stmt_get_col_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields) {
×
1950
  if (stmt == NULL || NULL == fieldNum) {
×
1951
    tscError("NULL parameter for %s", __FUNCTION__);
×
1952
    terrno = TSDB_CODE_INVALID_PARA;
×
1953
    return terrno;
×
1954
  }
1955

1956
  return stmtGetColFields(stmt, fieldNum, fields);
×
1957
}
1958

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

1966
int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
54✔
1967
  if (stmt == NULL || bind == NULL) {
54!
1968
    tscError("NULL parameter for %s", __FUNCTION__);
×
1969
    terrno = TSDB_CODE_INVALID_PARA;
×
1970
    return terrno;
×
1971
  }
1972

1973
  if (bind->num > 1) {
54✔
1974
    tscError("invalid bind number %d for %s", bind->num, __FUNCTION__);
6!
1975
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
6✔
1976
    return terrno;
6✔
1977
  }
1978

1979
  return stmtBindBatch(stmt, bind, -1);
48✔
1980
}
1981

1982
int taos_stmt_bind_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
59✔
1983
  if (stmt == NULL || bind == NULL) {
59!
1984
    tscError("NULL parameter for %s", __FUNCTION__);
×
1985
    terrno = TSDB_CODE_INVALID_PARA;
×
1986
    return terrno;
×
1987
  }
1988

1989
  if (bind->num <= 0 || bind->num > INT16_MAX) {
59!
1990
    tscError("invalid bind num %d", bind->num);
×
1991
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
1992
    return terrno;
×
1993
  }
1994

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

2007
  return stmtBindBatch(stmt, bind, -1);
59✔
2008
}
2009

2010
int taos_stmt_bind_single_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int colIdx) {
×
2011
  if (stmt == NULL || bind == NULL) {
×
2012
    tscError("NULL parameter for %s", __FUNCTION__);
×
2013
    terrno = TSDB_CODE_INVALID_PARA;
×
2014
    return terrno;
×
2015
  }
2016

2017
  if (colIdx < 0) {
×
2018
    tscError("invalid bind column idx %d", colIdx);
×
2019
    terrno = TSDB_CODE_INVALID_PARA;
×
2020
    return terrno;
×
2021
  }
2022

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

2035
  return stmtBindBatch(stmt, bind, colIdx);
×
2036
}
2037

2038
int taos_stmt_add_batch(TAOS_STMT *stmt) {
96✔
2039
  if (stmt == NULL) {
96!
2040
    tscError("NULL parameter for %s", __FUNCTION__);
×
2041
    terrno = TSDB_CODE_INVALID_PARA;
×
2042
    return terrno;
×
2043
  }
2044

2045
  return stmtAddBatch(stmt);
96✔
2046
}
2047

2048
int taos_stmt_execute(TAOS_STMT *stmt) {
89✔
2049
  if (stmt == NULL) {
89!
2050
    tscError("NULL parameter for %s", __FUNCTION__);
×
2051
    terrno = TSDB_CODE_INVALID_PARA;
×
2052
    return terrno;
×
2053
  }
2054

2055
  return stmtExec(stmt);
89✔
2056
}
2057

2058
int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert) {
×
2059
  if (stmt == NULL || insert == NULL) {
×
2060
    tscError("NULL parameter for %s", __FUNCTION__);
×
2061
    terrno = TSDB_CODE_INVALID_PARA;
×
2062
    return terrno;
×
2063
  }
2064

2065
  return stmtIsInsert(stmt, insert);
×
2066
}
2067

2068
int taos_stmt_num_params(TAOS_STMT *stmt, int *nums) {
×
2069
  if (stmt == NULL || nums == NULL) {
×
2070
    tscError("NULL parameter for %s", __FUNCTION__);
×
2071
    terrno = TSDB_CODE_INVALID_PARA;
×
2072
    return terrno;
×
2073
  }
2074

2075
  return stmtGetParamNum(stmt, nums);
×
2076
}
2077

2078
int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) {
×
2079
  if (stmt == NULL || type == NULL || NULL == bytes || idx < 0) {
×
2080
    tscError("invalid parameter for %s", __FUNCTION__);
×
2081
    terrno = TSDB_CODE_INVALID_PARA;
×
2082
    return terrno;
×
2083
  }
2084

2085
  return stmtGetParam(stmt, idx, type, bytes);
×
2086
}
2087

2088
TAOS_RES *taos_stmt_use_result(TAOS_STMT *stmt) {
16✔
2089
  if (stmt == NULL) {
16!
2090
    tscError("NULL parameter for %s", __FUNCTION__);
×
2091
    terrno = TSDB_CODE_INVALID_PARA;
×
2092
    return NULL;
×
2093
  }
2094

2095
  return stmtUseResult(stmt);
16✔
2096
}
2097

2098
char *taos_stmt_errstr(TAOS_STMT *stmt) { return (char *)stmtErrstr(stmt); }
16✔
2099

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

2107
  return stmtAffectedRows(stmt);
5✔
2108
}
2109

2110
int taos_stmt_affected_rows_once(TAOS_STMT *stmt) {
×
2111
  if (stmt == NULL) {
×
2112
    tscError("NULL parameter for %s", __FUNCTION__);
×
2113
    terrno = TSDB_CODE_INVALID_PARA;
×
2114
    return 0;
×
2115
  }
2116

2117
  return stmtAffectedRowsOnce(stmt);
×
2118
}
2119

2120
int taos_stmt_close(TAOS_STMT *stmt) {
45✔
2121
  if (stmt == NULL) {
45!
2122
    tscError("NULL parameter for %s", __FUNCTION__);
×
2123
    terrno = TSDB_CODE_INVALID_PARA;
×
2124
    return terrno;
×
2125
  }
2126

2127
  return stmtClose(stmt);
45✔
2128
}
2129

2130
TAOS_STMT2 *taos_stmt2_init(TAOS *taos, TAOS_STMT2_OPTION *option) {
×
2131
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
×
2132
  if (NULL == pObj) {
×
2133
    tscError("invalid parameter for %s", __FUNCTION__);
×
2134
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
2135
    return NULL;
×
2136
  }
2137

2138
  TAOS_STMT2 *pStmt = stmtInit2(pObj, option);
×
2139

2140
  releaseTscObj(*(int64_t *)taos);
×
2141

2142
  return pStmt;
×
2143
}
2144

2145
int taos_stmt2_prepare(TAOS_STMT2 *stmt, const char *sql, unsigned long length) {
×
2146
  if (stmt == NULL || sql == NULL) {
×
2147
    tscError("NULL parameter for %s", __FUNCTION__);
×
2148
    terrno = TSDB_CODE_INVALID_PARA;
×
2149
    return terrno;
×
2150
  }
2151

2152
  return stmtPrepare2(stmt, sql, length);
×
2153
}
2154

2155
int taos_stmt2_bind_param(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx) {
×
2156
  if (stmt == NULL) {
×
2157
    tscError("NULL parameter for %s", __FUNCTION__);
×
2158
    terrno = TSDB_CODE_INVALID_PARA;
×
2159
    return terrno;
×
2160
  }
2161

2162
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
×
2163
  if (pStmt->options.asyncExecFn && !pStmt->semWaited) {
×
2164
    if (tsem_wait(&pStmt->asyncQuerySem) != 0) {
×
2165
      tscError("wait async query sem failed");
×
2166
    }
2167
    pStmt->semWaited = true;
×
2168
  }
2169

2170
  int32_t code = 0;
×
2171
  for (int i = 0; i < bindv->count; ++i) {
×
2172
    if (bindv->tbnames && bindv->tbnames[i]) {
×
2173
      code = stmtSetTbName2(stmt, bindv->tbnames[i]);
×
2174
      if (code) {
×
2175
        return code;
×
2176
      }
2177
    }
2178

2179
    if (bindv->tags && bindv->tags[i]) {
×
2180
      code = stmtSetTbTags2(stmt, bindv->tags[i]);
×
2181
      if (code) {
×
2182
        return code;
×
2183
      }
2184
    }
2185

2186
    if (bindv->bind_cols && bindv->bind_cols[i]) {
×
2187
      TAOS_STMT2_BIND *bind = bindv->bind_cols[i];
×
2188

2189
      if (bind->num <= 0 || bind->num > INT16_MAX) {
×
2190
        tscError("invalid bind num %d", bind->num);
×
2191
        terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
2192
        return terrno;
×
2193
      }
2194

2195
      int32_t insert = 0;
×
2196
      (void)stmtIsInsert2(stmt, &insert);
×
2197
      if (0 == insert && bind->num > 1) {
×
2198
        tscError("only one row data allowed for query");
×
2199
        terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
2200
        return terrno;
×
2201
      }
2202

2203
      code = stmtBindBatch2(stmt, bind, col_idx);
×
2204
      if (TSDB_CODE_SUCCESS != code) {
×
2205
        return code;
×
2206
      }
2207
    }
2208
  }
2209

2210
  return TSDB_CODE_SUCCESS;
×
2211
}
2212

2213
int taos_stmt2_exec(TAOS_STMT2 *stmt, int *affected_rows) {
×
2214
  if (stmt == NULL) {
×
2215
    tscError("NULL parameter for %s", __FUNCTION__);
×
2216
    terrno = TSDB_CODE_INVALID_PARA;
×
2217
    return terrno;
×
2218
  }
2219

2220
  return stmtExec2(stmt, affected_rows);
×
2221
}
2222

2223
int taos_stmt2_close(TAOS_STMT2 *stmt) {
×
2224
  if (stmt == NULL) {
×
2225
    tscError("NULL parameter for %s", __FUNCTION__);
×
2226
    terrno = TSDB_CODE_INVALID_PARA;
×
2227
    return terrno;
×
2228
  }
2229

2230
  return stmtClose2(stmt);
×
2231
}
2232
/*
2233
int taos_stmt2_param_count(TAOS_STMT2 *stmt, int *nums) {
2234
  if (stmt == NULL || nums == NULL) {
2235
    tscError("NULL parameter for %s", __FUNCTION__);
2236
    terrno = TSDB_CODE_INVALID_PARA;
2237
    return terrno;
2238
  }
2239
  return stmtGetParamNum2(stmt, nums);
2240
}
2241
*/
2242
int taos_stmt2_is_insert(TAOS_STMT2 *stmt, int *insert) {
×
2243
  if (stmt == NULL || insert == NULL) {
×
2244
    tscError("NULL parameter for %s", __FUNCTION__);
×
2245
    terrno = TSDB_CODE_INVALID_PARA;
×
2246
    return terrno;
×
2247
  }
2248

2249
  return stmtIsInsert2(stmt, insert);
×
2250
}
2251

2252
int taos_stmt2_get_fields(TAOS_STMT2 *stmt, TAOS_FIELD_T field_type, int *count, TAOS_FIELD_E **fields) {
×
2253
  if (stmt == NULL || count == NULL) {
×
2254
    tscError("NULL parameter for %s", __FUNCTION__);
×
2255
    terrno = TSDB_CODE_INVALID_PARA;
×
2256
    return terrno;
×
2257
  }
2258

2259
  if (field_type == TAOS_FIELD_COL) {
×
2260
    return stmtGetColFields2(stmt, count, fields);
×
2261
  } else if (field_type == TAOS_FIELD_TAG) {
×
2262
    return stmtGetTagFields2(stmt, count, fields);
×
2263
  } else if (field_type == TAOS_FIELD_QUERY) {
×
2264
    return stmtGetParamNum2(stmt, count);
×
2265
  } else if (field_type == TAOS_FIELD_TBNAME) {
×
2266
    return stmtGetParamTbName(stmt, count);
×
2267
  } else {
2268
    tscError("invalid parameter for %s", __FUNCTION__);
×
2269
    terrno = TSDB_CODE_INVALID_PARA;
×
2270
    return terrno;
×
2271
  }
2272
}
2273

2274
int taos_stmt2_get_stb_fields(TAOS_STMT2 *stmt, int *count, TAOS_FIELD_STB **fields) {
×
2275
  if (stmt == NULL || count == NULL) {
×
2276
    tscError("NULL parameter for %s", __FUNCTION__);
×
2277
    terrno = TSDB_CODE_INVALID_PARA;
×
2278
    return terrno;
×
2279
  }
2280

2281
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
×
2282
  if (pStmt->sql.type == 0) {
×
2283
    int isInsert = 0;
×
2284
    (void)stmtIsInsert2(stmt, &isInsert);
×
2285
    if (!isInsert) {
×
2286
      pStmt->sql.type = STMT_TYPE_QUERY;
×
2287
    }
2288
  }
2289
  if (pStmt->sql.type == STMT_TYPE_QUERY) {
×
2290
    return stmtGetParamNum2(stmt, count);
×
2291
  }
2292

2293
  return stmtGetStbColFields2(stmt, count, fields);
×
2294
}
2295

2296
void taos_stmt2_free_fields(TAOS_STMT2 *stmt, TAOS_FIELD_E *fields) {
×
2297
  (void)stmt;
2298
  if (!fields) return;
×
2299
  taosMemoryFree(fields);
×
2300
}
2301

2302
DLL_EXPORT void taos_stmt2_free_stb_fields(TAOS_STMT2 *stmt, TAOS_FIELD_STB *fields) {
×
2303
  (void)stmt;
2304
  if (!fields) return;
×
2305
  taosMemoryFree(fields);
×
2306
}
2307

2308
TAOS_RES *taos_stmt2_result(TAOS_STMT2 *stmt) {
×
2309
  if (stmt == NULL) {
×
2310
    tscError("NULL parameter for %s", __FUNCTION__);
×
2311
    terrno = TSDB_CODE_INVALID_PARA;
×
2312
    return NULL;
×
2313
  }
2314

2315
  return stmtUseResult2(stmt);
×
2316
}
2317

2318
char *taos_stmt2_error(TAOS_STMT2 *stmt) { return (char *)stmtErrstr2(stmt); }
×
2319

2320
int taos_set_conn_mode(TAOS *taos, int mode, int value) {
5✔
2321
  if (taos == NULL) {
5!
2322
    terrno = TSDB_CODE_INVALID_PARA;
×
2323
    return terrno;
×
2324
  }
2325

2326
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
5✔
2327
  if (NULL == pObj) {
5!
2328
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
2329
    tscError("invalid parameter for %s", __func__);
×
2330
    return terrno;
×
2331
  }
2332
  switch (mode) {
5!
2333
    case TAOS_CONN_MODE_BI:
5✔
2334
      atomic_store_8(&pObj->biMode, value);
5✔
2335
      break;
5✔
2336
    default:
×
2337
      tscError("not supported mode.");
×
2338
      return TSDB_CODE_INVALID_PARA;
×
2339
  }
2340
  return 0;
5✔
2341
}
2342

2343
char *getBuildInfo() { return td_buildinfo; }
12✔
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