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

taosdata / TDengine / #4664

08 Aug 2025 08:36AM UTC coverage: 60.536% (+0.2%) from 60.372%
#4664

push

travis-ci

web-flow
test: update cases desc (#32498)

139177 of 291923 branches covered (47.68%)

Branch coverage included in aggregate %.

209648 of 284307 relevant lines covered (73.74%)

18318036.98 hits per line

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

52.63
/source/client/src/clientImpl.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 "cJSON.h"
17
#include "clientInt.h"
18
#include "clientLog.h"
19
#include "clientMonitor.h"
20
#include "command.h"
21
#include "decimal.h"
22
#include "scheduler.h"
23
#include "tdatablock.h"
24
#include "tdataformat.h"
25
#include "tdef.h"
26
#include "tglobal.h"
27
#include "tmisce.h"
28
#include "tmsg.h"
29
#include "tmsgtype.h"
30
#include "tpagedbuf.h"
31
#include "tref.h"
32
#include "tsched.h"
33
#include "tversion.h"
34

35
static int32_t initEpSetFromCfg(const char* firstEp, const char* secondEp, SCorEpSet* pEpSet);
36
static int32_t buildConnectMsg(SRequestObj* pRequest, SMsgSendInfo** pMsgSendInfo);
37

38
void setQueryRequest(int64_t rId) {
161,536✔
39
  SRequestObj* pReq = acquireRequest(rId);
161,536✔
40
  if (pReq != NULL) {
161,551✔
41
    pReq->isQuery = true;
161,549✔
42
    (void)releaseRequest(rId);
161,549✔
43
  }
44
}
161,545✔
45

46
static bool stringLengthCheck(const char* str, size_t maxsize) {
27,789✔
47
  if (str == NULL) {
27,789!
48
    return false;
×
49
  }
50

51
  size_t len = strlen(str);
27,789✔
52
  if (len <= 0 || len > maxsize) {
27,789!
53
    return false;
×
54
  }
55

56
  return true;
27,844✔
57
}
58

59
static bool validateUserName(const char* user) { return stringLengthCheck(user, TSDB_USER_LEN - 1); }
10,725✔
60

61
static bool validatePassword(const char* passwd) { return stringLengthCheck(passwd, TSDB_PASSWORD_MAX_LEN); }
10,724✔
62

63
static bool validateDbName(const char* db) { return stringLengthCheck(db, TSDB_DB_NAME_LEN - 1); }
6,469✔
64

65
static char* getClusterKey(const char* user, const char* auth, const char* ip, int32_t port) {
10,670✔
66
  char key[512] = {0};
10,670✔
67
  (void)snprintf(key, sizeof(key), "%s:%s:%s:%d", user, auth, ip, port);
10,670✔
68
  return taosStrdup(key);
10,670!
69
}
70

71
static int32_t escapeToPrinted(char* dst, size_t maxDstLength, const char* src, size_t srcLength) {
264✔
72
  if (dst == NULL || src == NULL || srcLength == 0) {
264!
73
    return 0;
×
74
  }
75
  
76
  size_t escapeLength = 0;
264✔
77
  for(size_t i = 0; i < srcLength; ++i) {
1,320✔
78
    if( src[i] == '\"' || src[i] == '\\' || src[i] == '\b' || src[i] == '\f' || src[i] == '\n' ||
1,056!
79
        src[i] == '\r' || src[i] == '\t') {
1,056!
80
      escapeLength += 1; 
×
81
    }    
82
  }
83

84
  size_t dstLength = srcLength;
264✔
85
  if(escapeLength == 0) {
264!
86
     (void)memcpy(dst, src, srcLength);
264✔
87
  } else {
88
    dstLength = 0;
×
89
    for(size_t i = 0; i < srcLength && dstLength <= maxDstLength; i++) {
×
90
      switch(src[i]) {
×
91
        case '\"':
×
92
          dst[dstLength++] = '\\';
×
93
          dst[dstLength++] = '\"';
×
94
          break;
×
95
        case '\\':
×
96
          dst[dstLength++] = '\\';
×
97
          dst[dstLength++] = '\\';
×
98
          break;
×
99
        case '\b':
×
100
          dst[dstLength++] = '\\';
×
101
          dst[dstLength++] = 'b';
×
102
          break;
×
103
        case '\f':
×
104
          dst[dstLength++] = '\\';
×
105
          dst[dstLength++] = 'f';
×
106
          break;
×
107
        case '\n':
×
108
          dst[dstLength++] = '\\';
×
109
          dst[dstLength++] = 'n';
×
110
          break;
×
111
        case '\r':
×
112
          dst[dstLength++] = '\\';
×
113
          dst[dstLength++] = 'r';
×
114
          break;
×
115
        case '\t':
×
116
          dst[dstLength++] = '\\';
×
117
          dst[dstLength++] = 't';
×
118
          break;
×
119
        default:
×
120
           dst[dstLength++] = src[i];
×
121
      }
122
    }
123
  }
124

125
  return dstLength;
264✔
126
}
127

128
bool chkRequestKilled(void* param) {
25,804,688✔
129
  bool         killed = false;
25,804,688✔
130
  SRequestObj* pRequest = acquireRequest((int64_t)param);
25,804,688✔
131
  if (NULL == pRequest || pRequest->killed) {
26,278,299!
132
    killed = true;
×
133
  }
134

135
  (void)releaseRequest((int64_t)param);
26,278,299✔
136

137
  return killed;
26,192,173✔
138
}
139

140
void cleanupAppInfo() {
3,514✔
141
  taosHashCleanup(appInfo.pInstMap);
3,514✔
142
  taosHashCleanup(appInfo.pInstMapByClusterId);
3,514✔
143
  tscInfo("cluster instance map cleaned");
3,514!
144
}
3,514✔
145

146
static int32_t taosConnectImpl(const char* user, const char* auth, const char* db, __taos_async_fn_t fp, void* param,
147
                               SAppInstInfo* pAppInfo, int connType, STscObj** pTscObj);
148

149
int32_t taos_connect_internal(const char* ip, const char* user, const char* pass, const char* auth, const char* db,
10,636✔
150
                              uint16_t port, int connType, STscObj** pObj) {
151
  TSC_ERR_RET(taos_init());
10,636!
152
  if (!validateUserName(user)) {
10,741!
153
    TSC_ERR_RET(TSDB_CODE_TSC_INVALID_USER_LENGTH);
×
154
  }
155
  int32_t code = 0;
10,729✔
156

157
  char localDb[TSDB_DB_NAME_LEN] = {0};
10,729✔
158
  if (db != NULL && strlen(db) > 0) {
10,729✔
159
    if (!validateDbName(db)) {
6,475!
160
      TSC_ERR_RET(TSDB_CODE_TSC_INVALID_DB_LENGTH);
×
161
    }
162

163
    tstrncpy(localDb, db, sizeof(localDb));
6,482✔
164
    (void)strdequote(localDb);
6,482✔
165
  }
166

167
  char secretEncrypt[TSDB_PASSWORD_LEN + 1] = {0};
10,736✔
168
  if (auth == NULL) {
10,736✔
169
    if (!validatePassword(pass)) {
10,733!
170
      TSC_ERR_RET(TSDB_CODE_TSC_INVALID_PASS_LENGTH);
×
171
    }
172

173
    taosEncryptPass_c((uint8_t*)pass, strlen(pass), secretEncrypt);
10,733✔
174
  } else {
175
    tstrncpy(secretEncrypt, auth, tListLen(secretEncrypt));
3✔
176
  }
177

178
  SCorEpSet epSet = {0};
10,662✔
179
  if (ip) {
10,662✔
180
    TSC_ERR_RET(initEpSetFromCfg(ip, NULL, &epSet));
4,234✔
181
  } else {
182
    TSC_ERR_RET(initEpSetFromCfg(tsFirst, tsSecond, &epSet));
6,428!
183
  }
184

185
  if (port) {
10,678✔
186
    epSet.epSet.eps[0].port = port;
109✔
187
    epSet.epSet.eps[1].port = port;
109✔
188
  }
189

190
  char* key = getClusterKey(user, secretEncrypt, ip, port);
10,678✔
191
  if (NULL == key) {
10,653!
192
    TSC_ERR_RET(terrno);
×
193
  }
194
  tscInfo("connecting to server, numOfEps:%d inUse:%d user:%s db:%s key:%s", epSet.epSet.numOfEps, epSet.epSet.inUse,
10,653!
195
          user, db, key);
196
  for (int32_t i = 0; i < epSet.epSet.numOfEps; ++i) {
27,978✔
197
    tscInfo("ep:%d, %s:%u", i, epSet.epSet.eps[i].fqdn, epSet.epSet.eps[i].port);
17,204!
198
  }
199
  // for (int32_t i = 0; i < epSet.epSet.numOfEps; i++) {
200
  //   if ((code = taosValidFqdn(tsEnableIpv6, epSet.epSet.eps[i].fqdn)) != 0) {
201
  //     taosMemFree(key);
202
  //     tscError("ipv6 flag %d, the local FQDN %s does not resolve to the ip address since %s", tsEnableIpv6,
203
  //              epSet.epSet.eps[i].fqdn, tstrerror(code));
204
  //     TSC_ERR_RET(code);
205
  //   }
206
  // }
207

208
  SAppInstInfo** pInst = NULL;
10,774✔
209
  code = taosThreadMutexLock(&appInfo.mutex);
10,774✔
210
  if (TSDB_CODE_SUCCESS != code) {
10,778!
211
    tscError("failed to lock app info, code:%s", tstrerror(TAOS_SYSTEM_ERROR(code)));
×
212
    TSC_ERR_RET(code);
×
213
  }
214

215
  pInst = taosHashGet(appInfo.pInstMap, key, strlen(key));
10,778✔
216
  SAppInstInfo* p = NULL;
10,778✔
217
  if (pInst == NULL) {
10,778✔
218
    p = taosMemoryCalloc(1, sizeof(struct SAppInstInfo));
3,356!
219
    if (NULL == p) {
3,356!
220
      TSC_ERR_JRET(terrno);
×
221
    }
222
    p->mgmtEp = epSet;
3,356✔
223
    code = taosThreadMutexInit(&p->qnodeMutex, NULL);
3,356✔
224
    if (TSDB_CODE_SUCCESS != code) {
3,356!
225
      taosMemoryFree(p);
×
226
      TSC_ERR_JRET(code);
×
227
    }
228
    code = openTransporter(user, secretEncrypt, tsNumOfCores / 2, &p->pTransporter);
3,356✔
229
    if (TSDB_CODE_SUCCESS != code) {
3,356!
230
      taosMemoryFree(p);
×
231
      TSC_ERR_JRET(code);
×
232
    }
233
    code = appHbMgrInit(p, key, &p->pAppHbMgr);
3,356✔
234
    if (TSDB_CODE_SUCCESS != code) {
3,356!
235
      destroyAppInst(&p);
×
236
      TSC_ERR_JRET(code);
×
237
    }
238
    code = taosHashPut(appInfo.pInstMap, key, strlen(key), &p, POINTER_BYTES);
3,356✔
239
    if (TSDB_CODE_SUCCESS != code) {
3,356!
240
      destroyAppInst(&p);
×
241
      TSC_ERR_JRET(code);
×
242
    }
243
    p->instKey = key;
3,356✔
244
    key = NULL;
3,356✔
245
    tscInfo("new app inst mgr:%p, user:%s, ip:%s, port:%d", p, user, epSet.epSet.eps[0].fqdn, epSet.epSet.eps[0].port);
3,356!
246

247
    pInst = &p;
3,356✔
248
  } else {
249
    if (NULL == *pInst || NULL == (*pInst)->pAppHbMgr) {
7,422!
250
      tscError("*pInst:%p, pAppHgMgr:%p", *pInst, (*pInst) ? (*pInst)->pAppHbMgr : NULL);
×
251
      TSC_ERR_JRET(TSDB_CODE_TSC_INTERNAL_ERROR);
×
252
    }
253
    // reset to 0 in case of conn with duplicated user key but its user has ever been dropped.
254
    atomic_store_8(&(*pInst)->pAppHbMgr->connHbFlag, 0);
7,422✔
255
  }
256

257
_return:
10,778✔
258

259
  if (TSDB_CODE_SUCCESS != code) {
10,778!
260
    (void)taosThreadMutexUnlock(&appInfo.mutex);
×
261
    taosMemoryFreeClear(key);
×
262
    return code;
×
263
  } else {
264
    code = taosThreadMutexUnlock(&appInfo.mutex);
10,778✔
265
    taosMemoryFreeClear(key);
10,778!
266
    if (TSDB_CODE_SUCCESS != code) {
10,778!
267
      tscError("failed to unlock app info, code:%s", tstrerror(TAOS_SYSTEM_ERROR(code)));
×
268
      return code;
×
269
    }
270
    return taosConnectImpl(user, &secretEncrypt[0], localDb, NULL, NULL, *pInst, connType, pObj);
10,778✔
271
  }
272
}
273

274
// SAppInstInfo* getAppInstInfo(const char* clusterKey) {
275
//   SAppInstInfo** ppAppInstInfo = taosHashGet(appInfo.pInstMap, clusterKey, strlen(clusterKey));
276
//   if (ppAppInstInfo != NULL && *ppAppInstInfo != NULL) {
277
//     return *ppAppInstInfo;
278
//   } else {
279
//     return NULL;
280
//   }
281
// }
282

283
void freeQueryParam(SSyncQueryParam* param) {
1,018✔
284
  if (param == NULL) return;
1,018!
285
  if (TSDB_CODE_SUCCESS != tsem_destroy(&param->sem)) {
1,018!
286
    tscError("failed to destroy semaphore in freeQueryParam");
×
287
  }
288
  taosMemoryFree(param);
1,018!
289
}
290

291
int32_t buildRequest(uint64_t connId, const char* sql, int sqlLen, void* param, bool validateSql,
8,617,992✔
292
                     SRequestObj** pRequest, int64_t reqid) {
293
  int32_t code = createRequest(connId, TSDB_SQL_SELECT, reqid, pRequest);
8,617,992✔
294
  if (TSDB_CODE_SUCCESS != code) {
8,632,585!
295
    tscError("failed to malloc sqlObj, %s", sql);
×
296
    return code;
×
297
  }
298

299
  (*pRequest)->sqlstr = taosMemoryMalloc(sqlLen + 1);
8,632,585!
300
  if ((*pRequest)->sqlstr == NULL) {
8,622,080!
301
    tscError("req:0x%" PRIx64 ", failed to prepare sql string buffer, %s", (*pRequest)->self, sql);
×
302
    destroyRequest(*pRequest);
×
303
    *pRequest = NULL;
×
304
    return terrno;
×
305
  }
306

307
  (void)strntolower((*pRequest)->sqlstr, sql, (int32_t)sqlLen);
8,622,080✔
308
  (*pRequest)->sqlstr[sqlLen] = 0;
8,633,113✔
309
  (*pRequest)->sqlLen = sqlLen;
8,633,113✔
310
  (*pRequest)->validateOnly = validateSql;
8,633,113✔
311
  (*pRequest)->stmtBindVersion = 0;
8,633,113✔
312

313
  ((SSyncQueryParam*)(*pRequest)->body.interParam)->userParam = param;
8,633,113✔
314

315
  STscObj* pTscObj = (*pRequest)->pTscObj;
8,633,113✔
316
  int32_t  err = taosHashPut(pTscObj->pRequests, &(*pRequest)->self, sizeof((*pRequest)->self), &(*pRequest)->self,
8,633,113✔
317
                             sizeof((*pRequest)->self));
318
  if (err) {
8,618,159!
319
    tscError("req:0x%" PRId64 ", failed to add to request container, QID:0x%" PRIx64 ", conn:%" PRId64 ", %s",
×
320
             (*pRequest)->self, (*pRequest)->requestId, pTscObj->id, sql);
321
    destroyRequest(*pRequest);
×
322
    *pRequest = NULL;
×
323
    return terrno;
×
324
  }
325

326
  (*pRequest)->allocatorRefId = -1;
8,618,159✔
327
  if (tsQueryUseNodeAllocator && !qIsInsertValuesSql((*pRequest)->sqlstr, (*pRequest)->sqlLen)) {
8,618,159!
328
    if (TSDB_CODE_SUCCESS !=
268,138!
329
        nodesCreateAllocator((*pRequest)->requestId, tsQueryNodeChunkSize, &((*pRequest)->allocatorRefId))) {
268,128✔
330
      tscError("req:0x%" PRId64 ", failed to create node allocator, QID:0x%" PRIx64 ", conn:%" PRId64 ", %s",
×
331
               (*pRequest)->self, (*pRequest)->requestId, pTscObj->id, sql);
332
      destroyRequest(*pRequest);
×
333
      *pRequest = NULL;
×
334
      return terrno;
×
335
    }
336
  }
337

338
  tscDebug("req:0x%" PRIx64 ", build request, QID:0x%" PRIx64, (*pRequest)->self, (*pRequest)->requestId);
8,629,347✔
339
  return TSDB_CODE_SUCCESS;
8,627,555✔
340
}
341

342
int32_t buildPreviousRequest(SRequestObj* pRequest, const char* sql, SRequestObj** pNewRequest) {
×
343
  int32_t code =
344
      buildRequest(pRequest->pTscObj->id, sql, strlen(sql), pRequest, pRequest->validateOnly, pNewRequest, 0);
×
345
  if (TSDB_CODE_SUCCESS == code) {
×
346
    pRequest->relation.prevRefId = (*pNewRequest)->self;
×
347
    (*pNewRequest)->relation.nextRefId = pRequest->self;
×
348
    (*pNewRequest)->relation.userRefId = pRequest->self;
×
349
    (*pNewRequest)->isSubReq = true;
×
350
  }
351
  return code;
×
352
}
353

354
int32_t parseSql(SRequestObj* pRequest, bool topicQuery, SQuery** pQuery, SStmtCallback* pStmtCb) {
11,883✔
355
  STscObj* pTscObj = pRequest->pTscObj;
11,883✔
356

357
  SParseContext cxt = {
11,883✔
358
      .requestId = pRequest->requestId,
11,883✔
359
      .requestRid = pRequest->self,
11,883✔
360
      .acctId = pTscObj->acctId,
11,883✔
361
      .db = pRequest->pDb,
11,883✔
362
      .topicQuery = topicQuery,
363
      .pSql = pRequest->sqlstr,
11,883✔
364
      .sqlLen = pRequest->sqlLen,
11,883✔
365
      .pMsg = pRequest->msgBuf,
11,883✔
366
      .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE,
367
      .pTransporter = pTscObj->pAppInfo->pTransporter,
11,883✔
368
      .pStmtCb = pStmtCb,
369
      .pUser = pTscObj->user,
11,883✔
370
      .isSuperUser = (0 == strcmp(pTscObj->user, TSDB_DEFAULT_USER)),
11,883✔
371
      .enableSysInfo = pTscObj->sysInfo,
11,883✔
372
      .svrVer = pTscObj->sVer,
11,883✔
373
      .nodeOffline = (pTscObj->pAppInfo->onlineDnodes < pTscObj->pAppInfo->totalDnodes),
11,883✔
374
      .stmtBindVersion = pRequest->stmtBindVersion,
11,883✔
375
      .setQueryFp = setQueryRequest,
376
      .timezone = pTscObj->optionInfo.timezone,
11,883✔
377
      .charsetCxt = pTscObj->optionInfo.charsetCxt,
11,883✔
378
  };
379

380
  cxt.mgmtEpSet = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
11,883✔
381
  int32_t code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &cxt.pCatalog);
11,900✔
382
  if (code != TSDB_CODE_SUCCESS) {
11,889!
383
    return code;
×
384
  }
385

386
  code = qParseSql(&cxt, pQuery);
11,889✔
387
  if (TSDB_CODE_SUCCESS == code) {
11,881✔
388
    if ((*pQuery)->haveResultSet) {
11,863!
389
      code = setResSchemaInfo(&pRequest->body.resInfo, (*pQuery)->pResSchema, (*pQuery)->numOfResCols,
×
390
                              (*pQuery)->pResExtSchema, pRequest->stmtBindVersion > 0);
×
391
      setResPrecision(&pRequest->body.resInfo, (*pQuery)->precision);
×
392
    }
393
  }
394

395
  if (TSDB_CODE_SUCCESS == code || NEED_CLIENT_HANDLE_ERROR(code)) {
11,882!
396
    TSWAP(pRequest->dbList, (*pQuery)->pDbList);
11,859✔
397
    TSWAP(pRequest->tableList, (*pQuery)->pTableList);
11,859✔
398
    TSWAP(pRequest->targetTableList, (*pQuery)->pTargetTableList);
11,859✔
399
  }
400

401
  taosArrayDestroy(cxt.pTableMetaPos);
11,882✔
402
  taosArrayDestroy(cxt.pTableVgroupPos);
11,887✔
403

404
  return code;
11,888✔
405
}
406

407
int32_t execLocalCmd(SRequestObj* pRequest, SQuery* pQuery) {
×
408
  SRetrieveTableRsp* pRsp = NULL;
×
409
  int8_t             biMode = atomic_load_8(&pRequest->pTscObj->biMode);
×
410
  int32_t code = qExecCommand(&pRequest->pTscObj->id, pRequest->pTscObj->sysInfo, pQuery->pRoot, &pRsp, biMode,
×
411
                              pRequest->pTscObj->optionInfo.charsetCxt);
×
412
  if (TSDB_CODE_SUCCESS == code && NULL != pRsp) {
×
413
    code = setQueryResultFromRsp(&pRequest->body.resInfo, pRsp, pRequest->body.resInfo.convertUcs4,
×
414
                                 pRequest->stmtBindVersion > 0);
×
415
  }
416

417
  return code;
×
418
}
419

