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

taosdata / TDengine / #3557

16 Dec 2024 01:23AM UTC coverage: 58.204% (+33.4%) from 24.813%
#3557

push

travis-ci

web-flow
Merge pull request #29105 from taosdata/fix/3_liaohj

enh: update the mnode epset in stream hb rsp.

128414 of 285296 branches covered (45.01%)

Branch coverage included in aggregate %.

36 of 64 new or added lines in 5 files covered. (56.25%)

225 existing lines in 34 files now uncovered.

201842 of 282116 relevant lines covered (71.55%)

19596843.67 hits per line

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

45.41
/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, ...) {
1,774✔
42
  if (arg == NULL) {
1,774!
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) {
249,599✔
48
    if (i % 1000 == 0) {
247,873✔
49
      (void)sched_yield();
247✔
50
    }
51
  }
52

53
  int ret = taos_options_imp(option, (const char *)arg);
1,744✔
54
  atomic_store_32(&lock, 0);
1,774✔
55
  return ret;
1,774✔
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(){
2,748✔
65
  pTimezoneMap = taosHashInit(0, MurmurHash3_32, false, HASH_ENTRY_LOCK);
2,748✔
66
  if (pTimezoneMap == NULL) {
2,748!
67
    return terrno;
×
68
  }
69
  taosHashSetFreeFp(pTimezoneMap, freeTz);
2,748✔
70

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

78
void tzCleanup(){
2,748✔
79
  taosHashCleanup(pTimezoneMap);
2,748✔
80
  taosHashCleanup(pTimezoneNameMap);
2,748✔
81
}
2,748✔
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
  taosFormatTimezoneStr(tx1, val, tz, output);
10✔
113
  code = taosHashPut(pTimezoneNameMap, &tz, sizeof(timezone_t), output, strlen(output) + 1);
10✔
114
  if (code != 0){
10!
115
    tscError("failed to put timezone %s to map", val);
×
116
  }
117

118
END:
10✔
119
  return tz;
17✔
120
}
121
#endif
122

123
static int32_t setConnectionOption(TAOS *taos, TSDB_OPTION_CONNECTION option, const char* val){
38✔
124
  if (taos == NULL) {
38✔
125
    return TSDB_CODE_INVALID_PARA;
1✔
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){
37!
135
    return TSDB_CODE_INVALID_PARA;
1✔
136
  }
137

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

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

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

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

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

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

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

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

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

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

225
  monitorClose();
2,748✔
226
  tscStopCrashReport();
2,748✔
227

228
  hbMgrCleanUp();
2,748✔
229

230
  catalogDestroy();
2,748✔
231
  schedulerDestroy();
2,748✔
232

233
  fmFuncMgtDestroy();
2,748✔
234
  qCleanupKeywordsTable();
2,748✔
235

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

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

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

249
  id = clientConnRefPool;
2,748✔
250
  clientConnRefPool = -1;
2,748✔
251
  taosCloseRef(id);
2,748✔
252

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

258
  taosConvDestroy();
2,748✔
259
  DestroyRegexCache();
2,748✔
260

261
  tscInfo("all local resources released");
2,748!
262
  taosCleanupCfg();
2,748✔
263
  taosCloseLog();
2,748✔
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,330✔
280
  tscDebug("try to connect to %s:%u, user:%s db:%s", ip, port, user, db);
12,330✔
281
  if (user == NULL) {
12,330!
282
    user = TSDB_DEFAULT_USER;
×
283
  }
284

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

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

303
  return NULL;
124✔
304
}
305

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

473
void taos_close_internal(void *taos) {
12,737✔
474
  if (taos == NULL) {
12,737!
475
    return;
×
476
  }
477

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

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

486
void taos_close(TAOS *taos) {
12,937✔
487
  if (taos == NULL) {
12,937✔
488
    return;
735✔
489
  }
490

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

497
  taos_close_internal(pObj);
12,202✔
498
  releaseTscObj(*(int64_t *)taos);
12,202✔
499
  taosMemoryFree(taos);
12,202!
500
}
501

502
int taos_errno(TAOS_RES *res) {
11,981,700✔
503
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
11,981,700!
UNCOV
504
    return terrno;
×
505
  }
506

507
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
11,989,692!
508
    return 0;
377✔
509
  }
510

511
  return ((SRequestObj *)res)->code;
11,989,315✔
512
}
513

