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

taosdata / TDengine / #3530

16 Nov 2024 07:44AM UTC coverage: 60.219% (-0.7%) from 60.888%
#3530

push

travis-ci

web-flow
Update 03-ad.md

118417 of 252124 branches covered (46.97%)

Branch coverage included in aggregate %.

198982 of 274951 relevant lines covered (72.37%)

6072359.98 hits per line

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

45.34
/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

34
#define TSC_VAR_NOT_RELEASE 1
35
#define TSC_VAR_RELEASED    0
36

37
static int32_t sentinel = TSC_VAR_NOT_RELEASE;
38
static int32_t createParseContext(const SRequestObj *pRequest, SParseContext **pCxt, SSqlCallbackWrapper *pWrapper);
39

40
int taos_options(TSDB_OPTION option, const void *arg, ...) {
1,969✔
41
  static int32_t lock = 0;
42

43
  for (int i = 1; atomic_val_compare_exchange_32(&lock, 0, 1) != 0; ++i) {
1,969!
44
    if (i % 1000 == 0) {
×
45
      tscInfo("haven't acquire lock after spin %d times.", i);
×
46
      (void)sched_yield();
×
47
    }
48
  }
49

50
  int ret = taos_options_imp(option, (const char *)arg);
1,969✔
51
  atomic_store_32(&lock, 0);
1,969✔
52
  return ret;
1,969✔
53
}
54
// this function may be called by user or system, or by both simultaneously.
55
void taos_cleanup(void) {
3,298✔
56
  tscDebug("start to cleanup client environment");
3,298✔
57
  if (atomic_val_compare_exchange_32(&sentinel, TSC_VAR_NOT_RELEASE, TSC_VAR_RELEASED) != TSC_VAR_NOT_RELEASE) {
3,298✔
58
    return;
10✔
59
  }
60

61
  monitorClose();
3,288✔
62
  tscStopCrashReport();
3,288✔
63

64
  hbMgrCleanUp();
3,288✔
65

66
  catalogDestroy();
3,288✔
67
  schedulerDestroy();
3,288✔
68

69
  fmFuncMgtDestroy();
3,288✔
70
  qCleanupKeywordsTable();
3,288✔
71

72
  if (TSDB_CODE_SUCCESS != cleanupTaskQueue()) {
3,288!
73
    tscWarn("failed to cleanup task queue");
×
74
  }
75

76
  tmqMgmtClose();
3,288✔
77

78
  int32_t id = clientReqRefPool;
3,288✔
79
  clientReqRefPool = -1;
3,288✔
80
  taosCloseRef(id);
3,288✔
81

82
  id = clientConnRefPool;
3,288✔
83
  clientConnRefPool = -1;
3,288✔
84
  taosCloseRef(id);
3,288✔
85

86
  nodesDestroyAllocatorSet();
3,288✔
87
  //  cleanupAppInfo();
88
  rpcCleanup();
3,288✔
89
  tscDebug("rpc cleanup");
3,288✔
90

91
  taosConvDestroy();
3,288✔
92
  DestroyRegexCache();
3,288✔
93

94
  tscInfo("all local resources released");
3,288!
95
  taosCleanupCfg();
3,288✔
96
  taosCloseLog();
3,288✔
97
}
98

99
static setConfRet taos_set_config_imp(const char *config) {
×
100
  setConfRet ret = {SET_CONF_RET_SUCC, {0}};
×
101
  // TODO: need re-implementation
102
  return ret;
×
103
}
104

105
setConfRet taos_set_config(const char *config) {
×
106
  // TODO  pthread_mutex_lock(&setConfMutex);
107
  setConfRet ret = taos_set_config_imp(config);
×
108
  //  pthread_mutex_unlock(&setConfMutex);
109
  return ret;
×
110
}
111

112
TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port) {
8,786✔
113
  tscDebug("try to connect to %s:%u, user:%s db:%s", ip, port, user, db);
8,786✔
114
  if (user == NULL) {
8,786!
115
    user = TSDB_DEFAULT_USER;
×
116
  }
117

118
  if (pass == NULL) {
8,786!
119
    pass = TSDB_DEFAULT_PASS;
×
120
  }
121

122
  STscObj *pObj = NULL;
8,786✔
123
  int32_t  code = taos_connect_internal(ip, user, pass, NULL, db, port, CONN_TYPE__QUERY, &pObj);
8,786✔
124
  if (TSDB_CODE_SUCCESS == code) {
8,786✔
125
    int64_t *rid = taosMemoryCalloc(1, sizeof(int64_t));
8,685✔
126
    if (NULL == rid) {
8,685!
127
      tscError("out of memory when taos connect to %s:%u, user:%s db:%s", ip, port, user, db);
×
128
      terrno = TSDB_CODE_OUT_OF_MEMORY;
×
129
      return NULL;
×
130
    }
131
    *rid = pObj->id;
8,685✔
132
    return (TAOS *)rid;
8,685✔
133
  } else {
134
    terrno = code;
101✔
135
  }
136

137
  return NULL;
101✔
138
}
139

140
int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type) {
70✔
141
  if (taos == NULL) {
70!
142
    terrno = TSDB_CODE_INVALID_PARA;
×
143
    return terrno;
×
144
  }
145

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

153
  switch (type) {
70!
154
    case TAOS_NOTIFY_PASSVER: {
20✔
155
      TSC_ERR_RET(taosThreadMutexLock(&pObj->mutex));
20!
156
      pObj->passInfo.fp = fp;
20✔
157
      pObj->passInfo.param = param;
20✔
158
      TSC_ERR_RET(taosThreadMutexUnlock(&pObj->mutex));
20!
159
      break;
20✔
160
    }
161
    case TAOS_NOTIFY_WHITELIST_VER: {
×
162
      TSC_ERR_RET(taosThreadMutexLock(&pObj->mutex));
×
163
      pObj->whiteListInfo.fp = fp;
×
164
      pObj->whiteListInfo.param = param;
×
165
      TSC_ERR_RET(taosThreadMutexUnlock(&pObj->mutex));
×
166
      break;
×
167
    }
168
    case TAOS_NOTIFY_USER_DROPPED: {
50✔
169
      TSC_ERR_RET(taosThreadMutexLock(&pObj->mutex));
50!
170
      pObj->userDroppedInfo.fp = fp;
50✔
171
      pObj->userDroppedInfo.param = param;
50✔
172
      TSC_ERR_RET(taosThreadMutexUnlock(&pObj->mutex));
50!
173
      break;
50✔
174
    }
175
    default: {
×
176
      terrno = TSDB_CODE_INVALID_PARA;
×
177
      releaseTscObj(*(int64_t *)taos);
×
178
      return terrno;
×
179
    }
180
  }
181

182
  releaseTscObj(*(int64_t *)taos);
70✔
183
  return 0;
70✔
184
}
185

186
typedef struct SFetchWhiteListInfo {
187
  int64_t                     connId;
188
  __taos_async_whitelist_fn_t userCbFn;
189
  void                       *userParam;
190
} SFetchWhiteListInfo;
191

192
int32_t fetchWhiteListCallbackFn(void *param, SDataBuf *pMsg, int32_t code) {
×
193
  SFetchWhiteListInfo *pInfo = (SFetchWhiteListInfo *)param;
×
194
  TAOS                *taos = &pInfo->connId;
×
195
  if (code != TSDB_CODE_SUCCESS) {
×
196
    pInfo->userCbFn(pInfo->userParam, code, taos, 0, NULL);
×
197
    taosMemoryFree(pMsg->pData);
×
198
    taosMemoryFree(pMsg->pEpSet);
×
199
    taosMemoryFree(pInfo);
×
200
    return code;
×
201
  }
202

203
  SGetUserWhiteListRsp wlRsp;
204
  if (TSDB_CODE_SUCCESS != tDeserializeSGetUserWhiteListRsp(pMsg->pData, pMsg->len, &wlRsp)) {
×
205
    taosMemoryFree(pMsg->pData);
×
206
    taosMemoryFree(pMsg->pEpSet);
×
207
    taosMemoryFree(pInfo);
×
208
    tFreeSGetUserWhiteListRsp(&wlRsp);
×
209
    return terrno;
×
210
  }
211

212
  uint64_t *pWhiteLists = taosMemoryMalloc(wlRsp.numWhiteLists * sizeof(uint64_t));
×
213
  if (pWhiteLists == NULL) {
×
214
    taosMemoryFree(pMsg->pData);
×
215
    taosMemoryFree(pMsg->pEpSet);
×
216
    taosMemoryFree(pInfo);
×
217
    tFreeSGetUserWhiteListRsp(&wlRsp);
×
218
    return terrno;
×
219
  }
220

221
  for (int i = 0; i < wlRsp.numWhiteLists; ++i) {
×
222
    pWhiteLists[i] = ((uint64_t)wlRsp.pWhiteLists[i].mask << 32) | wlRsp.pWhiteLists[i].ip;
×
223
  }
224

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

227
  taosMemoryFree(pWhiteLists);
×
228
  taosMemoryFree(pMsg->pData);
×
229
  taosMemoryFree(pMsg->pEpSet);
×
230
  taosMemoryFree(pInfo);
×
231
  tFreeSGetUserWhiteListRsp(&wlRsp);
×
232
  return code;
×
233
}
234

235
void taos_fetch_whitelist_a(TAOS *taos, __taos_async_whitelist_fn_t fp, void *param) {
×
236
  if (NULL == taos) {
×
237
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
238
    return;
×
239
  }
240

241
  int64_t connId = *(int64_t *)taos;
×
242

243
  STscObj *pTsc = acquireTscObj(connId);
×
244
  if (NULL == pTsc) {
×
245
    fp(param, TSDB_CODE_TSC_DISCONNECTED, taos, 0, NULL);
×
246
    return;
×
247
  }
248

249
  SGetUserWhiteListReq req;
250
  (void)memcpy(req.user, pTsc->user, TSDB_USER_LEN);
×
251
  int32_t msgLen = tSerializeSGetUserWhiteListReq(NULL, 0, &req);
×
252
  if (msgLen < 0) {
×
253
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
254
    releaseTscObj(connId);
×
255
    return;
×
256
  }
257

258
  void *pReq = taosMemoryMalloc(msgLen);
×
259
  if (pReq == NULL) {
×
260
    fp(param, TSDB_CODE_OUT_OF_MEMORY, taos, 0, NULL);
×
261
    releaseTscObj(connId);
×
262
    return;
×
263
  }
264

265
  if (tSerializeSGetUserWhiteListReq(pReq, msgLen, &req) < 0) {
×
266
    fp(param, TSDB_CODE_INVALID_PARA, taos, 0, NULL);
×
267
    taosMemoryFree(pReq);
×
268
    releaseTscObj(connId);
×
269
    return;
×
270
  }
271

272
  SFetchWhiteListInfo *pParam = taosMemoryMalloc(sizeof(SFetchWhiteListInfo));
×
273
  if (pParam == NULL) {
×
274
    fp(param, TSDB_CODE_OUT_OF_MEMORY, taos, 0, NULL);
×
275
    taosMemoryFree(pReq);
×
276
    releaseTscObj(connId);
×
277
    return;
×
278
  }
279

280
  pParam->connId = connId;
×
281
  pParam->userCbFn = fp;
×
282
  pParam->userParam = param;
×
283
  SMsgSendInfo *pSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
×
284
  if (pSendInfo == NULL) {
×
285
    fp(param, TSDB_CODE_OUT_OF_MEMORY, taos, 0, NULL);
×
286
    taosMemoryFree(pParam);
×
287
    taosMemoryFree(pReq);
×
288
    releaseTscObj(connId);
×
289
    return;
×
290
  }
291

292
  pSendInfo->msgInfo = (SDataBuf){.pData = pReq, .len = msgLen, .handle = NULL};
×
293
  pSendInfo->requestId = generateRequestId();
×
294
  pSendInfo->requestObjRefId = 0;
×
295
  pSendInfo->param = pParam;
×
296
  pSendInfo->fp = fetchWhiteListCallbackFn;
×
297
  pSendInfo->msgType = TDMT_MND_GET_USER_WHITELIST;
×
298

299
  SEpSet epSet = getEpSet_s(&pTsc->pAppInfo->mgmtEp);
×
300
  if (TSDB_CODE_SUCCESS != asyncSendMsgToServer(pTsc->pAppInfo->pTransporter, &epSet, NULL, pSendInfo)) {
×
301
    tscWarn("failed to async send msg to server");
×
302
  }
303
  releaseTscObj(connId);
×
304
  return;
×
305
}
306