420
int32_t execDdlQuery(SRequestObj* pRequest, SQuery* pQuery) {
482✔
421
  // drop table if exists not_exists_table
422
  if (NULL == pQuery->pCmdMsg) {
482!
423
    return TSDB_CODE_SUCCESS;
×
424
  }
425

426
  SCmdMsgInfo* pMsgInfo = pQuery->pCmdMsg;
482✔
427
  pRequest->type = pMsgInfo->msgType;
482✔
428
  pRequest->body.requestMsg = (SDataBuf){.pData = pMsgInfo->pMsg, .len = pMsgInfo->msgLen, .handle = NULL};
482✔
429
  pMsgInfo->pMsg = NULL;  // pMsg transferred to SMsgSendInfo management
482✔
430

431
  STscObj*      pTscObj = pRequest->pTscObj;
482✔
432
  SMsgSendInfo* pSendMsg = buildMsgInfoImpl(pRequest);
482✔
433

434
  // int64_t transporterId = 0;
435
  TSC_ERR_RET(asyncSendMsgToServer(pTscObj->pAppInfo->pTransporter, &pMsgInfo->epSet, NULL, pSendMsg));
482!
436
  TSC_ERR_RET(tsem_wait(&pRequest->body.rspSem));
482!
437
  return TSDB_CODE_SUCCESS;
483✔
438
}
439

440
static SAppInstInfo* getAppInfo(SRequestObj* pRequest) { return pRequest->pTscObj->pAppInfo; }
17,062,953✔
441

442
void asyncExecLocalCmd(SRequestObj* pRequest, SQuery* pQuery) {
3,989✔
443
  SRetrieveTableRsp* pRsp = NULL;
3,989✔
444
  if (pRequest->validateOnly) {
3,989✔
445
    doRequestCallback(pRequest, 0);
27✔
446
    return;
27✔
447
  }
448

449
  int32_t code = qExecCommand(&pRequest->pTscObj->id, pRequest->pTscObj->sysInfo, pQuery->pRoot, &pRsp,
3,961✔
450
                              atomic_load_8(&pRequest->pTscObj->biMode), pRequest->pTscObj->optionInfo.charsetCxt);
3,962✔
451
  if (TSDB_CODE_SUCCESS == code && NULL != pRsp) {
3,961!
452
    code = setQueryResultFromRsp(&pRequest->body.resInfo, pRsp, pRequest->body.resInfo.convertUcs4,
2,534✔
453
                                 pRequest->stmtBindVersion > 0);
2,534✔
454
  }
455

456
  SReqResultInfo* pResultInfo = &pRequest->body.resInfo;
3,961✔
457
  pRequest->code = code;
3,961✔
458

459
  if (pRequest->code != TSDB_CODE_SUCCESS) {
3,961✔
460
    pResultInfo->numOfRows = 0;
1✔
461
    tscError("req:0x%" PRIx64 ", fetch results failed, code:%s, QID:0x%" PRIx64, pRequest->self, tstrerror(code),
1!
462
             pRequest->requestId);
463
  } else {
464
    tscDebug(
3,960✔
465
        "req:0x%" PRIx64 ", fetch results, numOfRows:%" PRId64 " total Rows:%" PRId64 ", complete:%d, QID:0x%" PRIx64,
466
        pRequest->self, pResultInfo->numOfRows, pResultInfo->totalRows, pResultInfo->completed, pRequest->requestId);
467
  }
468

469
  doRequestCallback(pRequest, code);
3,961✔
470
}
471

472
int32_t asyncExecDdlQuery(SRequestObj* pRequest, SQuery* pQuery) {
16,147✔
473
  if (pRequest->validateOnly) {
16,147!
474
    doRequestCallback(pRequest, 0);
×
475
    return TSDB_CODE_SUCCESS;
×
476
  }
477

478
  // drop table if exists not_exists_table
479
  if (NULL == pQuery->pCmdMsg) {
16,147✔
480
    doRequestCallback(pRequest, 0);
6✔
481
    return TSDB_CODE_SUCCESS;
6✔
482
  }
483

484
  SCmdMsgInfo* pMsgInfo = pQuery->pCmdMsg;
16,141✔
485
  pRequest->type = pMsgInfo->msgType;
16,141✔
486
  pRequest->body.requestMsg = (SDataBuf){.pData = pMsgInfo->pMsg, .len = pMsgInfo->msgLen, .handle = NULL};
16,141✔
487
  pMsgInfo->pMsg = NULL;  // pMsg transferred to SMsgSendInfo management
16,141✔
488

489
  SAppInstInfo* pAppInfo = getAppInfo(pRequest);
16,141✔
490
  SMsgSendInfo* pSendMsg = buildMsgInfoImpl(pRequest);
16,117✔
491

492
  int32_t code = asyncSendMsgToServer(pAppInfo->pTransporter, &pMsgInfo->epSet, NULL, pSendMsg);
16,142✔
493
  if (code) {
16,173!
494
    doRequestCallback(pRequest, code);
×
495
  }
496
  return code;
16,173✔
497
}
498

499
int compareQueryNodeLoad(const void* elem1, const void* elem2) {
149,060✔
500
  SQueryNodeLoad* node1 = (SQueryNodeLoad*)elem1;
149,060✔
501
  SQueryNodeLoad* node2 = (SQueryNodeLoad*)elem2;
149,060✔
502

503
  if (node1->load < node2->load) {
149,060!
504
    return -1;
×
505
  }
506

507
  return node1->load > node2->load;
149,060✔
508
}
509

510
int32_t updateQnodeList(SAppInstInfo* pInfo, SArray* pNodeList) {
55,580✔
511
  TSC_ERR_RET(taosThreadMutexLock(&pInfo->qnodeMutex));
55,580!
512
  if (pInfo->pQnodeList) {
55,580✔
513
    taosArrayDestroy(pInfo->pQnodeList);
55,511✔
514
    pInfo->pQnodeList = NULL;
55,511✔
515
    tscDebug("QnodeList cleared in cluster 0x%" PRIx64, pInfo->clusterId);
55,511✔
516
  }
517

518
  if (pNodeList) {
55,580!
519
    pInfo->pQnodeList = taosArrayDup(pNodeList, NULL);
55,580✔
520
    taosArraySort(pInfo->pQnodeList, compareQueryNodeLoad);
55,580✔
521
    tscDebug("QnodeList updated in cluster 0x%" PRIx64 ", num:%ld", pInfo->clusterId,
55,580✔
522
             taosArrayGetSize(pInfo->pQnodeList));
523
  }
524
  TSC_ERR_RET(taosThreadMutexUnlock(&pInfo->qnodeMutex));
55,580!
525

526
  return TSDB_CODE_SUCCESS;
55,580✔
527
}
528

529
int32_t qnodeRequired(SRequestObj* pRequest, bool* required) {
8,617,626✔
530
  if (QUERY_POLICY_VNODE == tsQueryPolicy || QUERY_POLICY_CLIENT == tsQueryPolicy) {
8,617,626!
531
    *required = false;
8,617,626✔
532
    return TSDB_CODE_SUCCESS;
8,617,626✔
533
  }
534

535
  int32_t       code = TSDB_CODE_SUCCESS;
×
536
  SAppInstInfo* pInfo = pRequest->pTscObj->pAppInfo;
×
537
  *required = false;
×
538

539
  TSC_ERR_RET(taosThreadMutexLock(&pInfo->qnodeMutex));
×
540
  *required = (NULL == pInfo->pQnodeList);
×
541
  TSC_ERR_RET(taosThreadMutexUnlock(&pInfo->qnodeMutex));
×
542
  return TSDB_CODE_SUCCESS;
×
543
}
544

545
int32_t getQnodeList(SRequestObj* pRequest, SArray** pNodeList) {
×
546
  SAppInstInfo* pInfo = pRequest->pTscObj->pAppInfo;
×
547
  int32_t       code = 0;
×
548

549
  TSC_ERR_RET(taosThreadMutexLock(&pInfo->qnodeMutex));
×
550
  if (pInfo->pQnodeList) {
×
551
    *pNodeList = taosArrayDup(pInfo->pQnodeList, NULL);
×
552
  }
553
  TSC_ERR_RET(taosThreadMutexUnlock(&pInfo->qnodeMutex));
×
554
  if (NULL == *pNodeList) {
×
555
    SCatalog* pCatalog = NULL;
×
556
    code = catalogGetHandle(pRequest->pTscObj->pAppInfo->clusterId, &pCatalog);
×
557
    if (TSDB_CODE_SUCCESS == code) {
×
558
      *pNodeList = taosArrayInit(5, sizeof(SQueryNodeLoad));
×
559
      if (NULL == pNodeList) {
×
560
        TSC_ERR_RET(terrno);
×
561
      }
562
      SRequestConnInfo conn = {.pTrans = pRequest->pTscObj->pAppInfo->pTransporter,
×
563
                               .requestId = pRequest->requestId,
×
564
                               .requestObjRefId = pRequest->self,
×
565
                               .mgmtEps = getEpSet_s(&pRequest->pTscObj->pAppInfo->mgmtEp)};
×
566
      code = catalogGetQnodeList(pCatalog, &conn, *pNodeList);
×
567
    }
568

569
    if (TSDB_CODE_SUCCESS == code && *pNodeList) {
×
570
      code = updateQnodeList(pInfo, *pNodeList);
×
571
    }
572
  }
573

574
  return code;
×
575
}
576

577
int32_t getPlan(SRequestObj* pRequest, SQuery* pQuery, SQueryPlan** pPlan, SArray* pNodeList) {
21,863✔
578
  pRequest->type = pQuery->msgType;
21,863✔
579
  SAppInstInfo* pAppInfo = getAppInfo(pRequest);
21,863✔
580

581
  SPlanContext cxt = {.queryId = pRequest->requestId,
43,760✔
582
                      .acctId = pRequest->pTscObj->acctId,
21,876✔
583
                      .mgmtEpSet = getEpSet_s(&pAppInfo->mgmtEp),
21,876✔
584
                      .pAstRoot = pQuery->pRoot,
21,884✔
585
                      .showRewrite = pQuery->showRewrite,
21,884✔
586
                      .pMsg = pRequest->msgBuf,
21,884✔
587
                      .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE,
588
                      .pUser = pRequest->pTscObj->user,
21,884✔
589
                      .timezone = pRequest->pTscObj->optionInfo.timezone,
21,884✔
590
                      .sysInfo = pRequest->pTscObj->sysInfo};
21,884✔
591

592
  return qCreateQueryPlan(&cxt, pPlan, pNodeList);
21,884✔
593
}
594

595
int32_t setResSchemaInfo(SReqResultInfo* pResInfo, const SSchema* pSchema, int32_t numOfCols,
153,699✔
596
                         const SExtSchema* pExtSchema, bool isStmt) {
597
  if (pResInfo == NULL || pSchema == NULL || numOfCols <= 0) {
153,699!
598
    tscError("invalid paras, pResInfo == NULL || pSchema == NULL || numOfCols <= 0");
×
599
    return TSDB_CODE_INVALID_PARA;
×
600
  }
601

602
  pResInfo->numOfCols = numOfCols;
153,722✔
603
  if (pResInfo->fields != NULL) {
153,722!
604
    taosMemoryFree(pResInfo->fields);
×
605
  }
606
  if (pResInfo->userFields != NULL) {
153,722!
607
    taosMemoryFree(pResInfo->userFields);
×
608
  }
609
  pResInfo->fields = taosMemoryCalloc(numOfCols, sizeof(TAOS_FIELD_E));
153,722!
610
  if (NULL == pResInfo->fields) return terrno;
153,710!
611
  pResInfo->userFields = taosMemoryCalloc(numOfCols, sizeof(TAOS_FIELD));
153,710!
612
  if (NULL == pResInfo->userFields) {
153,694!
613
    taosMemoryFree(pResInfo->fields);
×
614
    return terrno;
×
615
  }
616
  if (numOfCols != pResInfo->numOfCols) {
153,694!
617
    tscError("numOfCols:%d != pResInfo->numOfCols:%d", numOfCols, pResInfo->numOfCols);
×
618
    return TSDB_CODE_FAILED;
×
619
  }
620

621
  for (int32_t i = 0; i < pResInfo->numOfCols; ++i) {
457,473✔
622
    pResInfo->fields[i].type = pSchema[i].type;
303,757✔
623

624
    pResInfo->userFields[i].type = pSchema[i].type;
303,757✔
625
    // userFields must convert to type bytes, no matter isStmt or not
626
    pResInfo->userFields[i].bytes = calcTypeBytesFromSchemaBytes(pSchema[i].type, pSchema[i].bytes, false);
303,757✔
627
    pResInfo->fields[i].bytes = calcTypeBytesFromSchemaBytes(pSchema[i].type, pSchema[i].bytes, isStmt);
303,776✔
628
    if (IS_DECIMAL_TYPE(pSchema[i].type) && pExtSchema) {
303,787!
629
      decimalFromTypeMod(pExtSchema[i].typeMod, &pResInfo->fields[i].precision, &pResInfo->fields[i].scale);
65✔
630
    }
631

632
    tstrncpy(pResInfo->fields[i].name, pSchema[i].name, tListLen(pResInfo->fields[i].name));
303,779✔
633
    tstrncpy(pResInfo->userFields[i].name, pSchema[i].name, tListLen(pResInfo->userFields[i].name));
303,779✔
634
  }
635
  return TSDB_CODE_SUCCESS;
153,716✔
636
}
637

638
void setResPrecision(SReqResultInfo* pResInfo, int32_t precision) {
150,336✔
639
  if (precision != TSDB_TIME_PRECISION_MILLI && precision != TSDB_TIME_PRECISION_MICRO &&
150,336!
640
      precision != TSDB_TIME_PRECISION_NANO) {
641
    return;
×
642
  }
643

644
  pResInfo->precision = precision;
150,336✔
645
}
646

647
int32_t buildVnodePolicyNodeList(SRequestObj* pRequest, SArray** pNodeList, SArray* pMnodeList, SArray* pDbVgList) {
224,411✔
648
  SArray* nodeList = taosArrayInit(4, sizeof(SQueryNodeLoad));
224,411✔
649
  if (NULL == nodeList) {
224,473!
650
    return terrno;
×
651
  }
652
  char* policy = (tsQueryPolicy == QUERY_POLICY_VNODE) ? "vnode" : "client";
224,477!
653

654
  int32_t dbNum = taosArrayGetSize(pDbVgList);
224,477✔
655
  for (int32_t i = 0; i < dbNum; ++i) {
447,928✔
656
    SArray* pVg = taosArrayGetP(pDbVgList, i);
223,409✔
657
    if (NULL == pVg) {
223,407!
658
      continue;
×
659
    }
660
    int32_t vgNum = taosArrayGetSize(pVg);
223,407✔
661
    if (vgNum <= 0) {
223,418✔
662
      continue;
271✔
663
    }
664

665
    for (int32_t j = 0; j < vgNum; ++j) {
2,000,522✔
666
      SVgroupInfo* pInfo = taosArrayGet(pVg, j);
1,777,353✔
667
      if (NULL == pInfo) {
1,777,285!
668
        taosArrayDestroy(nodeList);
×
669
        return TSDB_CODE_OUT_OF_RANGE;
×
670
      }
671
      SQueryNodeLoad load = {0};
1,777,285✔
672
      load.addr.nodeId = pInfo->vgId;
1,777,285✔
673
      load.addr.epSet = pInfo->epSet;
1,777,285✔
674

675
      if (NULL == taosArrayPush(nodeList, &load)) {
1,777,375!
676
        taosArrayDestroy(nodeList);
×
677
        return terrno;
×
678
      }
679
    }
680
  }
681

682
  int32_t vnodeNum = taosArrayGetSize(nodeList);
224,519✔
683
  if (vnodeNum > 0) {
224,511✔
684
    tscDebug("0x%" PRIx64 " %s policy, use vnode list, num:%d", pRequest->requestId, policy, vnodeNum);
222,779✔
685
    goto _return;
222,771✔
686
  }
687

688
  int32_t mnodeNum = taosArrayGetSize(pMnodeList);
1,732✔
689
  if (mnodeNum <= 0) {
1,735!
690
    tscDebug("0x%" PRIx64 " %s policy, empty node list", pRequest->requestId, policy);
×
691
    goto _return;
×
692
  }
693

694
  void* pData = taosArrayGet(pMnodeList, 0);
1,735✔
695
  if (NULL == pData) {
1,735!
696
    taosArrayDestroy(nodeList);
×
697
    return TSDB_CODE_OUT_OF_RANGE;
×
698
  }
699
  if (NULL == taosArrayAddBatch(nodeList, pData, mnodeNum)) {
1,735!
700
    taosArrayDestroy(nodeList);
×
701
    return terrno;
×
702
  }
703

704
  tscDebug("0x%" PRIx64 " %s policy, use mnode list, num:%d", pRequest->requestId, policy, mnodeNum);
1,735✔
705

706
_return:
136✔
707

708
  *pNodeList = nodeList;
224,492✔
709

710
  return TSDB_CODE_SUCCESS;
224,492✔
711
}
712

713
int32_t buildQnodePolicyNodeList(SRequestObj* pRequest, SArray** pNodeList, SArray* pMnodeList, SArray* pQnodeList) {
×
714
  SArray* nodeList = taosArrayInit(4, sizeof(SQueryNodeLoad));
×
715
  if (NULL == nodeList) {
×
716
    return terrno;
×
717
  }
718

719
  int32_t qNodeNum = taosArrayGetSize(pQnodeList);
×
720
  if (qNodeNum > 0) {
×
721
    void* pData = taosArrayGet(pQnodeList, 0);
×
722
    if (NULL == pData) {
×
723
      taosArrayDestroy(nodeList);
×
724
      return TSDB_CODE_OUT_OF_RANGE;
×
725
    }
726
    if (NULL == taosArrayAddBatch(nodeList, pData, qNodeNum)) {
×
727
      taosArrayDestroy(nodeList);
×
728
      return terrno;
×
729
    }
730
    tscDebug("0x%" PRIx64 " qnode policy, use qnode list, num:%d", pRequest->requestId, qNodeNum);
×
731
    goto _return;
×
732
  }
733

734
  int32_t mnodeNum = taosArrayGetSize(pMnodeList);
×
735
  if (mnodeNum <= 0) {
×
736
    tscDebug("0x%" PRIx64 " qnode policy, empty node list", pRequest->requestId);
×
737
    goto _return;
×
738
  }
739

740
  void* pData = taosArrayGet(pMnodeList, 0);
×
741
  if (NULL == pData) {
×
742
    taosArrayDestroy(nodeList);
×
743
    return TSDB_CODE_OUT_OF_RANGE;
×
744
  }
745
  if (NULL == taosArrayAddBatch(nodeList, pData, mnodeNum)) {
×
746
    taosArrayDestroy(nodeList);
×
747
    return terrno;
×
748
  }
749

750
  tscDebug("0x%" PRIx64 " qnode policy, use mnode list, num:%d", pRequest->requestId, mnodeNum);
×
751

752
_return:
×
753

754
  *pNodeList = nodeList;
×
755

756
  return TSDB_CODE_SUCCESS;
×
757
}
758

759
void freeVgList(void* list) {
21,791✔
760
  SArray* pList = *(SArray**)list;
21,791✔
761
  taosArrayDestroy(pList);
21,791✔
762
}
21,825✔
763

764
int32_t buildAsyncExecNodeList(SRequestObj* pRequest, SArray** pNodeList, SArray* pMnodeList, SMetaData* pResultMeta) {
202,592✔
765
  SArray* pDbVgList = NULL;
202,592✔
766
  SArray* pQnodeList = NULL;
202,592✔
767
  FDelete fp = NULL;
202,592✔
768
  int32_t code = 0;
202,592✔
769

770
  switch (tsQueryPolicy) {
202,592!
771
    case QUERY_POLICY_VNODE:
202,612✔
772
    case QUERY_POLICY_CLIENT: {
773
      if (pResultMeta) {
202,612!
774
        pDbVgList = taosArrayInit(4, POINTER_BYTES);
202,631✔
775
        if (NULL == pDbVgList) {
202,615!
776
          code = terrno;
×
777
          goto _return;
×
778
        }
779
        int32_t dbNum = taosArrayGetSize(pResultMeta->pDbVgroup);
202,615✔
780
        for (int32_t i = 0; i < dbNum; ++i) {
404,164✔
781
          SMetaRes* pRes = taosArrayGet(pResultMeta->pDbVgroup, i);
201,600✔
782
          if (pRes->code || NULL == pRes->pRes) {
201,574!
783
            continue;
×
784
          }
785

786
          if (NULL == taosArrayPush(pDbVgList, &pRes->pRes)) {
403,212!
787
            code = terrno;
×
788
            goto _return;
×
789
          }
790
        }
791
      } else {
792
        fp = freeVgList;
×
793

794
        int32_t dbNum = taosArrayGetSize(pRequest->dbList);
×
795
        if (dbNum > 0) {
×
796
          SCatalog*     pCtg = NULL;
×
797
          SAppInstInfo* pInst = pRequest->pTscObj->pAppInfo;
×
798
          code = catalogGetHandle(pInst->clusterId, &pCtg);
×
799
          if (code != TSDB_CODE_SUCCESS) {
×
800
            goto _return;
×
801
          }
802

803
          pDbVgList = taosArrayInit(dbNum, POINTER_BYTES);
×
804
          if (NULL == pDbVgList) {
×
805
            code = terrno;
×
806
            goto _return;
×
807
          }
808
          SArray* pVgList = NULL;
×
809
          for (int32_t i = 0; i < dbNum; ++i) {
×
810
            char*            dbFName = taosArrayGet(pRequest->dbList, i);
×
811
            SRequestConnInfo conn = {.pTrans = pInst->pTransporter,
×
812
                                     .requestId = pRequest->requestId,
×
813
                                     .requestObjRefId = pRequest->self,
×
814
                                     .mgmtEps = getEpSet_s(&pInst->mgmtEp)};
×
815

816
            // catalogGetDBVgList will handle dbFName == null.
817
            code = catalogGetDBVgList(pCtg, &conn, dbFName, &pVgList);
×
818
            if (code) {
×
819
              goto _return;
×
820
            }
821

822
            if (NULL == taosArrayPush(pDbVgList, &pVgList)) {
×
823
              code = terrno;
×
824
              goto _return;
×
825
            }
826
          }
827
        }
828
      }
829

830
      code = buildVnodePolicyNodeList(pRequest, pNodeList, pMnodeList, pDbVgList);
202,564✔
831
      break;
202,621✔
832
    }
833
    case QUERY_POLICY_HYBRID:
×
834
    case QUERY_POLICY_QNODE: {
835
      if (pResultMeta && taosArrayGetSize(pResultMeta->pQnodeList) > 0) {
×
836
        SMetaRes* pRes = taosArrayGet(pResultMeta->pQnodeList, 0);
×
837
        if (pRes->code) {
×
838
          pQnodeList = NULL;
×
839
        } else {
840
          pQnodeList = taosArrayDup((SArray*)pRes->pRes, NULL);
×
841
          if (NULL == pQnodeList) {
×
842
            code = terrno ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
843
            goto _return;
×
844
          }
845
        }
846
      } else {
847
        SAppInstInfo* pInst = pRequest->pTscObj->pAppInfo;
×
848
        TSC_ERR_JRET(taosThreadMutexLock(&pInst->qnodeMutex));
×
849
        if (pInst->pQnodeList) {
×
850
          pQnodeList = taosArrayDup(pInst->pQnodeList, NULL);
×
851
          if (NULL == pQnodeList) {
×
852
            code = terrno ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
853
            goto _return;
×
854
          }
855
        }
856
        TSC_ERR_JRET(taosThreadMutexUnlock(&pInst->qnodeMutex));
×
857
      }
858

859
      code = buildQnodePolicyNodeList(pRequest, pNodeList, pMnodeList, pQnodeList);
×
860
      break;
×
861
    }
862
    default:
×
863
      tscError("unknown query policy: %d", tsQueryPolicy);
×
864
      return TSDB_CODE_APP_ERROR;
×
865
  }
866

867
_return:
202,621✔
868
  taosArrayDestroyEx(pDbVgList, fp);
202,621✔
869
  taosArrayDestroy(pQnodeList);
202,621✔
870

871
  return code;
202,632✔
872
}
873

