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

taosdata / TDengine / #3558

17 Dec 2024 06:05AM UTC coverage: 59.778% (+1.6%) from 58.204%
#3558

push

travis-ci

web-flow
Merge pull request #29179 from taosdata/merge/mainto3.0

merge: form main to 3.0 branch

132787 of 287595 branches covered (46.17%)

Branch coverage included in aggregate %.

104 of 191 new or added lines in 5 files covered. (54.45%)

6085 existing lines in 168 files now uncovered.

209348 of 284746 relevant lines covered (73.52%)

8164844.48 hits per line

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

38.82
/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,606✔
42
  if (arg == NULL) {
1,606!
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) {
14,845✔
48
    if (i % 1000 == 0) {
13,239✔
49
      (void)sched_yield();
13✔
50
    }
51
  }
52

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

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

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

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

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

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

UNCOV
91
  tscDebug("set timezone to %s", val);
×
UNCOV
92
  tz = tzalloc(val);
×
UNCOV
93
  if (tz == NULL) {
×
UNCOV
94
    tscWarn("%s unknown timezone %s change to UTC", __func__, val);
×
UNCOV
95
    tz = tzalloc("UTC");
×
UNCOV
96
    if (tz == NULL) {
×
97
      tscError("%s set timezone UTC error", __func__);
×
98
      terrno = TAOS_SYSTEM_ERROR(errno);
×
99
      goto END;
×
100
    }
101
  }
UNCOV
102
  int32_t code = taosHashPut(pTimezoneMap, val, strlen(val), &tz, sizeof(timezone_t));
×
UNCOV
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

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

UNCOV
120
END:
×
UNCOV
121
  return tz;
×
122
}
123
#endif
124

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

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

UNCOV
136
  if (option < TSDB_OPTION_CONNECTION_CLEAR || option >= TSDB_MAX_OPTIONS_CONNECTION){
×
UNCOV
137
    return terrno = TSDB_CODE_INVALID_PARA;
×
138
  }
139

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

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

UNCOV
152
  if (option == TSDB_OPTION_CONNECTION_CLEAR){
×
UNCOV
153
    val = NULL;
×
154
  }
155

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

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

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

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

UNCOV
211
END:
×
UNCOV
212
  releaseTscObj(*(int64_t *)taos);
×
UNCOV
213
  return terrno = code;
×
214
}
215

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

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

227
  monitorClose();
1,975✔
228
  tscStopCrashReport();
1,975✔
229

230
  hbMgrCleanUp();
1,975✔
231

232
  catalogDestroy();
1,975✔
233
  schedulerDestroy();
1,975✔
234

235
  fmFuncMgtDestroy();
1,975✔
236
  qCleanupKeywordsTable();
1,975✔
237

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

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

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

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

255
  nodesDestroyAllocatorSet();
1,975✔
256
  //  cleanupAppInfo();
257
  rpcCleanup();
1,975✔
258
  tscDebug("rpc cleanup");
1,975✔
259

260
  taosConvDestroy();
1,975✔
261
  DestroyRegexCache();
1,975✔
262

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

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

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

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

287
  if (pass == NULL) {
9,327!
UNCOV
288
    pass = TSDB_DEFAULT_PASS;
×
289
  }
290

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

305
  return NULL;
129✔
306
}
307

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

475
void taos_close_internal(void *taos) {
9,735✔
476
  if (taos == NULL) {
9,735✔
477
    return;
1✔
478
  }
479

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

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

488
void taos_close(TAOS *taos) {
9,972✔
489
  if (taos == NULL) {
9,972✔
490
    return;
776✔
491
  }
492

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

499
  taos_close_internal(pObj);
9,196✔
500
  releaseTscObj(*(int64_t *)taos);
9,196✔
501
  taosMemoryFree(taos);
9,196!
502
}
503

504
int taos_errno(TAOS_RES *res) {
11,714,826✔
505
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
11,714,826!
506
    return terrno;
1✔
507
  }
508

509
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
11,722,566!
UNCOV
510
    return 0;
×
511
  }
512

513
  return ((SRequestObj *)res)->code;
11,722,629✔
514
}
515

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

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

525
  SRequestObj *pRequest = (SRequestObj *)res;
