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

taosdata / TDengine / #4541

19 Jul 2025 01:13AM UTC coverage: 56.753% (-1.6%) from 58.31%
#4541

push

travis-ci

web-flow
fix: subquery memleak (#32024)

124299 of 282344 branches covered (44.02%)

Branch coverage included in aggregate %.

181106 of 255787 relevant lines covered (70.8%)

24937406.43 hits per line

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

65.04
/source/libs/parser/src/parser.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 "parser.h"
17
#include "os.h"
18

19
#include "parInt.h"
20
#include "parToken.h"
21

22
bool qIsInsertValuesSql(const char* pStr, size_t length) {
37,999,576✔
23
  if (NULL == pStr) {
37,999,576✔
24
    return false;
1✔
25
  }
26

27
  const char* pSql = pStr;
37,999,575✔
28

29
  int32_t index = 0;
37,999,575✔
30
  SToken  t = tStrGetToken((char*)pStr, &index, false, NULL);
37,999,575✔
31
  if (TK_INSERT != t.type && TK_IMPORT != t.type) {
38,034,815✔
32
    return false;
2,843,486✔
33
  }
34

35
  do {
36
    pStr += index;
126,978,395✔
37
    index = 0;
126,978,395✔
38
    t = tStrGetToken((char*)pStr, &index, false, NULL);
126,978,395✔
39
    if (TK_USING == t.type || TK_VALUES == t.type || TK_FILE == t.type) {
126,771,568!
40
      return true;
34,984,198✔
41
    } else if (TK_SELECT == t.type) {
91,787,370✔
42
      return false;
265✔
43
    }
44
    if (0 == t.type || 0 == t.n) {
91,787,105!
45
      break;
46
    }
47
  } while (pStr - pSql < length);
91,790,864✔
48
  return false;
39✔
49
}
50

51
bool qIsCreateTbFromFileSql(const char* pStr, size_t length) {
1,424,446✔
52
  if (NULL == pStr) {
1,424,446!
53
    return false;
×
54
  }
55

56
  const char* pSql = pStr;
1,424,446✔
57

58
  int32_t index = 0;
1,424,446✔
59
  SToken  t = tStrGetToken((char*)pStr, &index, false, NULL);
1,424,446✔
60
  if (TK_CREATE != t.type) {
1,424,555✔
61
    return false;
1,289,164✔
62
  }
63

64
  do {
65
    pStr += index;
3,730,237✔
66
    index = 0;
3,730,237✔
67
    t = tStrGetToken((char*)pStr, &index, false, NULL);
3,730,237✔
68
    if (TK_FILE == t.type) {
3,730,236✔
69
      return true;
4✔
70
    }
71
    if (0 == t.type || 0 == t.n) {
3,730,232✔
72
      break;
73
    }
74
  } while (pStr - pSql < length);
3,594,964✔
75
  return false;
135,386✔
76
}
77

78
bool qParseDbName(const char* pStr, size_t length, char** pDbName) {
20,931✔
79
  (void)length;
80
  int32_t index = 0;
20,931✔
81
  SToken  t;
82

83
  if (NULL == pStr) {
20,931!
84
    *pDbName = NULL;
×
85
    return false;
×
86
  }
87

88
  t = tStrGetToken((char*)pStr, &index, false, NULL);
20,931✔
89
  if (TK_INSERT != t.type && TK_IMPORT != t.type) {
20,928!
90
    *pDbName = NULL;
32✔
91
    return false;
32✔
92
  }
93

94
  t = tStrGetToken((char*)pStr, &index, false, NULL);
20,896✔
95
  if (TK_INTO != t.type) {
20,916!
96
    *pDbName = NULL;
×
97
    return false;
×
98
  }
99

100
  t = tStrGetToken((char*)pStr, &index, false, NULL);
20,916✔
101
  if (t.n == 0 || t.z == NULL) {
20,911!
102
    *pDbName = NULL;
×
103
    return false;
×
104
  }
105
  char* dotPos = strnchr(t.z, '.', t.n, true);
20,917✔
106
  if (dotPos != NULL) {
20,908✔
107
    int dbNameLen = dotPos - t.z;
716✔
108
    *pDbName = taosMemoryMalloc(dbNameLen + 1);
716!
109
    if (*pDbName == NULL) {
694!
110
      return false;
×
111
    }
112
    strncpy(*pDbName, t.z, dbNameLen);
694✔
113
    (*pDbName)[dbNameLen] = '\0';
694✔
114
    return true;
694✔
115
  }
116
  return false;
20,192✔
117
}
118

119
static int32_t analyseSemantic(SParseContext* pCxt, SQuery* pQuery, SParseMetaCache* pMetaCache) {
1,390,825✔
120
  int32_t code = authenticate(pCxt, pQuery, pMetaCache);
1,390,825✔
121

122
  if (pCxt->parseOnly) {
1,390,818✔
123
    return code;
646✔
124
  }
125

126
  if (TSDB_CODE_SUCCESS == code && pQuery->placeholderNum > 0) {
1,390,172✔
127
    TSWAP(pQuery->pPrepareRoot, pQuery->pRoot);
26✔
128
    return TSDB_CODE_SUCCESS;
26✔
129
  }
130

131
  if (TSDB_CODE_SUCCESS == code) {
1,390,146✔
132
    code = translate(pCxt, pQuery, pMetaCache);
1,389,761✔
133
  }
134
  if (TSDB_CODE_SUCCESS == code) {
1,390,034✔
135
    code = calculateConstant(pCxt, pQuery);
1,293,749✔
136
  }
137
  return code;
1,389,916✔
138
}
139

140
static int32_t parseSqlIntoAst(SParseContext* pCxt, SQuery** pQuery) {
598✔
141
  int32_t code = parse(pCxt, pQuery);
598✔
142
  if (TSDB_CODE_SUCCESS == code) {
598✔
143
    code = analyseSemantic(pCxt, *pQuery, NULL);
583✔
144
  }
145
  return code;
598✔
146
}
147

148
static int32_t parseSqlSyntax(SParseContext* pCxt, SQuery** pQuery, SParseMetaCache* pMetaCache) {
1,424,420✔
149
  int32_t code = parse(pCxt, pQuery);
1,424,420✔
150
  if (TSDB_CODE_SUCCESS == code) {
1,424,319✔
151
    code = collectMetaKey(pCxt, *pQuery, pMetaCache);
1,390,103✔
152
  }
153
  return code;
1,424,414✔
154
}
155

156
static int32_t setValueByBindParam(SValueNode* pVal, TAOS_MULTI_BIND* pParam, void *charsetCxt) {
25✔
157
  if (!pParam || IS_NULL_TYPE(pParam->buffer_type)) {
25!
158
    return TSDB_CODE_APP_ERROR;
×
159
  }
160
  if (IS_VAR_DATA_TYPE(pVal->node.resType.type)) {
25!
161
    taosMemoryFreeClear(pVal->datum.p);
×
162
  }
163

164
  if (pParam->is_null && 1 == *(pParam->is_null)) {
25!
165
    pVal->node.resType.type = TSDB_DATA_TYPE_NULL;
×
166
    pVal->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_NULL].bytes;
×
167
    return TSDB_CODE_SUCCESS;
×
168
  }
169

170
  int32_t inputSize = (NULL != pParam->length ? *(pParam->length) : tDataTypes[pParam->buffer_type].bytes);
25✔
171
  pVal->node.resType.type = pParam->buffer_type;
25✔
172
  pVal->node.resType.bytes = inputSize;
25✔
173

174
  switch (pParam->buffer_type) {
25!
175
    case TSDB_DATA_TYPE_VARBINARY:
1✔
176
      pVal->datum.p = taosMemoryCalloc(1, pVal->node.resType.bytes + VARSTR_HEADER_SIZE + 1);
1!
177
      if (NULL == pVal->datum.p) {
1!
178
        return terrno;
×
179
      }
180
      varDataSetLen(pVal->datum.p, pVal->node.resType.bytes);
1✔
181
      memcpy(varDataVal(pVal->datum.p), pParam->buffer, pVal->node.resType.bytes);
1✔
182
      pVal->node.resType.bytes += VARSTR_HEADER_SIZE;
1✔
183
      break;
1✔
184
    case TSDB_DATA_TYPE_VARCHAR:
7✔
185
    case TSDB_DATA_TYPE_GEOMETRY:
186
      pVal->datum.p = taosMemoryCalloc(1, pVal->node.resType.bytes + VARSTR_HEADER_SIZE + 1);
7!
187
      if (NULL == pVal->datum.p) {
7!
188
        return terrno;
×
189
      }
190
      varDataSetLen(pVal->datum.p, pVal->node.resType.bytes);
7✔
191
      strncpy(varDataVal(pVal->datum.p), (const char*)pParam->buffer, pVal->node.resType.bytes);
7✔
192
      pVal->node.resType.bytes += VARSTR_HEADER_SIZE;
7✔
193
      break;
7✔
194
    case TSDB_DATA_TYPE_NCHAR: {
×
195
      pVal->node.resType.bytes *= TSDB_NCHAR_SIZE;
×
196
      pVal->datum.p = taosMemoryCalloc(1, pVal->node.resType.bytes + VARSTR_HEADER_SIZE + 1);
×
197
      if (NULL == pVal->datum.p) {
×
198
        return terrno;
×
199
      }
200

201
      int32_t output = 0;
×
202
      if (!taosMbsToUcs4(pParam->buffer, inputSize, (TdUcs4*)varDataVal(pVal->datum.p), pVal->node.resType.bytes,
×
203
                         &output, charsetCxt)) {
204
        return terrno;
×
205
      }
206
      varDataSetLen(pVal->datum.p, output);
×
207
      pVal->node.resType.bytes = output + VARSTR_HEADER_SIZE;
×
208
      break;
×
209
    }
210
    default: {
17✔
211
      int32_t code = nodesSetValueNodeValue(pVal, pParam->buffer);
17✔
212
      if (code) {
17!
213
        return code;
×
214
      }
215
      break;
17✔
216
    }
217
  }
218
  pVal->translate = true;
25✔
219
  return TSDB_CODE_SUCCESS;
25✔
220
}
221