307
void taos_close_internal(void *taos) {
9,227✔
308
  if (taos == NULL) {
9,227!
309
    return;
×
310
  }
311

312
  STscObj *pTscObj = (STscObj *)taos;
9,227✔
313
  tscDebug("0x%" PRIx64 " try to close connection, numOfReq:%d", pTscObj->id, pTscObj->numOfReqs);
9,227✔
314

315
  if (TSDB_CODE_SUCCESS != taosRemoveRef(clientConnRefPool, pTscObj->id)) {
9,227!
316
    tscError("0x%" PRIx64 " failed to remove ref from conn pool", pTscObj->id);
×
317
  }
318
}
319

320
void taos_close(TAOS *taos) {
9,448✔
321
  if (taos == NULL) {
9,448✔
322
    return;
765✔
323
  }
324

325
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
8,683✔
326
  if (NULL == pObj) {
8,683!
327
    taosMemoryFree(taos);
×
328
    return;
×
329
  }
330

331
  taos_close_internal(pObj);
8,683✔
332
  releaseTscObj(*(int64_t *)taos);
8,683✔
333
  taosMemoryFree(taos);
8,683✔
334
}
335

336
int taos_errno(TAOS_RES *res) {
4,265,729✔
337
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
4,265,729!
338
    return terrno;
18✔
339
  }
340

341
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
4,265,711!
342
    return 0;
246✔
343
  }
344

345
  return ((SRequestObj *)res)->code;
4,265,465✔
346
}
347

348
const char *taos_errstr(TAOS_RES *res) {
142,829✔
349
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
142,829!
350
    return (const char *)tstrerror(terrno);
114✔
351
  }
352

353
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
142,715!
354
    return "success";
×
355
  }
356

357
  SRequestObj *pRequest = (SRequestObj *)res;
142,715✔
358
  if (NULL != pRequest->msgBuf && (strlen(pRequest->msgBuf) > 0 || pRequest->code == TSDB_CODE_RPC_FQDN_ERROR)) {
142,715!
359
    return pRequest->msgBuf;
131,143✔
360
  } else {
361
    return (const char *)tstrerror(pRequest->code);
11,572✔
362
  }
363
}
364

365
void taos_free_result(TAOS_RES *res) {
2,767,047✔
366
  if (NULL == res) {
2,767,047✔
367
    return;
91✔
368
  }
369

370
  tscDebug("taos free res %p", res);
2,766,956✔
371

372
  if (TD_RES_QUERY(res)) {
2,766,957✔
373
    SRequestObj *pRequest = (SRequestObj *)res;
2,732,699✔
374
    tscDebug("0x%" PRIx64 " taos_free_result start to free query", pRequest->requestId);
2,732,699✔
375
    destroyRequest(pRequest);
2,732,699✔
376
    return;
2,732,700✔
377
  }
378
  SMqRspObj *pRsp = (SMqRspObj *)res;
34,258✔
379
  if (TD_RES_TMQ(res)) {
34,258✔
380
    tDeleteMqDataRsp(&pRsp->dataRsp);
34,039✔
381
    doFreeReqResultInfo(&pRsp->resInfo);
34,038✔
382
  } else if (TD_RES_TMQ_METADATA(res)) {
219✔
383
    tDeleteSTaosxRsp(&pRsp->dataRsp);
12✔
384
    doFreeReqResultInfo(&pRsp->resInfo);
12✔
385
  } else if (TD_RES_TMQ_META(res)) {
207✔
386
    tDeleteMqMetaRsp(&pRsp->metaRsp);
188✔
387
  } else if (TD_RES_TMQ_BATCH_META(res)) {
19!
388
    tDeleteMqBatchMetaRsp(&pRsp->batchMetaRsp);
19✔
389
  }
390
  taosMemoryFree(pRsp);
34,258✔
391
}
392

393
void taos_kill_query(TAOS *taos) {
10✔
394
  if (NULL == taos) {
10✔
395
    return;
5✔
396
  }
397

398
  int64_t  rid = *(int64_t *)taos;
5✔
399
  STscObj *pTscObj = acquireTscObj(rid);
5✔
400
  if (pTscObj) {
5!
401
    stopAllRequests(pTscObj->pRequests);
5✔
402
  }
403
  releaseTscObj(rid);
5✔
404
}
405

406
int taos_field_count(TAOS_RES *res) {
44,948,473✔
407
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
44,948,473!
408
    return 0;
×
409
  }
410

411
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
44,948,588✔
412
  return pResInfo->numOfCols;
44,948,588✔
413
}
414

415
int taos_num_fields(TAOS_RES *res) { return taos_field_count(res); }
25,335,901✔
416

417
TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) {
16,481,202✔
418
  if (taos_num_fields(res) == 0 || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
16,481,202!
419
    return NULL;
138,120✔
420
  }
421

422
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
16,343,033✔
423
  return pResInfo->userFields;
16,343,033✔
424
}
425

426
TAOS_RES *taos_query(TAOS *taos, const char *sql) { return taosQueryImpl(taos, sql, false, TD_REQ_FROM_APP); }
2,731,412✔
427
TAOS_RES *taos_query_with_reqid(TAOS *taos, const char *sql, int64_t reqid) {
×
428
  return taosQueryImplWithReqid(taos, sql, false, reqid);
×
429
}
430

431
TAOS_ROW taos_fetch_row(TAOS_RES *res) {
20,751,028✔
432
  if (res == NULL) {
20,751,028!
433
    return NULL;
×
434
  }
435

436
  if (TD_RES_QUERY(res)) {
20,751,028✔
437
    SRequestObj *pRequest = (SRequestObj *)res;
5,602,699✔
438
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
5,602,699!
439
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0 || pRequest->killed) {
5,602,545!
440
      return NULL;
156✔
441
    }
442

443
    if (pRequest->inCallback) {
5,602,536!
444
      tscError("can not call taos_fetch_row before query callback ends.");
×
445
      terrno = TSDB_CODE_TSC_INVALID_OPERATION;
×
446
      return NULL;
×
447
    }
448

449
    return doAsyncFetchRows(pRequest, true, true);
5,602,536✔
450
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
15,148,329!
451
    SMqRspObj      *msg = ((SMqRspObj *)res);
15,148,329✔
452
    SReqResultInfo *pResultInfo = NULL;
15,148,329✔
453
    if (msg->resIter == -1) {
15,148,329✔
454
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
33,755!
455
        return NULL;
×
456
      }
457
    } else {
458
      pResultInfo = tmqGetCurResInfo(res);
15,114,574✔
459
    }
460

461
    if (pResultInfo->current < pResultInfo->numOfRows) {
15,148,328✔
462
      doSetOneRowPtr(pResultInfo);
14,818,903✔
463
      pResultInfo->current += 1;
14,817,653✔
464
      return pResultInfo->row;
14,817,653✔
465
    } else {
466
      if (tmqGetNextResInfo(res, true, &pResultInfo) != 0) {
329,425✔
467
        return NULL;
33,750✔
468
      }
469

470
      doSetOneRowPtr(pResultInfo);
295,663✔
471
      pResultInfo->current += 1;
295,633✔
472
      return pResultInfo->row;
295,633✔
473
    }
474
  } else if (TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
×
475
    return NULL;
×
476
  } else {
477
    tscError("invalid result passed to taos_fetch_row");
×
478
    terrno = TSDB_CODE_TSC_INTERNAL_ERROR;
×
479
    return NULL;
×
480
  }
481
}
482

483
int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
15,118,798✔
484
  return taos_print_row_with_size(str, INT32_MAX, row, fields, num_fields);
15,118,798✔
485
}
486
int taos_print_row_with_size(char *str, uint32_t size, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) {
15,118,694✔
487
  int32_t len = 0;
15,118,694✔
488
  for (int i = 0; i < num_fields; ++i) {
90,817,749✔
489
    if (i > 0 && len < size - 1) {
75,681,229!
490
      str[len++] = ' ';
60,640,772✔
491
    }
492

493
    if (row[i] == NULL) {
75,681,229✔
494
      len += tsnprintf(str + len, size - len, "%s", TSDB_DATA_NULL_STR);
231,656✔
495
      continue;
231,664✔
496
    }
497

498
    switch (fields[i].type) {
75,449,573!
499
      case TSDB_DATA_TYPE_TINYINT:
×
500
        len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
×
501
        break;
×
502

503
      case TSDB_DATA_TYPE_UTINYINT:
×
504
        len += tsnprintf(str + len, size - len, "%u", *((uint8_t *)row[i]));
×
505
        break;
×
506

507
      case TSDB_DATA_TYPE_SMALLINT:
×
508
        len += tsnprintf(str + len, size - len, "%d", *((int16_t *)row[i]));
×
509
        break;
×
510

511
      case TSDB_DATA_TYPE_USMALLINT:
×
512
        len += tsnprintf(str + len, size - len, "%u", *((uint16_t *)row[i]));
×
513
        break;
×
514

515
      case TSDB_DATA_TYPE_INT:
16,467,653✔
516
        len += tsnprintf(str + len, size - len, "%d", *((int32_t *)row[i]));
16,467,653✔
517
        break;
16,470,548✔
518

519
      case TSDB_DATA_TYPE_UINT:
×
520
        len += tsnprintf(str + len, size - len, "%u", *((uint32_t *)row[i]));
×
521
        break;
×
522

523
      case TSDB_DATA_TYPE_BIGINT:
13,673,130✔
524
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
13,673,130✔
525
        break;
13,672,590✔
526

527
      case TSDB_DATA_TYPE_UBIGINT:
×
528
        len += tsnprintf(str + len, size - len, "%" PRIu64, *((uint64_t *)row[i]));
×
529
        break;
×
530

531
      case TSDB_DATA_TYPE_FLOAT: {
1,341✔
532
        float fv = 0;
1,341✔
533
        fv = GET_FLOAT_VAL(row[i]);
1,341✔
534
        len += tsnprintf(str + len, size - len, "%f", fv);
1,341✔
535
      } break;
1,341✔
536

537
      case TSDB_DATA_TYPE_DOUBLE: {
7,920,469✔
538
        double dv = 0;
7,920,469✔
539
        dv = GET_DOUBLE_VAL(row[i]);
7,920,469✔
540
        len += tsnprintf(str + len, size - len, "%lf", dv);
7,920,469✔
541
      } break;
7,920,773✔
542

543
      case TSDB_DATA_TYPE_VARBINARY: {
2✔
544
        void    *data = NULL;
2✔
545
        uint32_t tmp = 0;
2✔
546
        int32_t  charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
2✔
547
        if (taosAscii2Hex(row[i], charLen, &data, &tmp) < 0) {
2!
548
          break;
×
549
        }
550
        uint32_t copyLen = TMIN(size - len - 1, tmp);
2✔
551
        (void)memcpy(str + len, data, copyLen);
2✔
552
        len += copyLen;
2✔
553
        taosMemoryFree(data);
2✔
554
      } break;
2✔
555
      case TSDB_DATA_TYPE_BINARY:
16,829,406✔
556
      case TSDB_DATA_TYPE_NCHAR:
557
      case TSDB_DATA_TYPE_GEOMETRY: {
558
        int32_t charLen = varDataLen((char *)row[i] - VARSTR_HEADER_SIZE);
16,829,406✔
559
        if (fields[i].type == TSDB_DATA_TYPE_BINARY || fields[i].type == TSDB_DATA_TYPE_VARBINARY ||
16,829,406!
560
            fields[i].type == TSDB_DATA_TYPE_GEOMETRY) {
5,439,724!
561
          if (charLen > fields[i].bytes || charLen < 0) {
11,389,674!
562
            tscError("taos_print_row error binary. charLen:%d, fields[i].bytes:%d", charLen, fields[i].bytes);
×
563
            break;
×
564
          }
565
        } else {
566
          if (charLen > fields[i].bytes * TSDB_NCHAR_SIZE || charLen < 0) {
5,439,732✔
567
            tscError("taos_print_row error. charLen:%d, fields[i].bytes:%d", charLen, fields[i].bytes);
2,784!
568
            break;
×
569
          }
570
        }
571

572
        uint32_t copyLen = TMIN(size - len - 1, charLen);
16,828,457✔
573
        (void)memcpy(str + len, row[i], copyLen);
16,828,457✔
574
        len += copyLen;
16,828,457✔
575
      } break;
16,828,457✔
576

577
      case TSDB_DATA_TYPE_TIMESTAMP:
20,678,743✔
578
        len += tsnprintf(str + len, size - len, "%" PRId64, *((int64_t *)row[i]));
20,678,743✔
579
        break;
20,694,851✔
580

581
      case TSDB_DATA_TYPE_BOOL:
×
582
        len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
×
583
      default:
×
584
        break;
×
585
    }
586

587
    if (len >= size - 1) {
75,467,391!
588
      break;
×
589
    }
590
  }
591
  if (len < size) {
15,136,520✔
592
    str[len] = 0;
15,114,596✔
593
  }
594

595
  return len;
15,136,520✔
596
}
597