79,744✔
526
  if (NULL != pRequest->msgBuf && (strlen(pRequest->msgBuf) > 0 || pRequest->code == TSDB_CODE_RPC_FQDN_ERROR)) {
79,744!
527
    return pRequest->msgBuf;
70,696✔
528
  } else {
529
    return (const char *)tstrerror(pRequest->code);
9,048✔
530
  }
531
}
532

533
void taos_free_result(TAOS_RES *res) {
10,424,492✔
534
  if (NULL == res) {
10,424,492✔
535
    return;
50✔
536
  }
537

538
  tscDebug("taos free res %p", res);
10,424,442✔
539

540
  if (TD_RES_QUERY(res)) {
10,431,326✔
541
    SRequestObj *pRequest = (SRequestObj *)res;
10,398,763✔
542
    tscDebug("0x%" PRIx64 " taos_free_result start to free query", pRequest->requestId);
10,398,763✔
543
    destroyRequest(pRequest);
10,398,763✔
544
    return;
10,398,404✔
545
  }
546
  SMqRspObj *pRsp = (SMqRspObj *)res;
32,563✔
547
  if (TD_RES_TMQ(res)) {
32,563✔
548
    tDeleteMqDataRsp(&pRsp->dataRsp);
32,343✔
549
    doFreeReqResultInfo(&pRsp->resInfo);
32,343✔
550
  } else if (TD_RES_TMQ_METADATA(res)) {
220✔
551
    tDeleteSTaosxRsp(&pRsp->dataRsp);
13✔
552
    doFreeReqResultInfo(&pRsp->resInfo);
13✔
553
  } else if (TD_RES_TMQ_META(res)) {
207✔
554
    tDeleteMqMetaRsp(&pRsp->metaRsp);
188✔
555
  } else if (TD_RES_TMQ_BATCH_META(res)) {
19!
556
    tDeleteMqBatchMetaRsp(&pRsp->batchMetaRsp);
19✔
557
  }
558
  taosMemoryFree(pRsp);
32,563!
559
}
560

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

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

574
int taos_field_count(TAOS_RES *res) {
43,432,902✔
575
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
43,432,902!
UNCOV
576
    return 0;
×
577
  }
578

579
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
43,432,995✔
580
  return pResInfo->numOfCols;
43,432,995✔
581
}
582

583
int taos_num_fields(TAOS_RES *res) { return taos_field_count(res); }
24,494,076✔
584

585
TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) {
16,380,261✔
586
  if (taos_num_fields(res) == 0 || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
16,380,261!
587
    return NULL;
129,564✔
588
  }
589

590
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
16,250,630✔
591
  return pResInfo->userFields;
16,250,630✔
592
}
593

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

599
TAOS_ROW taos_fetch_row(TAOS_RES *res) {
20,695,926✔
600
  if (res == NULL) {
20,695,926!
UNCOV
601
    return NULL;
×
602
  }
603

604
  if (TD_RES_QUERY(res)) {
20,695,926✔
605
    SRequestObj *pRequest = (SRequestObj *)res;
5,579,379✔
606
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
5,579,379!
607
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0 || pRequest->killed) {
5,579,225!
608
      return NULL;
155✔
609
    }
610

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

617
    return doAsyncFetchRows(pRequest, true, true);
5,579,221✔
618
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
15,116,547!
619
    SMqRspObj      *msg = ((SMqRspObj *)res);
15,116,547✔
620
    SReqResultInfo *pResultInfo = NULL;
15,116,547✔
621
    if (msg->resIter == -1) {
15,116,547✔
622
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
31,974!
UNCOV
623
        return NULL;
×
624
      }
625
    } else {
626
      pResultInfo = tmqGetCurResInfo(res);
15,084,573✔
627
    }
628

629
    if (pResultInfo->current < pResultInfo->numOfRows) {
15,116,546✔
630
      doSetOneRowPtr(pResultInfo);
14,789,058✔
631
      pResultInfo->current += 1;
14,788,719✔
632
      return pResultInfo->row;
14,788,719✔
633
    } else {
634
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
327,488✔
635
        return NULL;
31,969✔
636
      }
637

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

651
int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
15,088,983✔
652
  return taos_print_row_with_size(str, INT32_MAX, row, fields, num_fields);