222
static EDealRes rewriteQueryExprAliasImpl(SNode* pNode, void* pContext) {
154✔
223
  if (nodesIsExprNode(pNode) && QUERY_NODE_COLUMN != nodeType(pNode)) {
154✔
224
    snprintf(((SExprNode*)pNode)->aliasName, TSDB_COL_NAME_LEN, "#%d", *(int32_t*)pContext);
72✔
225
    ++(*(int32_t*)pContext);
72✔
226
  }
227
  return DEAL_RES_CONTINUE;
154✔
228
}
229

230
static void rewriteQueryExprAlias(SNode* pRoot, int32_t* pNo) {
27✔
231
  switch (nodeType(pRoot)) {
27!
232
    case QUERY_NODE_SELECT_STMT:
27✔
233
      nodesWalkSelectStmt((SSelectStmt*)pRoot, SQL_CLAUSE_FROM, rewriteQueryExprAliasImpl, pNo);
27✔
234
      break;
27✔
235
    case QUERY_NODE_SET_OPERATOR: {
×
236
      SSetOperator* pSetOper = (SSetOperator*)pRoot;
×
237
      rewriteQueryExprAlias(pSetOper->pLeft, pNo);
×
238
      rewriteQueryExprAlias(pSetOper->pRight, pNo);
×
239
      break;
×
240
    }
241
    default:
×
242
      break;
×
243
  }
244
}
27✔
245