598
int *taos_fetch_lengths(TAOS_RES *res) {
18,607,120✔
599
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
18,607,120!
600
    return NULL;
×
601
  }
602

603
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
18,607,189✔
604
  return pResInfo->length;
18,607,189✔
605
}
606

607
TAOS_ROW *taos_result_block(TAOS_RES *res) {
×
608
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
×
609
    terrno = TSDB_CODE_INVALID_PARA;
×
610
    return NULL;
×
611
  }
612

613
  if (taos_is_update_query(res)) {
×
614
    return NULL;
×
615
  }
616

617
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
×
618
  return &pResInfo->row;
×
619
}
620

621
// todo intergrate with tDataTypes
622
const char *taos_data_type(int type) {
×
623
  switch (type) {
×
624
    case TSDB_DATA_TYPE_NULL:
×
625
      return "TSDB_DATA_TYPE_NULL";
×
626
    case TSDB_DATA_TYPE_BOOL:
×
627
      return "TSDB_DATA_TYPE_BOOL";
×
628
    case TSDB_DATA_TYPE_TINYINT:
×
629
      return "TSDB_DATA_TYPE_TINYINT";
×
630
    case TSDB_DATA_TYPE_SMALLINT:
×
631
      return "TSDB_DATA_TYPE_SMALLINT";
×
632
    case TSDB_DATA_TYPE_INT:
×
633
      return "TSDB_DATA_TYPE_INT";
×
634
    case TSDB_DATA_TYPE_BIGINT:
×
635
      return "TSDB_DATA_TYPE_BIGINT";
×
636
    case TSDB_DATA_TYPE_FLOAT:
×
637
      return "TSDB_DATA_TYPE_FLOAT";
×
638
    case TSDB_DATA_TYPE_DOUBLE:
×
639
      return "TSDB_DATA_TYPE_DOUBLE";
×
640
    case TSDB_DATA_TYPE_VARCHAR:
×
641
      return "TSDB_DATA_TYPE_VARCHAR";
×
642
      //    case TSDB_DATA_TYPE_BINARY:          return "TSDB_DATA_TYPE_VARCHAR";
643
    case TSDB_DATA_TYPE_TIMESTAMP:
×
644
      return "TSDB_DATA_TYPE_TIMESTAMP";
×
645
    case TSDB_DATA_TYPE_NCHAR:
×
646
      return "TSDB_DATA_TYPE_NCHAR";
×
647
    case TSDB_DATA_TYPE_JSON:
×
648
      return "TSDB_DATA_TYPE_JSON";
×
649
    case TSDB_DATA_TYPE_GEOMETRY:
×
650
      return "TSDB_DATA_TYPE_GEOMETRY";
×
651
    case TSDB_DATA_TYPE_UTINYINT:
×
652
      return "TSDB_DATA_TYPE_UTINYINT";
×
653
    case TSDB_DATA_TYPE_USMALLINT:
×
654
      return "TSDB_DATA_TYPE_USMALLINT";
×
655
    case TSDB_DATA_TYPE_UINT:
×
656
      return "TSDB_DATA_TYPE_UINT";
×
657
    case TSDB_DATA_TYPE_UBIGINT:
×
658
      return "TSDB_DATA_TYPE_UBIGINT";
×
659
    case TSDB_DATA_TYPE_VARBINARY:
×
660
      return "TSDB_DATA_TYPE_VARBINARY";
×
661
    case TSDB_DATA_TYPE_DECIMAL:
×
662
      return "TSDB_DATA_TYPE_DECIMAL";
×
663
    case TSDB_DATA_TYPE_BLOB:
×
664
      return "TSDB_DATA_TYPE_BLOB";
×
665
    case TSDB_DATA_TYPE_MEDIUMBLOB:
×
666
      return "TSDB_DATA_TYPE_MEDIUMBLOB";
×
667
    default:
×
668
      return "UNKNOWN";
×
669
  }
670
}
671

672
const char *taos_get_client_info() { return td_version; }
2,806✔
673

674
// return int32_t
675
int taos_affected_rows(TAOS_RES *res) {
1,575,499✔
676
  if (res == NULL || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
1,575,499!
677
      TD_RES_TMQ_BATCH_META(res)) {
1,575,499!
678
    return 0;
×
679
  }
680

681
  SRequestObj    *pRequest = (SRequestObj *)res;
1,575,499✔
682
  SReqResultInfo *pResInfo = &pRequest->body.resInfo;
1,575,499✔
683
  return (int)pResInfo->numOfRows;
1,575,499✔
684
}
685

686
// return int64_t
687
int64_t taos_affected_rows64(TAOS_RES *res) {
128,282✔
688
  if (res == NULL || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
128,282!
689
      TD_RES_TMQ_BATCH_META(res)) {
128,282!
690
    return 0;
×
691
  }
692

693
  SRequestObj    *pRequest = (SRequestObj *)res;
128,282✔
694
  SReqResultInfo *pResInfo = &pRequest->body.resInfo;
128,282✔
695
  return pResInfo->numOfRows;
128,282✔
696
}
697

698
int taos_result_precision(TAOS_RES *res) {
16,229,284✔
699
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
16,229,284!
700
    return TSDB_TIME_PRECISION_MILLI;
×
701
  }
702

703
  if (TD_RES_QUERY(res)) {
16,229,328✔
704
    SRequestObj *pRequest = (SRequestObj *)res;
1,099,411✔
705
    return pRequest->body.resInfo.precision;
1,099,411✔
706
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
15,129,917!
707
    SReqResultInfo *info = tmqGetCurResInfo(res);
15,129,917✔
708
    return info->precision;
15,129,917✔
709
  }
710
  return TSDB_TIME_PRECISION_MILLI;
×
711
}
712

713
int taos_select_db(TAOS *taos, const char *db) {
3,196✔
714
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
3,196✔
715
  if (pObj == NULL) {
3,197!
716
    releaseTscObj(*(int64_t *)taos);
×
717
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
718
    return TSDB_CODE_TSC_DISCONNECTED;
×
719
  }
720

721
  if (db == NULL || strlen(db) == 0) {
3,197!
722
    releaseTscObj(*(int64_t *)taos);
×
723
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
724
    return terrno;
×
725
  }
726

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

730
  TAOS_RES *pRequest = taos_query(taos, sql);
3,197✔
731
  int32_t   code = taos_errno(pRequest);
3,196✔
732

733
  taos_free_result(pRequest);
3,196✔
734
  releaseTscObj(*(int64_t *)taos);
3,197✔
735
  return code;
3,197✔
736
}
737

738
void taos_stop_query(TAOS_RES *res) {
2,743,752✔
739
  if (res == NULL || TD_RES_TMQ(res) || TD_RES_TMQ_META(res) || TD_RES_TMQ_METADATA(res) ||
2,743,752!
740
      TD_RES_TMQ_BATCH_META(res)) {
2,743,753!
741
    return;
×
742
  }
743

744
  stopAllQueries((SRequestObj *)res);
2,743,753✔
745
}
746

747
bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) {
368,770,651✔
748
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
368,770,651!
749
    return true;
×
750
  }
751
  SReqResultInfo *pResultInfo = tscGetCurResInfo(res);
368,770,651✔
752
  if (col >= pResultInfo->numOfCols || col < 0 || row >= pResultInfo->numOfRows || row < 0) {
368,770,651!
753
    return true;
×
754
  }
755

756
  SResultColumn *pCol = &pResultInfo->pCol[col];
368,770,651✔
757
  if (IS_VAR_DATA_TYPE(pResultInfo->fields[col].type)) {
368,770,651!
758
    return (pCol->offset[row] == -1);
×
759
  } else {
760
    return colDataIsNull_f(pCol->nullbitmap, row);
368,770,651✔
761
  }
762
}
763

764
bool taos_is_update_query(TAOS_RES *res) { return taos_num_fields(res) == 0; }
×
765

766
int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
1,468,615✔
767
  int32_t numOfRows = 0;
1,468,615✔
768
  /*int32_t code = */ terrno = taos_fetch_block_s(res, &numOfRows, rows);
1,468,615✔
769
  return numOfRows;
1,468,613✔
770
}
771

772
int taos_fetch_block_s(TAOS_RES *res, int *numOfRows, TAOS_ROW *rows) {
1,468,615✔
773
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
1,468,615!
774
    return 0;
×
775
  }
776

777
  if (TD_RES_QUERY(res)) {
1,468,615✔
778
    SRequestObj *pRequest = (SRequestObj *)res;
1,449,087✔
779

780
    (*rows) = NULL;
1,449,087✔
781
    (*numOfRows) = 0;
1,449,087✔
782

783
    if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
1,449,087!
784
        pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
1,446,588!
785
      return pRequest->code;
7,439✔
786
    }
787

788
    (void)doAsyncFetchRows(pRequest, false, true);
1,441,648✔
789

790
    // TODO refactor
791
    SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
1,441,648✔
792
    pResultInfo->current = pResultInfo->numOfRows;
1,441,648✔
793

794
    (*rows) = pResultInfo->row;
1,441,648✔
795
    (*numOfRows) = pResultInfo->numOfRows;
1,441,648✔
796
    return pRequest->code;
1,441,648✔
797
  } else if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
19,528!
798
    SReqResultInfo *pResultInfo = NULL;
19,528✔
799
    int32_t         code = tmqGetNextResInfo(res, true, &pResultInfo);
19,528✔
800
    if (code != 0) return code;
19,528✔
801

802
    pResultInfo->current = pResultInfo->numOfRows;
19,308✔
803
    (*rows) = pResultInfo->row;
19,308✔
804
    (*numOfRows) = pResultInfo->numOfRows;
19,308✔
805
    return 0;
19,308✔
806
  } else {
807
    tscError("taos_fetch_block_s invalid res type");
×
808
    return -1;
×
809
  }
810
}
811

812
int taos_fetch_raw_block(TAOS_RES *res, int *numOfRows, void **pData) {
8✔
813
  *numOfRows = 0;
8✔
814
  *pData = NULL;
8✔
815

816
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
8!
817
    return 0;
×
818
  }
819

820
  if (TD_RES_TMQ(res) || TD_RES_TMQ_METADATA(res)) {
8!
821
    SReqResultInfo *pResultInfo = NULL;
×
822
    int32_t         code = tmqGetNextResInfo(res, false, &pResultInfo);
×
823
    if (code != 0) {
×
824
      (*numOfRows) = 0;
×
825
      return 0;
×
826
    }
827

828
    pResultInfo->current = pResultInfo->numOfRows;
×
829
    (*numOfRows) = pResultInfo->numOfRows;
×
830
    (*pData) = (void *)pResultInfo->pData;
×
831
    return 0;
×
832
  }
833

834
  SRequestObj *pRequest = (SRequestObj *)res;
8✔
835

836
  if (pRequest->type == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pRequest->type == TSDB_SQL_INSERT ||
8!
837
      pRequest->code != TSDB_CODE_SUCCESS || taos_num_fields(res) == 0) {
8!
838
    return pRequest->code;
×
839
  }
840

841
  (void)doAsyncFetchRows(pRequest, false, false);
8✔
842

843
  SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
8✔
844

845
  pResultInfo->current = pResultInfo->numOfRows;
8✔
846
  (*numOfRows) = pResultInfo->numOfRows;
8✔
847
  (*pData) = (void *)pResultInfo->pData;
8✔
848

849
  return pRequest->code;
8✔
850
}
851