874
int32_t buildSyncExecNodeList(SRequestObj* pRequest, SArray** pNodeList, SArray* pMnodeList) {
21,826✔
875
  SArray* pDbVgList = NULL;
21,826✔
876
  SArray* pQnodeList = NULL;
21,826✔
877
  int32_t code = 0;
21,826✔
878

879
  switch (tsQueryPolicy) {
21,826!
880
    case QUERY_POLICY_VNODE:
21,840✔
881
    case QUERY_POLICY_CLIENT: {
882
      int32_t dbNum = taosArrayGetSize(pRequest->dbList);
21,840✔
883
      if (dbNum > 0) {
21,869✔
884
        SCatalog*     pCtg = NULL;
21,810✔
885
        SAppInstInfo* pInst = pRequest->pTscObj->pAppInfo;
21,810✔
886
        code = catalogGetHandle(pInst->clusterId, &pCtg);
21,810✔
887
        if (code != TSDB_CODE_SUCCESS) {
21,792!
888
          goto _return;
×
889
        }
890

891
        pDbVgList = taosArrayInit(dbNum, POINTER_BYTES);
21,792✔
892
        if (NULL == pDbVgList) {
21,796!
893
          code = terrno;
×
894
          goto _return;
×
895
        }
896
        SArray* pVgList = NULL;
21,800✔
897
        for (int32_t i = 0; i < dbNum; ++i) {
43,623✔
898
          char*            dbFName = taosArrayGet(pRequest->dbList, i);
21,765✔
899
          SRequestConnInfo conn = {.pTrans = pInst->pTransporter,
21,778✔
900
                                   .requestId = pRequest->requestId,
21,778✔
901
                                   .requestObjRefId = pRequest->self,
21,778✔
902
                                   .mgmtEps = getEpSet_s(&pInst->mgmtEp)};
21,778✔
903

904
          // catalogGetDBVgList will handle dbFName == null.
905
          code = catalogGetDBVgList(pCtg, &conn, dbFName, &pVgList);
21,821✔
906
          if (code) {
21,815!
907
            goto _return;
×
908
          }
909

910
          if (NULL == taosArrayPush(pDbVgList, &pVgList)) {
21,823!
911
            code = terrno;
×
912
            goto _return;
×
913
          }
914
        }
915
      }
916

917
      code = buildVnodePolicyNodeList(pRequest, pNodeList, pMnodeList, pDbVgList);
21,917✔
918
      break;
21,868✔
919
    }
920
    case QUERY_POLICY_HYBRID:
×
921
    case QUERY_POLICY_QNODE: {
922
      TSC_ERR_JRET(getQnodeList(pRequest, &pQnodeList));
×
923

924
      code = buildQnodePolicyNodeList(pRequest, pNodeList, pMnodeList, pQnodeList);
×
925
      break;
×
926
    }
927
    default:
×
928
      tscError("unknown query policy: %d", tsQueryPolicy);
×
929
      return TSDB_CODE_APP_ERROR;
×
930
  }
931

932
_return:
21,868✔
933

934
  taosArrayDestroyEx(pDbVgList, freeVgList);
21,868✔
935
  taosArrayDestroy(pQnodeList);
21,842✔
936

937
  return code;
21,855✔
938
}
939

940
int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList) {
21,833✔
941
  void* pTransporter = pRequest->pTscObj->pAppInfo->pTransporter;
21,833✔
942

943
  SExecResult      res = {0};
21,833✔
944
  SRequestConnInfo conn = {.pTrans = pRequest->pTscObj->pAppInfo->pTransporter,
21,833✔
945
                           .requestId = pRequest->requestId,
21,833✔
946
                           .requestObjRefId = pRequest->self};
21,833✔
947
  SSchedulerReq    req = {
43,687✔
948
         .syncReq = true,
949
         .localReq = (tsQueryPolicy == QUERY_POLICY_CLIENT),
21,833✔
950
         .pConn = &conn,
951
         .pNodeList = pNodeList,
952
         .pDag = pDag,
953
         .sql = pRequest->sqlstr,
21,833✔
954
         .startTs = pRequest->metric.start,
21,833✔
955
         .execFp = NULL,
956
         .cbParam = NULL,
957
         .chkKillFp = chkRequestKilled,
958
         .chkKillParam = (void*)pRequest->self,
21,833✔
959
         .pExecRes = &res,
960
         .source = pRequest->source,
21,833✔
961
         .pWorkerCb = getTaskPoolWorkerCb(),
21,833✔
962
  };
963

964
  int32_t code = schedulerExecJob(&req, &pRequest->body.queryJob);
21,854✔
965

966
  destroyQueryExecRes(&pRequest->body.resInfo.execRes);
21,890✔
967
  (void)memcpy(&pRequest->body.resInfo.execRes, &res, sizeof(res));
21,878✔
968

969
  if (code != TSDB_CODE_SUCCESS) {
21,878!
970
    schedulerFreeJob(&pRequest->body.queryJob, 0);
×
971

972
    pRequest->code = code;
×
973
    terrno = code;
×
974
    return pRequest->code;
5✔
975
  }
976

977
  if (TDMT_VND_SUBMIT == pRequest->type || TDMT_VND_DELETE == pRequest->type ||
21,878!
978
      TDMT_VND_CREATE_TABLE == pRequest->type) {
8✔
979
    pRequest->body.resInfo.numOfRows = res.numOfRows;
21,871✔
980
    if (TDMT_VND_SUBMIT == pRequest->type) {
21,871!
981
      STscObj*            pTscObj = pRequest->pTscObj;
21,876✔
982
      SAppClusterSummary* pActivity = &pTscObj->pAppInfo->summary;
21,876✔
983
      (void)atomic_add_fetch_64((int64_t*)&pActivity->numOfInsertRows, res.numOfRows);
21,876✔
984
    }
985

986
    schedulerFreeJob(&pRequest->body.queryJob, 0);
21,883✔
987
  }
988

989
  pRequest->code = res.code;
21,886✔
990
  terrno = res.code;
21,886✔
991
  return pRequest->code;
21,882✔
992
}
993

994
int32_t handleSubmitExecRes(SRequestObj* pRequest, void* res, SCatalog* pCatalog, SEpSet* epset) {
8,367,195✔
995
  SArray*      pArray = NULL;
8,367,195✔
996
  SSubmitRsp2* pRsp = (SSubmitRsp2*)res;
8,367,195✔
997
  if (NULL == pRsp->aCreateTbRsp) {
8,367,195✔
998
    return TSDB_CODE_SUCCESS;
8,338,339✔
999
  }
1000

1001
  int32_t tbNum = taosArrayGetSize(pRsp->aCreateTbRsp);
28,856✔
1002
  for (int32_t i = 0; i < tbNum; ++i) {
66,590✔
1003
    SVCreateTbRsp* pTbRsp = (SVCreateTbRsp*)taosArrayGet(pRsp->aCreateTbRsp, i);
34,690✔
1004
    if (pTbRsp->pMeta) {
34,685✔
1005
      TSC_ERR_RET(handleCreateTbExecRes(pTbRsp->pMeta, pCatalog));
32,394!
1006
    }
1007
  }
1008

1009
  return TSDB_CODE_SUCCESS;
31,900✔
1010
}
1011

1012
int32_t handleQueryExecRes(SRequestObj* pRequest, void* res, SCatalog* pCatalog, SEpSet* epset) {
140,011✔
1013
  int32_t code = 0;
140,011✔
1014
  SArray* pArray = NULL;
140,011✔
1015
  SArray* pTbArray = (SArray*)res;
140,011✔
1016
  int32_t tbNum = taosArrayGetSize(pTbArray);
140,011✔
1017
  if (tbNum <= 0) {
140,009!
1018
    return TSDB_CODE_SUCCESS;
×
1019
  }
1020

1021
  pArray = taosArrayInit(tbNum, sizeof(STbSVersion));
140,009✔
1022
  if (NULL == pArray) {
140,023!
1023
    return terrno;
×
1024
  }
1025

1026
  for (int32_t i = 0; i < tbNum; ++i) {
313,076✔
1027
    STbVerInfo* tbInfo = taosArrayGet(pTbArray, i);
173,052✔
1028
    if (NULL == tbInfo) {
173,054!
1029
      code = terrno;
×
1030
      goto _return;
×
1031
    }
1032
    STbSVersion tbSver = {
173,054✔
1033
        .tbFName = tbInfo->tbFName, .sver = tbInfo->sversion, .tver = tbInfo->tversion, .rver = tbInfo->rversion};
173,054✔
1034
    if (NULL == taosArrayPush(pArray, &tbSver)) {
173,053!
1035
      code = terrno;
×
1036
      goto _return;
×
1037
    }
1038
  }
1039

1040
  SRequestConnInfo conn = {.pTrans = pRequest->pTscObj->pAppInfo->pTransporter,
140,024✔
1041
                           .requestId = pRequest->requestId,
140,024✔
1042
                           .requestObjRefId = pRequest->self,
140,024✔
1043
                           .mgmtEps = *epset};
1044

1045
  code = catalogChkTbMetaVersion(pCatalog, &conn, pArray);
140,024✔
1046

1047
_return:
140,005✔
1048

1049
  taosArrayDestroy(pArray);
140,005✔
1050
  return code;
140,025✔
1051
}
1052

1053
int32_t handleAlterTbExecRes(void* res, SCatalog* pCatalog) {
2,331✔
1054
  return catalogUpdateTableMeta(pCatalog, (STableMetaRsp*)res);
2,331✔
1055
}
1056

1057
int32_t handleCreateTbExecRes(void* res, SCatalog* pCatalog) {
88,410✔
1058
  return catalogAsyncUpdateTableMeta(pCatalog, (STableMetaRsp*)res);
88,410✔
1059
}
1060

1061
int32_t handleQueryExecRsp(SRequestObj* pRequest) {
8,583,431✔
1062
  if (NULL == pRequest->body.resInfo.execRes.res) {
8,583,431✔
1063
    return pRequest->code;
65,938✔
1064
  }
1065

1066
  SCatalog*     pCatalog = NULL;
8,517,493✔
1067
  SAppInstInfo* pAppInfo = getAppInfo(pRequest);
8,517,493✔
1068

1069
  int32_t code = catalogGetHandle(pAppInfo->clusterId, &pCatalog);
8,517,155✔
1070
  if (code) {
8,529,441!
1071
    return code;
×
1072
  }
1073

1074
  SEpSet       epset = getEpSet_s(&pAppInfo->mgmtEp);
8,529,441✔
1075
  SExecResult* pRes = &pRequest->body.resInfo.execRes;
8,547,607✔
1076

1077
  switch (pRes->msgType) {
8,547,607!
1078
    case TDMT_VND_ALTER_TABLE:
948✔
1079
    case TDMT_MND_ALTER_STB: {
1080
      code = handleAlterTbExecRes(pRes->res, pCatalog);
948✔
1081
      break;
948✔
1082
    }
1083
    case TDMT_VND_CREATE_TABLE: {
33,176✔
1084
      SArray* pList = (SArray*)pRes->res;
33,176✔
1085
      int32_t num = taosArrayGetSize(pList);
33,176✔
1086
      for (int32_t i = 0; i < num; ++i) {
87,531✔
1087
        void* res = taosArrayGetP(pList, i);
54,354✔
1088
        // handleCreateTbExecRes will handle res == null
1089
        code = handleCreateTbExecRes(res, pCatalog);
54,344✔
1090
      }
1091
      break;
33,177✔
1092
    }
1093
    case TDMT_MND_CREATE_STB: {
371✔
1094
      code = handleCreateTbExecRes(pRes->res, pCatalog);
371✔
1095
      break;
371✔
1096
    }
1097
    case TDMT_VND_SUBMIT: {
8,373,805✔
1098
      (void)atomic_add_fetch_64((int64_t*)&pAppInfo->summary.insertBytes, pRes->numOfBytes);
8,373,805✔
1099

1100
      code = handleSubmitExecRes(pRequest, pRes->res, pCatalog, &epset);
8,375,034✔
1101
      break;
8,366,511✔
1102
    }
1103
    case TDMT_SCH_QUERY:
140,023✔
1104
    case TDMT_SCH_MERGE_QUERY: {
1105
      code = handleQueryExecRes(pRequest, pRes->res, pCatalog, &epset);
140,023✔
1106
      break;
140,008✔
1107
    }
1108
    default:
×
1109
      tscError("req:0x%" PRIx64 ", invalid exec result for request type:%d, QID:0x%" PRIx64, pRequest->self,
×
1110
               pRequest->type, pRequest->requestId);
1111
      code = TSDB_CODE_APP_ERROR;
×
1112
  }
1113

1114
  return code;
8,541,015✔
1115
}
1116

1117
static bool incompletaFileParsing(SNode* pStmt) {
8,589,479✔
1118
  return QUERY_NODE_VNODE_MODIFY_STMT != nodeType(pStmt) ? false : ((SVnodeModifyOpStmt*)pStmt)->fileProcessing;
8,589,479!
1119
}
1120

1121
void continuePostSubQuery(SRequestObj* pRequest, SSDataBlock* pBlock) {
×
1122
  SSqlCallbackWrapper* pWrapper = pRequest->pWrapper;
×
1123

1124
  int32_t code = nodesAcquireAllocator(pWrapper->pParseCtx->allocatorId);
×
1125
  if (TSDB_CODE_SUCCESS == code) {
×
1126
    int64_t analyseStart = taosGetTimestampUs();
×
1127
    code = qContinueParsePostQuery(pWrapper->pParseCtx, pRequest->pQuery, pBlock);
×
1128
    pRequest->metric.analyseCostUs += taosGetTimestampUs() - analyseStart;
×
1129
  }
1130

1131
  if (TSDB_CODE_SUCCESS == code) {
×
1132
    code = qContinuePlanPostQuery(pRequest->pPostPlan);
×
1133
  }
1134

1135
  code = nodesReleaseAllocator(pWrapper->pParseCtx->allocatorId);
×
1136
  handleQueryAnslyseRes(pWrapper, NULL, code);
×
1137
}
×
1138

1139
void returnToUser(SRequestObj* pRequest) {
2,977✔
1140
  if (pRequest->relation.userRefId == pRequest->self || 0 == pRequest->relation.userRefId) {
2,977!
1141
    // return to client
1142
    doRequestCallback(pRequest, pRequest->code);
2,977✔
1143
    return;
2,977✔
1144
  }
1145

1146
  SRequestObj* pUserReq = acquireRequest(pRequest->relation.userRefId);
×
1147
  if (pUserReq) {
×
1148
    pUserReq->code = pRequest->code;
×
1149
    // return to client
1150
    doRequestCallback(pUserReq, pUserReq->code);
×
1151
    (void)releaseRequest(pRequest->relation.userRefId);
×
1152
    return;
×
1153
  } else {
1154
    tscError("req:0x%" PRIx64 ", user ref 0x%" PRIx64 " is not there, QID:0x%" PRIx64, pRequest->self,
×
1155
             pRequest->relation.userRefId, pRequest->requestId);
1156
  }
1157
}
1158

1159
static int32_t createResultBlock(TAOS_RES* pRes, int32_t numOfRows, SSDataBlock** pBlock) {
×
1160
  int64_t     lastTs = 0;
×
1161
  TAOS_FIELD* pResFields = taos_fetch_fields(pRes);
×
1162
  int32_t     numOfFields = taos_num_fields(pRes);
×
1163

1164
  int32_t code = createDataBlock(pBlock);
×
1165
  if (code) {
×
1166
    return code;
×
1167
  }
1168

1169
  for (int32_t i = 0; i < numOfFields; ++i) {
×
1170
    SColumnInfoData colInfoData = createColumnInfoData(pResFields[i].type, pResFields[i].bytes, i + 1);
×
1171
    code = blockDataAppendColInfo(*pBlock, &colInfoData);
×
1172
    if (TSDB_CODE_SUCCESS != code) {
×
1173
      blockDataDestroy(*pBlock);
×
1174
      return code;
×
1175
    }
1176
  }
1177

1178
  code = blockDataEnsureCapacity(*pBlock, numOfRows);
×
1179
  if (TSDB_CODE_SUCCESS != code) {
×
1180
    blockDataDestroy(*pBlock);
×
1181
    return code;
×
1182
  }
1183

1184
  for (int32_t i = 0; i < numOfRows; ++i) {
×
1185
    TAOS_ROW pRow = taos_fetch_row(pRes);
×
1186
    if (NULL == pRow[0] || NULL == pRow[1] || NULL == pRow[2]) {
×
1187
      tscError("invalid data from vnode");
×
1188
      blockDataDestroy(*pBlock);
×
1189
      return TSDB_CODE_TSC_INTERNAL_ERROR;
×
1190
    }
1191
    int64_t ts = *(int64_t*)pRow[0];
×
1192
    if (lastTs < ts) {
×
1193
      lastTs = ts;
×
1194
    }
1195

1196
    for (int32_t j = 0; j < numOfFields; ++j) {
×
1197
      SColumnInfoData* pColInfoData = taosArrayGet((*pBlock)->pDataBlock, j);
×
1198
      code = colDataSetVal(pColInfoData, i, pRow[j], false);
×
1199
      if (TSDB_CODE_SUCCESS != code) {
×
1200
        blockDataDestroy(*pBlock);
×
1201
        return code;
×
1202
      }
1203
    }
1204

1205
    tscInfo("[create stream with histroy] lastKey:%" PRId64 " vgId:%d, vgVer:%" PRId64, ts, *(int32_t*)pRow[1],
×
1206
            *(int64_t*)pRow[2]);
1207
  }
1208

1209
  (*pBlock)->info.window.ekey = lastTs;
×
1210
  (*pBlock)->info.rows = numOfRows;
×
1211

1212
  tscInfo("[create stream with histroy] lastKey:%" PRId64 " numOfRows:%d from all vgroups", lastTs, numOfRows);
×
1213
  return TSDB_CODE_SUCCESS;
×
1214
}
1215

1216
void postSubQueryFetchCb(void* param, TAOS_RES* res, int32_t rowNum) {
×
1217
  SRequestObj* pRequest = (SRequestObj*)res;
×
1218
  if (pRequest->code) {
×
1219
    returnToUser(pRequest);
×
1220
    return;
×
1221
  }
1222

1223
  SSDataBlock* pBlock = NULL;
×
1224
  pRequest->code = createResultBlock(res, rowNum, &pBlock);
×
1225
  if (TSDB_CODE_SUCCESS != pRequest->code) {
×
1226
    tscError("req:0x%" PRIx64 ", create result block failed, QID:0x%" PRIx64 " %s", pRequest->self, pRequest->requestId,
×
1227
             tstrerror(pRequest->code));
1228
    returnToUser(pRequest);
×
1229
    return;
×
1230
  }
1231

1232
  SRequestObj* pNextReq = acquireRequest(pRequest->relation.nextRefId);
×
1233
  if (pNextReq) {
×
1234
    continuePostSubQuery(pNextReq, pBlock);
×
1235
    (void)releaseRequest(pRequest->relation.nextRefId);
×
1236
  } else {
1237
    tscError("req:0x%" PRIx64 ", next req ref 0x%" PRIx64 " is not there, QID:0x%" PRIx64, pRequest->self,
×
1238
             pRequest->relation.nextRefId, pRequest->requestId);
1239
  }
1240

1241
  blockDataDestroy(pBlock);
×
1242
}
1243

1244
void handlePostSubQuery(SSqlCallbackWrapper* pWrapper) {
×
1245
  SRequestObj* pRequest = pWrapper->pRequest;
×
1246
  if (TD_RES_QUERY(pRequest)) {
×
1247
    taosAsyncFetchImpl(pRequest, postSubQueryFetchCb, pWrapper);
×
1248
    return;
×
1249
  }
1250

1251
  SRequestObj* pNextReq = acquireRequest(pRequest->relation.nextRefId);
×
1252
  if (pNextReq) {
×
1253
    continuePostSubQuery(pNextReq, NULL);
×
1254
    (void)releaseRequest(pRequest->relation.nextRefId);
×
1255
  } else {
1256
    tscError("req:0x%" PRIx64 ", next req ref 0x%" PRIx64 " is not there, QID:0x%" PRIx64, pRequest->self,
×
1257
             pRequest->relation.nextRefId, pRequest->requestId);
1258
  }
1259
}
1260