514
const char *taos_errstr(TAOS_RES *res) {
85,753✔
515
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
85,753!
516
    return (const char *)tstrerror(terrno);
142✔
517
  }
518

519
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
85,611!
520
    return "success";
×
521
  }
522

523
  SRequestObj *pRequest = (SRequestObj *)res;
85,611✔
524
  if (NULL != pRequest->msgBuf && (strlen(pRequest->msgBuf) > 0 || pRequest->code == TSDB_CODE_RPC_FQDN_ERROR)) {
85,611!
525
    return pRequest->msgBuf;
75,428✔
526
  } else {
527
    return (const char *)tstrerror(pRequest->code);
10,183✔
528
  }
529
}
530

531
void taos_free_result(TAOS_RES *res) {
10,618,201✔
532
  if (NULL == res) {
10,618,201✔
533
    return;
87✔
534
  }
535

536
  tscDebug("taos free res %p", res);
10,618,114✔
537

538
  if (TD_RES_QUERY(res)) {
10,625,714✔
539
    SRequestObj *pRequest = (SRequestObj *)res;
10,596,011✔
540
    tscDebug("0x%" PRIx64 " taos_free_result start to free query", pRequest->requestId);
10,596,011✔
541
    destroyRequest(pRequest);
10,596,011✔
542
    return;
10,589,808✔
543
  }
544
  SMqRspObj *pRsp = (SMqRspObj *)res;
29,703✔
545
  if (TD_RES_TMQ(res)) {
29,703✔
546
    tDeleteMqDataRsp(&pRsp->dataRsp);
29,483✔
547
    doFreeReqResultInfo(&pRsp->resInfo);
29,483✔
548
  } else if (TD_RES_TMQ_METADATA(res)) {
220✔
549
    tDeleteSTaosxRsp(&pRsp->dataRsp);
13✔
550
    doFreeReqResultInfo(&pRsp->resInfo);
13✔
551
  } else if (TD_RES_TMQ_META(res)) {
207✔
552
    tDeleteMqMetaRsp(&pRsp->metaRsp);
188✔
553
  } else if (TD_RES_TMQ_BATCH_META(res)) {
19!
554
    tDeleteMqBatchMetaRsp(&pRsp->batchMetaRsp);
19✔
555
  }
556
  taosMemoryFree(pRsp);
29,703!
557
}
558

559
void taos_kill_query(TAOS *taos) {
10✔
560
  if (NULL == taos) {
10✔
561
    return;
5✔
562
  }
563

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

572
int taos_field_count(TAOS_RES *res) {
43,323,154✔
573
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
43,323,154!
574
    return 0;
×
575
  }
576

577
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
43,323,186✔
578
  return pResInfo->numOfCols;
43,323,186✔
579
}
580

581
int taos_num_fields(TAOS_RES *res) { return taos_field_count(res); }
24,470,141✔
582

583
TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) {
16,138,864✔
584
  if (taos_num_fields(res) == 0 || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
16,138,864!
585
    return NULL;
132,168✔
586
  }
587

588
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
16,006,354✔
589
  return pResInfo->userFields;
16,006,354✔
590
}
591

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

597
TAOS_ROW taos_fetch_row(TAOS_RES *res) {
20,519,435✔
598
  if (res == NULL) {
20,519,435!
599
    return NULL;
×
600
  }
601

602
  if (TD_RES_QUERY(res)) {
20,519,435✔
603
    SRequestObj *pRequest = (SRequestObj *)res;
5,659,815✔
604
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
5,659,815✔
605
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0 || pRequest->killed) {
5,659,680!
606
      return NULL;
139✔
607
    }
608

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

615
    return doAsyncFetchRows(pRequest, true, true);
5,659,674✔
616
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
14,859,620!
617
    SMqRspObj      *msg = ((SMqRspObj *)res);
14,859,620✔
618
    SReqResultInfo *pResultInfo = NULL;
14,859,620✔
619
    if (msg->resIter == -1) {
14,859,620✔
620
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
28,948!
621
        return NULL;
×
622
      }
623
    } else {
624
      pResultInfo = tmqGetCurResInfo(res);
14,830,672✔
625
    }
626

627
    if (pResultInfo->current < pResultInfo->numOfRows) {
14,859,620✔
628
      doSetOneRowPtr(pResultInfo);
14,525,994✔
629
      pResultInfo->current += 1;
14,525,310✔
630
      return pResultInfo->row;
14,525,310✔
631
    } else {
632
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
333,626✔
633
        return NULL;
28,943✔
634
      }