852
int *taos_get_column_data_offset(TAOS_RES *res, int columnIndex) {
757,282✔
853
  if (res == NULL || TD_RES_TMQ_META(res) || TD_RES_TMQ_BATCH_META(res)) {
757,282!
854
    return 0;
×
855
  }
856

857
  int32_t numOfFields = taos_num_fields(res);
757,282✔
858
  if (columnIndex < 0 || columnIndex >= numOfFields || numOfFields == 0) {
757,282!
859
    return 0;
×
860
  }
861

862
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
757,282✔
863
  TAOS_FIELD     *pField = &pResInfo->userFields[columnIndex];
757,282✔
864
  if (!IS_VAR_DATA_TYPE(pField->type)) {
757,282!
865
    return 0;
×
866
  }
867

868
  return pResInfo->pCol[columnIndex].offset;
757,282✔
869
}
870

871
int taos_is_null_by_column(TAOS_RES *res, int columnIndex, bool result[], int *rows) {
×
872
  if (res == NULL || result == NULL || rows == NULL || *rows <= 0 || columnIndex < 0 || TD_RES_TMQ_META(res) ||
×
873
      TD_RES_TMQ_BATCH_META(res)) {
×
874
    return TSDB_CODE_INVALID_PARA;
×
875
  }
876

877
  int32_t numOfFields = taos_num_fields(res);
×
878
  if (columnIndex >= numOfFields || numOfFields == 0) {
×
879
    return TSDB_CODE_INVALID_PARA;
×
880
  }
881

882
  SReqResultInfo *pResInfo = tscGetCurResInfo(res);
×
883
  TAOS_FIELD     *pField = &pResInfo->userFields[columnIndex];
×
884
  SResultColumn  *pCol = &pResInfo->pCol[columnIndex];
×
885

886
  if (*rows > pResInfo->numOfRows) {
×
887
    *rows = pResInfo->numOfRows;
×
888
  }
889
  if (IS_VAR_DATA_TYPE(pField->type)) {
×
890
    for (int i = 0; i < *rows; i++) {
×
891
      if (pCol->offset[i] == -1) {
×
892
        result[i] = true;
×
893
      } else {
894
        result[i] = false;
×
895
      }
896
    }
897
  } else {
898
    for (int i = 0; i < *rows; i++) {
×
899
      if (colDataIsNull_f(pCol->nullbitmap, i)) {
×
900
        result[i] = true;
×
901
      } else {
902
        result[i] = false;
×
903
      }
904
    }
905
  }
906
  return 0;
×
907
}
908

909
int taos_validate_sql(TAOS *taos, const char *sql) {
×
910
  TAOS_RES *pObj = taosQueryImpl(taos, sql, true, TD_REQ_FROM_APP);
×
911

912
  int code = taos_errno(pObj);
×
913

914
  taos_free_result(pObj);
×
915
  return code;
×
916
}
917

918
void taos_reset_current_db(TAOS *taos) {
×
919
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
×
920
  if (pTscObj == NULL) {
×
921
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
922
    return;
×
923
  }
924

925
  resetConnectDB(pTscObj);
×
926

927
  releaseTscObj(*(int64_t *)taos);
×
928
}
929

930
const char *taos_get_server_info(TAOS *taos) {
5✔
931
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
5✔
932
  if (pTscObj == NULL) {
5!
933
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
934
    return NULL;
×
935
  }
936

937
  releaseTscObj(*(int64_t *)taos);
5✔
938

939
  return pTscObj->sDetailVer;
5✔
940
}
941

942
int taos_get_current_db(TAOS *taos, char *database, int len, int *required) {
4✔
943
  STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
4✔
944
  if (pTscObj == NULL) {
4!
945
    return TSDB_CODE_TSC_DISCONNECTED;
×
946
  }
947

948
  int code = TSDB_CODE_SUCCESS;
4✔
949
  (void)taosThreadMutexLock(&pTscObj->mutex);
4✔
950
  if (database == NULL || len <= 0) {
4!
951
    if (required != NULL) *required = strlen(pTscObj->db) + 1;
2✔
952
    TSC_ERR_JRET(TSDB_CODE_INVALID_PARA);
2!
953
  } else if (len < strlen(pTscObj->db) + 1) {
2✔
954
    tstrncpy(database, pTscObj->db, len);
1✔
955
    if (required) *required = strlen(pTscObj->db) + 1;
1!
956
    TSC_ERR_JRET(TSDB_CODE_INVALID_PARA);
1!
957
  } else {
958
    tstrncpy(database, pTscObj->db, len);
1✔
959
    code = 0;
1✔
960
  }
961
_return:
4✔
962
  (void)taosThreadMutexUnlock(&pTscObj->mutex);
4✔
963
  releaseTscObj(*(int64_t *)taos);
4✔
964
  return code;
4✔
965
}
966

967
void destorySqlCallbackWrapper(SSqlCallbackWrapper *pWrapper) {
5,504,751✔
968
  if (NULL == pWrapper) {
5,504,751✔
969
    return;
2,759,974✔
970
  }
971
  destoryCatalogReq(pWrapper->pCatalogReq);
2,744,777✔
972
  taosMemoryFree(pWrapper->pCatalogReq);
2,744,782✔
973
  qDestroyParseContext(pWrapper->pParseCtx);
2,744,781✔
974
  taosMemoryFree(pWrapper);
2,744,781✔
975
}
976

977
void destroyCtxInRequest(SRequestObj *pRequest) {
17,107✔
978
  schedulerFreeJob(&pRequest->body.queryJob, 0);
17,107✔
979
  qDestroyQuery(pRequest->pQuery);
17,107✔
980
  pRequest->pQuery = NULL;
17,107✔
981
  destorySqlCallbackWrapper(pRequest->pWrapper);
17,107✔
982
  pRequest->pWrapper = NULL;
17,107✔
983
}
17,107✔
984

985
static void doAsyncQueryFromAnalyse(SMetaData *pResultMeta, void *param, int32_t code) {
1,077,602✔
986
  SSqlCallbackWrapper *pWrapper = (SSqlCallbackWrapper *)param;
1,077,602✔
987
  SRequestObj         *pRequest = pWrapper->pRequest;
1,077,602✔
988
  SQuery              *pQuery = pRequest->pQuery;
1,077,602✔
989

990
  qDebug("0x%" PRIx64 " start to semantic analysis,QID:0x%" PRIx64, pRequest->self, pRequest->requestId);
1,077,602✔
991

992
  int64_t analyseStart = taosGetTimestampUs();
1,077,602✔
993
  pRequest->metric.ctgCostUs = analyseStart - pRequest->metric.ctgStart;
1,077,602✔
994
  pWrapper->pParseCtx->parseOnly = pRequest->parseOnly;
1,077,602✔
995

996
  if (TSDB_CODE_SUCCESS == code) {
1,077,602✔
997
    code = qAnalyseSqlSemantic(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
1,077,597✔
998
  }
999

1000
  pRequest->metric.analyseCostUs += taosGetTimestampUs() - analyseStart;
1,077,594✔
1001

1002
  if (pRequest->parseOnly) {
1,077,594✔
1003
    (void)memcpy(&pRequest->parseMeta, pResultMeta, sizeof(*pResultMeta));
426✔
1004
    (void)memset(pResultMeta, 0, sizeof(*pResultMeta));
426✔
1005
  }
1006

1007
  handleQueryAnslyseRes(pWrapper, pResultMeta, code);
1,077,594✔
1008
}
1,077,595✔
1009

1010
int32_t cloneCatalogReq(SCatalogReq **ppTarget, SCatalogReq *pSrc) {
507✔
1011
  int32_t      code = TSDB_CODE_SUCCESS;
507✔
1012
  SCatalogReq *pTarget = taosMemoryCalloc(1, sizeof(SCatalogReq));
507✔
1013
  if (pTarget == NULL) {
507!
1014
    code = terrno;
×
1015
  } else {
1016
    pTarget->pDbVgroup = taosArrayDup(pSrc->pDbVgroup, NULL);
507✔
1017
    pTarget->pDbCfg = taosArrayDup(pSrc->pDbCfg, NULL);
507✔
1018
    pTarget->pDbInfo = taosArrayDup(pSrc->pDbInfo, NULL);
507✔
1019
    pTarget->pTableMeta = taosArrayDup(pSrc->pTableMeta, NULL);
507✔
1020
    pTarget->pTableHash = taosArrayDup(pSrc->pTableHash, NULL);
507✔
1021
    pTarget->pUdf = taosArrayDup(pSrc->pUdf, NULL);
507✔
1022
    pTarget->pIndex = taosArrayDup(pSrc->pIndex, NULL);
507✔
1023
    pTarget->pUser = taosArrayDup(pSrc->pUser, NULL);
507✔
1024
    pTarget->pTableIndex = taosArrayDup(pSrc->pTableIndex, NULL);
507✔
1025
    pTarget->pTableCfg = taosArrayDup(pSrc->pTableCfg, NULL);
507✔
1026
    pTarget->pTableTag = taosArrayDup(pSrc->pTableTag, NULL);
507✔
1027
    pTarget->pView = taosArrayDup(pSrc->pView, NULL);
507✔
1028
    pTarget->pTableTSMAs = taosArrayDup(pSrc->pTableTSMAs, NULL);
507✔
1029
    pTarget->pTSMAs = taosArrayDup(pSrc->pTSMAs, NULL);
507✔
1030
    pTarget->qNodeRequired = pSrc->qNodeRequired;
507✔
1031
    pTarget->dNodeRequired = pSrc->dNodeRequired;
507✔
1032
    pTarget->svrVerRequired = pSrc->svrVerRequired;
507✔
1033
    pTarget->forceUpdate = pSrc->forceUpdate;
507✔
1034
    pTarget->cloned = true;
507✔
1035

1036
    *ppTarget = pTarget;
507✔
1037
  }
1038

1039
  return code;
507✔
1040
}
1041

1042
void handleSubQueryFromAnalyse(SSqlCallbackWrapper *pWrapper, SMetaData *pResultMeta, SNode *pRoot) {
507✔
1043
  SRequestObj         *pNewRequest = NULL;
507✔
1044
  SSqlCallbackWrapper *pNewWrapper = NULL;
507✔
1045
  int32_t              code = buildPreviousRequest(pWrapper->pRequest, pWrapper->pRequest->sqlstr, &pNewRequest);
507✔
1046
  if (code) {
507!
1047
    handleQueryAnslyseRes(pWrapper, pResultMeta, code);
×
1048
    return;
×
1049
  }
1050

1051
  pNewRequest->pQuery = NULL;
507✔
1052
  code = nodesMakeNode(QUERY_NODE_QUERY, (SNode **)&pNewRequest->pQuery);
507✔
1053
  if (pNewRequest->pQuery) {
507!
1054
    pNewRequest->pQuery->pRoot = pRoot;
507✔
1055
    pRoot = NULL;
507✔
1056
    pNewRequest->pQuery->execStage = QUERY_EXEC_STAGE_ANALYSE;
507✔
1057
  }
1058
  if (TSDB_CODE_SUCCESS == code) {
507!
1059
    code = prepareAndParseSqlSyntax(&pNewWrapper, pNewRequest, false);
507✔
1060
  }
1061
  if (TSDB_CODE_SUCCESS == code) {
507!
1062
    code = cloneCatalogReq(&pNewWrapper->pCatalogReq, pWrapper->pCatalogReq);
507✔
1063
  }
1064
  if (TSDB_CODE_SUCCESS == code) {
507!
1065
    doAsyncQueryFromAnalyse(pResultMeta, pNewWrapper, code);
507✔
1066
    nodesDestroyNode(pRoot);
507✔
1067
  } else {
1068
    handleQueryAnslyseRes(pWrapper, pResultMeta, code);
×
1069
    return;
×
1070
  }
1071
}
1072

1073
void handleQueryAnslyseRes(SSqlCallbackWrapper *pWrapper, SMetaData *pResultMeta, int32_t code) {
1,078,076✔
1074
  SRequestObj *pRequest = pWrapper->pRequest;
1,078,076✔
1075
  SQuery      *pQuery = pRequest->pQuery;
1,078,076✔
1076

1077
  if (code == TSDB_CODE_SUCCESS && pQuery->pPrevRoot) {
1,078,076✔
1078
    SNode *prevRoot = pQuery->pPrevRoot;
507✔
1079
    pQuery->pPrevRoot = NULL;
507✔
1080
    handleSubQueryFromAnalyse(pWrapper, pResultMeta, prevRoot);
507✔
1081
    return;
507✔
1082
  }
1083

1084
  if (code == TSDB_CODE_SUCCESS) {
1,077,569✔
1085
    pRequest->stableQuery = pQuery->stableQuery;
980,017✔
1086
    if (pQuery->pRoot) {
980,017!
1087
      pRequest->stmtType = pQuery->pRoot->type;
980,017✔
1088
    }
1089

1090
    if (pQuery->haveResultSet) {
980,017✔
1091
      code = setResSchemaInfo(&pRequest->body.resInfo, pQuery->pResSchema, pQuery->numOfResCols);
823,066✔
1092
      setResPrecision(&pRequest->body.resInfo, pQuery->precision);
823,067✔
1093
    }
1094
  }
1095

1096
  if (code == TSDB_CODE_SUCCESS) {
1,077,571✔
1097
    TSWAP(pRequest->dbList, (pQuery)->pDbList);
980,014✔
1098
    TSWAP(pRequest->tableList, (pQuery)->pTableList);
980,014✔
1099
    TSWAP(pRequest->targetTableList, (pQuery)->pTargetTableList);
980,014✔
1100

1101
    launchAsyncQuery(pRequest, pQuery, pResultMeta, pWrapper);
980,014✔
1102
  } else {
1103
    destorySqlCallbackWrapper(pWrapper);
97,557✔
1104
    pRequest->pWrapper = NULL;
97,557✔
1105
    qDestroyQuery(pRequest->pQuery);
97,557✔
1106
    pRequest->pQuery = NULL;
97,557✔
1107

1108
    if (NEED_CLIENT_HANDLE_ERROR(code)) {
97,557!
1109
      tscDebug("0x%" PRIx64 " client retry to handle the error, code:%d - %s, tryCount:%d,QID:0x%" PRIx64,
16,640✔
1110
               pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId);
1111
      restartAsyncQuery(pRequest, code);
16,640✔
1112
      return;
16,640✔
1113
    }
1114

1115
    // return to app directly
1116
    tscError("0x%" PRIx64 " error occurs, code:%s, return to user app,QID:0x%" PRIx64, pRequest->self, tstrerror(code),
80,917!
1117
             pRequest->requestId);
1118
    pRequest->code = code;
80,917✔
1119
    returnToUser(pRequest);
80,917✔
1120
  }
1121
}
1122

1123
static int32_t getAllMetaAsync(SSqlCallbackWrapper *pWrapper, catalogCallback fp) {
1,080,236✔
1124
  SRequestConnInfo conn = {.pTrans = pWrapper->pParseCtx->pTransporter,
1,080,236✔
1125
                           .requestId = pWrapper->pParseCtx->requestId,
1,080,236✔
1126
                           .requestObjRefId = pWrapper->pParseCtx->requestRid,
1,080,236✔
1127
                           .mgmtEps = pWrapper->pParseCtx->mgmtEpSet};
1,080,236✔
1128

1129
  pWrapper->pRequest->metric.ctgStart = taosGetTimestampUs();
1,080,236✔
1130

1131
  return catalogAsyncGetAllMeta(pWrapper->pParseCtx->pCatalog, &conn, pWrapper->pCatalogReq, fp, pWrapper,
2,160,482✔
1132
                                &pWrapper->pRequest->body.queryJob);
1,080,242✔
1133
}
1134

1135
static void doAsyncQueryFromParse(SMetaData *pResultMeta, void *param, int32_t code);
1136

1137
static int32_t phaseAsyncQuery(SSqlCallbackWrapper *pWrapper) {
2,690,207✔
1138
  int32_t code = TSDB_CODE_SUCCESS;
2,690,207✔
1139
  switch (pWrapper->pRequest->pQuery->execStage) {
2,690,207!
1140
    case QUERY_EXEC_STAGE_PARSE: {
3,148✔
1141
      // continue parse after get metadata
1142
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromParse);
3,148✔
1143
      break;
3,148✔
1144
    }
1145
    case QUERY_EXEC_STAGE_ANALYSE: {
1,077,090✔
1146
      // analysis after get metadata
1147
      code = getAllMetaAsync(pWrapper, doAsyncQueryFromAnalyse);
1,077,090✔
1148
      break;
1,077,093✔
1149
    }
1150
    case QUERY_EXEC_STAGE_SCHEDULE: {
1,609,977✔
1151
      launchAsyncQuery(pWrapper->pRequest, pWrapper->pRequest->pQuery, NULL, pWrapper);
1,609,977✔
1152
      break;
1,609,978✔
1153
    }
1154
    default:
×
1155
      break;
×
1156
  }
1157
  return code;
2,690,211✔
1158
}
1159