15,088,983✔
653
}
654
int taos_print_row_with_size(char *str, uint32_t size, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
15,089,055✔
655
  int32_t len = 0;
15,089,055✔
656
  for (int i = 0; i < num_fields; ++i) {
90,765,859✔
657
    if (i > 0 && len < size - 1) {
75,667,421!
658
      str[len++] = ' ';
60,609,674✔
659
    }
660

661
    if (row[i] == NULL) {
75,667,421✔
662
      len += tsnprintf(str + len, size - len, "%s", TSDB_DATA_NULL_STR);
231,674✔
663
      continue;
231,689✔
664
    }
665

666
    switch (fields[i].type) {
75,435,747!
UNCOV
667
      case TSDB_DATA_TYPE_TINYINT:
×
UNCOV
668
        len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
×
669
        break;
×
670

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

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

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

683
      case TSDB_DATA_TYPE_INT:
16,463,716✔
684
        len += tsnprintf(str + len, size - len, "%d", *((int32_t *)row[i]));
16,463,716✔
685
        break;
16,465,899✔
686

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

691
      case TSDB_DATA_TYPE_BIGINT:
13,667,613✔
692
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
13,667,613✔
693
        break;
13,667,418✔
694

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

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

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

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

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

745
      case TSDB_DATA_TYPE_TIMESTAMP:
20,655,309✔
746
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
20,655,309✔
747
        break;
20,663,357✔
748

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

755
    if (len >= size - 1) {
75,445,115!
UNCOV
756
      break;
×
757
    }
758
  }
759
  if (len < size) {
15,098,438✔
760
    str[len] = 0;
15,087,914✔
761
  }
762

763
  return len;
15,098,438✔
764
}
765

766
int *taos_fetch_lengths(TAOS_RES *res) {
18,478,731✔
767
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
18,478,731!
UNCOV
768
    return NULL;
×
769
  }
770

771
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
18,478,760✔
772
  return pResInfo->length;
18,478,760✔
773
}
774

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

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

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

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

840
const char *taos_get_client_info() { return td_version; }
1,620✔
841

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

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

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

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

866
int taos_result_precision(TAOS_RES *res) {
16,010,615✔
867
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
16,010,615!
UNCOV
868
    return TSDB_TIME_PRECISION_MILLI;
×
869
  }
870

871
  if (TD_RES_QUERY(res)) {
16,010,631✔
872
    SRequestObj *pRequest = (SRequestObj *)res;
926,906✔
873
    return pRequest->body.resInfo.precision;
926,906✔
874
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
15,083,725!
875
    SReqResultInfo *info = tmqGetCurResInfo(res);
15,083,725✔
876
    return info->precision;
15,083,725✔
877
  }
UNCOV
878
  return TSDB_TIME_PRECISION_MILLI;
×
879
}
880

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

889
  if (db == NULL || strlen(db) == 0) {
107!
890
    releaseTscObj(*(int64_t *)taos);
×
UNCOV
891
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
UNCOV
892
    return terrno;
×
893
  }
894

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

898
  TAOS_RES *pRequest = taos_query(taos, sql);
107✔
899
  int32_t   code = taos_errno(pRequest);
107✔
900

901
  taos_free_result(pRequest);
107✔
902
  releaseTscObj(*(int64_t *)taos);
107✔
903
  return code;
107✔
904
}
905

906
void taos_stop_query(TAOS_RES *res) {
10,402,311✔
907
  if (res == NULL || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
10,402,311!
908
      TD_RES_TMQ_BATCH_META(res)) {
10,410,071!
UNCOV
909
    return;
×
910
  }
911

912
  stopAllQueries((SRequestObj *)res);
10,411,552✔
913
}
914

915
bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) {
244,506,007✔
916
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
244,506,007!
UNCOV
917
    return true;
×
918
  }
919
  SReqResultInfo *pResultInfo = tscGetCurResInfo(res);
244,506,099✔
920
  if (col >= pResultInfo->numOfCols || col < 0 || row >= pResultInfo->numOfRows || row < 0) {
244,506,099✔
921
    return true;
26✔
922
  }
923

924
  SResultColumn *pCol = &pResultInfo->pCol[col];
244,506,073✔
925
  if (IS_VAR_DATA_TYPE(pResultInfo->fields[col].type)) {
244,506,073!
UNCOV
926
    return (pCol->offset[row] == -1);
×
927
  } else {
928
    return colDataIsNull_f(pCol->nullbitmap, row);
244,506,073✔
929
  }