635

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

649
int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
14,840,749✔
650
  return taos_print_row_with_size(str, INT32_MAX, row, fields, num_fields);
14,840,749✔
651
}
652
int taos_print_row_with_size(char *str, uint32_t size, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
14,840,553✔
653
  int32_t len = 0;
14,840,553✔
654
  for (int i = 0; i < num_fields; ++i) {
88,219,259✔
655
    if (i > 0 && len < size - 1) {
73,369,391!
656
      str[len++] = ' ';
58,563,671✔
657
    }
658

659
    if (row[i] == NULL) {
73,369,391✔
660
      len += tsnprintf(str + len, size - len, "%s", TSDB_DATA_NULL_STR);
268,617✔
661
      continue;
268,603✔
662
    }
663

664
    switch (fields[i].type) {
73,100,774!
665
      case TSDB_DATA_TYPE_TINYINT:
6✔
666
        len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
6✔
667
        break;
6✔
668

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

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

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

681
      case TSDB_DATA_TYPE_INT:
15,992,034✔
682
        len += tsnprintf(str + len, size - len, "%d", *((int32_t *)row[i]));
15,992,034✔
683
        break;
15,995,865✔
684

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

689
      case TSDB_DATA_TYPE_BIGINT:
13,378,183✔
690
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
13,378,183✔
691
        break;
13,377,976✔
692

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

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

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

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

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

743
      case TSDB_DATA_TYPE_TIMESTAMP:
19,993,291✔
744
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
19,993,291✔
745
        break;
20,000,827✔
746

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

753
    if (len >= size - 1) {
73,110,103!
754
      break;
×
755
    }
756
  }
757
  if (len < size) {
14,849,868✔
758
    str[len] = 0;
14,838,880✔
759
  }
760

761
  return len;
14,849,868✔
762
}
763

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

769
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
18,273,395✔
770
  return pResInfo->length;
18,273,395✔
771
}
772

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

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

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

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

838
const char *taos_get_client_info() { return td_version; }
2,523✔
839

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

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

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

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

864
int taos_result_precision(TAOS_RES *res) {
15,774,302✔
865
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
15,774,302!
866
    return TSDB_TIME_PRECISION_MILLI;
×
867
  }
868

869
  if (TD_RES_QUERY(res)) {
15,774,318✔
870
    SRequestObj *pRequest = (SRequestObj *)res;
943,472✔
871
    return pRequest->body.resInfo.precision;
943,472✔
872
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
14,830,846!
873
    SReqResultInfo *info = tmqGetCurResInfo(res);
14,830,846✔
874
    return info->precision;
14,830,846✔
875
  }
876
  return TSDB_TIME_PRECISION_MILLI;
×
877
}
878

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

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

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

896
  TAOS_RES *pRequest = taos_query(taos, sql);
6,369✔
897
  int32_t   code = taos_errno(pRequest);
6,369✔
898

899
  taos_free_result(pRequest);
6,368✔
900
  releaseTscObj(*(int64_t *)taos);
6,369✔
901
  return code;
6,369✔
902
}
903

904
void taos_stop_query(TAOS_RES *res) {
10,601,811✔
905
  if (res == NULL || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
10,601,811!
906
      TD_RES_TMQ_BATCH_META(res)) {
10,609,280!
907
    return;
×
908
  }
909

910
  stopAllQueries((SRequestObj *)res);
10,610,689✔
911
}
912

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

922
  SResultColumn *pCol = &pResultInfo->pCol[col];
270,567,603✔
923
  if (IS_VAR_DATA_TYPE(pResultInfo->fields[col].type)) {
270,567,603!
924
    return (pCol->offset[row] == -1);
18✔
925
  } else {
926
    return colDataIsNull_f(pCol->nullbitmap, row);
270,567,585✔
927
  }
928
}
929

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

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

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

943
  if (TD_RES_QUERY(res)) {
1,218,518✔
944
    SRequestObj *pRequest = (SRequestObj *)res;
1,214,477✔
945

946
    (*rows) = NULL;
1,214,477✔
947
    (*numOfRows) = 0;
1,214,477✔
948

949
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
1,214,477!
950
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
1,212,015!
951
      return pRequest->code;
6,012✔
952
    }
953

954
    (void)doAsyncFetchRows(pRequest, false, true);