246
static void rewriteExprAlias(SNode* pRoot) {
27✔
247
  int32_t no = 1;
27✔
248
  rewriteQueryExprAlias(pRoot, &no);
27✔
249
}
27✔
250

251
int32_t qParseSql(SParseContext* pCxt, SQuery** pQuery) {
21,462✔
252
  int32_t code = TSDB_CODE_SUCCESS;
21,462✔
253
  if (qIsInsertValuesSql(pCxt->pSql, pCxt->sqlLen)) {
21,462✔
254
    code = parseInsertSql(pCxt, pQuery, NULL, NULL);
20,905✔
255
  } else {
256
    code = parseSqlIntoAst(pCxt, pQuery);
598✔
257
  }
258
  terrno = code;
21,463✔
259
  return code;
21,473✔
260
}
261

262
static int32_t parseQuerySyntax(SParseContext* pCxt, SQuery** pQuery, struct SCatalogReq* pCatalogReq) {
1,424,459✔
263
  SParseMetaCache metaCache = {0};
1,424,459✔
264
  int32_t         code = parseSqlSyntax(pCxt, pQuery, &metaCache);
1,424,459✔
265
  if (TSDB_CODE_SUCCESS == code) {
1,424,369✔
266
    code = buildCatalogReq(&metaCache, pCatalogReq);
1,390,175✔
267
  }
268
  destoryParseMetaCache(&metaCache, true);
1,424,269✔
269
  return code;
1,424,309✔
270
}
271