930
}
931

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

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

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

945
  if (TD_RES_QUERY(res)) {
1,165,571✔
946
    SRequestObj *pRequest = (SRequestObj *)res;
1,163,983✔
947

948
    (*rows) = NULL;
1,163,983✔
949
    (*numOfRows) = 0;
1,163,983✔
950

951
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
1,163,983!
952
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
1,161,484!
953
      return pRequest->code;
5,975✔
954
    }
955

956
    (void)doAsyncFetchRows(pRequest, false, true);
1,158,008✔
957

958
    // TODO refactor
959
    SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
1,158,007✔
960
    pResultInfo->current = pResultInfo->numOfRows;
1,158,007✔
961

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

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

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

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

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

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

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

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

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

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

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

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

1020
int *taos_get_column_data_offset(TAOS_RES *res, int columnIndex) {
470,442✔
1021
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
470,442!
UNCOV
1022
    return 0;
×
1023
  }
1024

1025
  int32_t numOfFields = taos_num_fields(res);
470,442✔
1026
  if (columnIndex < 0 || columnIndex >= numOfFields || numOfFields == 0) {
470,442!
UNCOV
1027
    return 0;
×
1028
  }
1029

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

1036
  return pResInfo->pCol[columnIndex].offset;
470,442✔
1037
}
1038

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

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

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

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

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

1080
  int code = taos_errno(pObj);
×
1081

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

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

1093
  resetConnectDB(pTscObj);
×
1094

UNCOV
1095
  releaseTscObj(*(int64_t *)taos);
×
1096
}
1097

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

1105
  releaseTscObj(*(int64_t *)taos);
5✔
1106

1107
  return pTscObj->sDetailVer;
5✔
1108
}
1109

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

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

1135
void destorySqlCallbackWrapper(SSqlCallbackWrapper *pWrapper) {
20,793,693✔
1136
  if (NULL == pWrapper) {
20,793,693✔
1137
    return;
10,408,376✔
1138
  }
1139
  destoryCatalogReq(pWrapper->pCatalogReq);
10,385,317✔
1140
  taosMemoryFree(pWrapper->pCatalogReq);
10,399,028!
1141
  qDestroyParseContext(pWrapper->pParseCtx);
10,417,629✔
1142
  taosMemoryFree(pWrapper);
10,417,759!
1143
}
1144

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

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

1158
  qDebug("0x%" PRIx64 " start to semantic analysis,QID:0x%" PRIx64, pRequest->self, pRequest->requestId);
980,724✔
1159

1160
  int64_t analyseStart = taosGetTimestampUs();
980,723✔
1161
  pRequest->metric.ctgCostUs = analyseStart - pRequest->metric.ctgStart;
980,723✔
1162
  pWrapper->pParseCtx->parseOnly = pRequest->parseOnly;
980,723✔
1163

1164
  if (TSDB_CODE_SUCCESS == code) {
980,723✔
1165
    code = qAnalyseSqlSemantic(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
980,721✔
1166
  }
1167

1168
  pRequest->metric.analyseCostUs += taosGetTimestampUs() - analyseStart;
980,712✔
1169

1170
  if (pRequest->parseOnly) {
980,712✔
1171
    (void)memcpy(&pRequest->parseMeta, pResultMeta, sizeof(*pResultMeta));
410✔
1172
    (void)memset(pResultMeta, 0, sizeof(*pResultMeta));
410✔
1173
  }
1174

1175
  handleQueryAnslyseRes(pWrapper, pResultMeta, code);
980,712✔
1176
}
980,687✔
1177

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

1204
    *ppTarget = pTarget;
507✔
1205
  }
1206

1207
  return code;
507✔
1208
}
1209

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

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