1,208,465✔
955

956
    // TODO refactor
957
    SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
1,208,465✔
958
    pResultInfo->current = pResultInfo->numOfRows;
1,208,465✔
959

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1034
  return pResInfo->pCol[columnIndex].offset;
498,920✔
1035
}
1036

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

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

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

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

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

1078
  int code = taos_errno(pObj);
×
1079

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

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

1091
  resetConnectDB(pTscObj);
×
1092

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

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

1103
  releaseTscObj(*(int64_t *)taos);
5✔
1104

1105
  return pTscObj->sDetailVer;
5✔
1106
}
1107

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

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

1133
void destorySqlCallbackWrapper(SSqlCallbackWrapper *pWrapper) {
21,182,876✔
1134
  if (NULL == pWrapper) {
21,182,876✔
1135
    return;
10,606,006✔
1136
  }
1137
  destoryCatalogReq(pWrapper->pCatalogReq);
10,576,870✔
1138
  taosMemoryFree(pWrapper->pCatalogReq);
10,592,637!
1139
  qDestroyParseContext(pWrapper->pParseCtx);
10,612,671✔
1140
  taosMemoryFree(pWrapper);
10,611,863!
1141
}
1142

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

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

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

1158
  int64_t analyseStart = taosGetTimestampUs();
1,066,501✔
1159
  pRequest->metric.ctgCostUs = analyseStart - pRequest->metric.ctgStart;
1,066,501✔
1160
  pWrapper->pParseCtx->parseOnly = pRequest->parseOnly;
1,066,501✔
1161

1162
  if (TSDB_CODE_SUCCESS == code) {
1,066,501✔
1163
    code = qAnalyseSqlSemantic(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
1,066,498✔
1164
  }
1165

1166
  pRequest->metric.analyseCostUs += taosGetTimestampUs() - analyseStart;
1,066,465✔
1167

1168
  if (pRequest->parseOnly) {
1,066,465✔
1169
    (void)memcpy(&pRequest->parseMeta, pResultMeta, sizeof(*pResultMeta));
408✔
1170
    (void)memset(pResultMeta, 0, sizeof(*pResultMeta));
408✔
1171
  }
1172

1173
  handleQueryAnslyseRes(pWrapper, pResultMeta, code);
1,066,465✔
1174
}
1,066,436✔
1175

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

1202
    *ppTarget = pTarget;
513✔
1203
  }
1204

1205
  return code;
513✔
1206
}
1207

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

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

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

1243
  if (code == TSDB_CODE_SUCCESS && pQuery->pPrevRoot) {
1,066,945✔
1244
    SNode *prevRoot = pQuery->pPrevRoot;
513✔
1245
    pQuery->pPrevRoot = NULL;
513✔
1246
    handleSubQueryFromAnalyse(pWrapper, pResultMeta, prevRoot);
513✔
1247
    return;
513✔
1248
  }
1249

1250
  if (code == TSDB_CODE_SUCCESS) {
1,066,432✔
1251
    pRequest->stableQuery = pQuery->stableQuery;
997,809✔
1252
    if (pQuery->pRoot) {
997,809!
1253
      pRequest->stmtType = pQuery->pRoot->type;
997,814✔
1254
    }
1255

1256
    if (pQuery->haveResultSet) {
997,809✔
1257
      code = setResSchemaInfo(&pRequest->body.resInfo, pQuery->pResSchema, pQuery->numOfResCols);
824,813✔
1258
      setResPrecision(&pRequest->body.resInfo, pQuery->precision);
824,813✔
1259
    }
1260
  }
1261

1262
  if (code == TSDB_CODE_SUCCESS) {
1,066,426✔
1263
    TSWAP(pRequest->dbList, (pQuery)->pDbList);
997,783✔
1264
    TSWAP(pRequest->tableList, (pQuery)->pTableList);
997,783✔
1265
    TSWAP(pRequest->targetTableList, (pQuery)->pTargetTableList);
997,783✔
1266

1267
    launchAsyncQuery(pRequest, pQuery, pResultMeta, pWrapper);
997,783✔
1268
  } else {
1269
    destorySqlCallbackWrapper(pWrapper);
68,643✔
1270
    pRequest->pWrapper = NULL;
68,643✔
1271
    qDestroyQuery(pRequest->pQuery);
68,643✔
1272
    pRequest->pQuery = NULL;
68,643✔
1273

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

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

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

1295
  pWrapper->pRequest->metric.ctgStart = taosGetTimestampUs();
1,099,180✔
1296

1297
  return catalogAsyncGetAllMeta(pWrapper->pParseCtx->pCatalog, &conn, pWrapper->pCatalogReq, fp, pWrapper,
2,198,453✔
1298
                                &pWrapper->pRequest->body.queryJob);
1,099,239✔
1299
}
1300

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