1261
// todo refacto the error code  mgmt
1262
void schedulerExecCb(SExecResult* pResult, void* param, int32_t code) {
8,540,271✔
1263
  SSqlCallbackWrapper* pWrapper = param;
8,540,271✔
1264
  SRequestObj*         pRequest = pWrapper->pRequest;
8,540,271✔
1265
  STscObj*             pTscObj = pRequest->pTscObj;
8,540,271✔
1266

1267
  pRequest->code = code;
8,540,271✔
1268
  if (pResult) {
8,540,271!
1269
    destroyQueryExecRes(&pRequest->body.resInfo.execRes);
8,542,080✔
1270
    (void)memcpy(&pRequest->body.resInfo.execRes, pResult, sizeof(*pResult));
8,549,482✔
1271
  }
1272

1273
  int32_t type = pRequest->type;
8,547,673✔
1274
  if (TDMT_VND_SUBMIT == type || TDMT_VND_DELETE == type || TDMT_VND_CREATE_TABLE == type) {
8,547,673✔
1275
    if (pResult) {
8,398,672!
1276
      pRequest->body.resInfo.numOfRows += pResult->numOfRows;
8,405,313✔
1277

1278
      // record the insert rows
1279
      if (TDMT_VND_SUBMIT == type) {
8,405,313✔
1280
        SAppClusterSummary* pActivity = &pTscObj->pAppInfo->summary;
8,319,663✔
1281
        (void)atomic_add_fetch_64((int64_t*)&pActivity->numOfInsertRows, pResult->numOfRows);
8,319,663✔
1282
      }
1283
    }
1284
    schedulerFreeJob(&pRequest->body.queryJob, 0);
8,434,492✔
1285
  }
1286

1287
  taosMemoryFree(pResult);
8,578,883!
1288
  tscDebug("req:0x%" PRIx64 ", enter scheduler exec cb, code:%s, QID:0x%" PRIx64, pRequest->self, tstrerror(code),
8,592,894✔
1289
           pRequest->requestId);
1290

1291
  if (code != TSDB_CODE_SUCCESS && NEED_CLIENT_HANDLE_ERROR(code) && pRequest->sqlstr != NULL) {
8,577,017!
1292
    tscDebug("req:0x%" PRIx64 ", client retry to handle the error, code:%s, tryCount:%d, QID:0x%" PRIx64,
262✔
1293
             pRequest->self, tstrerror(code), pRequest->retry, pRequest->requestId);
1294
    if (TSDB_CODE_SUCCESS != removeMeta(pTscObj, pRequest->targetTableList, IS_VIEW_REQUEST(pRequest->type))) {
262!
1295
      tscError("req:0x%" PRIx64 ", remove meta failed, QID:0x%" PRIx64, pRequest->self, pRequest->requestId);
×
1296
    }
1297
    restartAsyncQuery(pRequest, code);
260✔
1298
    return;
261✔
1299
  }
1300

1301
  tscTrace("req:0x%" PRIx64 ", scheduler exec cb, request type:%s", pRequest->self, TMSG_INFO(pRequest->type));
8,576,755!
1302
  if (NEED_CLIENT_RM_TBLMETA_REQ(pRequest->type) && NULL == pRequest->body.resInfo.execRes.res) {
8,576,755!
1303
    if (TSDB_CODE_SUCCESS != removeMeta(pTscObj, pRequest->targetTableList, IS_VIEW_REQUEST(pRequest->type))) {
1,563!
1304
      tscError("req:0x%" PRIx64 ", remove meta failed, QID:0x%" PRIx64, pRequest->self, pRequest->requestId);
×
1305
    }
1306
  }
1307

1308
  pRequest->metric.execCostUs = taosGetTimestampUs() - pRequest->metric.execStart;
8,568,531✔
1309
  int32_t code1 = handleQueryExecRsp(pRequest);
8,568,531✔
1310
  if (pRequest->code == TSDB_CODE_SUCCESS && pRequest->code != code1) {
8,584,636!
1311
    pRequest->code = code1;
×
1312
  }
1313

1314
  if (pRequest->code == TSDB_CODE_SUCCESS && NULL != pRequest->pQuery &&
17,174,200!
1315
      incompletaFileParsing(pRequest->pQuery->pRoot)) {
8,588,544✔
1316
    continueInsertFromCsv(pWrapper, pRequest);
×
1317
    return;
×
1318
  }
1319

1320
  if (pRequest->relation.nextRefId) {
8,591,040!
1321
    handlePostSubQuery(pWrapper);
×
1322
  } else {
1323
    destorySqlCallbackWrapper(pWrapper);
8,591,040✔
1324
    pRequest->pWrapper = NULL;
8,594,040✔
1325

1326
    // return to client
1327
    doRequestCallback(pRequest, code);
8,594,040✔
1328
  }
1329
}
1330

1331
void launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, bool keepQuery, void** res) {
22,340✔
1332
  int32_t code = 0;
22,340✔
1333
  int32_t subplanNum = 0;
22,340✔
1334

1335
  if (pQuery->pRoot) {
22,340✔
1336
    pRequest->stmtType = pQuery->pRoot->type;
21,889✔
1337
  }
1338

1339
  if (pQuery->pRoot && !pRequest->inRetry) {
22,340!
1340
    STscObj*            pTscObj = pRequest->pTscObj;
21,888✔
1341
    SAppClusterSummary* pActivity = &pTscObj->pAppInfo->summary;
21,888✔
1342
    if (QUERY_NODE_VNODE_MODIFY_STMT == pQuery->pRoot->type) {
21,888✔
1343
      (void)atomic_add_fetch_64((int64_t*)&pActivity->numOfInsertsReq, 1);
21,884✔
1344
    } else if (QUERY_NODE_SELECT_STMT == pQuery->pRoot->type) {
5!
1345
      (void)atomic_add_fetch_64((int64_t*)&pActivity->numOfQueryReq, 1);
7✔
1346
    }
1347
  }
1348

1349
  pRequest->body.execMode = pQuery->execMode;
22,369✔
1350
  switch (pQuery->execMode) {
22,369!
1351
    case QUERY_EXEC_MODE_LOCAL:
×
1352
      if (!pRequest->validateOnly) {
×
1353
        if (NULL == pQuery->pRoot) {
×
1354
          terrno = TSDB_CODE_INVALID_PARA;
×
1355
          code = terrno;
×
1356
        } else {
1357
          code = execLocalCmd(pRequest, pQuery);
×
1358
        }
1359
      }
1360
      break;
×
1361
    case QUERY_EXEC_MODE_RPC:
483✔
1362
      if (!pRequest->validateOnly) {
483!
1363
        code = execDdlQuery(pRequest, pQuery);
483✔
1364
      }
1365
      break;
483✔
1366
    case QUERY_EXEC_MODE_SCHEDULE: {
21,886✔
1367
      SArray* pMnodeList = taosArrayInit(4, sizeof(SQueryNodeLoad));
21,886✔
1368
      if (NULL == pMnodeList) {
21,863!
1369
        code = terrno;
×
1370
        break;
×
1371
      }
1372
      SQueryPlan* pDag = NULL;
21,863✔
1373
      code = getPlan(pRequest, pQuery, &pDag, pMnodeList);
21,863✔
1374
      if (TSDB_CODE_SUCCESS == code) {
21,830!
1375
        pRequest->body.subplanNum = pDag->numOfSubplans;
21,840✔
1376
        if (!pRequest->validateOnly) {
21,840!
1377
          SArray* pNodeList = NULL;
21,888✔
1378
          code = buildSyncExecNodeList(pRequest, &pNodeList, pMnodeList);
21,888✔
1379
          if (TSDB_CODE_SUCCESS == code) {
21,848!
1380
            code = scheduleQuery(pRequest, pDag, pNodeList);
21,853✔
1381
          }
1382
          taosArrayDestroy(pNodeList);
21,866✔
1383
        }
1384
      }
1385
      taosArrayDestroy(pMnodeList);
21,821✔
1386
      break;
21,890✔
1387
    }
1388
    case QUERY_EXEC_MODE_EMPTY_RESULT:
×
1389
      pRequest->type = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
×
1390
      break;
×
1391
    default:
×
1392
      break;
×
1393
  }
1394

1395
  if (!keepQuery) {
22,373!
1396
    qDestroyQuery(pQuery);
×
1397
  }
1398

1399
  if (NEED_CLIENT_RM_TBLMETA_REQ(pRequest->type) && NULL == pRequest->body.resInfo.execRes.res) {
22,373!
1400
    int ret = removeMeta(pRequest->pTscObj, pRequest->targetTableList, IS_VIEW_REQUEST(pRequest->type));
112!
1401
    if (TSDB_CODE_SUCCESS != ret) {
112!
1402
      tscError("req:0x%" PRIx64 ", remove meta failed,code:%d, QID:0x%" PRIx64, pRequest->self, ret,
×
1403
               pRequest->requestId);
1404
    }
1405
  }
1406

1407
  if (TSDB_CODE_SUCCESS == code) {
22,373✔
1408
    code = handleQueryExecRsp(pRequest);
22,364✔
1409
  }
1410

1411
  if (TSDB_CODE_SUCCESS != code) {
22,385✔
1412
    pRequest->code = code;
106✔
1413
  }
1414

1415
  if (res) {
22,385!
1416
    *res = pRequest->body.resInfo.execRes.res;
×
1417
    pRequest->body.resInfo.execRes.res = NULL;
×
1418
  }
1419
}
22,385✔
1420

1421
static int32_t asyncExecSchQuery(SRequestObj* pRequest, SQuery* pQuery, SMetaData* pResultMeta,
8,561,695✔
1422
                                 SSqlCallbackWrapper* pWrapper) {
1423
  int32_t code = TSDB_CODE_SUCCESS;
8,561,695✔
1424
  pRequest->type = pQuery->msgType;
8,561,695✔
1425
  SArray*     pMnodeList = NULL;
8,561,695✔
1426
  SQueryPlan* pDag = NULL;
8,561,695✔
1427
  int64_t     st = taosGetTimestampUs();
8,559,487✔
1428

1429
  if (!pRequest->parseOnly) {
8,559,487!
1430
    pMnodeList = taosArrayInit(4, sizeof(SQueryNodeLoad));
8,563,133✔
1431
    if (NULL == pMnodeList) {
8,566,098!
1432
      code = terrno;
×
1433
    }
1434
    SPlanContext cxt = {.queryId = pRequest->requestId,
17,132,452✔
1435
                        .acctId = pRequest->pTscObj->acctId,
8,566,098✔
1436
                        .mgmtEpSet = getEpSet_s(&pRequest->pTscObj->pAppInfo->mgmtEp),
8,566,098✔
1437
                        .pAstRoot = pQuery->pRoot,
8,566,354✔
1438
                        .showRewrite = pQuery->showRewrite,
8,566,354✔
1439
                        .isView = pWrapper->pParseCtx->isView,
8,566,354✔
1440
                        .isAudit = pWrapper->pParseCtx->isAudit,
8,566,354✔
1441
                        .pMsg = pRequest->msgBuf,
8,566,354✔
1442
                        .msgLen = ERROR_MSG_BUF_DEFAULT_SIZE,
1443
                        .pUser = pRequest->pTscObj->user,
8,566,354✔
1444
                        .sysInfo = pRequest->pTscObj->sysInfo,
8,566,354✔
1445
                        .timezone = pRequest->pTscObj->optionInfo.timezone,
8,566,354✔
1446
                        .allocatorId = pRequest->allocatorRefId};
8,566,354✔
1447
    if (TSDB_CODE_SUCCESS == code) {
8,566,354!
1448
      code = qCreateQueryPlan(&cxt, &pDag, pMnodeList);
8,571,785✔
1449
    }
1450
    if (code) {
8,537,825✔
1451
      tscError("req:0x%" PRIx64 ", failed to create query plan, code:%s 0x%" PRIx64, pRequest->self, tstrerror(code),
559!
1452
               pRequest->requestId);
1453
    } else {
1454
      pRequest->body.subplanNum = pDag->numOfSubplans;
8,537,266✔
1455
      TSWAP(pRequest->pPostPlan, pDag->pPostPlan);
8,537,266✔
1456
    }
1457
  }
1458

1459
  pRequest->metric.execStart = taosGetTimestampUs();
8,527,879✔
1460
  pRequest->metric.planCostUs = pRequest->metric.execStart - st;
8,527,879✔
1461

1462
  if (TSDB_CODE_SUCCESS == code && !pRequest->validateOnly) {
17,087,008!
1463
    SArray* pNodeList = NULL;
8,550,648✔
1464
    if (QUERY_NODE_VNODE_MODIFY_STMT != nodeType(pQuery->pRoot)) {
8,550,648✔
1465
      code = buildAsyncExecNodeList(pRequest, &pNodeList, pMnodeList, pResultMeta);
202,629✔
1466
    }
1467

1468
    SRequestConnInfo conn = {.pTrans = getAppInfo(pRequest)->pTransporter,
8,550,649✔
1469
                             .requestId = pRequest->requestId,
8,525,434✔
1470
                             .requestObjRefId = pRequest->self};
8,525,434✔
1471
    SSchedulerReq    req = {
17,056,566✔
1472
           .syncReq = false,
1473
           .localReq = (tsQueryPolicy == QUERY_POLICY_CLIENT),
8,525,434✔
1474
           .pConn = &conn,
1475
           .pNodeList = pNodeList,
1476
           .pDag = pDag,
1477
           .allocatorRefId = pRequest->allocatorRefId,
8,525,434✔
1478
           .sql = pRequest->sqlstr,
8,525,434✔
1479
           .startTs = pRequest->metric.start,
8,525,434✔
1480
           .execFp = schedulerExecCb,
1481
           .cbParam = pWrapper,
1482
           .chkKillFp = chkRequestKilled,
1483
           .chkKillParam = (void*)pRequest->self,
8,525,434✔
1484
           .pExecRes = NULL,
1485
           .source = pRequest->source,
8,525,434✔
1486
           .pWorkerCb = getTaskPoolWorkerCb(),
8,525,434✔
1487
    };
1488
    if (TSDB_CODE_SUCCESS == code) {
8,531,132✔
1489
      code = schedulerExecJob(&req, &pRequest->body.queryJob);
8,528,256✔
1490
    }
1491

1492
    taosArrayDestroy(pNodeList);
8,563,782✔
1493
  } else {
1494
    qDestroyQueryPlan(pDag);
×
1495
    tscDebug("req:0x%" PRIx64 ", plan not executed, code:%s 0x%" PRIx64, pRequest->self, tstrerror(code),
839!
1496
             pRequest->requestId);
1497
    destorySqlCallbackWrapper(pWrapper);
839✔
1498
    pRequest->pWrapper = NULL;
839✔
1499
    if (TSDB_CODE_SUCCESS != code) {
839✔
1500
      pRequest->code = terrno;
559✔
1501
    }
1502

1503
    doRequestCallback(pRequest, code);
839✔
1504
  }
1505

1506
  // todo not to be released here
1507
  taosArrayDestroy(pMnodeList);
8,559,968✔
1508

1509
  return code;
8,561,519✔
1510
}
1511

1512
void launchAsyncQuery(SRequestObj* pRequest, SQuery* pQuery, SMetaData* pResultMeta, SSqlCallbackWrapper* pWrapper) {
8,539,330✔
1513
  int32_t code = 0;
8,539,330✔
1514

1515
  if (pRequest->parseOnly) {
8,539,330✔
1516
    doRequestCallback(pRequest, 0);
651✔
1517
    return;
651✔
1518
  }
1519

1520
  pRequest->body.execMode = pQuery->execMode;
8,538,679✔
1521
  if (QUERY_EXEC_MODE_SCHEDULE != pRequest->body.execMode) {
8,538,679✔
1522
    destorySqlCallbackWrapper(pWrapper);
20,317✔
1523
    pRequest->pWrapper = NULL;
20,303✔
1524
  }
1525

1526
  if (pQuery->pRoot && !pRequest->inRetry) {
8,538,665!
1527
    STscObj*            pTscObj = pRequest->pTscObj;
8,546,322✔
1528
    SAppClusterSummary* pActivity = &pTscObj->pAppInfo->summary;
8,546,322✔
1529
    if (QUERY_NODE_VNODE_MODIFY_STMT == pQuery->pRoot->type &&
8,546,322✔
1530
        (0 == ((SVnodeModifyOpStmt*)pQuery->pRoot)->sqlNodeType)) {
8,359,854✔
1531
      (void)atomic_add_fetch_64((int64_t*)&pActivity->numOfInsertsReq, 1);
8,327,124✔
1532
    } else if (QUERY_NODE_SELECT_STMT == pQuery->pRoot->type) {
219,198✔
1533
      (void)atomic_add_fetch_64((int64_t*)&pActivity->numOfQueryReq, 1);
147,342✔
1534
    }
1535
  }
1536

1537
  switch (pQuery->execMode) {
8,608,242!
1538
    case QUERY_EXEC_MODE_LOCAL:
3,989✔
1539
      asyncExecLocalCmd(pRequest, pQuery);
3,989✔
1540
      break;
3,989✔
1541
    case QUERY_EXEC_MODE_RPC:
16,146✔
1542
      code = asyncExecDdlQuery(pRequest, pQuery);
16,146✔
1543
      break;
16,175✔
1544
    case QUERY_EXEC_MODE_SCHEDULE: {
8,587,932✔
1545
      code = asyncExecSchQuery(pRequest, pQuery, pResultMeta, pWrapper);
8,587,932✔
1546
      break;
8,549,778✔
1547
    }
1548
    case QUERY_EXEC_MODE_EMPTY_RESULT:
175✔
1549
      pRequest->type = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
175✔
1550
      doRequestCallback(pRequest, 0);
175✔
1551
      break;
175✔
1552
    default:
×
1553
      tscError("req:0x%" PRIx64 ", invalid execMode %d", pRequest->self, pQuery->execMode);
×
1554
      doRequestCallback(pRequest, -1);
×
1555
      break;
×
1556
  }
1557
}
1558

1559
int32_t refreshMeta(STscObj* pTscObj, SRequestObj* pRequest) {
7✔
1560
  SCatalog* pCatalog = NULL;
7✔
1561
  int32_t   code = 0;
7✔
1562
  int32_t   dbNum = taosArrayGetSize(pRequest->dbList);
7✔
1563
  int32_t   tblNum = taosArrayGetSize(pRequest->tableList);
7✔
1564

1565
  if (dbNum <= 0 && tblNum <= 0) {
7!
1566
    return TSDB_CODE_APP_ERROR;
7✔
1567
  }
1568

1569
  code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCatalog);
×
1570
  if (code != TSDB_CODE_SUCCESS) {
×
1571
    return code;
×
1572
  }
1573

1574
  SRequestConnInfo conn = {.pTrans = pTscObj->pAppInfo->pTransporter,
×
1575
                           .requestId = pRequest->requestId,
×
1576
                           .requestObjRefId = pRequest->self,
×
1577
                           .mgmtEps = getEpSet_s(&pTscObj->pAppInfo->mgmtEp)};
×
1578

1579
  for (int32_t i = 0; i < dbNum; ++i) {
×
1580
    char* dbFName = taosArrayGet(pRequest->dbList, i);
×
1581

1582
    // catalogRefreshDBVgInfo will handle dbFName == null.
1583
    code = catalogRefreshDBVgInfo(pCatalog, &conn, dbFName);
×
1584
    if (code != TSDB_CODE_SUCCESS) {
×
1585
      return code;
×
1586
    }
1587
  }
1588

1589
  for (int32_t i = 0; i < tblNum; ++i) {
×
1590
    SName* tableName = taosArrayGet(pRequest->tableList, i);
×
1591

1592
    // catalogRefreshTableMeta will handle tableName == null.
1593
    code = catalogRefreshTableMeta(pCatalog, &conn, tableName, -1);
×
1594
    if (code != TSDB_CODE_SUCCESS) {
×
1595
      return code;
×
1596
    }
1597
  }
1598

1599
  return code;
×
1600
}
1601

1602
int32_t removeMeta(STscObj* pTscObj, SArray* tbList, bool isView) {
2,444✔
1603
  SCatalog* pCatalog = NULL;
2,444✔
1604
  int32_t   tbNum = taosArrayGetSize(tbList);
2,444✔
1605
  int32_t   code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCatalog);
2,444✔
1606
  if (code != TSDB_CODE_SUCCESS) {
2,445!
1607
    return code;
×
1608
  }
1609

1610
  if (isView) {
2,445✔
1611
    for (int32_t i = 0; i < tbNum; ++i) {
944✔
1612
      SName* pViewName = taosArrayGet(tbList, i);
472✔
1613
      char   dbFName[TSDB_DB_FNAME_LEN];
1614
      if (NULL == pViewName) {
472!
1615
        continue;
×
1616
      }
1617
      (void)tNameGetFullDbName(pViewName, dbFName);
472✔
1618
      TSC_ERR_RET(catalogRemoveViewMeta(pCatalog, dbFName, 0, pViewName->tname, 0));
472!
1619
    }
1620
  } else {
1621
    for (int32_t i = 0; i < tbNum; ++i) {
2,229✔
1622
      SName* pTbName = taosArrayGet(tbList, i);
256✔
1623
      TSC_ERR_RET(catalogRemoveTableMeta(pCatalog, pTbName));
256!
1624
    }
1625
  }
1626

1627
  return TSDB_CODE_SUCCESS;
2,445✔
1628
}
1629