1241
void handleQueryAnslyseRes(SSqlCallbackWrapper *pWrapper, SMetaData *pResultMeta, int32_t code) {
981,172✔
1242
  SRequestObj *pRequest = pWrapper->pRequest;
981,172✔
1243
  SQuery      *pQuery = pRequest->pQuery;
981,172✔
1244

1245
  if (code == TSDB_CODE_SUCCESS && pQuery->pPrevRoot) {
981,172✔
1246
    SNode *prevRoot = pQuery->pPrevRoot;
507✔
1247
    pQuery->pPrevRoot = NULL;
507✔
1248
    handleSubQueryFromAnalyse(pWrapper, pResultMeta, prevRoot);
507✔
1249
    return;
507✔
1250
  }
1251

1252
  if (code == TSDB_CODE_SUCCESS) {
980,665✔
1253
    pRequest->stableQuery = pQuery->stableQuery;
913,588✔
1254
    if (pQuery->pRoot) {
913,588!
1255
      pRequest->stmtType = pQuery->pRoot->type;
913,590✔
1256
    }
1257

1258
    if (pQuery->haveResultSet) {
913,588✔
1259
      code = setResSchemaInfo(&pRequest->body.resInfo, pQuery->pResSchema, pQuery->numOfResCols);
779,250✔
1260
      setResPrecision(&pRequest->body.resInfo, pQuery->precision);
779,249✔
1261
    }
1262
  }
1263

1264
  if (code == TSDB_CODE_SUCCESS) {
980,674✔
1265
    TSWAP(pRequest->dbList, (pQuery)->pDbList);
913,575✔
1266
    TSWAP(pRequest->tableList, (pQuery)->pTableList);
913,575✔
1267
    TSWAP(pRequest->targetTableList, (pQuery)->pTargetTableList);
913,575✔
1268

1269
    launchAsyncQuery(pRequest, pQuery, pResultMeta, pWrapper);
913,575✔
1270
  } else {
1271
    destorySqlCallbackWrapper(pWrapper);
67,099✔
1272
    pRequest->pWrapper = NULL;
67,099✔
1273
    qDestroyQuery(pRequest->pQuery);
67,099✔
1274
    pRequest->pQuery = NULL;
67,099✔
1275

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

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

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

1297
  pWrapper->pRequest->metric.ctgStart = taosGetTimestampUs();
1,011,463✔
1298

1299
  return catalogAsyncGetAllMeta(pWrapper->pParseCtx->pCatalog, &conn, pWrapper->pCatalogReq, fp, pWrapper,
2,022,989✔
1300
                                &pWrapper->pRequest->body.queryJob);
1,011,509✔
1301
}
1302

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

1305
static int32_t phaseAsyncQuery(SSqlCallbackWrapper *pWrapper) {
10,350,773✔
1306
  int32_t code = TSDB_CODE_SUCCESS;
10,350,773✔
1307
  switch (pWrapper->pRequest->pQuery->execStage) {
10,350,773!
1308
    case QUERY_EXEC_STAGE_PARSE: {
31,291✔
1309
      // continue parse after get metadata
1310
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromParse);
31,291✔
1311
      break;
31,294✔
1312
    }
1313
    case QUERY_EXEC_STAGE_ANALYSE: {
980,196✔
1314
      // analysis after get metadata
1315
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromAnalyse);
980,196✔
1316
      break;
980,201✔
1317
    }
1318
    case QUERY_EXEC_STAGE_SCHEDULE: {
9,351,905✔
1319
      launchAsyncQuery(pWrapper->pRequest, pWrapper->pRequest->pQuery, NULL, pWrapper);
9,351,905✔
1320
      break;
9,365,081✔
1321
    }
UNCOV
1322
    default:
×
UNCOV
1323
      break;
×
1324
  }
1325
  return code;
10,363,957✔
1326
}
1327

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

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