272
static int32_t parseCreateTbFromFileSyntax(SParseContext* pCxt, SQuery** pQuery, struct SCatalogReq* pCatalogReq) {
4✔
273
  if (NULL == *pQuery) return parseQuerySyntax(pCxt, pQuery, pCatalogReq);
4✔
274

275
  return continueCreateTbFromFile(pCxt, pQuery);
2✔
276
}
277

278
int32_t qParseSqlSyntax(SParseContext* pCxt, SQuery** pQuery, struct SCatalogReq* pCatalogReq) {
18,998,938✔
279
  int32_t code = nodesAcquireAllocator(pCxt->allocatorId);
18,998,938✔
280
  if (TSDB_CODE_SUCCESS == code) {
18,996,089!
281
    if (qIsInsertValuesSql(pCxt->pSql, pCxt->sqlLen)) {
18,996,588✔
282
      code = parseInsertSql(pCxt, pQuery, pCatalogReq, NULL);
17,582,069✔
283
    } else if (qIsCreateTbFromFileSql(pCxt->pSql, pCxt->sqlLen)) {
1,423,984✔
284
      code = parseCreateTbFromFileSyntax(pCxt, pQuery, pCatalogReq);
4✔
285
    } else {
286
      code = parseQuerySyntax(pCxt, pQuery, pCatalogReq);
1,424,552✔
287
    }
288
  }
289
  (void)nodesReleaseAllocator(pCxt->allocatorId);
18,784,027✔
290
  terrno = code;
18,796,098✔
291
  return code;
18,826,675✔
292
}
293

294
int32_t qAnalyseSqlSemantic(SParseContext* pCxt, const struct SCatalogReq* pCatalogReq,
1,390,298✔
295
                            struct SMetaData* pMetaData, SQuery* pQuery) {
296
  SParseMetaCache metaCache = {0};
1,390,298✔
297
  int32_t         code = nodesAcquireAllocator(pCxt->allocatorId);
1,390,298✔
298
  if (TSDB_CODE_SUCCESS == code && pCatalogReq) {
1,390,278!
299
    code = putMetaDataToCache(pCatalogReq, pMetaData, &metaCache);
1,390,284✔
300
  }
301
  if (TSDB_CODE_SUCCESS == code) {
1,390,250!
302
    code = analyseSemantic(pCxt, pQuery, &metaCache);
1,390,264✔
303
  }
304
  (void)nodesReleaseAllocator(pCxt->allocatorId);
1,389,940✔
305
  destoryParseMetaCache(&metaCache, false);
1,390,178✔
306
  terrno = code;
1,390,090✔
307
  return code;
1,390,067✔
308
}
309

310
int32_t qContinueParseSql(SParseContext* pCxt, struct SCatalogReq* pCatalogReq, const struct SMetaData* pMetaData,
110,991✔
311
                          SQuery* pQuery) {
312
  return parseInsertSql(pCxt, &pQuery, pCatalogReq, pMetaData);
110,991✔
313
}
314

315
int32_t qContinueParsePostQuery(SParseContext* pCxt, SQuery* pQuery, SSDataBlock* pBlock) {
×
316
  int32_t code = TSDB_CODE_SUCCESS;
×
317
  switch (nodeType(pQuery->pRoot)) {
×
318
    default:
319
      break;
×
320
  }
321

322
  return code;
×
323
}
324