1630
int32_t initEpSetFromCfg(const char* firstEp, const char* secondEp, SCorEpSet* pEpSet) {
10,479✔
1631
  pEpSet->version = 0;
10,479✔
1632

1633
  // init mnode ip set
1634
  SEpSet* mgmtEpSet = &(pEpSet->epSet);
10,479✔
1635
  mgmtEpSet->numOfEps = 0;
10,479✔
1636
  mgmtEpSet->inUse = 0;
10,479✔
1637

1638
  if (firstEp && firstEp[0] != 0) {
10,479!
1639
    if (strlen(firstEp) >= TSDB_EP_LEN) {
10,723!
1640
      terrno = TSDB_CODE_TSC_INVALID_FQDN;
×
1641
      return -1;
×
1642
    }
1643

1644
    int32_t code = taosGetFqdnPortFromEp(firstEp, &mgmtEpSet->eps[mgmtEpSet->numOfEps]);
10,723✔
1645
    if (code != TSDB_CODE_SUCCESS) {
10,682!
1646
      terrno = TSDB_CODE_TSC_INVALID_FQDN;
×
1647
      return terrno;
×
1648
    }
1649
    // uint32_t addr = 0;
1650
    SIpAddr addr = {0};
10,682✔
1651
    code = taosGetIpFromFqdn(tsEnableIpv6, mgmtEpSet->eps[mgmtEpSet->numOfEps].fqdn, &addr);
10,682✔
1652
    if (code) {
10,690✔
1653
      tscError("failed to resolve firstEp fqdn: %s, code:%s", mgmtEpSet->eps[mgmtEpSet->numOfEps].fqdn,
3!
1654
               tstrerror(TSDB_CODE_TSC_INVALID_FQDN));
1655
      (void)memset(&(mgmtEpSet->eps[mgmtEpSet->numOfEps]), 0, sizeof(mgmtEpSet->eps[mgmtEpSet->numOfEps]));
3✔
1656
    } else {
1657
      mgmtEpSet->numOfEps++;
10,687✔
1658
    }
1659
  }
1660

1661
  if (secondEp && secondEp[0] != 0) {
10,446!
1662
    if (strlen(secondEp) >= TSDB_EP_LEN) {
6,428!
1663
      terrno = TSDB_CODE_TSC_INVALID_FQDN;
×
1664
      return terrno;
×
1665
    }
1666

1667
    int32_t code = taosGetFqdnPortFromEp(secondEp, &mgmtEpSet->eps[mgmtEpSet->numOfEps]);
6,428✔
1668
    if (code != TSDB_CODE_SUCCESS) {
6,429!
1669
      return code;
×
1670
    }
1671
    SIpAddr addr = {0};
6,429✔
1672
    code = taosGetIpFromFqdn(tsEnableIpv6, mgmtEpSet->eps[mgmtEpSet->numOfEps].fqdn, &addr);
6,429✔
1673
    if (code) {
6,429!
1674
      tscError("failed to resolve secondEp fqdn: %s, code:%s", mgmtEpSet->eps[mgmtEpSet->numOfEps].fqdn,
×
1675
               tstrerror(TSDB_CODE_TSC_INVALID_FQDN));
1676
      (void)memset(&(mgmtEpSet->eps[mgmtEpSet->numOfEps]), 0, sizeof(mgmtEpSet->eps[mgmtEpSet->numOfEps]));
×
1677
    } else {
1678
      mgmtEpSet->numOfEps++;
6,429✔
1679
    }
1680
  }
1681

1682
  if (mgmtEpSet->numOfEps == 0) {
10,447✔
1683
    terrno = TSDB_CODE_RPC_NETWORK_UNAVAIL;
3✔
1684
    return TSDB_CODE_RPC_NETWORK_UNAVAIL;
3✔
1685
  }
1686

1687
  return 0;
10,444✔
1688
}
1689

1690
int32_t taosConnectImpl(const char* user, const char* auth, const char* db, __taos_async_fn_t fp, void* param,
10,778✔
1691
                        SAppInstInfo* pAppInfo, int connType, STscObj** pTscObj) {
1692
  *pTscObj = NULL;
10,778✔
1693
  int32_t code = createTscObj(user, auth, db, connType, pAppInfo, pTscObj);
10,778✔
1694
  if (TSDB_CODE_SUCCESS != code) {
10,777!
1695
    return code;
×
1696
  }
1697

1698
  SRequestObj* pRequest = NULL;
10,777✔
1699
  code = createRequest((*pTscObj)->id, TDMT_MND_CONNECT, 0, &pRequest);
10,777✔
1700
  if (TSDB_CODE_SUCCESS != code) {
10,768!
1701
    destroyTscObj(*pTscObj);
×
1702
    return code;
×
1703
  }
1704

1705
  pRequest->sqlstr = taosStrdup("taos_connect");
10,768!
1706
  if (pRequest->sqlstr) {
10,767!
1707
    pRequest->sqlLen = strlen(pRequest->sqlstr);
10,767✔
1708
  } else {
1709
    return terrno;
×
1710
  }
1711

1712
  SMsgSendInfo* body = NULL;
10,767✔
1713
  code = buildConnectMsg(pRequest, &body);
10,767✔
1714
  if (TSDB_CODE_SUCCESS != code) {
10,745!
1715
    destroyTscObj(*pTscObj);
×
1716
    return code;
×
1717
  }
1718

1719
  // int64_t transporterId = 0;
1720
  SEpSet epset = getEpSet_s(&(*pTscObj)->pAppInfo->mgmtEp);
10,745✔
1721
  code = asyncSendMsgToServer((*pTscObj)->pAppInfo->pTransporter, &epset, NULL, body);
10,755✔
1722
  if (TSDB_CODE_SUCCESS != code) {
10,771!
1723
    destroyTscObj(*pTscObj);
×
1724
    tscError("failed to send connect msg to server, code:%s", tstrerror(code));
×
1725
    return code;
×
1726
  }
1727
  if (TSDB_CODE_SUCCESS != tsem_wait(&pRequest->body.rspSem)) {
10,771✔
1728
    destroyTscObj(*pTscObj);
1✔
1729
    tscError("failed to wait sem, code:%s", terrstr());
×
1730
    return terrno;
×
1731
  }
1732
  if (pRequest->code != TSDB_CODE_SUCCESS) {
10,776✔
1733
    const char* errorMsg = (code == TSDB_CODE_RPC_FQDN_ERROR) ? taos_errstr(pRequest) : tstrerror(pRequest->code);
30!
1734
    tscError("failed to connect to server, reason: %s", errorMsg);
30!
1735

1736
    terrno = pRequest->code;
30✔
1737
    destroyRequest(pRequest);
30✔
1738
    taos_close_internal(*pTscObj);
30✔
1739
    *pTscObj = NULL;
30✔
1740
    return terrno;
30✔
1741
  } else {
1742
    tscInfo("conn:0x%" PRIx64 ", connection is opening, connId:%u, dnodeConn:%p, QID:0x%" PRIx64, (*pTscObj)->id,
10,746!
1743
            (*pTscObj)->connId, (*pTscObj)->pAppInfo->pTransporter, pRequest->requestId);
1744
    destroyRequest(pRequest);
10,747✔
1745
  }
1746
  return code;
10,737✔
1747
}
1748

1749
static int32_t buildConnectMsg(SRequestObj* pRequest, SMsgSendInfo** pMsgSendInfo) {
10,763✔
1750
  *pMsgSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
10,763!
1751
  if (*pMsgSendInfo == NULL) {
10,768!
1752
    return terrno;
×
1753
  }
1754

1755
  (*pMsgSendInfo)->msgType = TDMT_MND_CONNECT;
10,768✔
1756

1757
  (*pMsgSendInfo)->requestObjRefId = pRequest->self;
10,768✔
1758
  (*pMsgSendInfo)->requestId = pRequest->requestId;
10,768✔
1759
  (*pMsgSendInfo)->fp = getMsgRspHandle((*pMsgSendInfo)->msgType);
10,768✔
1760
  (*pMsgSendInfo)->param = taosMemoryCalloc(1, sizeof(pRequest->self));
10,776!
1761
  if (NULL == (*pMsgSendInfo)->param) {
10,776!
1762
    taosMemoryFree(*pMsgSendInfo);
×
1763
    return terrno;
×
1764
  }
1765

1766
  *(int64_t*)(*pMsgSendInfo)->param = pRequest->self;
10,776✔
1767

1768
  SConnectReq connectReq = {0};
10,776✔
1769
  STscObj*    pObj = pRequest->pTscObj;
10,776✔
1770

1771
  char* db = getDbOfConnection(pObj);
10,776✔
1772
  if (db != NULL) {
10,777✔
1773
    tstrncpy(connectReq.db, db, sizeof(connectReq.db));
6,519✔
1774
  } else if (terrno) {
4,258!
1775
    taosMemoryFree(*pMsgSendInfo);
×
1776
    return terrno;
×
1777
  }
1778
  taosMemoryFreeClear(db);
10,772!
1779

1780
  connectReq.connType = pObj->connType;
10,778✔
1781
  connectReq.pid = appInfo.pid;
10,778✔
1782
  connectReq.startTime = appInfo.startTime;
10,778✔
1783

1784
  tstrncpy(connectReq.app, appInfo.appName, sizeof(connectReq.app));
10,778✔
1785
  tstrncpy(connectReq.user, pObj->user, sizeof(connectReq.user));
10,778✔
1786
  tstrncpy(connectReq.passwd, pObj->pass, sizeof(connectReq.passwd));
10,778✔
1787
  tstrncpy(connectReq.sVer, td_version, sizeof(connectReq.sVer));
10,778✔
1788

1789
  int32_t contLen = tSerializeSConnectReq(NULL, 0, &connectReq);
10,778✔
1790
  void*   pReq = taosMemoryMalloc(contLen);
10,735!
1791
  if (NULL == pReq) {
10,745!
1792
    taosMemoryFree(*pMsgSendInfo);
×
1793
    return terrno;
×
1794
  }
1795

1796
  if (-1 == tSerializeSConnectReq(pReq, contLen, &connectReq)) {
10,745✔
1797
    taosMemoryFree(*pMsgSendInfo);
1!
1798
    taosMemoryFree(pReq);
×
1799
    return terrno;
×
1800
  }
1801

1802
  (*pMsgSendInfo)->msgInfo.len = contLen;
10,746✔
1803
  (*pMsgSendInfo)->msgInfo.pData = pReq;
10,746✔
1804
  return TSDB_CODE_SUCCESS;
10,746✔
1805
}
1806

1807
void updateTargetEpSet(SMsgSendInfo* pSendInfo, STscObj* pTscObj, SRpcMsg* pMsg, SEpSet* pEpSet) {
9,308,101✔
1808
  if (NULL == pEpSet) {
9,308,101✔
1809
    return;
9,293,521✔
1810
  }
1811

1812
  switch (pSendInfo->target.type) {
14,580✔
1813
    case TARGET_TYPE_MNODE:
4✔
1814
      if (NULL == pTscObj) {
4!
1815
        tscError("mnode epset changed but not able to update it, msg:%s, reqObjRefId:%" PRIx64,
×
1816
                 TMSG_INFO(pMsg->msgType), pSendInfo->requestObjRefId);
1817
        return;
×
1818
      }
1819

1820
      SEpSet  originEpset = getEpSet_s(&pTscObj->pAppInfo->mgmtEp);
4✔
1821
      SEpSet* pOrig = &originEpset;
4✔
1822
      SEp*    pOrigEp = &pOrig->eps[pOrig->inUse];
4✔
1823
      SEp*    pNewEp = &pEpSet->eps[pEpSet->inUse];
4✔
1824
      tscDebug("mnode epset updated from %d/%d=>%s:%d to %d/%d=>%s:%d in client", pOrig->inUse, pOrig->numOfEps,
4!
1825
               pOrigEp->fqdn, pOrigEp->port, pEpSet->inUse, pEpSet->numOfEps, pNewEp->fqdn, pNewEp->port);
1826
      updateEpSet_s(&pTscObj->pAppInfo->mgmtEp, pEpSet);
4✔
1827
      break;
15,413✔
1828
    case TARGET_TYPE_VNODE: {
15,060✔
1829
      if (NULL == pTscObj) {
15,060!
1830
        tscError("vnode epset changed but not able to update it, msg:%s, reqObjRefId:%" PRIx64,
×
1831
                 TMSG_INFO(pMsg->msgType), pSendInfo->requestObjRefId);
1832
        return;
×
1833
      }
1834

1835
      SCatalog* pCatalog = NULL;
15,060✔
1836
      int32_t   code = catalogGetHandle(pTscObj->pAppInfo->clusterId, &pCatalog);
15,060✔
1837
      if (code != TSDB_CODE_SUCCESS) {
15,057!
1838
        tscError("fail to get catalog handle, clusterId:0x%" PRIx64 ", error:%s", pTscObj->pAppInfo->clusterId,
×
1839
                 tstrerror(code));
1840
        return;
×
1841
      }
1842

1843
      code = catalogUpdateVgEpSet(pCatalog, pSendInfo->target.dbFName, pSendInfo->target.vgId, pEpSet);
15,057✔
1844
      if (code != TSDB_CODE_SUCCESS) {
15,062!
1845
        tscError("fail to update catalog vg epset, clusterId:0x%" PRIx64 ", error:%s", pTscObj->pAppInfo->clusterId,
×
1846
                 tstrerror(code));
1847
        return;
×
1848
      }
1849
      taosMemoryFreeClear(pSendInfo->target.dbFName);
15,062!
1850
      break;
15,061✔
1851
    }
1852
    default:
18✔
1853
      tscDebug("epset changed, not updated, msgType %s", TMSG_INFO(pMsg->msgType));
18!
1854
      break;
348✔
1855
  }
1856
}
1857

1858
int32_t doProcessMsgFromServerImpl(SRpcMsg* pMsg, SEpSet* pEpSet) {
9,316,386✔
1859
  SMsgSendInfo* pSendInfo = (SMsgSendInfo*)pMsg->info.ahandle;
9,316,386✔
1860
  if (pMsg->info.ahandle == NULL) {
9,316,386✔
1861
    tscError("doProcessMsgFromServer pMsg->info.ahandle == NULL");
61!
1862
    rpcFreeCont(pMsg->pCont);
61✔
1863
    taosMemoryFree(pEpSet);
61!
1864
    return TSDB_CODE_TSC_INTERNAL_ERROR;
61✔
1865
  }
1866

1867
  STscObj* pTscObj = NULL;
9,316,325✔
1868

1869
  STraceId* trace = &pMsg->info.traceId;
9,316,325✔
1870
  char      tbuf[40] = {0};
9,316,325✔
1871
  TRACE_TO_STR(trace, tbuf);
9,316,325!
1872

1873
  tscDebug("QID:%s, process message from server, handle:%p, message:%s, size:%d, code:%s", tbuf, pMsg->info.handle,
9,315,410!
1874
           TMSG_INFO(pMsg->msgType), pMsg->contLen, tstrerror(pMsg->code));
1875

1876
  if (pSendInfo->requestObjRefId != 0) {
9,315,411✔
1877
    SRequestObj* pRequest = (SRequestObj*)taosAcquireRef(clientReqRefPool, pSendInfo->requestObjRefId);
8,979,260✔
1878
    if (pRequest) {
8,976,464✔
1879
      if (pRequest->self != pSendInfo->requestObjRefId) {
8,975,160!
1880
        tscError("doProcessMsgFromServer req:0x%" PRId64 " != pSendInfo->requestObjRefId:0x%" PRId64, pRequest->self,
×
1881
                 pSendInfo->requestObjRefId);
1882

1883
        if (TSDB_CODE_SUCCESS != taosReleaseRef(clientReqRefPool, pSendInfo->requestObjRefId)) {
×
1884
          tscError("doProcessMsgFromServer taosReleaseRef failed");
×
1885
        }
1886
        rpcFreeCont(pMsg->pCont);
×
1887
        taosMemoryFree(pEpSet);
×
1888
        destroySendMsgInfo(pSendInfo);
×
1889
        return TSDB_CODE_TSC_INTERNAL_ERROR;
×
1890
      }
1891
      pTscObj = pRequest->pTscObj;
8,975,160✔
1892
    }
1893
  }
1894

1895
  updateTargetEpSet(pSendInfo, pTscObj, pMsg, pEpSet);
9,312,615✔
1896

1897
  SDataBuf buf = {.msgType = pMsg->msgType,
9,308,206✔
1898
                  .len = pMsg->contLen,
9,308,206✔
1899
                  .pData = NULL,
1900
                  .handle = pMsg->info.handle,
9,308,206✔
1901
                  .handleRefId = pMsg->info.refId,
9,308,206✔
1902
                  .pEpSet = pEpSet};
1903

1904
  if (pMsg->contLen > 0) {
9,308,206✔
1905
    buf.pData = taosMemoryCalloc(1, pMsg->contLen);
9,237,615!
1906
    if (buf.pData == NULL) {
9,240,451!
1907
      pMsg->code = terrno;
×
1908
    } else {
1909
      (void)memcpy(buf.pData, pMsg->pCont, pMsg->contLen);
9,240,451✔
1910
    }
1911
  }
1912

1913
  (void)pSendInfo->fp(pSendInfo->param, &buf, pMsg->code);
9,311,042✔
1914

1915
  if (pTscObj) {
9,300,404✔
1916
    int32_t code = taosReleaseRef(clientReqRefPool, pSendInfo->requestObjRefId);
8,963,430✔
1917
    if (TSDB_CODE_SUCCESS != code) {
8,972,633!
1918
      tscError("doProcessMsgFromServer taosReleaseRef failed");
×
1919
      terrno = code;
×
1920
      pMsg->code = code;
×
1921
    }
1922
  }
1923

1924
  rpcFreeCont(pMsg->pCont);
9,309,607✔
1925
  destroySendMsgInfo(pSendInfo);
9,314,171✔
1926
  return TSDB_CODE_SUCCESS;
9,315,657✔
1927
}
1928

1929
int32_t doProcessMsgFromServer(void* param) {
9,317,850✔
1930
  AsyncArg* arg = (AsyncArg*)param;
9,317,850✔
1931
  int32_t   code = doProcessMsgFromServerImpl(&arg->msg, arg->pEpset);
9,317,850✔
1932
  taosMemoryFree(arg);
9,313,858!
1933
  return code;
9,316,246✔
1934
}
1935

1936
void processMsgFromServer(void* parent, SRpcMsg* pMsg, SEpSet* pEpSet) {
9,292,287✔
1937
  int32_t code = 0;
9,292,287✔
1938
  SEpSet* tEpSet = NULL;
9,292,287✔
1939

1940
  tscDebug("msg callback, ahandle %p", pMsg->info.ahandle);
9,292,287✔
1941

1942
  if (pEpSet != NULL) {
9,298,658✔
1943
    tEpSet = taosMemoryCalloc(1, sizeof(SEpSet));
15,409!
1944
    if (NULL == tEpSet) {
15,407!
1945
      code = terrno;
×
1946
      pMsg->code = terrno;
×
1947
      goto _exit;
×
1948
    }
1949
    (void)memcpy((void*)tEpSet, (void*)pEpSet, sizeof(SEpSet));
15,407✔
1950
  }
1951

1952
  // pMsg is response msg
1953
  if (pMsg->msgType == TDMT_MND_CONNECT + 1) {
9,298,656✔
1954
    // restore origin code
1955
    if (pMsg->code == TSDB_CODE_RPC_SOMENODE_NOT_CONNECTED) {
10,770!
1956
      pMsg->code = TSDB_CODE_RPC_NETWORK_UNAVAIL;
×
1957
    } else if (pMsg->code == TSDB_CODE_RPC_SOMENODE_BROKEN_LINK) {
10,770!
1958
      pMsg->code = TSDB_CODE_RPC_BROKEN_LINK;
×
1959
    }
1960
  } else {
1961
    // uniform to one error code: TSDB_CODE_RPC_SOMENODE_NOT_CONNECTED
1962
    if (pMsg->code == TSDB_CODE_RPC_SOMENODE_BROKEN_LINK) {
9,287,886!
1963
      pMsg->code = TSDB_CODE_RPC_SOMENODE_NOT_CONNECTED;
×
1964
    }
1965
  }
1966

1967
  AsyncArg* arg = taosMemoryCalloc(1, sizeof(AsyncArg));
9,298,656!
1968
  if (NULL == arg) {
9,297,506!
1969
    code = terrno;
×
1970
    pMsg->code = code;
×
1971
    goto _exit;
×
1972
  }
1973

1974
  arg->msg = *pMsg;
9,297,506✔
1975
  arg->pEpset = tEpSet;
9,297,506✔
1976

1977
  if ((code = taosAsyncExec(doProcessMsgFromServer, arg, NULL)) != 0) {
9,297,506✔
1978
    pMsg->code = code;
1,004✔
1979
    taosMemoryFree(arg);
1,004!
1980
    goto _exit;
×
1981
  }
1982
  return;
9,310,942✔
1983

1984
_exit:
×
1985
  tscError("failed to sched msg to tsc since %s", tstrerror(code));
×
1986
  code = doProcessMsgFromServerImpl(pMsg, tEpSet);
×
1987
  if (code != 0) {
×
1988
    tscError("failed to sched msg to tsc, tsc ready quit");
×
1989
  }
1990
}
1991

1992
TAOS* taos_connect_auth(const char* ip, const char* user, const char* auth, const char* db, uint16_t port) {
3✔
1993
  tscInfo("try to connect to %s:%u by auth, user:%s db:%s", ip, port, user, db);
3!
1994
  if (user == NULL) {
3!
1995
    user = TSDB_DEFAULT_USER;
×
1996
  }
1997

1998
  if (auth == NULL) {
3!
1999
    tscError("No auth info is given, failed to connect to server");
×
2000
    return NULL;
×
2001
  }
2002

2003
  STscObj* pObj = NULL;
3✔
2004
  int32_t  code = taos_connect_internal(ip, user, NULL, auth, db, port, CONN_TYPE__QUERY, &pObj);
3✔
2005
  if (TSDB_CODE_SUCCESS == code) {
3✔
2006
    int64_t* rid = taosMemoryCalloc(1, sizeof(int64_t));
1!
2007
    if (NULL == rid) {
1!
2008
      tscError("out of memory when taos connect to %s:%u, user:%s db:%s", ip, port, user, db);
×
2009
    }
2010
    *rid = pObj->id;
1✔
2011
    return (TAOS*)rid;
1✔
2012
  }
2013

2014
  return NULL;
2✔
2015
}
2016

2017
// TAOS* taos_connect_l(const char* ip, int ipLen, const char* user, int userLen, const char* pass, int passLen,
2018
//                      const char* db, int dbLen, uint16_t port) {
2019
//   char ipStr[TSDB_EP_LEN] = {0};
2020
//   char dbStr[TSDB_DB_NAME_LEN] = {0};
2021
//   char userStr[TSDB_USER_LEN] = {0};
2022
//   char passStr[TSDB_PASSWORD_LEN] = {0};
2023
//
2024
//   tstrncpy(ipStr, ip, TMIN(TSDB_EP_LEN - 1, ipLen));
2025
//   tstrncpy(userStr, user, TMIN(TSDB_USER_LEN - 1, userLen));
2026
//   tstrncpy(passStr, pass, TMIN(TSDB_PASSWORD_LEN - 1, passLen));
2027
//   tstrncpy(dbStr, db, TMIN(TSDB_DB_NAME_LEN - 1, dbLen));
2028
//   return taos_connect(ipStr, userStr, passStr, dbStr, port);
2029
// }
2030