1337
  if (code == TSDB_CODE_SUCCESS) {
31,296✔
1338
    // pWrapper->pCatalogReq->forceUpdate = false;
1339
    code = qContinueParseSql(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
30,861✔
1340
  }
1341

1342
  if (TSDB_CODE_SUCCESS == code) {
31,293✔
1343
    code = phaseAsyncQuery(pWrapper);
30,278✔
1344
  }
1345

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

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

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

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

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

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

1389
  *pCxt = taosMemoryCalloc(1, sizeof(SParseContext));
10,397,332!
1390
  if (*pCxt == NULL) {
10,403,467!
UNCOV
1391
    return terrno;
×
1392
  }
1393

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

1423
int32_t prepareAndParseSqlSyntax(SSqlCallbackWrapper **ppWrapper, SRequestObj *pRequest, bool updateMetaForce) {
10,390,595✔
1424
  int32_t              code = TSDB_CODE_SUCCESS;
10,390,595✔
1425
  STscObj             *pTscObj = pRequest->pTscObj;
10,390,595✔
1426
  SSqlCallbackWrapper *pWrapper = taosMemoryCalloc(1, sizeof(SSqlCallbackWrapper));
10,390,595!
1427
  if (pWrapper == NULL) {
10,409,095!
UNCOV
1428
    code = terrno;
×
1429
  } else {
1430
    pWrapper->pRequest = pRequest;
10,409,095✔
1431
    pRequest->pWrapper = pWrapper;
10,409,095✔
1432
    *ppWrapper = pWrapper;
10,409,095✔
1433
  }
1434

1435
  if (TSDB_CODE_SUCCESS == code) {
10,409,095!
1436
    code = createParseContext(pRequest, &pWrapper->pParseCtx, pWrapper);
10,410,709✔
1437
  }
1438

1439
  if (TSDB_CODE_SUCCESS == code) {
10,353,219!
1440
    pWrapper->pParseCtx->mgmtEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
10,355,171✔
1441
    code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pWrapper->pParseCtx->pCatalog);
10,415,952✔
1442
  }
1443

1444
  if (TSDB_CODE_SUCCESS == code && NULL == pRequest->pQuery) {
10,403,431✔
1445
    int64_t syntaxStart = taosGetTimestampUs();
10,378,652✔
1446

1447
    pWrapper->pCatalogReq = taosMemoryCalloc(1, sizeof(SCatalogReq));
10,378,652!
1448
    if (pWrapper->pCatalogReq == NULL) {
10,411,076!
UNCOV
1449
      code = terrno;
×
1450
    } else {
1451
      pWrapper->pCatalogReq->forceUpdate = updateMetaForce;
10,411,076✔
1452
      TSC_ERR_RET(qnodeRequired(pRequest, &pWrapper->pCatalogReq->qNodeRequired));
10,411,076!
1453
      code = qParseSqlSyntax(pWrapper->pParseCtx, &pRequest->pQuery, pWrapper->pCatalogReq);
10,408,613✔
1454
    }
1455

1456
    pRequest->metric.parseCostUs += taosGetTimestampUs() - syntaxStart;
10,329,003✔
1457
  }
1458

1459
  return code;
10,355,610✔
1460
}
1461

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

1466
  if (pRequest->retry++ > REQUEST_TOTAL_EXEC_TIMES) {
10,397,222✔
1467
    code = pRequest->prevCode;
4,059✔
1468
    terrno = code;
4,059✔
1469
    pRequest->code = code;
4,059✔
1470
    tscDebug("call sync query cb with code: %s", tstrerror(code));
4,059✔
1471
    doRequestCallback(pRequest, code);
4,059✔
1472
    return;
4,071✔
1473
  }
1474

1475
  if (TSDB_CODE_SUCCESS == code) {
10,393,163✔
1476
    code = prepareAndParseSqlSyntax(&pWrapper, pRequest, updateMetaForce);
10,392,593✔
1477
  }
1478

1479
  if (TSDB_CODE_SUCCESS == code) {
10,341,923✔
1480
    pRequest->stmtType = pRequest->pQuery->pRoot->type;
10,327,688✔
1481
    code = phaseAsyncQuery(pWrapper);
10,327,688✔
1482
  }
1483

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

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

1505
    terrno = code;
22,452✔
1506
    pRequest->code = code;
22,452✔
1507
    doRequestCallback(pRequest, code);
22,452✔
1508
  }
1509
}
1510

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

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

1549
static int32_t doAsyncFetch(void *pParam) {
825,101✔
1550
  SAsyncFetchParam *param = pParam;
825,101✔
1551
  taosAsyncFetchImpl(param->pReq, param->fp, param->param);
825,101✔
1552
  taosMemoryFree(param);
825,098!
1553
  return TSDB_CODE_SUCCESS;
825,101✔
1554
}
1555

1556
void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
825,105✔
1557
  if (res == NULL || fp == NULL) {
825,105!
UNCOV
1558
    tscError("taos_fetch_rows_a invalid paras");
×
UNCOV
1559
    return;
×
1560
  }
1561
  if (!TD_RES_QUERY(res)) {
825,106!
1562
    tscError("taos_fetch_rows_a res is NULL");
×
UNCOV
1563
    fp(param, res, TSDB_CODE_APP_ERROR);
×
UNCOV
1564
    return;
×
1565
  }