1160
static void doAsyncQueryFromParse(SMetaData *pResultMeta, void *param, int32_t code) {
3,148✔
1161
  SSqlCallbackWrapper *pWrapper = (SSqlCallbackWrapper *)param;
3,148✔
1162
  SRequestObj         *pRequest = pWrapper->pRequest;
3,148✔
1163
  SQuery              *pQuery = pRequest->pQuery;
3,148✔
1164

1165
  pRequest->metric.ctgCostUs += taosGetTimestampUs() - pRequest->metric.ctgStart;
3,148✔
1166
  qDebug("0x%" PRIx64 " start to continue parse,QID:0x%" PRIx64 ", code:%s", pRequest->self, pRequest->requestId,
3,148✔
1167
         tstrerror(code));
1168

1169
  if (code == TSDB_CODE_SUCCESS) {
3,148✔
1170
    // pWrapper->pCatalogReq->forceUpdate = false;
1171
    code = qContinueParseSql(pWrapper->pParseCtx, pWrapper->pCatalogReq, pResultMeta, pQuery);
3,035✔
1172
  }
1173

1174
  if (TSDB_CODE_SUCCESS == code) {
3,148✔
1175
    code = phaseAsyncQuery(pWrapper);
2,342✔
1176
  }
1177

1178
  if (TSDB_CODE_SUCCESS != code) {
3,148✔
1179
    tscError("0x%" PRIx64 " error happens, code:%d - %s,QID:0x%" PRIx64, pWrapper->pRequest->self, code,
806!
1180
             tstrerror(code), pWrapper->pRequest->requestId);
1181
    destorySqlCallbackWrapper(pWrapper);
806✔
1182
    pRequest->pWrapper = NULL;
806✔
1183
    terrno = code;
806✔
1184
    pRequest->code = code;
806✔
1185
    doRequestCallback(pRequest, code);
806✔
1186
  }
1187
}
3,148✔
1188

1189
void continueInsertFromCsv(SSqlCallbackWrapper *pWrapper, SRequestObj *pRequest) {
20✔
1190
  int32_t code = qParseSqlSyntax(pWrapper->pParseCtx, &pRequest->pQuery, pWrapper->pCatalogReq);
20✔
1191
  if (TSDB_CODE_SUCCESS == code) {
20!
1192
    code = phaseAsyncQuery(pWrapper);
20✔
1193
  }
1194

1195
  if (TSDB_CODE_SUCCESS != code) {
20!
1196
    tscError("0x%" PRIx64 " error happens, code:%d - %s,QID:0x%" PRIx64, pWrapper->pRequest->self, code,
×
1197
             tstrerror(code), pWrapper->pRequest->requestId);
1198
    destorySqlCallbackWrapper(pWrapper);
×
1199
    pRequest->pWrapper = NULL;
×
1200
    terrno = code;
×
1201
    pRequest->code = code;
×
1202
    doRequestCallback(pRequest, code);
×
1203
  }
1204
}
20✔
1205

1206
void taos_query_a(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param) {
520✔
1207
  int64_t connId = *(int64_t *)taos;
520✔
1208
  tscDebug("taos_query_a start with sql:%s", sql);
520✔
1209
  taosAsyncQueryImpl(connId, sql, fp, param, false, TD_REQ_FROM_APP);
520✔
1210
  tscDebug("taos_query_a end with sql:%s", sql);
520✔
1211
}
520✔
1212

1213
void taos_query_a_with_reqid(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param, int64_t reqid) {
×
1214
  int64_t connId = *(int64_t *)taos;
×
1215
  taosAsyncQueryImplWithReqid(connId, sql, fp, param, false, reqid);
×
1216
}
×
1217

1218
int32_t createParseContext(const SRequestObj *pRequest, SParseContext **pCxt, SSqlCallbackWrapper *pWrapper) {
2,744,774✔
1219
  const STscObj *pTscObj = pRequest->pTscObj;
2,744,774✔
1220

1221
  *pCxt = taosMemoryCalloc(1, sizeof(SParseContext));
2,744,774✔
1222
  if (*pCxt == NULL) {
2,744,771!
1223
    return terrno;
×
1224
  }
1225

1226
  **pCxt = (SParseContext){.requestId = pRequest->requestId,
2,744,771✔
1227
                           .requestRid = pRequest->self,
2,744,771✔
1228
                           .acctId = pTscObj->acctId,
2,744,771✔
1229
                           .db = pRequest->pDb,
2,744,771✔
1230
                           .topicQuery = false,
1231
                           .pSql = pRequest->sqlstr,
2,744,771✔
1232
                           .sqlLen = pRequest->sqlLen,
2,744,771✔
1233
                           .pMsg = pRequest->msgBuf,
2,744,771✔
1234
                           .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE,
1235
                           .pTransporter = pTscObj->pAppInfo->pTransporter,
2,744,771✔
1236
                           .pStmtCb = NULL,
1237
                           .pUser = pTscObj->user,
2,744,771✔
1238
                           .pEffectiveUser = pRequest->effectiveUser,
2,744,771✔
1239
                           .isSuperUser = (0 == strcmp(pTscObj->user, TSDB_DEFAULT_USER)),
2,744,771✔
1240
                           .enableSysInfo = pTscObj->sysInfo,
2,744,771✔
1241
                           .async = true,
1242
                           .svrVer = pTscObj->sVer,
2,744,771✔
1243
                           .nodeOffline = (pTscObj->pAppInfo->onlineDnodes < pTscObj->pAppInfo->totalDnodes),
2,744,771✔
1244
                           .allocatorId = pRequest->allocatorRefId,
2,744,771✔
1245
                           .parseSqlFp = clientParseSql,
1246
                           .parseSqlParam = pWrapper,
1247
                           .setQueryFp = setQueryRequest};
1248
  int8_t biMode = atomic_load_8(&((STscObj *)pTscObj)->biMode);
2,744,771✔
1249
  (*pCxt)->biMode = biMode;
2,744,772✔
1250
  return TSDB_CODE_SUCCESS;
2,744,772✔
1251
}
1252

1253
int32_t prepareAndParseSqlSyntax(SSqlCallbackWrapper **ppWrapper, SRequestObj *pRequest, bool updateMetaForce) {
2,744,776✔
1254
  int32_t              code = TSDB_CODE_SUCCESS;
2,744,776✔
1255
  STscObj             *pTscObj = pRequest->pTscObj;
2,744,776✔
1256
  SSqlCallbackWrapper *pWrapper = taosMemoryCalloc(1, sizeof(SSqlCallbackWrapper));
2,744,776✔
1257
  if (pWrapper == NULL) {
2,744,784✔
1258
    code = terrno;
4✔
1259
  } else {
1260
    pWrapper->pRequest = pRequest;
2,744,780✔
1261
    pRequest->pWrapper = pWrapper;
2,744,780✔
1262
    *ppWrapper = pWrapper;
2,744,780✔
1263
  }
1264

1265
  if (TSDB_CODE_SUCCESS == code) {
2,744,780!
1266
    code = createParseContext(pRequest, &pWrapper->pParseCtx, pWrapper);
2,744,781✔
1267
  }
1268

1269
  if (TSDB_CODE_SUCCESS == code) {
2,744,772!
1270
    pWrapper->pParseCtx->mgmtEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
2,744,773✔
1271
    code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pWrapper->pParseCtx->pCatalog);
2,744,785✔
1272
  }
1273