1303
static int32_t phaseAsyncQuery(SSqlCallbackWrapper *pWrapper) {
10,543,604✔
1304
  int32_t code = TSDB_CODE_SUCCESS;
10,543,604✔
1305
  switch (pWrapper->pRequest->pQuery->execStage) {
10,543,604!
1306
    case QUERY_EXEC_STAGE_PARSE: {
33,266✔
1307
      // continue parse after get metadata
1308
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromParse);
33,266✔
1309
      break;
33,262✔
1310
    }
1311
    case QUERY_EXEC_STAGE_ANALYSE: {
1,065,955✔
1312
      // analysis after get metadata
1313
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromAnalyse);
1,065,955✔
1314
      break;
1,065,958✔
1315
    }
1316
    case QUERY_EXEC_STAGE_SCHEDULE: {
9,457,699✔
1317
      launchAsyncQuery(pWrapper->pRequest, pWrapper->pRequest->pQuery, NULL, pWrapper);
9,457,699✔
1318
      break;
9,472,486✔
1319
    }
1320
    default:
×
1321
      break;
×
1322
  }
1323
  return code;
10,558,390✔
1324
}
1325

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

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

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

1340
  if (TSDB_CODE_SUCCESS == code) {
33,264✔
1341
    code = phaseAsyncQuery(pWrapper);
32,218✔
1342
  }
1343

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

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

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

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

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

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

1387
  *pCxt = taosMemoryCalloc(1, sizeof(SParseContext));
10,596,107!
1388
  if (*pCxt == NULL) {
10,597,971!
1389
    return terrno;
×
1390
  }
1391

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

1421
int32_t prepareAndParseSqlSyntax(SSqlCallbackWrapper **ppWrapper, SRequestObj *pRequest, bool updateMetaForce) {
10,590,501✔
1422
  int32_t              code = TSDB_CODE_SUCCESS;
10,590,501✔
1423
  STscObj             *pTscObj = pRequest->pTscObj;
10,590,501✔
1424
  SSqlCallbackWrapper *pWrapper = taosMemoryCalloc(1, sizeof(SSqlCallbackWrapper));
10,590,501!
1425
  if (pWrapper == NULL) {
10,606,200!
1426
    code = terrno;
×
1427
  } else {
1428
    pWrapper->pRequest = pRequest;
10,606,200✔
1429
    pRequest->pWrapper = pWrapper;
10,606,200✔
1430
    *ppWrapper = pWrapper;
10,606,200✔
1431
  }
1432

1433
  if (TSDB_CODE_SUCCESS == code) {
10,606,200!
1434
    code = createParseContext(pRequest, &pWrapper->pParseCtx, pWrapper);
10,606,708✔
1435
  }
1436

1437
  if (TSDB_CODE_SUCCESS == code) {
10,544,008!
1438
    pWrapper->pParseCtx->mgmtEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
10,544,629✔
1439
    code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pWrapper->pParseCtx->pCatalog);
10,614,383✔
1440
  }
1441

1442
  if (TSDB_CODE_SUCCESS == code && NULL == pRequest->pQuery) {
10,582,994✔
1443
    int64_t syntaxStart = taosGetTimestampUs();
10,566,053✔
1444

1445
    pWrapper->pCatalogReq = taosMemoryCalloc(1, sizeof(SCatalogReq));
10,566,053!
1446
    if (pWrapper->pCatalogReq == NULL) {
10,606,895!
1447
      code = terrno;
×
1448
    } else {
1449
      pWrapper->pCatalogReq->forceUpdate = updateMetaForce;
10,606,895✔
1450
      TSC_ERR_RET(qnodeRequired(pRequest, &pWrapper->pCatalogReq->qNodeRequired));
10,606,895!
1451
      code = qParseSqlSyntax(pWrapper->pParseCtx, &pRequest->pQuery, pWrapper->pCatalogReq);
10,604,021✔
1452
    }
1453

1454
    pRequest->metric.parseCostUs += taosGetTimestampUs() - syntaxStart;
10,515,943✔
1455
  }