1566

1567
  SRequestObj *pRequest = res;
825,106✔
1568
  if (TSDB_SQL_RETRIEVE_EMPTY_RESULT == pRequest->type) {
825,106✔
1569
    fp(param, res, 0);
5✔
1570
    return;
5✔
1571
  }
1572

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1663
_return:
×
1664

1665
  terrno = code;
×
1666

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

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

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

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

1691
  pRequest->syncQuery = true;
×
1692

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

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

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

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

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

1714
  *vgId = vgInfo.vgId;
×
1715

1716
_return:
×
1717

1718
  terrno = code;
×
1719

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

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

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

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

1744
  pRequest->syncQuery = true;
×
1745

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

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

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

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

1763
_return:
×
1764

1765
  terrno = code;
×
1766

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

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

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

UNCOV
1783
  if (NULL == tableNameList) {
×
UNCOV
1784
    return TSDB_CODE_SUCCESS;
×
1785
  }
1786

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

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

UNCOV
1802
  pRequest->syncQuery = true;
×
1803

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

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

UNCOV
1816
  SRequestConnInfo conn = {
×
UNCOV
1817
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
×
1818

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

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

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

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

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

1852
  return pStmt;
10✔
1853
}
1854

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

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

UNCOV
1869
  return pStmt;
×
1870
}
1871

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

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

UNCOV
1886
  return pStmt;
×
1887
}
1888

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

1896
  return stmtPrepare(stmt, sql, length);
18✔
1897
}
1898

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

1906
  int32_t code = stmtSetTbName(stmt, name);
×
UNCOV
1907
  if (code) {
×
UNCOV
1908
    return code;
×
1909
  }
1910

UNCOV
1911
  if (tags) {
×
UNCOV
1912
    return stmtSetTbTags(stmt, tags);
×
1913
  }
1914

UNCOV
1915
  return TSDB_CODE_SUCCESS;
×
1916
}
1917

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

1925
  return stmtSetTbName(stmt, name);
32✔
1926
}
1927

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2008
  return stmtBindBatch(stmt, bind, -1);
34✔
2009
}
2010

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

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

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

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

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

2046
  return stmtAddBatch(stmt);
34✔
2047
}
2048

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

2056
  return stmtExec(stmt);
34✔
2057
}
2058

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

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

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

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

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

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

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

UNCOV
2096
  return stmtUseResult(stmt);
×
2097
}
2098

2099
char *taos_stmt_errstr(TAOS_STMT *stmt) { return (char *)stmtErrstr(stmt); }
1✔
2100

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

2108
  return stmtAffectedRows(stmt);
2✔
2109
}
2110

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

UNCOV
2118
  return stmtAffectedRowsOnce(stmt);
×
2119
}
2120

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

2128
  return stmtClose(stmt);
10✔
2129
}
2130

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

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

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

UNCOV
2143
  return pStmt;
×
2144
}
2145

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

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

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

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

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

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

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

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

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

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

UNCOV
2211
  return TSDB_CODE_SUCCESS;
×
2212
}
2213

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

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

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

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

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

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

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

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

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

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

2297
DLL_EXPORT void taos_stmt2_free_fields(TAOS_STMT2 *stmt, TAOS_FIELD_ALL *fields) {
×
2298
  (void)stmt;
UNCOV
2299
  if (!fields) return;
×
UNCOV
2300
  taosMemoryFree(fields);
×
2301
}
2302

2303
TAOS_RES *taos_stmt2_result(TAOS_STMT2 *stmt) {
×
2304
  if (stmt == NULL) {
×
UNCOV
2305
    tscError("NULL parameter for %s", __FUNCTION__);
×
UNCOV
2306
    terrno = TSDB_CODE_INVALID_PARA;
×
2307
    return NULL;
×
2308
  }
2309

2310
  return stmtUseResult2(stmt);
×
2311
}
2312

UNCOV
2313
char *taos_stmt2_error(TAOS_STMT2 *stmt) { return (char *)stmtErrstr2(stmt); }
×
2314

2315
int taos_set_conn_mode(TAOS *taos, int mode, int value) {
5✔
2316
  if (taos == NULL) {
5!
2317
    terrno = TSDB_CODE_INVALID_PARA;
×
UNCOV
2318
    return terrno;
×
2319
  }
2320

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

2338
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