325
static void destoryTablesReq(void* p) {
5,288,790✔
326
  STablesReq* pRes = (STablesReq*)p;
5,288,790✔
327
  taosArrayDestroy(pRes->pTables);
5,288,790✔
328
}
5,288,821✔
329

330
void destoryCatalogReq(SCatalogReq* pCatalogReq) {
18,983,710✔
331
  if (NULL == pCatalogReq) {
18,983,710✔
332
    return;
661✔
333
  }
334
  taosArrayDestroy(pCatalogReq->pDbVgroup);
18,983,049✔
335
  taosArrayDestroy(pCatalogReq->pDbCfg);
18,983,630✔
336
  taosArrayDestroy(pCatalogReq->pDbInfo);
18,989,278✔
337
  if (pCatalogReq->cloned) {
18,987,522!
338
    taosArrayDestroy(pCatalogReq->pTableMeta);
×
339
    taosArrayDestroy(pCatalogReq->pTableHash);
×
340
#ifdef TD_ENTERPRISE
341
    taosArrayDestroy(pCatalogReq->pView);
×
342
#endif
343
    taosArrayDestroy(pCatalogReq->pTableTSMAs);
×
344
    taosArrayDestroy(pCatalogReq->pTSMAs);
×
345
    taosArrayDestroy(pCatalogReq->pTableName);
×
346
  } else {
347
    taosArrayDestroyEx(pCatalogReq->pTableMeta, destoryTablesReq);
18,987,522✔
348
    taosArrayDestroyEx(pCatalogReq->pTableHash, destoryTablesReq);
18,972,511✔
349
#ifdef TD_ENTERPRISE
350
    taosArrayDestroyEx(pCatalogReq->pView, destoryTablesReq);
18,981,692✔
351
#endif
352
    taosArrayDestroyEx(pCatalogReq->pTableTSMAs, destoryTablesReq);
18,990,346✔
353
    taosArrayDestroyEx(pCatalogReq->pTSMAs, destoryTablesReq);
18,995,698✔
354
    taosArrayDestroyEx(pCatalogReq->pTableName, destoryTablesReq);
18,996,780✔
355
  }
356
  taosArrayDestroy(pCatalogReq->pUdf);
18,997,676✔
357
  taosArrayDestroy(pCatalogReq->pIndex);
18,988,797✔
358
  taosArrayDestroy(pCatalogReq->pUser);
18,986,118✔
359
  taosArrayDestroy(pCatalogReq->pTableIndex);
18,979,950✔
360
  taosArrayDestroy(pCatalogReq->pTableCfg);
18,974,813✔
361
  taosArrayDestroy(pCatalogReq->pTableTag);
18,976,751✔
362
  taosArrayDestroy(pCatalogReq->pVStbRefDbs);
18,980,997✔
363
}
364

365
void tfreeSParseQueryRes(void* p) {
646✔
366
  if (NULL == p) {
646!
367
    return;
×
368
  }
369

370
  SParseQueryRes* pRes = p;
646✔
371
  destoryCatalogReq(pRes->pCatalogReq);
646✔
372
  taosMemoryFree(pRes->pCatalogReq);
646!
373
  catalogFreeMetaData(&pRes->meta);
646✔
374
}
375

376
void qDestroyParseContext(SParseContext* pCxt) {
19,003,460✔
377
  if (NULL == pCxt) {
19,003,460!
378
    return;
×
379
  }
380

381
  taosArrayDestroyEx(pCxt->pSubMetaList, tfreeSParseQueryRes);
19,003,460✔
382
  taosArrayDestroy(pCxt->pTableMetaPos);
19,011,291✔
383
  taosArrayDestroy(pCxt->pTableVgroupPos);
19,007,361✔
384
  taosMemoryFree(pCxt);
19,003,781!
385
}
386

387
void qDestroyQuery(SQuery* pQueryNode) { nodesDestroyNode((SNode*)pQueryNode); }
19,274,384✔
388

389
int32_t qExtractResultSchema(const SNode* pRoot, int32_t* numOfCols, SSchema** pSchema) {
424✔
390
  return extractResultSchema(pRoot, numOfCols, pSchema, NULL);
424✔
391
}
392