1274
  if (TSDB_CODE_SUCCESS == code && NULL == pRequest->pQuery) {
2,744,781✔
1275
    int64_t syntaxStart = taosGetTimestampUs();
2,744,266✔
1276

1277
    pWrapper->pCatalogReq = taosMemoryCalloc(1, sizeof(SCatalogReq));
2,744,266✔
1278
    if (pWrapper->pCatalogReq == NULL) {
2,744,271!
1279
      code = terrno;
×
1280
    } else {
1281
      pWrapper->pCatalogReq->forceUpdate = updateMetaForce;
2,744,271✔
1282
      TSC_ERR_RET(qnodeRequired(pRequest, &pWrapper->pCatalogReq->qNodeRequired));
2,744,271!
1283
      code = qParseSqlSyntax(pWrapper->pParseCtx, &pRequest->pQuery, pWrapper->pCatalogReq);
2,744,274✔
1284
    }
1285

1286
    pRequest->metric.parseCostUs += taosGetTimestampUs() - syntaxStart;
2,744,266✔
1287
  }
1288

1289
  return code;
2,744,776✔
1290
}
1291

1292
void doAsyncQuery(SRequestObj *pRequest, bool updateMetaForce) {
2,749,882✔
1293
  SSqlCallbackWrapper *pWrapper = NULL;
2,749,882✔
1294
  int32_t              code = TSDB_CODE_SUCCESS;
2,749,882✔
1295

1296
  if (pRequest->retry++ > REQUEST_TOTAL_EXEC_TIMES) {
2,749,882✔
1297
    code = pRequest->prevCode;
5,611✔
1298
    terrno = code;
5,611✔
1299
    pRequest->code = code;
5,611✔
1300
    tscDebug("call sync query cb with code: %s", tstrerror(code));
5,611✔
1301
    doRequestCallback(pRequest, code);
5,611✔
1302
    return;
5,787✔
1303
  }
1304

1305
  if (TSDB_CODE_SUCCESS == code) {
2,744,271!
1306
    code = prepareAndParseSqlSyntax(&pWrapper, pRequest, updateMetaForce);
2,744,271✔
1307
  }
1308

1309
  if (TSDB_CODE_SUCCESS == code) {
2,744,268✔
1310
    pRequest->stmtType = pRequest->pQuery->pRoot->type;
2,687,851✔
1311
    code = phaseAsyncQuery(pWrapper);
2,687,851✔
1312
  }
1313

1314
  if (TSDB_CODE_SUCCESS != code) {
2,744,274✔
1315
    tscError("0x%" PRIx64 " error happens, code:%d - %s,QID:0x%" PRIx64, pRequest->self, code, tstrerror(code),
56,418!
1316
             pRequest->requestId);
1317
    destorySqlCallbackWrapper(pWrapper);
56,418✔
1318
    pRequest->pWrapper = NULL;
56,418✔
1319
    qDestroyQuery(pRequest->pQuery);
56,418✔
1320
    pRequest->pQuery = NULL;
56,418✔
1321

1322
    if (NEED_CLIENT_HANDLE_ERROR(code)) {
56,418!
1323
      tscDebug("0x%" PRIx64 " client retry to handle the error, code:%d - %s, tryCount:%d,QID:0x%" PRIx64,
176✔
1324
               pRequest->self, code, tstrerror(code), pRequest->retry, pRequest->requestId);
1325
      code = refreshMeta(pRequest->pTscObj, pRequest);
176✔
1326
      if (code != 0) {
176!
1327
        tscWarn("0x%" PRIx64 " refresh meta failed, code:%d - %s,QID:0x%" PRIx64, pRequest->self, code, tstrerror(code),
176!
1328
                pRequest->requestId);
1329
      }
1330
      pRequest->prevCode = code;
176✔
1331
      doAsyncQuery(pRequest, true);
176✔
1332
      return;
176✔
1333
    }
1334

1335
    terrno = code;
56,242✔
1336
    pRequest->code = code;
56,242✔
1337
    doRequestCallback(pRequest, code);
56,242✔
1338
  }
1339
}
1340

1341
void restartAsyncQuery(SRequestObj *pRequest, int32_t code) {
17,107✔
1342
  tscInfo("restart request: %s p: %p", pRequest->sqlstr, pRequest);
17,107!
1343
  SRequestObj *pUserReq = pRequest;
17,107✔
1344
  (void)acquireRequest(pRequest->self);
17,107✔
1345
  while (pUserReq) {
17,131!
1346
    if (pUserReq->self == pUserReq->relation.userRefId || pUserReq->relation.userRefId == 0) {
17,131!
1347
      break;
1348
    } else {
1349
      int64_t nextRefId = pUserReq->relation.nextRefId;
24✔
1350
      (void)releaseRequest(pUserReq->self);
24✔
1351
      if (nextRefId) {
24!
1352
        pUserReq = acquireRequest(nextRefId);
24✔
1353
      }
1354
    }
1355
  }
1356
  bool hasSubRequest = pUserReq != pRequest || pRequest->relation.prevRefId != 0;
17,107!
1357
  if (pUserReq) {
17,107!
1358
    destroyCtxInRequest(pUserReq);
17,107✔
1359
    pUserReq->prevCode = code;
17,107✔
1360
    (void)memset(&pUserReq->relation, 0, sizeof(pUserReq->relation));
17,107✔
1361
  } else {
1362
    tscError("User req is missing");
×
1363
    (void)removeFromMostPrevReq(pRequest);
×
1364
    return;
×
1365
  }
1366
  if (hasSubRequest)
17,107✔
1367
    (void)removeFromMostPrevReq(pRequest);
24✔
1368
  else
1369
    (void)releaseRequest(pUserReq->self);
17,083✔
1370
  doAsyncQuery(pUserReq, true);
17,107✔
1371
}
1372

1373
typedef struct SAsyncFetchParam {
1374
  SRequestObj      *pReq;
1375
  __taos_async_fn_t fp;
1376
  void             *param;
1377
} SAsyncFetchParam;
1378

1379
static int32_t doAsyncFetch(void *pParam) {
948,468✔
1380
  SAsyncFetchParam *param = pParam;
948,468✔
1381
  taosAsyncFetchImpl(param->pReq, param->fp, param->param);
948,468✔
1382
  taosMemoryFree(param);
948,468✔
1383
  return TSDB_CODE_SUCCESS;
948,468✔
1384
}
1385

1386
void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
948,464✔
1387
  if (res == NULL || fp == NULL) {
948,464!
1388
    tscError("taos_fetch_rows_a invalid paras");
×
1389
    return;
×
1390
  }
1391
  if (!TD_RES_QUERY(res)) {
948,466!
1392
    tscError("taos_fetch_rows_a res is NULL");
×
1393
    fp(param, res, TSDB_CODE_APP_ERROR);
×
1394
    return;
×
1395
  }
1396

1397
  SRequestObj *pRequest = res;
948,466✔
1398
  if (TSDB_SQL_RETRIEVE_EMPTY_RESULT == pRequest->type) {
948,466!
1399
    fp(param, res, 0);
×
1400
    return;
×
1401
  }
1402

1403
  SAsyncFetchParam *pParam = taosMemoryCalloc(1, sizeof(SAsyncFetchParam));
948,466✔
1404
  if (!pParam) {
948,467!
1405
    fp(param, res, terrno);
×
1406
    return;
×
1407
  }
1408
  pParam->pReq = pRequest;
948,467✔
1409
  pParam->fp = fp;
948,467✔
1410
  pParam->param = param;
948,467✔
1411
  int32_t code = taosAsyncExec(doAsyncFetch, pParam, NULL);
948,467✔
1412
  if (TSDB_CODE_SUCCESS != code) {
948,468!
1413
    taosMemoryFree(pParam);
×
1414
    fp(param, res, code);
×
1415
    return;
×
1416
  }
1417
}
1418

1419
void taos_fetch_raw_block_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) {
×
1420
  if (res == NULL || fp == NULL) {
×
1421
    tscError("taos_fetch_raw_block_a invalid paras");
×
1422
    return;
×
1423
  }
1424
  if (!TD_RES_QUERY(res)) {
×
1425
    tscError("taos_fetch_raw_block_a res is NULL");
×
1426
    return;
×
1427
  }
1428
  SRequestObj    *pRequest = res;
×
1429
  SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
×
1430

1431
  // set the current block is all consumed
1432
  pResultInfo->convertUcs4 = false;
×
1433

1434
  // it is a local executed query, no need to do async fetch
1435
  taos_fetch_rows_a(pRequest, fp, param);
×
1436
}
1437

1438
const void *taos_get_raw_block(TAOS_RES *res) {
×
1439
  if (res == NULL) {
×
1440
    tscError("taos_get_raw_block invalid paras");
×
1441
    return NULL;
×
1442
  }
1443
  if (!TD_RES_QUERY(res)) {
×
1444
    tscError("taos_get_raw_block res is NULL");
×
1445
    return NULL;
×
1446
  }
1447
  SRequestObj *pRequest = res;
×
1448

1449
  return pRequest->body.resInfo.pData;
×
1450
}
1451