2031
void doSetOneRowPtr(SReqResultInfo* pResultInfo) {
3,141,581✔
2032
  for (int32_t i = 0; i < pResultInfo->numOfCols; ++i) {
17,331,947✔
2033
    SResultColumn* pCol = &pResultInfo->pCol[i];
14,190,366✔
2034

2035
    int32_t type = pResultInfo->fields[i].type;
14,190,366✔
2036
    int32_t schemaBytes = calcSchemaBytesFromTypeBytes(type, pResultInfo->userFields[i].bytes, false);
14,190,366✔
2037

2038
    if (IS_VAR_DATA_TYPE(type)) {
14,190,366!
2039
      if (!IS_VAR_NULL_TYPE(type, schemaBytes) && pCol->offset[pResultInfo->current] != -1) {
5,867,241!
2040
        char* pStart = pResultInfo->pCol[i].offset[pResultInfo->current] + pResultInfo->pCol[i].pData;
2,827,959✔
2041

2042
        if (IS_STR_DATA_BLOB(type)) {
2,827,959!
2043
          pResultInfo->length[i] = blobDataLen(pStart);
9✔
2044
          pResultInfo->row[i] = blobDataVal(pStart);
9✔
2045
        } else {
2046
          pResultInfo->length[i] = varDataLen(pStart);
2,827,950✔
2047
          pResultInfo->row[i] = varDataVal(pStart);
2,827,950✔
2048
        }
2049
      } else {
2050
        pResultInfo->row[i] = NULL;
211,323✔
2051
        pResultInfo->length[i] = 0;
211,323✔
2052
      }
2053
    } else {
2054
      if (!colDataIsNull_f(pCol, pResultInfo->current)) {
11,151,084!
2055
        pResultInfo->row[i] = pResultInfo->pCol[i].pData + schemaBytes * pResultInfo->current;
9,432,846✔
2056
        pResultInfo->length[i] = schemaBytes;
9,432,846✔
2057
      } else {
2058
        pResultInfo->row[i] = NULL;
1,718,238✔
2059
        pResultInfo->length[i] = 0;
1,718,238✔
2060
      }
2061
    }
2062
  }
2063
}
3,141,581✔
2064

2065
void* doFetchRows(SRequestObj* pRequest, bool setupOneRowPtr, bool convertUcs4) {
×
2066
  if (pRequest == NULL) {
×
2067
    return NULL;
×
2068
  }
2069

2070
  SReqResultInfo* pResultInfo = &pRequest->body.resInfo;
×
2071
  if (pResultInfo->pData == NULL || pResultInfo->current >= pResultInfo->numOfRows) {
×
2072
    // All data has returned to App already, no need to try again
2073
    if (pResultInfo->completed) {
×
2074
      pResultInfo->numOfRows = 0;
×
2075
      return NULL;
×
2076
    }
2077

2078
    SReqResultInfo* pResInfo = &pRequest->body.resInfo;
×
2079
    SSchedulerReq   req = {.syncReq = true, .pFetchRes = (void**)&pResInfo->pData};
×
2080

2081
    pRequest->code = schedulerFetchRows(pRequest->body.queryJob, &req);
×
2082
    if (pRequest->code != TSDB_CODE_SUCCESS) {
×
2083
      pResultInfo->numOfRows = 0;
×
2084
      return NULL;
×
2085
    }
2086

2087
    pRequest->code = setQueryResultFromRsp(&pRequest->body.resInfo, (const SRetrieveTableRsp*)pResInfo->pData,
×
2088
                                           convertUcs4, pRequest->stmtBindVersion > 0);
×
2089
    if (pRequest->code != TSDB_CODE_SUCCESS) {
×
2090
      pResultInfo->numOfRows = 0;
×
2091
      return NULL;
×
2092
    }
2093

2094
    tscDebug("req:0x%" PRIx64 ", fetch results, numOfRows:%" PRId64 " total Rows:%" PRId64
×
2095
             ", complete:%d, QID:0x%" PRIx64,
2096
             pRequest->self, pResInfo->numOfRows, pResInfo->totalRows, pResInfo->completed, pRequest->requestId);
2097

2098
    STscObj*            pTscObj = pRequest->pTscObj;
×
2099
    SAppClusterSummary* pActivity = &pTscObj->pAppInfo->summary;
×
2100
    (void)atomic_add_fetch_64((int64_t*)&pActivity->fetchBytes, pRequest->body.resInfo.payloadLen);
×
2101

2102
    if (pResultInfo->numOfRows == 0) {
×
2103
      return NULL;
×
2104
    }
2105
  }
2106

2107
  if (setupOneRowPtr) {
×
2108
    doSetOneRowPtr(pResultInfo);
×
2109
    pResultInfo->current += 1;
×
2110
  }
2111

2112
  return pResultInfo->row;
×
2113
}
2114

2115
static void syncFetchFn(void* param, TAOS_RES* res, int32_t numOfRows) {
145,171✔
2116
  tsem_t* sem = param;
145,171✔
2117
  if (TSDB_CODE_SUCCESS != tsem_post(sem)) {
145,171!
2118
    tscError("failed to post sem, code:%s", terrstr());
×
2119
  }
2120
}
145,170✔
2121

2122
void* doAsyncFetchRows(SRequestObj* pRequest, bool setupOneRowPtr, bool convertUcs4) {
3,171,338✔
2123
  if (pRequest == NULL) {
3,171,338!
2124
    return NULL;
×
2125
  }
2126

2127
  SReqResultInfo* pResultInfo = &pRequest->body.resInfo;
3,171,338✔
2128
  if (pResultInfo->pData == NULL || pResultInfo->current >= pResultInfo->numOfRows) {
3,171,338✔
2129
    // All data has returned to App already, no need to try again
2130
    if (pResultInfo->completed) {
171,826✔
2131
      pResultInfo->numOfRows = 0;
26,658✔
2132
      return NULL;
26,658✔
2133
    }
2134

2135
    // convert ucs4 to native multi-bytes string
2136
    pResultInfo->convertUcs4 = convertUcs4;
145,168✔
2137
    tsem_t sem;
2138
    if (TSDB_CODE_SUCCESS != tsem_init(&sem, 0, 0)) {
145,168!
2139
      tscError("failed to init sem, code:%s", terrstr());
×
2140
    }
2141
    taos_fetch_rows_a(pRequest, syncFetchFn, &sem);
145,167✔
2142
    if (TSDB_CODE_SUCCESS != tsem_wait(&sem)) {
145,170!
2143
      tscError("failed to wait sem, code:%s", terrstr());
×
2144
    }
2145
    if (TSDB_CODE_SUCCESS != tsem_destroy(&sem)) {
145,170!
2146
      tscError("failed to destroy sem, code:%s", terrstr());
×
2147
    }
2148
    pRequest->inCallback = false;
145,162✔
2149
  }
2150

2151
  if (pResultInfo->numOfRows == 0 || pRequest->code != TSDB_CODE_SUCCESS) {
3,144,674!
2152
    return NULL;
1,740✔
2153
  } else {
2154
    if (setupOneRowPtr) {
3,142,934✔
2155
      doSetOneRowPtr(pResultInfo);
3,136,380✔
2156
      pResultInfo->current += 1;
3,136,355✔
2157
    }
2158

2159
    return pResultInfo->row;
3,142,909✔
2160
  }
2161
}
2162

2163
static int32_t doPrepareResPtr(SReqResultInfo* pResInfo) {
156,389✔
2164
  if (pResInfo->row == NULL) {
156,389✔
2165
    pResInfo->row = taosMemoryCalloc(pResInfo->numOfCols, POINTER_BYTES);
150,343!
2166
    pResInfo->pCol = taosMemoryCalloc(pResInfo->numOfCols, sizeof(SResultColumn));
150,353!
2167
    pResInfo->length = taosMemoryCalloc(pResInfo->numOfCols, sizeof(int32_t));
150,348!
2168
    pResInfo->convertBuf = taosMemoryCalloc(pResInfo->numOfCols, POINTER_BYTES);
150,352!
2169

2170
    if (pResInfo->row == NULL || pResInfo->pCol == NULL || pResInfo->length == NULL || pResInfo->convertBuf == NULL) {
150,352!
2171
      taosMemoryFree(pResInfo->row);
×
2172
      taosMemoryFree(pResInfo->pCol);
×
2173
      taosMemoryFree(pResInfo->length);
×
2174
      taosMemoryFree(pResInfo->convertBuf);
×
2175
      return terrno;
×
2176
    }
2177
  }
2178

2179
  return TSDB_CODE_SUCCESS;
156,398✔
2180
}
2181

2182
static int32_t doConvertUCS4(SReqResultInfo* pResultInfo, int32_t* colLength, bool isStmt) {
156,289✔
2183
  int32_t idx = -1;
156,289✔
2184
  iconv_t conv = taosAcquireConv(&idx, C2M, pResultInfo->charsetCxt);
156,289✔
2185
  if (conv == (iconv_t)-1) return TSDB_CODE_TSC_INTERNAL_ERROR;
156,296!
2186

2187
  for (int32_t i = 0; i < pResultInfo->numOfCols; ++i) {
471,052✔
2188
    int32_t type = pResultInfo->fields[i].type;
314,757✔
2189
    int32_t schemaBytes =
2190
        calcSchemaBytesFromTypeBytes(pResultInfo->fields[i].type, pResultInfo->fields[i].bytes, isStmt);
314,757✔
2191

2192
    if (type == TSDB_DATA_TYPE_NCHAR && colLength[i] > 0) {
314,756✔
2193
      char* p = taosMemoryRealloc(pResultInfo->convertBuf[i], colLength[i]);
5,017!
2194
      if (p == NULL) {
5,017!
2195
        taosReleaseConv(idx, conv, C2M, pResultInfo->charsetCxt);
×
2196
        return terrno;
×
2197
      }
2198

2199
      pResultInfo->convertBuf[i] = p;
5,017✔
2200

2201
      SResultColumn* pCol = &pResultInfo->pCol[i];
5,017✔
2202
      for (int32_t j = 0; j < pResultInfo->numOfRows; ++j) {
636,923✔
2203
        if (pCol->offset[j] != -1) {
631,906✔
2204
          char* pStart = pCol->offset[j] + pCol->pData;
552,381✔
2205

2206
          int32_t len = taosUcs4ToMbsEx((TdUcs4*)varDataVal(pStart), varDataLen(pStart), varDataVal(p), conv);
552,381✔
2207
          if (len < 0 || len > schemaBytes || (p + len) >= (pResultInfo->convertBuf[i] + colLength[i])) {
552,380!
2208
            tscError(
×
2209
                "doConvertUCS4 error, invalid data. len:%d, bytes:%d, (p + len):%p, (pResultInfo->convertBuf[i] + "
2210
                "colLength[i]):%p",
2211
                len, schemaBytes, (p + len), (pResultInfo->convertBuf[i] + colLength[i]));
2212
            taosReleaseConv(idx, conv, C2M, pResultInfo->charsetCxt);
×
2213
            return TSDB_CODE_TSC_INTERNAL_ERROR;
×
2214
          }
2215

2216
          varDataSetLen(p, len);
552,381✔
2217
          pCol->offset[j] = (p - pResultInfo->convertBuf[i]);
552,381✔
2218
          p += (len + VARSTR_HEADER_SIZE);
552,381✔
2219
        }
2220
      }
2221

2222
      pResultInfo->pCol[i].pData = pResultInfo->convertBuf[i];
5,017✔
2223
      pResultInfo->row[i] = pResultInfo->pCol[i].pData;
5,017✔
2224
    }
2225
  }
2226
  taosReleaseConv(idx, conv, C2M, pResultInfo->charsetCxt);
156,295✔
2227
  return TSDB_CODE_SUCCESS;
156,293✔
2228
}
2229

2230
static int32_t convertDecimalType(SReqResultInfo* pResultInfo) {
156,287✔
2231
  for (int32_t i = 0; i < pResultInfo->numOfCols; ++i) {
471,061✔
2232
    TAOS_FIELD_E* pFieldE = pResultInfo->fields + i;
314,774✔
2233
    TAOS_FIELD*   pField = pResultInfo->userFields + i;
314,774✔
2234
    int32_t       type = pFieldE->type;
314,774✔
2235
    int32_t       bufLen = 0;
314,774✔
2236
    char*         p = NULL;
314,774✔
2237
    if (!IS_DECIMAL_TYPE(type) || !pResultInfo->pCol[i].pData) {
314,774✔
2238
      continue;
314,710✔
2239
    } else {
2240
      bufLen = 64;
64✔
2241
      p = taosMemoryRealloc(pResultInfo->convertBuf[i], bufLen * pResultInfo->numOfRows);
64!
2242
      pFieldE->bytes = bufLen;
64✔
2243
      pField->bytes = bufLen;
64✔
2244
    }
2245
    if (!p) return terrno;
64!
2246
    pResultInfo->convertBuf[i] = p;
64✔
2247

2248
    for (int32_t j = 0; j < pResultInfo->numOfRows; ++j) {
185✔
2249
      int32_t code = decimalToStr((DecimalWord*)(pResultInfo->pCol[i].pData + j * tDataTypes[type].bytes), type,
121✔
2250
                                  pFieldE->precision, pFieldE->scale, p, bufLen);
121✔
2251
      p += bufLen;
121✔
2252
      if (TSDB_CODE_SUCCESS != code) {
121!
2253
        return code;
×
2254
      }
2255
    }
2256
    pResultInfo->pCol[i].pData = pResultInfo->convertBuf[i];
64✔
2257
    pResultInfo->row[i] = pResultInfo->pCol[i].pData;
64✔
2258
  }
2259
  return 0;
156,287✔
2260
}
2261

2262
int32_t getVersion1BlockMetaSize(const char* p, int32_t numOfCols) {
58✔
2263
  return sizeof(int32_t) + sizeof(int32_t) + sizeof(int32_t) * 3 + sizeof(uint64_t) +
58✔
2264
         numOfCols * (sizeof(int8_t) + sizeof(int32_t));
2265
}
2266

2267
static int32_t estimateJsonLen(SReqResultInfo* pResultInfo) {
29✔
2268
  char*   p = (char*)pResultInfo->pData;
29✔
2269
  int32_t blockVersion = *(int32_t*)p;
29✔
2270

2271
  int32_t numOfRows = pResultInfo->numOfRows;
29✔
2272
  int32_t numOfCols = pResultInfo->numOfCols;
29✔
2273

2274
  // | version | total length | total rows | total columns | flag seg| block group id | column schema | each column
2275
  // length |
2276
  int32_t cols = *(int32_t*)(p + sizeof(int32_t) * 3);
29✔
2277
  if (numOfCols != cols) {
29!
2278
    tscError("estimateJsonLen error: numOfCols:%d != cols:%d", numOfCols, cols);
×
2279
    return TSDB_CODE_TSC_INTERNAL_ERROR;
×
2280
  }
2281

2282
  int32_t  len = getVersion1BlockMetaSize(p, numOfCols);
29✔
2283
  int32_t* colLength = (int32_t*)(p + len);
29✔
2284
  len += sizeof(int32_t) * numOfCols;
29✔
2285

2286
  char* pStart = p + len;
29✔
2287
  for (int32_t i = 0; i < numOfCols; ++i) {
142✔
2288
    int32_t colLen = (blockVersion == BLOCK_VERSION_1) ? htonl(colLength[i]) : colLength[i];
113!
2289

2290
    if (pResultInfo->fields[i].type == TSDB_DATA_TYPE_JSON) {
113✔
2291
      int32_t* offset = (int32_t*)pStart;
57✔
2292
      int32_t  lenTmp = numOfRows * sizeof(int32_t);
57✔
2293
      len += lenTmp;
57✔
2294
      pStart += lenTmp;
57✔
2295

2296
      int32_t estimateColLen = 0;
57✔
2297
      for (int32_t j = 0; j < numOfRows; ++j) {
354✔
2298
        if (offset[j] == -1) {
297✔
2299
          continue;
32✔
2300
        }
2301
        char* data = offset[j] + pStart;
265✔
2302

2303
        int32_t jsonInnerType = *data;
265✔
2304
        char*   jsonInnerData = data + CHAR_BYTES;
265✔
2305
        if (jsonInnerType == TSDB_DATA_TYPE_NULL) {
265!
2306
          estimateColLen += (VARSTR_HEADER_SIZE + strlen(TSDB_DATA_NULL_STR_L));
×
2307
        } else if (tTagIsJson(data)) {
265✔
2308
          estimateColLen += (VARSTR_HEADER_SIZE + ((const STag*)(data))->len);
1✔
2309
        } else if (jsonInnerType == TSDB_DATA_TYPE_NCHAR) {  // value -> "value"
264!
2310
          estimateColLen += varDataTLen(jsonInnerData) + CHAR_BYTES * 2;
264✔
2311
        } else if (jsonInnerType == TSDB_DATA_TYPE_DOUBLE) {
×
2312
          estimateColLen += (VARSTR_HEADER_SIZE + 32);
×
2313
        } else if (jsonInnerType == TSDB_DATA_TYPE_BOOL) {
×
2314
          estimateColLen += (VARSTR_HEADER_SIZE + 5);
×
2315
        } else if (IS_STR_DATA_BLOB(jsonInnerType)) {
×
2316
          estimateColLen += (BLOBSTR_HEADER_SIZE + 32);
×
2317
        } else {
2318
          tscError("estimateJsonLen error: invalid type:%d", jsonInnerType);
×
2319
          return -1;
×
2320
        }
2321
      }
2322
      len += TMAX(colLen, estimateColLen);
57✔
2323
    } else if (IS_VAR_DATA_TYPE(pResultInfo->fields[i].type)) {
56!
2324
      int32_t lenTmp = numOfRows * sizeof(int32_t);
×
2325
      len += (lenTmp + colLen);
×
2326
      pStart += lenTmp;
×
2327
    } else {
2328
      int32_t lenTmp = BitmapLen(pResultInfo->numOfRows);
56✔
2329
      len += (lenTmp + colLen);
56✔
2330
      pStart += lenTmp;
56✔
2331
    }
2332
    pStart += colLen;
113✔
2333
  }
2334

2335
  // Ensure the complete structure of the block, including the blankfill field,
2336
  // even though it is not used on the client side.
2337
  len += sizeof(bool);
29✔
2338
  return len;
29✔
2339
}
2340

2341
static int32_t doConvertJson(SReqResultInfo* pResultInfo) {
156,398✔
2342
  int32_t numOfRows = pResultInfo->numOfRows;
156,398✔
2343
  int32_t numOfCols = pResultInfo->numOfCols;
156,398✔
2344
  bool    needConvert = false;
156,398✔
2345
  for (int32_t i = 0; i < numOfCols; ++i) {
471,597✔
2346
    if (pResultInfo->fields[i].type == TSDB_DATA_TYPE_JSON) {
315,228✔
2347
      needConvert = true;
29✔
2348
      break;
29✔
2349
    }
2350
  }
2351

2352
  if (!needConvert) {
156,398✔
2353
    return TSDB_CODE_SUCCESS;
156,370✔
2354
  }
2355

2356
  tscDebug("start to convert form json format string");
28✔
2357

2358
  char*   p = (char*)pResultInfo->pData;
28✔
2359
  int32_t blockVersion = *(int32_t*)p;
28✔
2360
  int32_t dataLen = estimateJsonLen(pResultInfo);
28✔
2361
  if (dataLen <= 0) {
29!
2362
    tscError("doConvertJson error: estimateJsonLen failed");
×
2363
    return TSDB_CODE_TSC_INTERNAL_ERROR;
×
2364
  }
2365

2366
  taosMemoryFreeClear(pResultInfo->convertJson);
29!
2367
  pResultInfo->convertJson = taosMemoryCalloc(1, dataLen);
29!
2368
  if (pResultInfo->convertJson == NULL) return terrno;
29!
2369
  char* p1 = pResultInfo->convertJson;
29✔
2370

2371
  int32_t totalLen = 0;
29✔
2372
  int32_t cols = *(int32_t*)(p + sizeof(int32_t) * 3);
29✔
2373
  if (numOfCols != cols) {
29!
2374
    tscError("doConvertJson error: numOfCols:%d != cols:%d", numOfCols, cols);
×
2375
    return TSDB_CODE_TSC_INTERNAL_ERROR;
×
2376
  }
2377

2378
  int32_t len = getVersion1BlockMetaSize(p, numOfCols);
29✔
2379
  (void)memcpy(p1, p, len);
29✔
2380

2381
  p += len;
29✔
2382
  p1 += len;
29✔
2383
  totalLen += len;
29✔
2384

2385
  len = sizeof(int32_t) * numOfCols;
29✔
2386
  int32_t* colLength = (int32_t*)p;
29✔
2387
  int32_t* colLength1 = (int32_t*)p1;
29✔
2388
  (void)memcpy(p1, p, len);
29✔
2389
  p += len;
29✔
2390
  p1 += len;
29✔
2391
  totalLen += len;
29✔
2392

2393
  char* pStart = p;
29✔
2394
  char* pStart1 = p1;
29✔
2395
  for (int32_t i = 0; i < numOfCols; ++i) {
142✔
2396
    int32_t colLen = (blockVersion == BLOCK_VERSION_1) ? htonl(colLength[i]) : colLength[i];
113!
2397
    int32_t colLen1 = (blockVersion == BLOCK_VERSION_1) ? htonl(colLength1[i]) : colLength1[i];
113!
2398
    if (colLen >= dataLen) {
113!
2399
      tscError("doConvertJson error: colLen:%d >= dataLen:%d", colLen, dataLen);
×
2400
      return TSDB_CODE_TSC_INTERNAL_ERROR;
×
2401
    }
2402
    if (pResultInfo->fields[i].type == TSDB_DATA_TYPE_JSON) {
113✔
2403
      int32_t* offset = (int32_t*)pStart;
57✔
2404
      int32_t* offset1 = (int32_t*)pStart1;
57✔
2405
      len = numOfRows * sizeof(int32_t);
57✔
2406
      (void)memcpy(pStart1, pStart, len);
57✔
2407
      pStart += len;
57✔
2408
      pStart1 += len;
57✔
2409
      totalLen += len;
57✔
2410

2411
      len = 0;
57✔
2412
      for (int32_t j = 0; j < numOfRows; ++j) {
354✔
2413
        if (offset[j] == -1) {
297✔
2414
          continue;
32✔
2415
        }
2416
        char* data = offset[j] + pStart;
265✔
2417

2418
        int32_t jsonInnerType = *data;
265✔
2419
        char*   jsonInnerData = data + CHAR_BYTES;
265✔
2420
        char    dst[TSDB_MAX_JSON_TAG_LEN] = {0};
265✔
2421
        if (jsonInnerType == TSDB_DATA_TYPE_NULL) {
265!
2422
          (void)snprintf(varDataVal(dst), TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE, "%s", TSDB_DATA_NULL_STR_L);
×
2423
          varDataSetLen(dst, strlen(varDataVal(dst)));
×
2424
        } else if (tTagIsJson(data)) {
265✔
2425
          char* jsonString = NULL;
1✔
2426
          parseTagDatatoJson(data, &jsonString, pResultInfo->charsetCxt);
1✔
2427
          if (jsonString == NULL) {
1!
2428
            tscError("doConvertJson error: parseTagDatatoJson failed");
×
2429
            return terrno;
×
2430
          }
2431
          STR_TO_VARSTR(dst, jsonString);
1✔
2432
          taosMemoryFree(jsonString);
1!
2433
        } else if (jsonInnerType == TSDB_DATA_TYPE_NCHAR) {  // value -> "value"
264!
2434
          *(char*)varDataVal(dst) = '\"';
264✔
2435
          char    tmp[TSDB_MAX_JSON_TAG_LEN] = {0};
264✔
2436
          int32_t length = taosUcs4ToMbs((TdUcs4*)varDataVal(jsonInnerData), varDataLen(jsonInnerData),
264✔
2437
                                         varDataVal(tmp), pResultInfo->charsetCxt);
2438
          if (length <= 0) {
264!
2439
            tscError("charset:%s to %s. convert failed.", DEFAULT_UNICODE_ENCODEC,
×
2440
                     pResultInfo->charsetCxt != NULL ? ((SConvInfo*)(pResultInfo->charsetCxt))->charset : tsCharset);
2441
            length = 0;
×
2442
          }
2443
          int32_t escapeLength = escapeToPrinted(varDataVal(dst) + CHAR_BYTES, TSDB_MAX_JSON_TAG_LEN - CHAR_BYTES * 2,varDataVal(tmp), length);
264✔
2444
          varDataSetLen(dst, escapeLength + CHAR_BYTES * 2);
264✔
2445
          *(char*)POINTER_SHIFT(varDataVal(dst), escapeLength + CHAR_BYTES) = '\"';
264✔
2446
          tscError("value:%s.", varDataVal(dst));
264!
2447
        } else if (jsonInnerType == TSDB_DATA_TYPE_DOUBLE) {
×
2448
          double jsonVd = *(double*)(jsonInnerData);
×
2449
          (void)snprintf(varDataVal(dst), TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE, "%.9lf", jsonVd);
×
2450
          varDataSetLen(dst, strlen(varDataVal(dst)));
×
2451
        } else if (jsonInnerType == TSDB_DATA_TYPE_BOOL) {
×
2452
          (void)snprintf(varDataVal(dst), TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE, "%s",
×
2453
                         (*((char*)jsonInnerData) == 1) ? "true" : "false");
×
2454
          varDataSetLen(dst, strlen(varDataVal(dst)));
×
2455
        } else {
2456
          tscError("doConvertJson error: invalid type:%d", jsonInnerType);
×
2457
          return TSDB_CODE_TSC_INTERNAL_ERROR;
×
2458
        }
2459

2460
        offset1[j] = len;
265✔
2461
        (void)memcpy(pStart1 + len, dst, varDataTLen(dst));
265✔
2462
        len += varDataTLen(dst);
265✔
2463
      }
2464
      colLen1 = len;
57✔
2465
      totalLen += colLen1;
57✔
2466
      colLength1[i] = (blockVersion == BLOCK_VERSION_1) ? htonl(len) : len;
57!
2467
    } else if (IS_VAR_DATA_TYPE(pResultInfo->fields[i].type)) {
56!
2468
      len = numOfRows * sizeof(int32_t);
×
2469
      (void)memcpy(pStart1, pStart, len);
×
2470
      pStart += len;
×
2471
      pStart1 += len;
×
2472
      totalLen += len;
×
2473
      totalLen += colLen;
×
2474
      (void)memcpy(pStart1, pStart, colLen);
×
2475
    } else {
2476
      len = BitmapLen(pResultInfo->numOfRows);
56✔
2477
      (void)memcpy(pStart1, pStart, len);
56✔
2478
      pStart += len;
56✔
2479
      pStart1 += len;
56✔
2480
      totalLen += len;
56✔
2481
      totalLen += colLen;
56✔
2482
      (void)memcpy(pStart1, pStart, colLen);
56✔
2483
    }
2484
    pStart += colLen;
113✔
2485
    pStart1 += colLen1;
113✔
2486
  }
2487

2488
  // Ensure the complete structure of the block, including the blankfill field,
2489
  // even though it is not used on the client side.
2490
  // (void)memcpy(pStart1, pStart, sizeof(bool));
2491
  totalLen += sizeof(bool);
29✔
2492

2493
  *(int32_t*)(pResultInfo->convertJson + 4) = totalLen;
29✔
2494
  pResultInfo->pData = pResultInfo->convertJson;
29✔
2495
  return TSDB_CODE_SUCCESS;
29✔
2496
}
2497