1456

1457
  return code;
10,535,939✔
1458
}
1459

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

1464
  if (pRequest->retry++ > REQUEST_TOTAL_EXEC_TIMES) {
10,597,525✔
1465
    code = pRequest->prevCode;
4,584✔
1466
    terrno = code;
4,584✔
1467
    pRequest->code = code;
4,584✔
1468
    tscDebug("call sync query cb with code: %s", tstrerror(code));
4,584✔
1469
    doRequestCallback(pRequest, code);
4,584✔
1470
    return;
4,696✔
1471
  }
1472

1473
  if (TSDB_CODE_SUCCESS == code) {
10,592,941!
1474
    code = prepareAndParseSqlSyntax(&pWrapper, pRequest, updateMetaForce);
10,598,072✔
1475
  }
1476

1477
  if (TSDB_CODE_SUCCESS == code) {
10,533,960✔
1478
    pRequest->stmtType = pRequest->pQuery->pRoot->type;
10,520,400✔
1479
    code = phaseAsyncQuery(pWrapper);
10,520,400✔
1480
  }
1481

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

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

1503
    terrno = code;
25,085✔
1504
    pRequest->code = code;
25,085✔
1505
    doRequestCallback(pRequest, code);
25,085✔
1506
  }
1507
}
1508

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

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

1547
static int32_t doAsyncFetch(void *pParam) {
877,847✔
1548
  SAsyncFetchParam *param = pParam;
877,847✔
1549
  taosAsyncFetchImpl(param->pReq, param->fp, param->param);
877,847✔
1550
  taosMemoryFree(param);
877,842!
1551
  return TSDB_CODE_SUCCESS;
877,845✔
1552
}
1553

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

1565
  SRequestObj *pRequest = res;
877,851✔
1566
  if (TSDB_SQL_RETRIEVE_EMPTY_RESULT == pRequest->type) {
877,851✔
1567
    fp(param, res, 0);
5✔
1568
    return;
5✔
1569
  }
1570

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1661
_return:
×
1662

1663
  terrno = code;
×
1664

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

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

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

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

1689
  pRequest->syncQuery = true;
×
1690

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

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

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

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

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

1712
  *vgId = vgInfo.vgId;
×
1713

1714
_return:
×
1715

1716
  terrno = code;
×
1717

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

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

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

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

1742
  pRequest->syncQuery = true;
×
1743

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

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

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

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

1761
_return:
×
1762

1763
  terrno = code;
×
1764

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

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

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

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

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

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

1800
  pRequest->syncQuery = true;
3✔
1801

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

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

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

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

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

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

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

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

1850
  return pStmt;
23✔
1851
}
1852

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

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

1867
  return pStmt;
×
1868
}
1869

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

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

1884
  return pStmt;
8✔
1885
}
1886

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

1894
  return stmtPrepare(stmt, sql, length);
47✔
1895
}
1896

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

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

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

1913
  return TSDB_CODE_SUCCESS;
×
1914
}
1915

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

1923
  return stmtSetTbName(stmt, name);
96✔
1924
}
1925

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

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

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

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

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

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

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

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

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

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

1978
  return stmtBindBatch(stmt, bind, -1);
5✔
1979
}
1980

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

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

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

2006
  return stmtBindBatch(stmt, bind, -1);
99✔
2007
}
2008

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

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

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

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

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

2044
  return stmtAddBatch(stmt);
101✔
2045
}
2046

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

2054
  return stmtExec(stmt);
101✔
2055
}
2056

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

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

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

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

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

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

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

2094
  return stmtUseResult(stmt);
1✔
2095
}
2096

2097
char *taos_stmt_errstr(TAOS_STMT *stmt) { return (char *)stmtErrstr(stmt); }
4✔
2098

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

2106
  return stmtAffectedRows(stmt);
3✔
2107
}
2108

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

2116
  return stmtAffectedRowsOnce(stmt);
×
2117
}
2118

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

2126
  return stmtClose(stmt);
31✔
2127
}
2128

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

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

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

2141
  return pStmt;
×
2142
}
2143

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

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

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

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

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

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

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

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

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

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

2209
  return TSDB_CODE_SUCCESS;
×
2210
}
2211

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

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

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

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

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

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

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

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

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

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

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

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

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

2314
  return stmtUseResult2(stmt);
×
2315
}
2316

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

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

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

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