1452
int taos_get_db_route_info(TAOS *taos, const char *db, TAOS_DB_ROUTE_INFO *dbInfo) {
×
1453
  if (NULL == taos) {
×
1454
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1455
    return terrno;
×
1456
  }
1457

1458
  if (NULL == db || NULL == dbInfo) {
×
1459
    tscError("invalid input param, db:%p, dbInfo:%p", db, dbInfo);
×
1460
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1461
    return terrno;
×
1462
  }
1463

1464
  int64_t      connId = *(int64_t *)taos;
×
1465
  SRequestObj *pRequest = NULL;
×
1466
  char        *sql = "taos_get_db_route_info";
×
1467
  int32_t      code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
×
1468
  if (code != TSDB_CODE_SUCCESS) {
×
1469
    terrno = code;
×
1470
    return terrno;
×
1471
  }
1472

1473
  STscObj  *pTscObj = pRequest->pTscObj;
×
1474
  SCatalog *pCtg = NULL;
×
1475
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
×
1476
  if (code != TSDB_CODE_SUCCESS) {
×
1477
    goto _return;
×
1478
  }
1479

1480
  SRequestConnInfo conn = {
×
1481
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
×
1482

1483
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
×
1484

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

1488
  code = catalogGetDBVgInfo(pCtg, &conn, dbFName, dbInfo);
×
1489
  if (code) {
×
1490
    goto _return;
×
1491
  }
1492

1493
_return:
×
1494

1495
  terrno = code;
×
1496

1497
  destroyRequest(pRequest);
×
1498
  return code;
×
1499
}
1500

1501
int taos_get_table_vgId(TAOS *taos, const char *db, const char *table, int *vgId) {
×
1502
  if (NULL == taos) {
×
1503
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1504
    return terrno;
×
1505
  }
1506

1507
  if (NULL == db || NULL == table || NULL == vgId) {
×
1508
    tscError("invalid input param, db:%p, table:%p, vgId:%p", db, table, vgId);
×
1509
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1510
    return terrno;
×
1511
  }
1512

1513
  int64_t      connId = *(int64_t *)taos;
×
1514
  SRequestObj *pRequest = NULL;
×
1515
  char        *sql = "taos_get_table_vgId";
×
1516
  int32_t      code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
×
1517
  if (code != TSDB_CODE_SUCCESS) {
×
1518
    return terrno;
×
1519
  }
1520

1521
  pRequest->syncQuery = true;
×
1522

1523
  STscObj  *pTscObj = pRequest->pTscObj;
×
1524
  SCatalog *pCtg = NULL;
×
1525
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
×
1526
  if (code != TSDB_CODE_SUCCESS) {
×
1527
    goto _return;
×
1528
  }
1529

1530
  SRequestConnInfo conn = {
×
1531
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
×
1532

1533
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
×
1534

1535
  SName tableName = {0};
×
1536
  toName(pTscObj->acctId, db, table, &tableName);
×
1537

1538
  SVgroupInfo vgInfo;
1539
  code = catalogGetTableHashVgroup(pCtg, &conn, &tableName, &vgInfo);
×
1540
  if (code) {
×
1541
    goto _return;
×
1542
  }
1543

1544
  *vgId = vgInfo.vgId;
×
1545

1546
_return:
×
1547

1548
  terrno = code;
×
1549

1550
  destroyRequest(pRequest);
×
1551
  return code;
×
1552
}
1553

1554
int taos_get_tables_vgId(TAOS *taos, const char *db, const char *table[], int tableNum, int *vgId) {
×
1555
  if (NULL == taos) {
×
1556
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1557
    return terrno;
×
1558
  }
1559

1560
  if (NULL == db || NULL == table || NULL == vgId || tableNum <= 0) {
×
1561
    tscError("invalid input param, db:%p, table:%p, vgId:%p, tbNum:%d", db, table, vgId, tableNum);
×
1562
    terrno = TSDB_CODE_TSC_INVALID_INPUT;
×
1563
    return terrno;
×
1564
  }
1565

1566
  int64_t      connId = *(int64_t *)taos;
×
1567
  SRequestObj *pRequest = NULL;
×
1568
  char        *sql = "taos_get_table_vgId";
×
1569
  int32_t      code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
×
1570
  if (code != TSDB_CODE_SUCCESS) {
×
1571
    return terrno;
×
1572
  }
1573

1574
  pRequest->syncQuery = true;
×
1575

1576
  STscObj  *pTscObj = pRequest->pTscObj;
×
1577
  SCatalog *pCtg = NULL;
×
1578
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCtg);
×
1579
  if (code != TSDB_CODE_SUCCESS) {
×
1580
    goto _return;
×
1581
  }
1582

1583
  SRequestConnInfo conn = {
×
1584
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
×
1585

1586
  conn.mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
×
1587

1588
  code = catalogGetTablesHashVgId(pCtg, &conn, pTscObj->acctId, db, table, tableNum, vgId);
×
1589
  if (code) {
×
1590
    goto _return;
×
1591
  }
1592

1593
_return:
×
1594

1595
  terrno = code;
×
1596

1597
  destroyRequest(pRequest);
×
1598
  return code;
×
1599
}
1600

1601
int taos_load_table_info(TAOS *taos, const char *tableNameList) {
3✔
1602
  if (NULL == taos) {
3!
1603
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1604
    return terrno;
×
1605
  }
1606

1607
  int64_t       connId = *(int64_t *)taos;
3✔
1608
  const int32_t MAX_TABLE_NAME_LENGTH = 12 * 1024 * 1024;  // 12MB list
3✔
1609
  int32_t       code = 0;
3✔
1610
  SRequestObj  *pRequest = NULL;
3✔
1611
  SCatalogReq   catalogReq = {0};
3✔
1612

1613
  if (NULL == tableNameList) {
3!
1614
    return TSDB_CODE_SUCCESS;
×
1615
  }
1616

1617
  int32_t length = (int32_t)strlen(tableNameList);
3✔
1618
  if (0 == length) {
3!
1619
    return TSDB_CODE_SUCCESS;
×
1620
  } else if (length > MAX_TABLE_NAME_LENGTH) {
3!
1621
    tscError("tableNameList too long, length:%d, maximum allowed:%d", length, MAX_TABLE_NAME_LENGTH);
×
1622
    return TSDB_CODE_TSC_INVALID_OPERATION;
×
1623
  }
1624

1625
  char *sql = "taos_load_table_info";
3✔
1626
  code = buildRequest(connId, sql, strlen(sql), NULL, false, &pRequest, 0);
3✔
1627
  if (code != TSDB_CODE_SUCCESS) {
3!
1628
    terrno = code;
×
1629
    goto _return;
×
1630
  }
1631

1632
  pRequest->syncQuery = true;
3✔
1633

1634
  STscObj *pTscObj = pRequest->pTscObj;
3✔
1635
  code = transferTableNameList(tableNameList, pTscObj->acctId, pTscObj->db, &catalogReq.pTableMeta);
3✔
1636
  if (code) {
3!
1637
    goto _return;
×
1638
  }
1639

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

1646
  SRequestConnInfo conn = {
3✔
1647
      .pTrans = pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
3✔
1648

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

1651
  code = catalogAsyncGetAllMeta(pCtg, &conn, &catalogReq, syncCatalogFn, pRequest->body.interParam, NULL);
3✔
1652
  if (code) {
3!
1653
    goto _return;
×
1654
  }
1655

1656
  SSyncQueryParam *pParam = pRequest->body.interParam;
3✔
1657
  code = tsem_wait(&pParam->sem);
3✔
1658
  if (code) {
3!
1659
    tscError("tsem wait failed, code:%d - %s", code, tstrerror(code));
×
1660
    goto _return;
×
1661
  }
1662
_return:
3✔
1663
  destoryCatalogReq(&catalogReq);
3✔
1664
  destroyRequest(pRequest);
3✔
1665
  return code;
3✔
1666
}
1667

1668
TAOS_STMT *taos_stmt_init(TAOS *taos) {
41✔
1669
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
41✔
1670
  if (NULL == pObj) {
41!
1671
    tscError("invalid parameter for %s", __FUNCTION__);
×
1672
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1673
    return NULL;
×
1674
  }
1675

1676
  TAOS_STMT *pStmt = stmtInit(pObj, 0, NULL);
41✔
1677
  if (NULL == pStmt) {
41!
1678
    tscError("stmt init failed, errcode:%s", terrstr());
×
1679
  }
1680
  releaseTscObj(*(int64_t *)taos);
41✔
1681

1682
  return pStmt;
41✔
1683
}
1684

1685
TAOS_STMT *taos_stmt_init_with_reqid(TAOS *taos, int64_t reqid) {
×
1686
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
×
1687
  if (NULL == pObj) {
×
1688
    tscError("invalid parameter for %s", __FUNCTION__);
×
1689
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1690
    return NULL;
×
1691
  }
1692

1693
  TAOS_STMT *pStmt = stmtInit(pObj, reqid, NULL);
×
1694
  if (NULL == pStmt) {
×
1695
    tscError("stmt init failed, errcode:%s", terrstr());
×
1696
  }
1697
  releaseTscObj(*(int64_t *)taos);
×
1698

1699
  return pStmt;
×
1700
}
1701

1702
TAOS_STMT *taos_stmt_init_with_options(TAOS *taos, TAOS_STMT_OPTIONS *options) {
4✔
1703
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
4✔
1704
  if (NULL == pObj) {
4!
1705
    tscError("invalid parameter for %s", __FUNCTION__);
×
1706
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1707
    return NULL;
×
1708
  }
1709

1710
  TAOS_STMT *pStmt = stmtInit(pObj, options->reqId, options);
4✔
1711
  if (NULL == pStmt) {
4!
1712
    tscError("stmt init failed, errcode:%s", terrstr());
×
1713
  }
1714
  releaseTscObj(*(int64_t *)taos);
4✔
1715

1716
  return pStmt;
4✔
1717
}
1718

1719
int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length) {
53✔
1720
  if (stmt == NULL || sql == NULL) {
53!
1721
    tscError("NULL parameter for %s", __FUNCTION__);
×
1722
    terrno = TSDB_CODE_INVALID_PARA;
×
1723
    return terrno;
×
1724
  }
1725

1726
  return stmtPrepare(stmt, sql, length);
53✔
1727
}
1728

1729
int taos_stmt_set_tbname_tags(TAOS_STMT *stmt, const char *name, TAOS_MULTI_BIND *tags) {
8✔
1730
  if (stmt == NULL || name == NULL) {
8!
1731
    tscError("NULL parameter for %s", __FUNCTION__);
×
1732
    terrno = TSDB_CODE_INVALID_PARA;
×
1733
    return terrno;
×
1734
  }
1735

1736
  int32_t code = stmtSetTbName(stmt, name);
8✔
1737
  if (code) {
8!
1738
    return code;
×
1739
  }
1740

1741
  if (tags) {
8!
1742
    return stmtSetTbTags(stmt, tags);
8✔
1743
  }
1744

1745
  return TSDB_CODE_SUCCESS;
×
1746
}
1747

1748
int taos_stmt_set_tbname(TAOS_STMT *stmt, const char *name) {
48✔
1749
  if (stmt == NULL || name == NULL) {
48!
1750
    tscError("NULL parameter for %s", __FUNCTION__);
×
1751
    terrno = TSDB_CODE_INVALID_PARA;
×
1752
    return terrno;
×
1753
  }
1754

1755
  return stmtSetTbName(stmt, name);
48✔
1756
}
1757

1758
int taos_stmt_set_tags(TAOS_STMT *stmt, TAOS_MULTI_BIND *tags) {
×
1759
  if (stmt == NULL || tags == NULL) {
×
1760
    tscError("NULL parameter for %s", __FUNCTION__);
×
1761
    terrno = TSDB_CODE_INVALID_PARA;
×
1762
    return terrno;
×
1763
  }
1764

1765
  return stmtSetTbTags(stmt, tags);
×
1766
}
1767

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

1770
int taos_stmt_get_tag_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields) {
×
1771
  if (stmt == NULL || NULL == fieldNum) {
×
1772
    tscError("NULL parameter for %s", __FUNCTION__);
×
1773
    terrno = TSDB_CODE_INVALID_PARA;
×
1774
    return terrno;
×
1775
  }
1776

1777
  return stmtGetTagFields(stmt, fieldNum, fields);
×
1778
}
1779

1780
int taos_stmt_get_col_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields) {
×
1781
  if (stmt == NULL || NULL == fieldNum) {
×
1782
    tscError("NULL parameter for %s", __FUNCTION__);
×
1783
    terrno = TSDB_CODE_INVALID_PARA;
×
1784
    return terrno;
×
1785
  }
1786

1787
  return stmtGetColFields(stmt, fieldNum, fields);
×
1788
}
1789

1790
// let stmt to reclaim TAOS_FIELD_E that was allocated by `taos_stmt_get_tag_fields`/`taos_stmt_get_col_fields`
1791
void taos_stmt_reclaim_fields(TAOS_STMT *stmt, TAOS_FIELD_E *fields) {
×
1792
  (void)stmt;
1793
  if (!fields) return;
×
1794
  taosMemoryFree(fields);
×
1795
}
1796

1797
int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
54✔
1798
  if (stmt == NULL || bind == NULL) {
54!
1799
    tscError("NULL parameter for %s", __FUNCTION__);
×
1800
    terrno = TSDB_CODE_INVALID_PARA;
×
1801
    return terrno;
×
1802
  }
1803

1804
  if (bind->num > 1) {
54✔
1805
    tscError("invalid bind number %d for %s", bind->num, __FUNCTION__);
6!
1806
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
6✔
1807
    return terrno;
6✔
1808
  }
1809

1810
  return stmtBindBatch(stmt, bind, -1);
48✔
1811
}
1812

1813
int taos_stmt_bind_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind) {
59✔
1814
  if (stmt == NULL || bind == NULL) {
59!
1815
    tscError("NULL parameter for %s", __FUNCTION__);
×
1816
    terrno = TSDB_CODE_INVALID_PARA;
×
1817
    return terrno;
×
1818
  }
1819

1820
  if (bind->num <= 0 || bind->num > INT16_MAX) {
59!
1821
    tscError("invalid bind num %d", bind->num);
×
1822
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
1823
    return terrno;
×
1824
  }
1825

1826
  int32_t insert = 0;
59✔
1827
  int32_t code = stmtIsInsert(stmt, &insert);
59✔
1828
  if (TSDB_CODE_SUCCESS != code) {
59!
1829
    tscError("stmt insert failed, errcode:%s", tstrerror(code));
×
1830
    return code;
×
1831
  }
1832
  if (0 == insert && bind->num > 1) {
59!
1833
    tscError("only one row data allowed for query");
×
1834
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
1835
    return terrno;
×
1836
  }
1837

1838
  return stmtBindBatch(stmt, bind, -1);
59✔
1839
}
1840

1841
int taos_stmt_bind_single_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int colIdx) {
×
1842
  if (stmt == NULL || bind == NULL) {
×
1843
    tscError("NULL parameter for %s", __FUNCTION__);
×
1844
    terrno = TSDB_CODE_INVALID_PARA;
×
1845
    return terrno;
×
1846
  }
1847

1848
  if (colIdx < 0) {
×
1849
    tscError("invalid bind column idx %d", colIdx);
×
1850
    terrno = TSDB_CODE_INVALID_PARA;
×
1851
    return terrno;
×
1852
  }
1853

1854
  int32_t insert = 0;
×
1855
  int32_t code = stmtIsInsert(stmt, &insert);
×
1856
  if (TSDB_CODE_SUCCESS != code) {
×
1857
    tscError("stmt insert failed, errcode:%s", tstrerror(code));
×
1858
    return code;
×
1859
  }
1860
  if (0 == insert && bind->num > 1) {
×
1861
    tscError("only one row data allowed for query");
×
1862
    terrno = TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR;
×
1863
    return terrno;
×
1864
  }
1865

1866
  return stmtBindBatch(stmt, bind, colIdx);
×
1867
}
1868