2498
int32_t setResultDataPtr(SReqResultInfo* pResultInfo, bool convertUcs4, bool isStmt) {
158,649✔
2499
  bool convertForDecimal = convertUcs4;
158,649✔
2500
  if (pResultInfo == NULL || pResultInfo->numOfCols <= 0 || pResultInfo->fields == NULL) {
158,649!
2501
    tscError("setResultDataPtr paras error");
×
2502
    return TSDB_CODE_TSC_INTERNAL_ERROR;
×
2503
  }
2504

2505
  if (pResultInfo->numOfRows == 0) {
158,657✔
2506
    return TSDB_CODE_SUCCESS;
2,261✔
2507
  }
2508

2509
  if (pResultInfo->pData == NULL) {
156,396!
2510
    tscError("setResultDataPtr error: pData is NULL");
×
2511
    return TSDB_CODE_TSC_INTERNAL_ERROR;
×
2512
  }
2513

2514
  int32_t code = doPrepareResPtr(pResultInfo);
156,396✔
2515
  if (code != TSDB_CODE_SUCCESS) {
156,400!
2516
    return code;
×
2517
  }
2518
  code = doConvertJson(pResultInfo);
156,400✔
2519
  if (code != TSDB_CODE_SUCCESS) {
156,399!
2520
    return code;
×
2521
  }
2522

2523
  char* p = (char*)pResultInfo->pData;
156,399✔
2524

2525
  // version:
2526
  int32_t blockVersion = *(int32_t*)p;
156,399✔
2527
  p += sizeof(int32_t);
156,399✔
2528

2529
  int32_t dataLen = *(int32_t*)p;
156,399✔
2530
  p += sizeof(int32_t);
156,399✔
2531

2532
  int32_t rows = *(int32_t*)p;
156,399✔
2533
  p += sizeof(int32_t);
156,399✔
2534

2535
  int32_t cols = *(int32_t*)p;
156,399✔
2536
  p += sizeof(int32_t);
156,399✔
2537

2538
  if (rows != pResultInfo->numOfRows || cols != pResultInfo->numOfCols) {
156,399!
2539
    tscError("setResultDataPtr paras error:rows;%d numOfRows:%" PRId64 " cols:%d numOfCols:%d", rows,
×
2540
             pResultInfo->numOfRows, cols, pResultInfo->numOfCols);
2541
    return TSDB_CODE_TSC_INTERNAL_ERROR;
×
2542
  }
2543

2544
  int32_t hasColumnSeg = *(int32_t*)p;
156,399✔
2545
  p += sizeof(int32_t);
156,399✔
2546

2547
  uint64_t groupId = taosGetUInt64Aligned((uint64_t*)p);
156,399✔
2548
  p += sizeof(uint64_t);
156,399✔
2549

2550
  // check fields
2551
  for (int32_t i = 0; i < pResultInfo->numOfCols; ++i) {
471,679✔
2552
    int8_t type = *(int8_t*)p;
315,281✔
2553
    p += sizeof(int8_t);
315,281✔
2554

2555
    int32_t bytes = *(int32_t*)p;
315,281✔
2556
    p += sizeof(int32_t);
315,281✔
2557

2558
    if (IS_DECIMAL_TYPE(type) && pResultInfo->fields[i].precision == 0) {
315,281!
2559
      extractDecimalTypeInfoFromBytes(&bytes, &pResultInfo->fields[i].precision, &pResultInfo->fields[i].scale);
×
2560
    }
2561
  }
2562

2563
  int32_t* colLength = (int32_t*)p;
156,398✔
2564
  p += sizeof(int32_t) * pResultInfo->numOfCols;
156,398✔
2565

2566
  char* pStart = p;
156,398✔
2567
  for (int32_t i = 0; i < pResultInfo->numOfCols; ++i) {
471,672✔
2568
    if ((pStart - pResultInfo->pData) >= dataLen) {
315,276!
2569
      tscError("setResultDataPtr invalid offset over dataLen %d", dataLen);
×
2570
      return TSDB_CODE_TSC_INTERNAL_ERROR;
×
2571
    }
2572
    if (blockVersion == BLOCK_VERSION_1) {
315,276✔
2573
      colLength[i] = htonl(colLength[i]);
304,886✔
2574
    }
2575
    if (colLength[i] >= dataLen) {
315,276!
2576
      tscError("invalid colLength %d, dataLen %d", colLength[i], dataLen);
×
2577
      return TSDB_CODE_TSC_INTERNAL_ERROR;
×
2578
    }
2579
    if (IS_INVALID_TYPE(pResultInfo->fields[i].type)) {
315,276!
2580
      tscError("invalid type %d", pResultInfo->fields[i].type);
2!
2581
      return TSDB_CODE_TSC_INTERNAL_ERROR;
×
2582
    }
2583
    if (IS_VAR_DATA_TYPE(pResultInfo->fields[i].type)) {
315,274!
2584
      pResultInfo->pCol[i].offset = (int32_t*)pStart;
54,434✔
2585
      pStart += pResultInfo->numOfRows * sizeof(int32_t);
54,434✔
2586
    } else {
2587
      pResultInfo->pCol[i].nullbitmap = pStart;
260,840✔
2588
      pStart += BitmapLen(pResultInfo->numOfRows);
260,840✔
2589
    }
2590

2591
    pResultInfo->pCol[i].pData = pStart;
315,274✔
2592
    pResultInfo->length[i] =
630,548✔
2593
        calcSchemaBytesFromTypeBytes(pResultInfo->fields[i].type, pResultInfo->fields[i].bytes, isStmt);
315,274✔
2594
    pResultInfo->row[i] = pResultInfo->pCol[i].pData;
315,274✔
2595

2596
    pStart += colLength[i];
315,274✔
2597
  }
2598

2599
  p = pStart;
156,396✔
2600
  // bool blankFill = *(bool*)p;
2601
  p += sizeof(bool);
156,396✔
2602
  int32_t offset = p - pResultInfo->pData;
156,396✔
2603
  if (offset > dataLen) {
156,396!
2604
    tscError("invalid offset %d, dataLen %d", offset, dataLen);
×
2605
    return TSDB_CODE_TSC_INTERNAL_ERROR;
×
2606
  }
2607

2608
#ifndef DISALLOW_NCHAR_WITHOUT_ICONV
2609
  if (convertUcs4) {
156,396✔
2610
    code = doConvertUCS4(pResultInfo, colLength, isStmt);
156,292✔
2611
  }
2612
#endif
2613
  if (TSDB_CODE_SUCCESS == code && convertForDecimal) {
156,398!
2614
    code = convertDecimalType(pResultInfo);
156,293✔
2615
  }
2616
  return code;
156,398✔
2617
}
2618

2619
char* getDbOfConnection(STscObj* pObj) {
8,648,463✔
2620
  terrno = TSDB_CODE_SUCCESS;
8,648,463✔
2621
  char* p = NULL;
8,648,975✔
2622
  (void)taosThreadMutexLock(&pObj->mutex);
8,648,975✔
2623
  size_t len = strlen(pObj->db);
8,653,575✔
2624
  if (len > 0) {
8,653,575✔
2625
    p = taosStrndup(pObj->db, tListLen(pObj->db));
8,630,964!
2626
    if (p == NULL) {
8,625,930!
2627
      tscError("failed to taosStrndup db name");
×
2628
    }
2629
  }
2630

2631
  (void)taosThreadMutexUnlock(&pObj->mutex);
8,648,541✔
2632
  return p;
8,653,244✔
2633
}
2634

2635
void setConnectionDB(STscObj* pTscObj, const char* db) {
5,334✔
2636
  if (db == NULL || pTscObj == NULL) {
5,334!
2637
    tscError("setConnectionDB para is NULL");
×
2638
    return;
×
2639
  }
2640

2641
  (void)taosThreadMutexLock(&pTscObj->mutex);
5,340✔
2642
  tstrncpy(pTscObj->db, db, tListLen(pTscObj->db));
5,340✔
2643
  (void)taosThreadMutexUnlock(&pTscObj->mutex);
5,340✔
2644
}
2645

2646
void resetConnectDB(STscObj* pTscObj) {
×
2647
  if (pTscObj == NULL) {
×
2648
    return;
×
2649
  }
2650

2651
  (void)taosThreadMutexLock(&pTscObj->mutex);
×
2652
  pTscObj->db[0] = 0;
×
2653
  (void)taosThreadMutexUnlock(&pTscObj->mutex);
×
2654
}
2655

2656
int32_t setQueryResultFromRsp(SReqResultInfo* pResultInfo, const SRetrieveTableRsp* pRsp, bool convertUcs4,
155,297✔
2657
                              bool isStmt) {
2658
  if (pResultInfo == NULL || pRsp == NULL) {
155,297!
2659
    tscError("setQueryResultFromRsp paras is null");
×
2660
    return TSDB_CODE_TSC_INTERNAL_ERROR;
×
2661
  }
2662

2663
  taosMemoryFreeClear(pResultInfo->pRspMsg);
155,302!
2664
  pResultInfo->pRspMsg = (const char*)pRsp;
155,302✔
2665
  pResultInfo->numOfRows = htobe64(pRsp->numOfRows);
155,302✔
2666
  pResultInfo->current = 0;
155,301✔
2667
  pResultInfo->completed = (pRsp->completed == 1);
155,301✔
2668
  pResultInfo->precision = pRsp->precision;
155,301✔
2669

2670
  // decompress data if needed
2671
  int32_t payloadLen = htonl(pRsp->payloadLen);
155,301✔
2672

2673
  if (pRsp->compressed) {
155,301!
2674
    if (pResultInfo->decompBuf == NULL) {
×
2675
      pResultInfo->decompBuf = taosMemoryMalloc(payloadLen);
×
2676
      if (pResultInfo->decompBuf == NULL) {
×
2677
        tscError("failed to prepare the decompress buffer, size:%d", payloadLen);
×
2678
        return terrno;
×
2679
      }
2680
      pResultInfo->decompBufSize = payloadLen;
×
2681
    } else {
2682
      if (pResultInfo->decompBufSize < payloadLen) {
×
2683
        char* p = taosMemoryRealloc(pResultInfo->decompBuf, payloadLen);
×
2684
        if (p == NULL) {
×
2685
          tscError("failed to prepare the decompress buffer, size:%d", payloadLen);
×
2686
          return terrno;
×
2687
        }
2688

2689
        pResultInfo->decompBuf = p;
×
2690
        pResultInfo->decompBufSize = payloadLen;
×
2691
      }
2692
    }
2693
  }
2694

2695
  if (payloadLen > 0) {
155,301✔
2696
    int32_t compLen = *(int32_t*)pRsp->data;
153,039✔
2697
    int32_t rawLen = *(int32_t*)(pRsp->data + sizeof(int32_t));
153,039✔
2698

2699
    char* pStart = (char*)pRsp->data + sizeof(int32_t) * 2;
153,039✔
2700

2701
    if (pRsp->compressed && compLen < rawLen) {
153,039!
2702
      int32_t len = tsDecompressString(pStart, compLen, 1, pResultInfo->decompBuf, rawLen, ONE_STAGE_COMP, NULL, 0);
×
2703
      if (len < 0) {
×
2704
        tscError("tsDecompressString failed");
×
2705
        return terrno ? terrno : TSDB_CODE_FAILED;
×
2706
      }
2707
      if (len != rawLen) {
×
2708
        tscError("tsDecompressString failed, len:%d != rawLen:%d", len, rawLen);
×
2709
        return TSDB_CODE_TSC_INTERNAL_ERROR;
×
2710
      }
2711
      pResultInfo->pData = pResultInfo->decompBuf;
×
2712
      pResultInfo->payloadLen = rawLen;
×
2713
    } else {
2714
      pResultInfo->pData = pStart;
153,039✔
2715
      pResultInfo->payloadLen = htonl(pRsp->compLen);
153,039✔
2716
      if (pRsp->compLen != pRsp->payloadLen) {
153,039!
2717
        tscError("pRsp->compLen:%d != pRsp->payloadLen:%d", pRsp->compLen, pRsp->payloadLen);
×
2718
        return TSDB_CODE_TSC_INTERNAL_ERROR;
×
2719
      }
2720
    }
2721
  }
2722

2723
  // TODO handle the compressed case
2724
  pResultInfo->totalRows += pResultInfo->numOfRows;
155,301✔
2725

2726
  int32_t code = setResultDataPtr(pResultInfo, convertUcs4, isStmt);
155,301✔
2727
  return code;
155,303✔
2728
}
2729

2730
TSDB_SERVER_STATUS taos_check_server_status(const char* fqdn, int port, char* details, int maxlen) {
4✔
2731
  TSDB_SERVER_STATUS code = TSDB_SRV_STATUS_UNAVAILABLE;
4✔
2732
  void*              clientRpc = NULL;
4✔
2733
  SServerStatusRsp   statusRsp = {0};
4✔
2734
  SEpSet             epSet = {.inUse = 0, .numOfEps = 1};
4✔
2735
  SRpcMsg  rpcMsg = {.info.ahandle = (void*)0x9527, .info.notFreeAhandle = 1, .msgType = TDMT_DND_SERVER_STATUS};
4✔
2736
  SRpcMsg  rpcRsp = {0};
4✔
2737
  SRpcInit rpcInit = {0};
4✔
2738
  char     pass[TSDB_PASSWORD_LEN + 1] = {0};
4✔
2739

2740
  rpcInit.label = "CHK";
4✔
2741
  rpcInit.numOfThreads = 1;
4✔
2742
  rpcInit.cfp = NULL;
4✔
2743
  rpcInit.sessions = 16;
4✔
2744
  rpcInit.connType = TAOS_CONN_CLIENT;
4✔
2745
  rpcInit.idleTime = tsShellActivityTimer * 1000;
4✔
2746
  rpcInit.compressSize = tsCompressMsgSize;
4✔
2747
  rpcInit.user = "_dnd";
4✔
2748

2749
  int32_t connLimitNum = tsNumOfRpcSessions / (tsNumOfRpcThreads * 3);
4✔
2750
  connLimitNum = TMAX(connLimitNum, 10);
4✔
2751
  connLimitNum = TMIN(connLimitNum, 500);
4✔
2752
  rpcInit.connLimitNum = connLimitNum;
4✔
2753
  rpcInit.timeToGetConn = tsTimeToGetAvailableConn;
4✔
2754
  rpcInit.readTimeout = tsReadTimeout;
4✔
2755
  rpcInit.ipv6 = tsEnableIpv6;
4✔
2756
  if (TSDB_CODE_SUCCESS != taosVersionStrToInt(td_version, &rpcInit.compatibilityVer)) {
4!
2757
    tscError("faild to convert taos version from str to int, errcode:%s", terrstr());
×
2758
    goto _OVER;
×
2759
  }
2760

2761
  clientRpc = rpcOpen(&rpcInit);
4✔
2762
  if (clientRpc == NULL) {
4!
2763
    code = terrno;
×
2764
    tscError("failed to init server status client since %s", tstrerror(code));
×
2765
    goto _OVER;
×
2766
  }
2767

2768
  if (fqdn == NULL) {
4!
2769
    fqdn = tsLocalFqdn;
4✔
2770
  }
2771

2772
  if (port == 0) {
4!
2773
    port = tsServerPort;
4✔
2774
  }
2775

2776
  tstrncpy(epSet.eps[0].fqdn, fqdn, TSDB_FQDN_LEN);
4✔
2777
  epSet.eps[0].port = (uint16_t)port;
4✔
2778
  int32_t ret = rpcSendRecv(clientRpc, &epSet, &rpcMsg, &rpcRsp);
4✔
2779
  if (TSDB_CODE_SUCCESS != ret) {
4!
2780
    tscError("failed to send recv since %s", tstrerror(ret));
×
2781
    goto _OVER;
×
2782
  }
2783

2784
  if (rpcRsp.code != 0 || rpcRsp.contLen <= 0 || rpcRsp.pCont == NULL) {
4!
2785
    tscError("failed to send server status req since %s", terrstr());
1!
2786
    goto _OVER;
1✔
2787
  }
2788

2789
  if (tDeserializeSServerStatusRsp(rpcRsp.pCont, rpcRsp.contLen, &statusRsp) != 0) {
3!
2790
    tscError("failed to parse server status rsp since %s", terrstr());
×
2791
    goto _OVER;
×
2792
  }
2793

2794
  code = statusRsp.statusCode;
3✔
2795
  if (details != NULL) {
3!
2796
    tstrncpy(details, statusRsp.details, maxlen);
3✔
2797
  }
2798

2799
_OVER:
×
2800
  if (clientRpc != NULL) {
4!
2801
    rpcClose(clientRpc);
4✔
2802
  }
2803
  if (rpcRsp.pCont != NULL) {
4✔
2804
    rpcFreeCont(rpcRsp.pCont);
3✔
2805
  }
2806
  return code;
4✔
2807
}
2808