393
int32_t qSetSTableIdForRsma(SNode* pStmt, int64_t uid) {
×
394
  if (QUERY_NODE_SELECT_STMT == nodeType(pStmt)) {
×
395
    SNode* pTable = ((SSelectStmt*)pStmt)->pFromTable;
×
396
    if (QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
×
397
      ((SRealTableNode*)pTable)->pMeta->uid = uid;
×
398
      ((SRealTableNode*)pTable)->pMeta->suid = uid;
×
399
      return TSDB_CODE_SUCCESS;
×
400
    }
401
  }
402
  return TSDB_CODE_FAILED;
×
403
}
404

405
int32_t qInitKeywordsTable() { return taosInitKeywordsTable(); }
18,898✔
406

407
void qCleanupKeywordsTable() { taosCleanupKeywordsTable(); }
18,705✔
408

409
int32_t qStmtBindParams(SQuery* pQuery, TAOS_MULTI_BIND* pParams, int32_t colIdx, void *charsetCxt) {
22✔
410
  int32_t code = TSDB_CODE_SUCCESS;
22✔
411

412
  if (colIdx < 0) {
22✔
413
    int32_t size = taosArrayGetSize(pQuery->pPlaceholderValues);
18✔
414
    for (int32_t i = 0; i < size; ++i) {
39✔
415
      code = setValueByBindParam((SValueNode*)taosArrayGetP(pQuery->pPlaceholderValues, i), pParams + i, charsetCxt);
21✔
416
      if (TSDB_CODE_SUCCESS != code) {
21!
417
        return code;
×
418
      }
419
    }
420
  } else {
421
    code = setValueByBindParam((SValueNode*)taosArrayGetP(pQuery->pPlaceholderValues, colIdx), pParams, charsetCxt);
4✔
422
  }
423

424
  if (TSDB_CODE_SUCCESS == code && (colIdx < 0 || colIdx + 1 == pQuery->placeholderNum)) {
22!
425
    nodesDestroyNode(pQuery->pRoot);
22✔
426
    pQuery->pRoot = NULL;
22✔
427
    code = nodesCloneNode(pQuery->pPrepareRoot, &pQuery->pRoot);
22✔
428
  }
429
  if (TSDB_CODE_SUCCESS == code) {
22!
430
    rewriteExprAlias(pQuery->pRoot);
22✔
431
  }
432
  return code;
22✔
433
}
434

435
static int32_t setValueByBindParam2(SValueNode* pVal, TAOS_STMT2_BIND* pParam, void* charsetCxt) {
9✔
436
  if (!pParam || IS_NULL_TYPE(pParam->buffer_type)) {
9!
437
    return TSDB_CODE_APP_ERROR;
×
438
  }
439
  if (IS_VAR_DATA_TYPE(pVal->node.resType.type)) {
9!
440
    taosMemoryFreeClear(pVal->datum.p);
×
441
  }
442

443
  if (pParam->is_null && 1 == *(pParam->is_null)) {
9!
444
    pVal->node.resType.type = TSDB_DATA_TYPE_NULL;
×
445
    pVal->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_NULL].bytes;
×
446
    return TSDB_CODE_SUCCESS;
×
447
  }
448

449
  int32_t inputSize = (NULL != pParam->length ? *(pParam->length) : tDataTypes[pParam->buffer_type].bytes);
9!
450
  pVal->node.resType.type = pParam->buffer_type;
9✔
451
  pVal->node.resType.bytes = inputSize;
9✔
452