1869
int taos_stmt_add_batch(TAOS_STMT *stmt) {
96✔
1870
  if (stmt == NULL) {
96!
1871
    tscError("NULL parameter for %s", __FUNCTION__);
×
1872
    terrno = TSDB_CODE_INVALID_PARA;
×
1873
    return terrno;
×
1874
  }
1875

1876
  return stmtAddBatch(stmt);
96✔
1877
}
1878

1879
int taos_stmt_execute(TAOS_STMT *stmt) {
89✔
1880
  if (stmt == NULL) {
89!
1881
    tscError("NULL parameter for %s", __FUNCTION__);
×
1882
    terrno = TSDB_CODE_INVALID_PARA;
×
1883
    return terrno;
×
1884
  }
1885

1886
  return stmtExec(stmt);
89✔
1887
}
1888

1889
int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert) {
×
1890
  if (stmt == NULL || insert == NULL) {
×
1891
    tscError("NULL parameter for %s", __FUNCTION__);
×
1892
    terrno = TSDB_CODE_INVALID_PARA;
×
1893
    return terrno;
×
1894
  }
1895

1896
  return stmtIsInsert(stmt, insert);
×
1897
}
1898

1899
int taos_stmt_num_params(TAOS_STMT *stmt, int *nums) {
×
1900
  if (stmt == NULL || nums == NULL) {
×
1901
    tscError("NULL parameter for %s", __FUNCTION__);
×
1902
    terrno = TSDB_CODE_INVALID_PARA;
×
1903
    return terrno;
×
1904
  }
1905

1906
  return stmtGetParamNum(stmt, nums);
×
1907
}
1908

1909
int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) {
×
1910
  if (stmt == NULL || type == NULL || NULL == bytes || idx < 0) {
×
1911
    tscError("invalid parameter for %s", __FUNCTION__);
×
1912
    terrno = TSDB_CODE_INVALID_PARA;
×
1913
    return terrno;
×
1914
  }
1915

1916
  return stmtGetParam(stmt, idx, type, bytes);
×
1917
}
1918

1919
TAOS_RES *taos_stmt_use_result(TAOS_STMT *stmt) {
16✔
1920
  if (stmt == NULL) {
16!
1921
    tscError("NULL parameter for %s", __FUNCTION__);
×
1922
    terrno = TSDB_CODE_INVALID_PARA;
×
1923
    return NULL;
×
1924
  }
1925

1926
  return stmtUseResult(stmt);
16✔
1927
}
1928

1929
char *taos_stmt_errstr(TAOS_STMT *stmt) { return (char *)stmtErrstr(stmt); }
16✔
1930

1931
int taos_stmt_affected_rows(TAOS_STMT *stmt) {
5✔
1932
  if (stmt == NULL) {
5!
1933
    tscError("NULL parameter for %s", __FUNCTION__);
×
1934
    terrno = TSDB_CODE_INVALID_PARA;
×
1935
    return 0;
×
1936
  }
1937

1938
  return stmtAffectedRows(stmt);
5✔
1939
}
1940

1941
int taos_stmt_affected_rows_once(TAOS_STMT *stmt) {
×
1942
  if (stmt == NULL) {
×
1943
    tscError("NULL parameter for %s", __FUNCTION__);
×
1944
    terrno = TSDB_CODE_INVALID_PARA;
×
1945
    return 0;
×
1946
  }
1947

1948
  return stmtAffectedRowsOnce(stmt);
×
1949
}
1950

1951
int taos_stmt_close(TAOS_STMT *stmt) {
45✔
1952
  if (stmt == NULL) {
45!
1953
    tscError("NULL parameter for %s", __FUNCTION__);
×
1954
    terrno = TSDB_CODE_INVALID_PARA;
×
1955
    return terrno;
×
1956
  }
1957

1958
  return stmtClose(stmt);
45✔
1959
}
1960

1961
TAOS_STMT2 *taos_stmt2_init(TAOS *taos, TAOS_STMT2_OPTION *option) {
×
1962
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
×
1963
  if (NULL == pObj) {
×
1964
    tscError("invalid parameter for %s", __FUNCTION__);
×
1965
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
1966
    return NULL;
×
1967
  }
1968

1969
  TAOS_STMT2 *pStmt = stmtInit2(pObj, option);
×
1970

1971
  releaseTscObj(*(int64_t *)taos);
×
1972

1973
  return pStmt;
×
1974
}
1975

1976
int taos_stmt2_prepare(TAOS_STMT2 *stmt, const char *sql, unsigned long length) {
×
1977
  if (stmt == NULL || sql == NULL) {
×
1978
    tscError("NULL parameter for %s", __FUNCTION__);
×
1979
    terrno = TSDB_CODE_INVALID_PARA;
×
1980
    return terrno;
×
1981
  }
1982

1983
  return stmtPrepare2(stmt, sql, length);
×
1984
}
1985

1986
int taos_stmt2_bind_param(TAOS_STMT2 *stmt, TAOS_STMT2_BINDV *bindv, int32_t col_idx) {
×
1987
  if (stmt == NULL) {
×
1988
    tscError("NULL parameter for %s", __FUNCTION__);
×
1989
    terrno = TSDB_CODE_INVALID_PARA;
×
1990
    return terrno;
×
1991
  }
1992

1993
  STscStmt2 *pStmt = (STscStmt2 *)stmt;
×
1994
  if (pStmt->options.asyncExecFn && !pStmt->semWaited) {
×
1995
    if (tsem_wait(&pStmt->asyncQuerySem) != 0) {
×
1996
      tscError("wait async query sem failed");
×
1997
    }
1998
    pStmt->semWaited = true;
×
1999
  }
2000

2001
  int32_t code = 0;
×
2002
  for (int i = 0; i < bindv->count; ++i) {
×
2003
    if (bindv->tbnames && bindv->tbnames[i]) {
×
2004
      code = stmtSetTbName2(stmt, bindv->tbnames[i]);
×
2005
      if (code) {
×
2006
        return code;
×
2007
      }
2008
    }
2009

2010
    if (bindv->tags && bindv->tags[i]) {
×
2011
      code = stmtSetTbTags2(stmt, bindv->tags[i]);
×
2012
      if (code) {
×
2013
        return code;
×
2014
      }
2015
    }
2016

2017
    if (bindv->bind_cols && bindv->bind_cols[i]) {
×
2018
      TAOS_STMT2_BIND *bind = bindv->bind_cols[i];
×
2019

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

2026
      int32_t insert = 0;
×
2027
      (void)stmtIsInsert2(stmt, &insert);
×
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
      code = stmtBindBatch2(stmt, bind, col_idx);
×
2035
      if (TSDB_CODE_SUCCESS != code) {
×
2036
        return code;
×
2037
      }
2038
    }
2039
  }
2040

2041
  return TSDB_CODE_SUCCESS;
×
2042
}
2043

2044
int taos_stmt2_exec(TAOS_STMT2 *stmt, int *affected_rows) {
×
2045
  if (stmt == NULL) {
×
2046
    tscError("NULL parameter for %s", __FUNCTION__);
×
2047
    terrno = TSDB_CODE_INVALID_PARA;
×
2048
    return terrno;
×
2049
  }
2050

2051
  return stmtExec2(stmt, affected_rows);
×
2052
}
2053

2054
int taos_stmt2_close(TAOS_STMT2 *stmt) {
×
2055
  if (stmt == NULL) {
×
2056
    tscError("NULL parameter for %s", __FUNCTION__);
×
2057
    terrno = TSDB_CODE_INVALID_PARA;
×
2058
    return terrno;
×
2059
  }
2060

2061
  return stmtClose2(stmt);
×
2062
}
2063
/*
2064
int taos_stmt2_param_count(TAOS_STMT2 *stmt, int *nums) {
2065
  if (stmt == NULL || nums == NULL) {
2066
    tscError("NULL parameter for %s", __FUNCTION__);
2067
    terrno = TSDB_CODE_INVALID_PARA;
2068
    return terrno;
2069
  }
2070
  return stmtGetParamNum2(stmt, nums);
2071
}
2072
*/
2073
int taos_stmt2_is_insert(TAOS_STMT2 *stmt, int *insert) {
×
2074
  if (stmt == NULL || insert == NULL) {
×
2075
    tscError("NULL parameter for %s", __FUNCTION__);
×
2076
    terrno = TSDB_CODE_INVALID_PARA;
×
2077
    return terrno;
×
2078
  }
2079

2080
  return stmtIsInsert2(stmt, insert);
×
2081
}
2082

2083
int taos_stmt2_get_fields(TAOS_STMT2 *stmt, TAOS_FIELD_T field_type, int *count, TAOS_FIELD_E **fields) {
×
2084
  if (stmt == NULL || count == NULL) {
×
2085
    tscError("NULL parameter for %s", __FUNCTION__);
×
2086
    terrno = TSDB_CODE_INVALID_PARA;
×
2087
    return terrno;
×
2088
  }
2089

2090
  if (field_type == TAOS_FIELD_COL) {
×
2091
    return stmtGetColFields2(stmt, count, fields);
×
2092
  } else if (field_type == TAOS_FIELD_TAG) {
×
2093
    return stmtGetTagFields2(stmt, count, fields);
×
2094
  } else if (field_type == TAOS_FIELD_QUERY) {
×
2095
    return stmtGetParamNum2(stmt, count);
×
2096
  } else if (field_type == TAOS_FIELD_TBNAME) {
×
2097
    return stmtGetParamTbName(stmt, count);
×
2098
  } else {
2099
    tscError("invalid parameter for %s", __FUNCTION__);
×
2100
    terrno = TSDB_CODE_INVALID_PARA;
×
2101
    return terrno;
×
2102
  }
2103
}
2104

2105
int taos_stmt2_get_stb_fields(TAOS_STMT2 *stmt, int *count, TAOS_FIELD_STB **fields) {
×
2106
  if (stmt == NULL || count == NULL) {
×
2107
    tscError("NULL parameter for %s", __FUNCTION__);
×
2108
    terrno = TSDB_CODE_INVALID_PARA;
×
2109
    return terrno;
×
2110
  }
2111

2112
  return stmtGetStbColFields2(stmt, count, fields);
×
2113
}
2114

2115
void taos_stmt2_free_fields(TAOS_STMT2 *stmt, TAOS_FIELD_E *fields) {
×
2116
  (void)stmt;
2117
  if (!fields) return;
×
2118
  taosMemoryFree(fields);
×
2119
}
2120

2121
DLL_EXPORT void taos_stmt2_free_stb_fields(TAOS_STMT2 *stmt, TAOS_FIELD_STB *fields) {
×
2122
  (void)stmt;
2123
  if (!fields) return;
×
2124
  taosMemoryFree(fields);
×
2125
}
2126

2127
TAOS_RES *taos_stmt2_result(TAOS_STMT2 *stmt) {
×
2128
  if (stmt == NULL) {
×
2129
    tscError("NULL parameter for %s", __FUNCTION__);
×
2130
    terrno = TSDB_CODE_INVALID_PARA;
×
2131
    return NULL;
×
2132
  }
2133

2134
  return stmtUseResult2(stmt);
×
2135
}
2136

2137
char *taos_stmt2_error(TAOS_STMT2 *stmt) { return (char *)stmtErrstr2(stmt); }
×
2138

2139
int taos_set_conn_mode(TAOS *taos, int mode, int value) {
4✔
2140
  if (taos == NULL) {
4!
2141
    terrno = TSDB_CODE_INVALID_PARA;
×
2142
    return terrno;
×
2143
  }
2144

2145
  STscObj *pObj = acquireTscObj(*(int64_t *)taos);
4✔
2146
  if (NULL == pObj) {
4!
2147
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
2148
    tscError("invalid parameter for %s", __func__);
×
2149
    return terrno;
×
2150
  }
2151
  switch (mode) {
4!
2152
    case TAOS_CONN_MODE_BI:
4✔
2153
      atomic_store_8(&pObj->biMode, value);
4✔
2154
      break;
4✔
2155
    default:
×
2156
      tscError("not supported mode.");
×
2157
      return TSDB_CODE_INVALID_PARA;
×
2158
  }
2159
  return 0;
4✔
2160
}
2161

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