2809
int32_t appendTbToReq(SHashObj* pHash, int32_t pos1, int32_t len1, int32_t pos2, int32_t len2, const char* str,
×
2810
                      int32_t acctId, char* db) {
2811
  SName name = {0};
×
2812

2813
  if (len1 <= 0) {
×
2814
    return -1;
×
2815
  }
2816

2817
  const char* dbName = db;
×
2818
  const char* tbName = NULL;
×
2819
  int32_t     dbLen = 0;
×
2820
  int32_t     tbLen = 0;
×
2821
  if (len2 > 0) {
×
2822
    dbName = str + pos1;
×
2823
    dbLen = len1;
×
2824
    tbName = str + pos2;
×
2825
    tbLen = len2;
×
2826
  } else {
2827
    dbLen = strlen(db);
×
2828
    tbName = str + pos1;
×
2829
    tbLen = len1;
×
2830
  }
2831

2832
  if (dbLen <= 0 || tbLen <= 0) {
×
2833
    return -1;
×
2834
  }
2835

2836
  if (tNameSetDbName(&name, acctId, dbName, dbLen)) {
×
2837
    return -1;
×
2838
  }
2839

2840
  if (tNameAddTbName(&name, tbName, tbLen)) {
×
2841
    return -1;
×
2842
  }
2843

2844
  char dbFName[TSDB_DB_FNAME_LEN] = {0};
×
2845
  (void)snprintf(dbFName, TSDB_DB_FNAME_LEN, "%d.%.*s", acctId, dbLen, dbName);
×
2846

2847
  STablesReq* pDb = taosHashGet(pHash, dbFName, strlen(dbFName));
×
2848
  if (pDb) {
×
2849
    if (NULL == taosArrayPush(pDb->pTables, &name)) {
×
2850
      return terrno ? terrno : TSDB_CODE_OUT_OF_MEMORY;
×
2851
    }
2852
  } else {
2853
    STablesReq db;
2854
    db.pTables = taosArrayInit(20, sizeof(SName));
×
2855
    if (NULL == db.pTables) {
×
2856
      return terrno;
×
2857
    }
2858
    tstrncpy(db.dbFName, dbFName, TSDB_DB_FNAME_LEN);
×
2859
    if (NULL == taosArrayPush(db.pTables, &name)) {
×
2860
      return terrno;
×
2861
    }
2862
    TSC_ERR_RET(taosHashPut(pHash, dbFName, strlen(dbFName), &db, sizeof(db)));
×
2863
  }
2864

2865
  return TSDB_CODE_SUCCESS;
×
2866
}
2867

2868
int32_t transferTableNameList(const char* tbList, int32_t acctId, char* dbName, SArray** pReq) {
×
2869
  SHashObj* pHash = taosHashInit(3, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
×
2870
  if (NULL == pHash) {
×
2871
    return terrno;
×
2872
  }
2873

2874
  bool    inEscape = false;
×
2875
  int32_t code = 0;
×
2876
  void*   pIter = NULL;
×
2877

2878
  int32_t vIdx = 0;
×
2879
  int32_t vPos[2];
2880
  int32_t vLen[2];
2881

2882
  (void)memset(vPos, -1, sizeof(vPos));
×
2883
  (void)memset(vLen, 0, sizeof(vLen));
×
2884

2885
  for (int32_t i = 0;; ++i) {
×
2886
    if (0 == *(tbList + i)) {
×
2887
      if (vPos[vIdx] >= 0 && vLen[vIdx] <= 0) {
×
2888
        vLen[vIdx] = i - vPos[vIdx];
×
2889
      }
2890

2891
      code = appendTbToReq(pHash, vPos[0], vLen[0], vPos[1], vLen[1], tbList, acctId, dbName);
×
2892
      if (code) {
×
2893
        goto _return;
×
2894
      }
2895

2896
      break;
×
2897
    }
2898

2899
    if ('`' == *(tbList + i)) {
×
2900
      inEscape = !inEscape;
×
2901
      if (!inEscape) {
×
2902
        if (vPos[vIdx] >= 0) {
×
2903
          vLen[vIdx] = i - vPos[vIdx];
×
2904
        } else {
2905
          goto _return;
×
2906
        }
2907
      }
2908

2909
      continue;
×
2910
    }
2911

2912
    if (inEscape) {
×
2913
      if (vPos[vIdx] < 0) {
×
2914
        vPos[vIdx] = i;
×
2915
      }
2916
      continue;
×
2917
    }
2918

2919
    if ('.' == *(tbList + i)) {
×
2920
      if (vPos[vIdx] < 0) {
×
2921
        goto _return;
×
2922
      }
2923
      if (vLen[vIdx] <= 0) {
×
2924
        vLen[vIdx] = i - vPos[vIdx];
×
2925
      }
2926
      vIdx++;
×
2927
      if (vIdx >= 2) {
×
2928
        goto _return;
×
2929
      }
2930
      continue;
×
2931
    }
2932

2933
    if (',' == *(tbList + i)) {
×
2934
      if (vPos[vIdx] < 0) {
×
2935
        goto _return;
×
2936
      }
2937
      if (vLen[vIdx] <= 0) {
×
2938
        vLen[vIdx] = i - vPos[vIdx];
×
2939
      }
2940

2941
      code = appendTbToReq(pHash, vPos[0], vLen[0], vPos[1], vLen[1], tbList, acctId, dbName);
×
2942
      if (code) {
×
2943
        goto _return;
×
2944
      }
2945

2946
      (void)memset(vPos, -1, sizeof(vPos));
×
2947
      (void)memset(vLen, 0, sizeof(vLen));
×
2948
      vIdx = 0;
×
2949
      continue;
×
2950
    }
2951

2952
    if (' ' == *(tbList + i) || '\r' == *(tbList + i) || '\t' == *(tbList + i) || '\n' == *(tbList + i)) {
×
2953
      if (vPos[vIdx] >= 0 && vLen[vIdx] <= 0) {
×
2954
        vLen[vIdx] = i - vPos[vIdx];
×
2955
      }
2956
      continue;
×
2957
    }
2958

2959
    if (('a' <= *(tbList + i) && 'z' >= *(tbList + i)) || ('A' <= *(tbList + i) && 'Z' >= *(tbList + i)) ||
×
2960
        ('0' <= *(tbList + i) && '9' >= *(tbList + i)) || ('_' == *(tbList + i))) {
×
2961
      if (vLen[vIdx] > 0) {
×
2962
        goto _return;
×
2963
      }
2964
      if (vPos[vIdx] < 0) {
×
2965
        vPos[vIdx] = i;
×
2966
      }
2967
      continue;
×
2968
    }
2969

2970
    goto _return;
×
2971
  }
2972

2973
  int32_t dbNum = taosHashGetSize(pHash);
×
2974
  *pReq = taosArrayInit(dbNum, sizeof(STablesReq));
×
2975
  if (NULL == pReq) {
×
2976
    TSC_ERR_JRET(terrno);
×
2977
  }
2978
  pIter = taosHashIterate(pHash, NULL);
×
2979
  while (pIter) {
×
2980
    STablesReq* pDb = (STablesReq*)pIter;
×
2981
    if (NULL == taosArrayPush(*pReq, pDb)) {
×
2982
      TSC_ERR_JRET(terrno);
×
2983
    }
2984
    pIter = taosHashIterate(pHash, pIter);
×
2985
  }
2986

2987
  taosHashCleanup(pHash);
×
2988

2989
  return TSDB_CODE_SUCCESS;
×
2990

2991
_return:
×
2992

2993
  terrno = TSDB_CODE_TSC_INVALID_OPERATION;
×
2994

2995
  pIter = taosHashIterate(pHash, NULL);
×
2996
  while (pIter) {
×
2997
    STablesReq* pDb = (STablesReq*)pIter;
×
2998
    taosArrayDestroy(pDb->pTables);
×
2999
    pIter = taosHashIterate(pHash, pIter);
×
3000
  }
3001

3002
  taosHashCleanup(pHash);
×
3003

3004
  return terrno;
×
3005
}
3006

3007
void syncCatalogFn(SMetaData* pResult, void* param, int32_t code) {
×
3008
  SSyncQueryParam* pParam = param;
×
3009
  pParam->pRequest->code = code;
×
3010

3011
  if (TSDB_CODE_SUCCESS != tsem_post(&pParam->sem)) {
×
3012
    tscError("failed to post semaphore since %s", tstrerror(terrno));
×
3013
  }
3014
}
×
3015

3016
void syncQueryFn(void* param, void* res, int32_t code) {
8,613,881✔
3017
  SSyncQueryParam* pParam = param;
8,613,881✔
3018
  pParam->pRequest = res;
8,613,881✔
3019

3020
  if (pParam->pRequest) {
8,613,881✔
3021
    pParam->pRequest->code = code;
8,611,815✔
3022
    clientOperateReport(pParam->pRequest);
8,611,815✔
3023
  }
3024

3025
  if (TSDB_CODE_SUCCESS != tsem_post(&pParam->sem)) {
8,616,529!
3026
    tscError("failed to post semaphore since %s", tstrerror(terrno));
×
3027
  }
3028
}
8,618,275✔
3029

3030
void taosAsyncQueryImpl(uint64_t connId, const char* sql, __taos_async_fn_t fp, void* param, bool validateOnly,
8,603,947✔
3031
                        int8_t source) {
3032
  if (sql == NULL || NULL == fp) {
8,603,947!
3033
    terrno = TSDB_CODE_INVALID_PARA;
×
3034
    if (fp) {
×
3035
      fp(param, NULL, terrno);
×
3036
    }
3037

3038
    return;
×
3039
  }
3040

3041
  size_t sqlLen = strlen(sql);
8,613,129✔
3042
  if (sqlLen > (size_t)TSDB_MAX_ALLOWED_SQL_LEN) {
8,613,129!
3043
    tscError("conn:0x%" PRIx64 ", sql string exceeds max length:%d", connId, TSDB_MAX_ALLOWED_SQL_LEN);
×
3044
    terrno = TSDB_CODE_TSC_EXCEED_SQL_LIMIT;
×
3045
    fp(param, NULL, terrno);
×
3046
    return;
×
3047
  }
3048

3049
  tscDebug("conn:0x%" PRIx64 ", taos_query execute, sql:%s", connId, sql);
8,613,129✔
3050

3051
  SRequestObj* pRequest = NULL;
8,613,129✔
3052
  int32_t      code = buildRequest(connId, sql, sqlLen, param, validateOnly, &pRequest, 0);
8,613,129✔
3053
  if (code != TSDB_CODE_SUCCESS) {
8,611,609!
3054
    terrno = code;
×
3055
    fp(param, NULL, terrno);
×
3056
    return;
×
3057
  }
3058

3059
  pRequest->source = source;
8,611,609✔
3060
  pRequest->body.queryFp = fp;
8,611,609✔
3061
  doAsyncQuery(pRequest, false);
8,611,609✔
3062
}
3063

3064
void taosAsyncQueryImplWithReqid(uint64_t connId, const char* sql, __taos_async_fn_t fp, void* param, bool validateOnly,
×
3065
                                 int64_t reqid) {
3066
  if (sql == NULL || NULL == fp) {
×
3067
    terrno = TSDB_CODE_INVALID_PARA;
×
3068
    if (fp) {
×
3069
      fp(param, NULL, terrno);
×
3070
    }
3071

3072
    return;
×
3073
  }
3074

3075
  size_t sqlLen = strlen(sql);
×
3076
  if (sqlLen > (size_t)TSDB_MAX_ALLOWED_SQL_LEN) {
×
3077
    tscError("conn:0x%" PRIx64 ", QID:0x%" PRIx64 ", sql string exceeds max length:%d", connId, reqid,
×
3078
             TSDB_MAX_ALLOWED_SQL_LEN);
3079
    terrno = TSDB_CODE_TSC_EXCEED_SQL_LIMIT;
×
3080
    fp(param, NULL, terrno);
×
3081
    return;
×
3082
  }
3083

3084
  tscDebug("conn:0x%" PRIx64 ", taos_query execute, QID:0x%" PRIx64 ", sql:%s", connId, reqid, sql);
×
3085

3086
  SRequestObj* pRequest = NULL;
×
3087
  int32_t      code = buildRequest(connId, sql, sqlLen, param, validateOnly, &pRequest, reqid);
×
3088
  if (code != TSDB_CODE_SUCCESS) {
×
3089
    terrno = code;
×
3090
    fp(param, NULL, terrno);
×
3091
    return;
×
3092
  }
3093

3094
  pRequest->body.queryFp = fp;
×
3095
  doAsyncQuery(pRequest, false);
×
3096
}
3097

3098
TAOS_RES* taosQueryImpl(TAOS* taos, const char* sql, bool validateOnly, int8_t source) {
8,599,659✔
3099
  if (NULL == taos) {
8,599,659!
3100
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
3101
    return NULL;
×
3102
  }
3103

3104
  SSyncQueryParam* param = taosMemoryCalloc(1, sizeof(SSyncQueryParam));
8,599,659!
3105
  if (NULL == param) {
8,612,730!
3106
    return NULL;
×
3107
  }
3108
  int32_t code = tsem_init(&param->sem, 0, 0);
8,612,730✔
3109
  if (TSDB_CODE_SUCCESS != code) {
8,611,382!
3110
    taosMemoryFree(param);
×
3111
    return NULL;
×
3112
  }
3113

3114
  taosAsyncQueryImpl(*(int64_t*)taos, sql, syncQueryFn, param, validateOnly, source);
8,611,382✔
3115
  code = tsem_wait(&param->sem);
8,563,097✔
3116
  if (TSDB_CODE_SUCCESS != code) {
8,616,791!
3117
    taosMemoryFree(param);
×
3118
    return NULL;
×
3119
  }
3120
  code = tsem_destroy(&param->sem);
8,616,791✔
3121
  if (TSDB_CODE_SUCCESS != code) {
8,612,697!
3122
    tscError("failed to destroy semaphore since %s", tstrerror(code));
×
3123
  }
3124

3125
  SRequestObj* pRequest = NULL;
8,612,324✔
3126
  if (param->pRequest != NULL) {
8,612,324!
3127
    param->pRequest->syncQuery = true;
8,612,324✔
3128
    pRequest = param->pRequest;
8,612,324✔
3129
    param->pRequest->inCallback = false;
8,612,324✔
3130
  }
3131
  taosMemoryFree(param);
8,612,324!
3132

3133
  // tscDebug("QID:0x%" PRIx64 ", taos_query end, conn:0x%" PRIx64 ", res:%p", pRequest ? pRequest->requestId : 0,
3134
  //          *(int64_t*)taos, pRequest);
3135

3136
  return pRequest;
8,608,878✔
3137
}
3138

3139
TAOS_RES* taosQueryImplWithReqid(TAOS* taos, const char* sql, bool validateOnly, int64_t reqid) {
×
3140
  if (NULL == taos) {
×
3141
    terrno = TSDB_CODE_TSC_DISCONNECTED;
×
3142
    return NULL;
×
3143
  }
3144

3145
  SSyncQueryParam* param = taosMemoryCalloc(1, sizeof(SSyncQueryParam));
×
3146
  if (param == NULL) {
×
3147
    return NULL;
×
3148
  }
3149
  int32_t code = tsem_init(&param->sem, 0, 0);
×
3150
  if (TSDB_CODE_SUCCESS != code) {
×
3151
    taosMemoryFree(param);
×
3152
    return NULL;
×
3153
  }
3154

3155
  taosAsyncQueryImplWithReqid(*(int64_t*)taos, sql, syncQueryFn, param, validateOnly, reqid);
×
3156
  code = tsem_wait(&param->sem);
×
3157
  if (TSDB_CODE_SUCCESS != code) {
×
3158
    taosMemoryFree(param);
×
3159
    return NULL;
×
3160
  }
3161
  SRequestObj* pRequest = NULL;
×
3162
  if (param->pRequest != NULL) {
×
3163
    param->pRequest->syncQuery = true;
×
3164
    pRequest = param->pRequest;
×
3165
  }
3166
  taosMemoryFree(param);
×
3167

3168
  // tscDebug("QID:0x%" PRIx64 ", taos_query end, conn:0x%" PRIx64 ", res:%p", pRequest ? pRequest->requestId : 0,
3169
  //   *(int64_t*)taos, pRequest);
3170

3171
  return pRequest;
×
3172
}
3173

3174
static void fetchCallback(void* pResult, void* param, int32_t code) {
152,676✔
3175
  SRequestObj* pRequest = (SRequestObj*)param;
152,676✔
3176

3177
  SReqResultInfo* pResultInfo = &pRequest->body.resInfo;
152,676✔
3178

3179
  tscDebug("req:0x%" PRIx64 ", enter scheduler fetch cb, code:%d - %s, QID:0x%" PRIx64, pRequest->self, code,
152,676✔
3180
           tstrerror(code), pRequest->requestId);
3181

3182
  pResultInfo->pData = pResult;
152,668✔
3183
  pResultInfo->numOfRows = 0;
152,668✔
3184

3185
  if (code != TSDB_CODE_SUCCESS) {
152,668✔
3186
    pRequest->code = code;
1✔
3187
    taosMemoryFreeClear(pResultInfo->pData);
1!
3188
    pRequest->body.fetchFp(((SSyncQueryParam*)pRequest->body.interParam)->userParam, pRequest, code);
1✔
3189
    return;
1✔
3190
  }
3191

3192
  if (pRequest->code != TSDB_CODE_SUCCESS) {
152,667!
3193
    taosMemoryFreeClear(pResultInfo->pData);
×
3194
    pRequest->body.fetchFp(((SSyncQueryParam*)pRequest->body.interParam)->userParam, pRequest, pRequest->code);
×
3195
    return;
×
3196
  }
3197

3198
  pRequest->code = setQueryResultFromRsp(pResultInfo, (const SRetrieveTableRsp*)pResultInfo->pData,
305,336✔
3199
                                         pResultInfo->convertUcs4, pRequest->stmtBindVersion > 0);
152,667✔
3200
  if (pRequest->code != TSDB_CODE_SUCCESS) {
152,669!
3201
    pResultInfo->numOfRows = 0;
×
3202
    tscError("req:0x%" PRIx64 ", fetch results failed, code:%s, QID:0x%" PRIx64, pRequest->self,
×
3203
             tstrerror(pRequest->code), pRequest->requestId);
3204
  } else {
3205
    tscDebug(
152,669✔
3206
        "req:0x%" PRIx64 ", fetch results, numOfRows:%" PRId64 " total Rows:%" PRId64 ", complete:%d, QID:0x%" PRIx64,
3207
        pRequest->self, pResultInfo->numOfRows, pResultInfo->totalRows, pResultInfo->completed, pRequest->requestId);
3208

3209
    STscObj*            pTscObj = pRequest->pTscObj;
152,669✔
3210
    SAppClusterSummary* pActivity = &pTscObj->pAppInfo->summary;
152,669✔
3211
    (void)atomic_add_fetch_64((int64_t*)&pActivity->fetchBytes, pRequest->body.resInfo.payloadLen);
152,669✔
3212
  }
3213

3214
  pRequest->body.fetchFp(((SSyncQueryParam*)pRequest->body.interParam)->userParam, pRequest, pResultInfo->numOfRows);
152,681✔
3215
}
3216

3217
void taosAsyncFetchImpl(SRequestObj* pRequest, __taos_async_fn_t fp, void* param) {
161,484✔
3218
  pRequest->body.fetchFp = fp;
161,484✔
3219
  ((SSyncQueryParam*)pRequest->body.interParam)->userParam = param;
161,484✔
3220

3221
  SReqResultInfo* pResultInfo = &pRequest->body.resInfo;
161,484✔
3222

3223
  // this query has no results or error exists, return directly
3224
  if (taos_num_fields(pRequest) == 0 || pRequest->code != TSDB_CODE_SUCCESS) {
161,484!
3225
    pResultInfo->numOfRows = 0;
×
3226
    pRequest->body.fetchFp(param, pRequest, pResultInfo->numOfRows);
×
3227
    return;
8,803✔
3228
  }
3229

3230
  // all data has returned to App already, no need to try again
3231
  if (pResultInfo->completed) {
161,483✔
3232
    // it is a local executed query, no need to do async fetch
3233
    if (QUERY_EXEC_MODE_SCHEDULE != pRequest->body.execMode) {
8,803✔
3234
      if (pResultInfo->localResultFetched) {
2,726✔
3235
        pResultInfo->numOfRows = 0;
1,363✔
3236
        pResultInfo->current = 0;
1,363✔
3237
      } else {
3238
        pResultInfo->localResultFetched = true;
1,363✔
3239
      }
3240
    } else {
3241
      pResultInfo->numOfRows = 0;
6,077✔
3242
    }
3243

3244
    pRequest->body.fetchFp(param, pRequest, pResultInfo->numOfRows);
8,803✔
3245
    return;
8,803✔
3246
  }
3247

3248
  SSchedulerReq req = {
152,680✔
3249
      .syncReq = false,
3250
      .fetchFp = fetchCallback,
3251
      .cbParam = pRequest,
3252
  };
3253

3254
  int32_t code = schedulerFetchRows(pRequest->body.queryJob, &req);
152,680✔
3255
  if (TSDB_CODE_SUCCESS != code) {
152,674!
3256
    tscError("0x%" PRIx64 " failed to schedule fetch rows", pRequest->requestId);
×
3257
    // pRequest->body.fetchFp(param, pRequest, code);
3258
  }
3259
}
3260

3261
void doRequestCallback(SRequestObj* pRequest, int32_t code) {
8,612,468✔
3262
  pRequest->inCallback = true;
8,612,468✔
3263
  int64_t this = pRequest->self;
8,612,468✔
3264
  if (tsQueryTbNotExistAsEmpty && TD_RES_QUERY(&pRequest->resType) && pRequest->isQuery &&
8,612,468!
3265
      (code == TSDB_CODE_PAR_TABLE_NOT_EXIST || code == TSDB_CODE_TDB_TABLE_NOT_EXIST)) {
×
3266
    code = TSDB_CODE_SUCCESS;
×
3267
    pRequest->type = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
×
3268
  }
3269

3270
  tscDebug("QID:0x%" PRIx64 ", taos_query end, req:0x%" PRIx64 ", res:%p", pRequest->requestId, pRequest->self,
8,612,468✔
3271
           pRequest);
3272

3273
  if (pRequest->body.queryFp != NULL) {
8,612,468!
3274
    pRequest->body.queryFp(((SSyncQueryParam*)pRequest->body.interParam)->userParam, pRequest, code);
8,613,487✔
3275
  }
3276

3277
  SRequestObj* pReq = acquireRequest(this);
8,617,481✔
3278
  if (pReq != NULL) {
8,620,040✔
3279
    pReq->inCallback = false;
8,617,657✔
3280
    (void)releaseRequest(this);
8,617,657✔
3281
  }
3282
}
8,614,842✔
3283

3284
int32_t clientParseSql(void* param, const char* dbName, const char* sql, bool parseOnly, const char* effectiveUser,
1,018✔
3285
                       SParseSqlRes* pRes) {
3286
#ifndef TD_ENTERPRISE
3287
  return TSDB_CODE_SUCCESS;
3288
#else
3289
  return clientParseSqlImpl(param, dbName, sql, parseOnly, effectiveUser, pRes);
1,018✔
3290
#endif
3291
}
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