453
  switch (pParam->buffer_type) {
9!
454
    case TSDB_DATA_TYPE_VARBINARY:
×
455
      pVal->datum.p = taosMemoryCalloc(1, pVal->node.resType.bytes + VARSTR_HEADER_SIZE + 1);
×
456
      if (NULL == pVal->datum.p) {
×
457
        return terrno;
×
458
      }
459
      varDataSetLen(pVal->datum.p, pVal->node.resType.bytes);
×
460
      memcpy(varDataVal(pVal->datum.p), pParam->buffer, pVal->node.resType.bytes);
×
461
      pVal->node.resType.bytes += VARSTR_HEADER_SIZE;
×
462
      break;
×
463
    case TSDB_DATA_TYPE_VARCHAR:
×
464
    case TSDB_DATA_TYPE_GEOMETRY:
465
      pVal->datum.p = taosMemoryCalloc(1, pVal->node.resType.bytes + VARSTR_HEADER_SIZE + 1);
×
466
      if (NULL == pVal->datum.p) {
×
467
        return terrno;
×
468
      }
469
      varDataSetLen(pVal->datum.p, pVal->node.resType.bytes);
×
470
      strncpy(varDataVal(pVal->datum.p), (const char*)pParam->buffer, pVal->node.resType.bytes);
×
471
      pVal->node.resType.bytes += VARSTR_HEADER_SIZE;
×
472
      break;
×
473
    case TSDB_DATA_TYPE_NCHAR: {
×
474
      pVal->node.resType.bytes *= TSDB_NCHAR_SIZE;
×
475
      pVal->datum.p = taosMemoryCalloc(1, pVal->node.resType.bytes + VARSTR_HEADER_SIZE + 1);
×
476
      if (NULL == pVal->datum.p) {
×
477
        return terrno;
×
478
      }
479

480
      int32_t output = 0;
×
481
      if (!taosMbsToUcs4(pParam->buffer, inputSize, (TdUcs4*)varDataVal(pVal->datum.p), pVal->node.resType.bytes,
×
482
                         &output, charsetCxt)) {
483
        return terrno;
×
484
      }
485
      varDataSetLen(pVal->datum.p, output);
×
486
      pVal->node.resType.bytes = output + VARSTR_HEADER_SIZE;
×
487
      break;
×
488
    }
489
    case TSDB_DATA_TYPE_BLOB:
×
490
    case TSDB_DATA_TYPE_MEDIUMBLOB:
491
      return TSDB_CODE_INVALID_PARA;
×
492
    default: {
9✔
493
      int32_t code = nodesSetValueNodeValue(pVal, pParam->buffer);
9✔
494
      if (code) {
9!
495
        return code;
×
496
      }
497
      break;
9✔
498
    }
499
  }
500
  pVal->translate = true;
9✔
501
  return TSDB_CODE_SUCCESS;
9✔
502
}
503

504
int32_t qStmtBindParams2(SQuery* pQuery, TAOS_STMT2_BIND* pParams, int32_t colIdx, void* charsetCxt) {
5✔
505
  int32_t code = TSDB_CODE_SUCCESS;
5✔
506

507
  if (colIdx < 0) {
5!
508
    int32_t size = taosArrayGetSize(pQuery->pPlaceholderValues);
5✔
509
    for (int32_t i = 0; i < size; ++i) {
14✔
510
      code = setValueByBindParam2((SValueNode*)taosArrayGetP(pQuery->pPlaceholderValues, i), pParams + i, charsetCxt);
9✔
511
      if (TSDB_CODE_SUCCESS != code) {
9!
512
        return code;
×
513
      }
514
    }
515
  } else {
516
    code = setValueByBindParam2((SValueNode*)taosArrayGetP(pQuery->pPlaceholderValues, colIdx), pParams, charsetCxt);
×
517
  }
518

519
  if (TSDB_CODE_SUCCESS == code && (colIdx < 0 || colIdx + 1 == pQuery->placeholderNum)) {
5!
520
    nodesDestroyNode(pQuery->pRoot);
5✔
521
    pQuery->pRoot = NULL;
5✔
522
    code = nodesCloneNode(pQuery->pPrepareRoot, &pQuery->pRoot);
5✔
523
  }
524
  if (TSDB_CODE_SUCCESS == code) {
5!
525
    rewriteExprAlias(pQuery->pRoot);
5✔
526
  }
527
  return code;
5✔
528
}
529

530
int32_t qStmtParseQuerySql(SParseContext* pCxt, SQuery* pQuery) {
27✔
531
  int32_t code = translate(pCxt, pQuery, NULL);
27✔
532
  if (TSDB_CODE_SUCCESS == code) {
27!
533
    code = calculateConstant(pCxt, pQuery);
27✔
534
  }
535
  return code;
27✔
536
}
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