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

taosdata / TDengine / #3796

31 Mar 2025 10:39AM UTC coverage: 30.372% (-7.1%) from 37.443%
#3796

push

travis-ci

happyguoxy
test:add test cases

69287 of 309062 branches covered (22.42%)

Branch coverage included in aggregate %.

118044 of 307720 relevant lines covered (38.36%)

278592.15 hits per line

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

60.61
/source/libs/parser/src/parInsertStmt.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 "geosWrapper.h"
17
#include "os.h"
18
#include "parInsertUtil.h"
19
#include "parInt.h"
20
#include "parToken.h"
21
#include "query.h"
22
#include "tglobal.h"
23
#include "ttime.h"
24
#include "ttypes.h"
25

26
typedef struct SKvParam {
27
  int16_t  pos;
28
  SArray*  pTagVals;
29
  SSchema* schema;
30
  char     buf[TSDB_MAX_TAGS_LEN];
31
} SKvParam;
32

33
int32_t qCloneCurrentTbData(STableDataCxt* pDataBlock, SSubmitTbData** pData) {
63✔
34
  *pData = taosMemoryCalloc(1, sizeof(SSubmitTbData));
63!
35
  if (NULL == *pData) {
63!
36
    return terrno;
×
37
  }
38

39
  SSubmitTbData* pNew = *pData;
63✔
40

41
  *pNew = *pDataBlock->pData;
63✔
42

43
  int32_t code = cloneSVreateTbReq(pDataBlock->pData->pCreateTbReq, &pNew->pCreateTbReq);
63✔
44
  if (TSDB_CODE_SUCCESS != code) {
63!
45
    taosMemoryFreeClear(*pData);
×
46
    return code;
×
47
  }
48
  pNew->aCol = taosArrayDup(pDataBlock->pData->aCol, NULL);
63✔
49
  if (!pNew->aCol) {
63!
50
    code = terrno;
×
51
    taosMemoryFreeClear(*pData);
×
52
    return code;
×
53
  }
54

55
  int32_t colNum = taosArrayGetSize(pNew->aCol);
63✔
56
  for (int32_t i = 0; i < colNum; ++i) {
252✔
57
    if (pDataBlock->pData->flags & SUBMIT_REQ_COLUMN_DATA_FORMAT) {
189✔
58
      SColData* pCol = (SColData*)taosArrayGet(pNew->aCol, i);
187✔
59
      tColDataDeepClear(pCol);
187✔
60
    } else {
61
      pNew->aCol = taosArrayInit(20, POINTER_BYTES);
2✔
62
    }
63
  }
64

65
  return TSDB_CODE_SUCCESS;
63✔
66
}
67

68
int32_t qAppendStmtTableOutput(SQuery* pQuery, SHashObj* pAllVgHash, STableColsData* pTbData, STableDataCxt* pTbCtx,
93✔
69
                               SStbInterlaceInfo* pBuildInfo, SVCreateTbReq* ctbReq) {
70
  // merge according to vgId
71
  return insAppendStmtTableDataCxt(pAllVgHash, pTbData, pTbCtx, pBuildInfo, ctbReq);
93✔
72
}
73

74
int32_t qBuildStmtFinOutput(SQuery* pQuery, SHashObj* pAllVgHash, SArray* pVgDataBlocks) {
36✔
75
  int32_t             code = TSDB_CODE_SUCCESS;
36✔
76
  SVnodeModifyOpStmt* pStmt = (SVnodeModifyOpStmt*)pQuery->pRoot;
36✔
77

78
  if (TSDB_CODE_SUCCESS == code) {
36!
79
    code = insBuildVgDataBlocks(pAllVgHash, pVgDataBlocks, &pStmt->pDataBlocks, true);
36✔
80
  }
81

82
  if (pStmt->freeArrayFunc) {
36!
83
    pStmt->freeArrayFunc(pVgDataBlocks);
36✔
84
  }
85
  return code;
36✔
86
}
87

88
/*
89
int32_t qBuildStmtOutputFromTbList(SQuery* pQuery, SHashObj* pVgHash, SArray* pBlockList, STableDataCxt* pTbCtx, int32_t
90
tbNum) { int32_t             code = TSDB_CODE_SUCCESS; SArray*             pVgDataBlocks = NULL; SVnodeModifyOpStmt*
91
pStmt = (SVnodeModifyOpStmt*)pQuery->pRoot;
92

93
  // merge according to vgId
94
  if (tbNum > 0) {
95
    code = insMergeStmtTableDataCxt(pTbCtx, pBlockList, &pVgDataBlocks, true, tbNum);
96
  }
97

98
  if (TSDB_CODE_SUCCESS == code) {
99
    code = insBuildVgDataBlocks(pVgHash, pVgDataBlocks, &pStmt->pDataBlocks);
100
  }
101

102
  if (pStmt->freeArrayFunc) {
103
    pStmt->freeArrayFunc(pVgDataBlocks);
104
  }
105
  return code;
106
}
107
*/
108

109
int32_t qBuildStmtOutput(SQuery* pQuery, SHashObj* pVgHash, SHashObj* pBlockHash) {
63✔
110
  int32_t             code = TSDB_CODE_SUCCESS;
63✔
111
  SArray*             pVgDataBlocks = NULL;
63✔
112
  SVnodeModifyOpStmt* pStmt = (SVnodeModifyOpStmt*)pQuery->pRoot;
63✔
113

114
  // merge according to vgId
115
  if (taosHashGetSize(pBlockHash) > 0) {
63!
116
    code = insMergeTableDataCxt(pBlockHash, &pVgDataBlocks, true);
63✔
117
  }
118

119
  if (TSDB_CODE_SUCCESS == code) {
63!
120
    code = insBuildVgDataBlocks(pVgHash, pVgDataBlocks, &pStmt->pDataBlocks, false);
63✔
121
  }
122

123
  if (pStmt->freeArrayFunc) {
63!
124
    pStmt->freeArrayFunc(pVgDataBlocks);
63✔
125
  }
126
  return code;
63✔
127
}
128

129
int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, const char* sTableName, char* tName,
13✔
130
                           TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen, void* charsetCxt) {
131
  STableDataCxt* pDataBlock = (STableDataCxt*)pBlock;
13✔
132
  SMsgBuf        pBuf = {.buf = msgBuf, .len = msgBufLen};
13✔
133
  int32_t        code = TSDB_CODE_SUCCESS;
13✔
134
  SBoundColInfo* tags = (SBoundColInfo*)boundTags;
13✔
135
  if (NULL == tags) {
13!
136
    return TSDB_CODE_APP_ERROR;
×
137
  }
138

139
  SArray* pTagArray = taosArrayInit(tags->numOfBound, sizeof(STagVal));
13✔
140
  if (!pTagArray) {
13!
141
    return buildInvalidOperationMsg(&pBuf, "out of memory");
×
142
  }
143

144
  SArray* tagName = taosArrayInit(8, TSDB_COL_NAME_LEN);
13✔
145
  if (!tagName) {
13!
146
    code = buildInvalidOperationMsg(&pBuf, "out of memory");
×
147
    goto end;
×
148
  }
149

150
  SSchema* pSchema = getTableTagSchema(pDataBlock->pMeta);
13✔
151

152
  bool  isJson = false;
13✔
153
  STag* pTag = NULL;
13✔
154

155
  for (int c = 0; c < tags->numOfBound; ++c) {
46✔
156
    if (bind[c].is_null && bind[c].is_null[0]) {
33!
157
      continue;
×
158
    }
159

160
    SSchema* pTagSchema = &pSchema[tags->pColIndex[c]];
33✔
161
    int32_t  colLen = pTagSchema->bytes;
33✔
162
    if (IS_VAR_DATA_TYPE(pTagSchema->type)) {
33!
163
      if (!bind[c].length) {
13!
164
        code = buildInvalidOperationMsg(&pBuf, "var tag length is null");
×
165
        goto end;
×
166
      }
167
      colLen = bind[c].length[0];
13✔
168
      if ((colLen + VARSTR_HEADER_SIZE) > pTagSchema->bytes) {
13!
169
        code = buildInvalidOperationMsg(&pBuf, "tag length is too big");
×
170
        goto end;
×
171
      }
172
    }
173
    if (NULL == taosArrayPush(tagName, pTagSchema->name)) {
66!
174
      code = terrno;
×
175
      goto end;
×
176
    }
177
    if (pTagSchema->type == TSDB_DATA_TYPE_JSON) {
33!
178
      if (colLen > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) {
×
179
        code = buildSyntaxErrMsg(&pBuf, "json string too long than 4095", bind[c].buffer);
×
180
        goto end;
×
181
      }
182

183
      isJson = true;
×
184
      char* tmp = taosMemoryCalloc(1, colLen + 1);
×
185
      if (!tmp) {
×
186
        code = terrno;
×
187
        goto end;
×
188
      }
189
      memcpy(tmp, bind[c].buffer, colLen);
×
190
      code = parseJsontoTagData(tmp, pTagArray, &pTag, &pBuf, charsetCxt);
×
191
      taosMemoryFree(tmp);
×
192
      if (code != TSDB_CODE_SUCCESS) {
×
193
        goto end;
×
194
      }
195
    } else {
196
      STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type};
33✔
197
      //      strcpy(val.colName, pTagSchema->name);
198
      if (pTagSchema->type == TSDB_DATA_TYPE_BINARY || pTagSchema->type == TSDB_DATA_TYPE_VARBINARY ||
33!
199
          pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) {
22✔
200
        if (pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) {
12✔
201
          code = initCtxAsText();
1✔
202
          if (code) {
1!
203
            qError("geometry init failed:%s", tstrerror(code));
×
204
            goto end;
×
205
          }
206
          code = checkWKB(bind[c].buffer, colLen);
1✔
207
          if (code) {
1!
208
            qError("stmt bind invalid geometry tag:%s, must be WKB format", (char*)bind[c].buffer);
×
209
            goto end;
×
210
          }
211
        }
212
        val.pData = (uint8_t*)bind[c].buffer;
12✔
213
        val.nData = colLen;
12✔
214
      } else if (pTagSchema->type == TSDB_DATA_TYPE_NCHAR) {
21✔
215
        int32_t output = 0;
1✔
216
        void*   p = taosMemoryCalloc(1, colLen * TSDB_NCHAR_SIZE);
1!
217
        if (p == NULL) {
1!
218
          code = terrno;
×
219
          goto end;
×
220
        }
221
        if (!taosMbsToUcs4(bind[c].buffer, colLen, (TdUcs4*)(p), colLen * TSDB_NCHAR_SIZE, &output, charsetCxt)) {
1!
222
          if (terrno == TAOS_SYSTEM_ERROR(E2BIG)) {
×
223
            taosMemoryFree(p);
×
224
            code = generateSyntaxErrMsg(&pBuf, TSDB_CODE_PAR_VALUE_TOO_LONG, pTagSchema->name);
×
225
            goto end;
×
226
          }
227
          char buf[512] = {0};
×
228
          snprintf(buf, tListLen(buf), " taosMbsToUcs4 error:%s", strerror(terrno));
×
229
          taosMemoryFree(p);
×
230
          code = buildSyntaxErrMsg(&pBuf, buf, bind[c].buffer);
×
231
          goto end;
×
232
        }
233
        val.pData = p;
1✔
234
        val.nData = output;
1✔
235
      } else {
236
        memcpy(&val.i64, bind[c].buffer, colLen);
20✔
237
      }
238
      if (IS_VAR_DATA_TYPE(pTagSchema->type) && val.nData > pTagSchema->bytes) {
33!
239
        code = TSDB_CODE_PAR_VALUE_TOO_LONG;
×
240
        goto end;
×
241
      }
242
      if (NULL == taosArrayPush(pTagArray, &val)) {
33!
243
        code = terrno;
×
244
        goto end;
×
245
      }
246
    }
247
  }
248

249
  if (!isJson && (code = tTagNew(pTagArray, 1, false, &pTag)) != TSDB_CODE_SUCCESS) {
13!
250
    goto end;
×
251
  }
252

253
  if (NULL == pDataBlock->pData->pCreateTbReq) {
13✔
254
    pDataBlock->pData->pCreateTbReq = taosMemoryCalloc(1, sizeof(SVCreateTbReq));
4!
255
    if (NULL == pDataBlock->pData->pCreateTbReq) {
4!
256
      code = terrno;
×
257
      goto end;
×
258
    }
259
  }
260

261
  code = insBuildCreateTbReq(pDataBlock->pData->pCreateTbReq, tName, pTag, suid, sTableName, tagName,
13✔
262
                             pDataBlock->pMeta->tableInfo.numOfTags, TSDB_DEFAULT_TABLE_TTL);
13✔
263
  pTag = NULL;
13✔
264

265
end:
13✔
266
  for (int i = 0; i < taosArrayGetSize(pTagArray); ++i) {
46✔
267
    STagVal* p = (STagVal*)taosArrayGet(pTagArray, i);
33✔
268
    if (p->type == TSDB_DATA_TYPE_NCHAR) {
33✔
269
      taosMemoryFreeClear(p->pData);
1!
270
    }
271
  }
272
  taosArrayDestroy(pTagArray);
13✔
273
  taosArrayDestroy(tagName);
13✔
274
  taosMemoryFree(pTag);
13!
275

276
  return code;
13✔
277
}
278

279
int32_t convertStmtNcharCol(SMsgBuf* pMsgBuf, SSchema* pSchema, TAOS_MULTI_BIND* src, TAOS_MULTI_BIND* dst, void* charsetCxt) {
3✔
280
  int32_t output = 0;
3✔
281
  int32_t newBuflen = (pSchema->bytes - VARSTR_HEADER_SIZE) * src->num;
3✔
282
  if (dst->buffer_length < newBuflen) {
3!
283
    dst->buffer = taosMemoryRealloc(dst->buffer, newBuflen);
3!
284
    if (NULL == dst->buffer) {
3!
285
      return terrno;
×
286
    }
287
  }
288

289
  if (NULL == dst->length) {
3!
290
    dst->length = taosMemoryRealloc(dst->length, sizeof(int32_t) * src->num);
3!
291
    if (NULL == dst->length) {
3!
292
      taosMemoryFreeClear(dst->buffer);
×
293
      return terrno;
×
294
    }
295
  }
296

297
  dst->buffer_length = pSchema->bytes - VARSTR_HEADER_SIZE;
3✔
298

299
  for (int32_t i = 0; i < src->num; ++i) {
6✔
300
    if (src->is_null && src->is_null[i]) {
3!
301
      continue;
×
302
    }
303

304
    if (!taosMbsToUcs4(((char*)src->buffer) + src->buffer_length * i, src->length[i],
3!
305
                       (TdUcs4*)(((char*)dst->buffer) + dst->buffer_length * i), dst->buffer_length, &output, charsetCxt)) {
3✔
306
      if (terrno == TAOS_SYSTEM_ERROR(E2BIG)) {
×
307
        return generateSyntaxErrMsg(pMsgBuf, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name);
×
308
      }
309
      char buf[512] = {0};
×
310
      snprintf(buf, tListLen(buf), "%s", strerror(terrno));
×
311
      return buildSyntaxErrMsg(pMsgBuf, buf, NULL);
×
312
    }
313

314
    dst->length[i] = output;
3✔
315
  }
316

317
  dst->buffer_type = src->buffer_type;
3✔
318
  dst->is_null = src->is_null;
3✔
319
  dst->num = src->num;
3✔
320

321
  return TSDB_CODE_SUCCESS;
3✔
322
}
323

324
int32_t qBindStmtStbColsValue(void* pBlock, SArray* pCols, TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen,
27✔
325
                              STSchema** pTSchema, SBindInfo* pBindInfos, void* charsetCxt) {
326
  STableDataCxt*   pDataBlock = (STableDataCxt*)pBlock;
27✔
327
  SSchema*         pSchema = getTableColumnSchema(pDataBlock->pMeta);
27✔
328
  SBoundColInfo*   boundInfo = &pDataBlock->boundColsInfo;
27✔
329
  SMsgBuf          pBuf = {.buf = msgBuf, .len = msgBufLen};
27✔
330
  int32_t          rowNum = bind->num;
27✔
331
  TAOS_MULTI_BIND  ncharBind = {0};
27✔
332
  TAOS_MULTI_BIND* pBind = NULL;
27✔
333
  int32_t          code = 0;
27✔
334
  int16_t          lastColId = -1;
27✔
335
  bool             colInOrder = true;
27✔
336

337
  if (NULL == pTSchema || NULL == *pTSchema) {
27!
338
    *pTSchema = tBuildTSchema(pSchema, pDataBlock->pMeta->tableInfo.numOfColumns, pDataBlock->pMeta->sversion);
1✔
339
  }
340

341
  for (int c = 0; c < boundInfo->numOfBound; ++c) {
135✔
342
    SSchema* pColSchema = &pSchema[boundInfo->pColIndex[c]];
108✔
343
    if (pColSchema->colId <= lastColId) {
108!
344
      colInOrder = false;
×
345
    } else {
346
      lastColId = pColSchema->colId;
108✔
347
    }
348
    // SColData* pCol = taosArrayGet(pCols, c);
349

350
    if (bind[c].num != rowNum) {
108!
351
      code = buildInvalidOperationMsg(&pBuf, "row number in each bind param should be the same");
×
352
      goto _return;
×
353
    }
354

355
    if ((!(rowNum == 1 && bind[c].is_null && *bind[c].is_null)) &&
108!
356
        bind[c].buffer_type != pColSchema->type) {  // for rowNum ==1 , connector may not set buffer_type
108!
357
      code = buildInvalidOperationMsg(&pBuf, "column type mis-match with buffer type");
×
358
      goto _return;
×
359
    }
360

361
    if (TSDB_DATA_TYPE_NCHAR == pColSchema->type) {
108!
362
      code = convertStmtNcharCol(&pBuf, pColSchema, bind + c, &ncharBind, charsetCxt);
×
363
      if (code) {
×
364
        goto _return;
×
365
      }
366
      pBind = &ncharBind;
×
367
    } else {
368
      pBind = bind + c;
108✔
369
    }
370

371
    pBindInfos[c].columnId = pColSchema->colId;
108✔
372
    pBindInfos[c].bind = pBind;
108✔
373
    pBindInfos[c].type = pColSchema->type;
108✔
374

375
    // code = tColDataAddValueByBind(pCol, pBind, IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes -
376
    // VARSTR_HEADER_SIZE: -1); if (code) {
377
    //   goto _return;
378
    // }
379
  }
380

381
  code = tRowBuildFromBind(pBindInfos, boundInfo->numOfBound, colInOrder, *pTSchema, pCols, &pDataBlock->ordered, &pDataBlock->duplicateTs);
27✔
382

383
  parserDebug("stmt all %d columns bind %d rows data", boundInfo->numOfBound, rowNum);
27!
384

385
_return:
27✔
386

387
  taosMemoryFree(ncharBind.buffer);
27!
388
  taosMemoryFree(ncharBind.length);
27!
389

390
  return code;
27✔
391
}
392

393
int32_t qBindStmtColsValue(void* pBlock, SArray* pCols, TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen, void* charsetCxt) {
60✔
394
  STableDataCxt*   pDataBlock = (STableDataCxt*)pBlock;
60✔
395
  SSchema*         pSchema = getTableColumnSchema(pDataBlock->pMeta);
60✔
396
  SBoundColInfo*   boundInfo = &pDataBlock->boundColsInfo;
60✔
397
  SMsgBuf          pBuf = {.buf = msgBuf, .len = msgBufLen};
60✔
398
  int32_t          rowNum = bind->num;
60✔
399
  TAOS_MULTI_BIND  ncharBind = {0};
60✔
400
  TAOS_MULTI_BIND* pBind = NULL;
60✔
401
  int32_t          code = 0;
60✔
402

403
  for (int c = 0; c < boundInfo->numOfBound; ++c) {
316✔
404
    SSchema*  pColSchema = &pSchema[boundInfo->pColIndex[c]];
257✔
405
    SColData* pCol = taosArrayGet(pCols, c);
257✔
406

407
    if (bind[c].num != rowNum) {
257!
408
      code = buildInvalidOperationMsg(&pBuf, "row number in each bind param should be the same");
×
409
      goto _return;
×
410
    }
411

412
    if ((!(rowNum == 1 && bind[c].is_null && *bind[c].is_null)) &&
257!
413
        bind[c].buffer_type != pColSchema->type) {  // for rowNum ==1 , connector may not set buffer_type
257!
414
      code = buildInvalidOperationMsg(&pBuf, "column type mis-match with buffer type");
×
415
      goto _return;
×
416
    }
417

418
    if (TSDB_DATA_TYPE_NCHAR == pColSchema->type) {
257✔
419
      code = convertStmtNcharCol(&pBuf, pColSchema, bind + c, &ncharBind, charsetCxt);
3✔
420
      if (code) {
3!
421
        goto _return;
×
422
      }
423
      pBind = &ncharBind;
3✔
424
    } else {
425
      pBind = bind + c;
254✔
426
    }
427

428
    code = tColDataAddValueByBind(pCol, pBind,
257✔
429
                                  IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1,
257!
430
                                  initCtxAsText, checkWKB);
431
    if (code) {
257✔
432
      goto _return;
1✔
433
    }
434
  }
435

436
  parserDebug("stmt all %d columns bind %d rows data", boundInfo->numOfBound, rowNum);
59!
437

438
_return:
59✔
439

440
  taosMemoryFree(ncharBind.buffer);
60!
441
  taosMemoryFree(ncharBind.length);
60!
442

443
  return code;
60✔
444
}
445

446
int32_t qBindStmtSingleColValue(void* pBlock, SArray* pCols, TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen,
×
447
                                int32_t colIdx, int32_t rowNum, void* charsetCxt) {
448
  STableDataCxt*   pDataBlock = (STableDataCxt*)pBlock;
×
449
  SSchema*         pSchema = getTableColumnSchema(pDataBlock->pMeta);
×
450
  SBoundColInfo*   boundInfo = &pDataBlock->boundColsInfo;
×
451
  SMsgBuf          pBuf = {.buf = msgBuf, .len = msgBufLen};
×
452
  SSchema*         pColSchema = &pSchema[boundInfo->pColIndex[colIdx]];
×
453
  SColData*        pCol = taosArrayGet(pCols, colIdx);
×
454
  TAOS_MULTI_BIND  ncharBind = {0};
×
455
  TAOS_MULTI_BIND* pBind = NULL;
×
456
  int32_t          code = 0;
×
457

458
  if (bind->num != rowNum) {
×
459
    return buildInvalidOperationMsg(&pBuf, "row number in each bind param should be the same");
×
460
  }
461

462
  // Column index exceeds the number of columns
463
  if (colIdx >= pCols->size && pCol == NULL) {
×
464
    return buildInvalidOperationMsg(&pBuf, "column index exceeds the number of columns");
×
465
  }
466

467
  if (bind->buffer_type != pColSchema->type) {
×
468
    return buildInvalidOperationMsg(&pBuf, "column type mis-match with buffer type");
×
469
  }
470

471
  if (TSDB_DATA_TYPE_NCHAR == pColSchema->type) {
×
472
    code = convertStmtNcharCol(&pBuf, pColSchema, bind, &ncharBind, charsetCxt);
×
473
    if (code) {
×
474
      goto _return;
×
475
    }
476
    pBind = &ncharBind;
×
477
  } else {
478
    pBind = bind;
×
479
  }
480

481
  code = tColDataAddValueByBind(pCol, pBind,
×
482
                                IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1,
×
483
                                initCtxAsText, checkWKB);
484

485
  parserDebug("stmt col %d bind %d rows data", colIdx, rowNum);
×
486

487
_return:
×
488

489
  taosMemoryFree(ncharBind.buffer);
×
490
  taosMemoryFree(ncharBind.length);
×
491

492
  return code;
×
493
}
494

495
int32_t qBindStmtTagsValue2(void* pBlock, void* boundTags, int64_t suid, const char* sTableName, char* tName,
112✔
496
                            TAOS_STMT2_BIND* bind, char* msgBuf, int32_t msgBufLen, void* charsetCxt,
497
                            SVCreateTbReq* pCreateTbReq) {
498
  STableDataCxt* pDataBlock = (STableDataCxt*)pBlock;
112✔
499
  SMsgBuf        pBuf = {.buf = msgBuf, .len = msgBufLen};
112✔
500
  int32_t        code = TSDB_CODE_SUCCESS;
112✔
501
  SBoundColInfo* tags = (SBoundColInfo*)boundTags;
112✔
502
  if (NULL == tags) {
112!
503
    return TSDB_CODE_APP_ERROR;
×
504
  }
505

506
  SArray* pTagArray = taosArrayInit(tags->numOfBound, sizeof(STagVal));
112✔
507
  if (!pTagArray) {
112!
508
    return buildInvalidOperationMsg(&pBuf, "out of memory");
×
509
  }
510

511
  SArray* tagName = taosArrayInit(8, TSDB_COL_NAME_LEN);
112✔
512
  if (!tagName) {
112!
513
    code = buildInvalidOperationMsg(&pBuf, "out of memory");
×
514
    goto end;
×
515
  }
516

517
  SSchema* pSchema = getTableTagSchema(pDataBlock->pMeta);
112✔
518

519
  bool  isJson = false;
112✔
520
  STag* pTag = NULL;
112✔
521

522
  for (int c = 0; c < tags->numOfBound; ++c) {
353✔
523
    if (bind == NULL) {
242!
524
      break;
×
525
    }
526
    if (bind[c].is_null && bind[c].is_null[0]) {
242!
527
      continue;
×
528
    }
529

530
    SSchema* pTagSchema = &pSchema[tags->pColIndex[c]];
242✔
531
    int32_t  colLen = pTagSchema->bytes;
242✔
532
    if (IS_VAR_DATA_TYPE(pTagSchema->type)) {
242!
533
      if (!bind[c].length) {
102!
534
        code = buildInvalidOperationMsg(&pBuf, "var tag length is null");
×
535
        goto end;
×
536
      }
537
      colLen = bind[c].length[0];
102✔
538
      if ((colLen + VARSTR_HEADER_SIZE) > pTagSchema->bytes) {
102!
539
        code = buildInvalidOperationMsg(&pBuf, "tag length is too big");
×
540
        goto end;
×
541
      }
542
    }
543
    if (NULL == taosArrayPush(tagName, pTagSchema->name)) {
484!
544
      code = terrno;
×
545
      goto end;
×
546
    }
547
    if (pTagSchema->type == TSDB_DATA_TYPE_JSON) {
242!
548
      if (colLen > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) {
×
549
        code = buildSyntaxErrMsg(&pBuf, "json string too long than 4095", bind[c].buffer);
×
550
        goto end;
×
551
      }
552

553
      isJson = true;
×
554
      char* tmp = taosMemoryCalloc(1, colLen + 1);
×
555
      if (!tmp) {
×
556
        code = terrno;
×
557
        goto end;
×
558
      }
559
      memcpy(tmp, bind[c].buffer, colLen);
×
560
      code = parseJsontoTagData(tmp, pTagArray, &pTag, &pBuf, charsetCxt);
×
561
      taosMemoryFree(tmp);
×
562
      if (code != TSDB_CODE_SUCCESS) {
×
563
        goto end;
×
564
      }
565
    } else {
566
      STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type};
242✔
567
      //      strcpy(val.colName, pTagSchema->name);
568
      if (pTagSchema->type == TSDB_DATA_TYPE_BINARY || pTagSchema->type == TSDB_DATA_TYPE_VARBINARY ||
242!
569
          pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) {
151✔
570
        if (pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) {
98✔
571
          code = initCtxAsText();
7✔
572
          if (code) {
7!
573
            qError("geometry init failed:%s", tstrerror(code));
×
574
            goto end;
1✔
575
          }
576
          code = checkWKB(bind[c].buffer, colLen);
7✔
577
          if (code) {
7✔
578
            qError("stmt2 bind invalid geometry tag:%s, must be WKB format", (char*)bind[c].buffer);
1!
579
            goto end;
1✔
580
          }
581
        }
582
        val.pData = (uint8_t*)bind[c].buffer;
97✔
583
        val.nData = colLen;
97✔
584
      } else if (pTagSchema->type == TSDB_DATA_TYPE_NCHAR) {
144✔
585
        int32_t output = 0;
4✔
586
        void*   p = taosMemoryCalloc(1, colLen * TSDB_NCHAR_SIZE);
4!
587
        if (p == NULL) {
4!
588
          code = terrno;
×
589
          goto end;
×
590
        }
591
        if (!taosMbsToUcs4(bind[c].buffer, colLen, (TdUcs4*)(p), colLen * TSDB_NCHAR_SIZE, &output, charsetCxt)) {
4!
592
          if (terrno == TAOS_SYSTEM_ERROR(E2BIG)) {
×
593
            taosMemoryFree(p);
×
594
            code = generateSyntaxErrMsg(&pBuf, TSDB_CODE_PAR_VALUE_TOO_LONG, pTagSchema->name);
×
595
            goto end;
×
596
          }
597
          char buf[512] = {0};
×
598
          snprintf(buf, tListLen(buf), " taosMbsToUcs4 error:%s", strerror(terrno));
×
599
          taosMemoryFree(p);
×
600
          code = buildSyntaxErrMsg(&pBuf, buf, bind[c].buffer);
×
601
          goto end;
×
602
        }
603
        val.pData = p;
4✔
604
        val.nData = output;
4✔
605
      } else {
606
        memcpy(&val.i64, bind[c].buffer, colLen);
140✔
607
      }
608
      if (IS_VAR_DATA_TYPE(pTagSchema->type) && val.nData > pTagSchema->bytes) {
241!
609
        code = TSDB_CODE_PAR_VALUE_TOO_LONG;
×
610
        goto end;
×
611
      }
612
      if (NULL == taosArrayPush(pTagArray, &val)) {
241!
613
        code = terrno;
×
614
        goto end;
×
615
      }
616
    }
617
  }
618

619
  if (!isJson && (code = tTagNew(pTagArray, 1, false, &pTag)) != TSDB_CODE_SUCCESS) {
111!
620
    goto end;
×
621
  }
622

623
  if (pCreateTbReq){
111✔
624
    code = insBuildCreateTbReq(pCreateTbReq, tName, pTag, suid, sTableName, tagName,
37✔
625
                               pDataBlock->pMeta->tableInfo.numOfTags, TSDB_DEFAULT_TABLE_TTL);
37✔
626
    pTag = NULL;
37✔
627
    goto end;
37✔
628
  }
629

630
  if (NULL == pDataBlock->pData->pCreateTbReq) {
74✔
631
    pDataBlock->pData->pCreateTbReq = taosMemoryCalloc(1, sizeof(SVCreateTbReq));
7!
632
    if (NULL == pDataBlock->pData->pCreateTbReq) {
7!
633
      code = terrno;
×
634
      goto end;
×
635
    }
636
  } else {
637
    SVCreateTbReq* tmp = pDataBlock->pData->pCreateTbReq;
67✔
638
    taosMemoryFreeClear(tmp->name);
67!
639
    taosMemoryFreeClear(tmp->ctb.pTag);
67!
640
    taosMemoryFreeClear(tmp->ctb.stbName);
67!
641
    taosArrayDestroy(tmp->ctb.tagName);
67✔
642
    tmp->ctb.tagName = NULL;
67✔
643
  }
644

645
  code = insBuildCreateTbReq(pDataBlock->pData->pCreateTbReq, tName, pTag, suid, sTableName, tagName,
74✔
646
                             pDataBlock->pMeta->tableInfo.numOfTags, TSDB_DEFAULT_TABLE_TTL);
74✔
647
  pTag = NULL;
74✔
648

649
end:
112✔
650
  for (int i = 0; i < taosArrayGetSize(pTagArray); ++i) {
353✔
651
    STagVal* p = (STagVal*)taosArrayGet(pTagArray, i);
241✔
652
    if (p->type == TSDB_DATA_TYPE_NCHAR) {
241✔
653
      taosMemoryFreeClear(p->pData);
4!
654
    }
655
  }
656
  taosArrayDestroy(pTagArray);
112✔
657
  taosArrayDestroy(tagName);
112✔
658
  taosMemoryFree(pTag);
112!
659

660
  return code;
112✔
661
}
662

663
static int32_t convertStmtStbNcharCol2(SMsgBuf* pMsgBuf, SSchema* pSchema, TAOS_STMT2_BIND* src, TAOS_STMT2_BIND* dst, void *charsetCxt) {
5✔
664
  int32_t       output = 0;
5✔
665
  const int32_t max_buf_len = pSchema->bytes - VARSTR_HEADER_SIZE;
5✔
666

667
  dst->buffer = taosMemoryCalloc(src->num, max_buf_len);
5!
668
  if (NULL == dst->buffer) {
5!
669
    return terrno;
×
670
  }
671

672
  dst->length = taosMemoryCalloc(src->num, sizeof(int32_t));
5!
673
  if (NULL == dst->length) {
5!
674
    taosMemoryFreeClear(dst->buffer);
×
675
    return terrno;
×
676
  }
677

678
  char* src_buf = src->buffer;
5✔
679
  char* dst_buf = dst->buffer;
5✔
680
  for (int32_t i = 0; i < src->num; ++i) {
55✔
681
    if (src->is_null && src->is_null[i]) {
50!
682
      continue;
×
683
    }
684

685
    if (!taosMbsToUcs4(src_buf, src->length[i], (TdUcs4*)dst_buf, max_buf_len, &output, charsetCxt)) {
50!
686
      if (terrno == TAOS_SYSTEM_ERROR(E2BIG)) {
×
687
        return generateSyntaxErrMsg(pMsgBuf, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name);
×
688
      }
689
      char buf[512] = {0};
×
690
      snprintf(buf, tListLen(buf), "%s", strerror(terrno));
×
691
      return buildSyntaxErrMsg(pMsgBuf, buf, NULL);
×
692
    }
693

694
    dst->length[i] = output;
50✔
695
    src_buf += src->length[i];
50✔
696
    dst_buf += output;
50✔
697
  }
698

699
  dst->buffer_type = src->buffer_type;
5✔
700
  dst->is_null = src->is_null;
5✔
701
  dst->num = src->num;
5✔
702

703
  return TSDB_CODE_SUCCESS;
5✔
704
}
705

706
int32_t qBindStmtStbColsValue2(void* pBlock, SArray* pCols, TAOS_STMT2_BIND* bind, char* msgBuf, int32_t msgBufLen,
67✔
707
                               STSchema** pTSchema, SBindInfo2* pBindInfos, void *charsetCxt) {
708
  STableDataCxt*  pDataBlock = (STableDataCxt*)pBlock;
67✔
709
  SSchema*        pSchema = getTableColumnSchema(pDataBlock->pMeta);
67✔
710
  SBoundColInfo*  boundInfo = &pDataBlock->boundColsInfo;
67✔
711
  SMsgBuf         pBuf = {.buf = msgBuf, .len = msgBufLen};
67✔
712
  int32_t         rowNum = bind->num;
67✔
713
  SArray*         ncharBinds = NULL;
67✔
714
  TAOS_STMT2_BIND ncharBind = {0};
67✔
715
  int32_t         code = 0;
67✔
716
  int16_t         lastColId = -1;
67✔
717
  bool            colInOrder = true;
67✔
718
  int             ncharColNums = 0;
67✔
719

720
  if (NULL == pTSchema || NULL == *pTSchema) {
67!
721
    *pTSchema = tBuildTSchema(pSchema, pDataBlock->pMeta->tableInfo.numOfColumns, pDataBlock->pMeta->sversion);
12✔
722
  }
723

724
  for (int c = 0; c < boundInfo->numOfBound; ++c) {
187✔
725
    if (TSDB_DATA_TYPE_NCHAR == pSchema[boundInfo->pColIndex[c]].type) {
120✔
726
      ncharColNums++;
5✔
727
    }
728
  }
729
  if (ncharColNums > 0) {
67✔
730
    ncharBinds = taosArrayInit(ncharColNums, sizeof(ncharBind));
1✔
731
    if (!ncharBinds) {
1!
732
      code = terrno;
×
733
      goto _return;
×
734
    }
735
  }
736

737
  for (int c = 0; c < boundInfo->numOfBound; ++c) {
187✔
738
    SSchema* pColSchema = &pSchema[boundInfo->pColIndex[c]];
120✔
739
    if (pColSchema->colId <= lastColId) {
120✔
740
      colInOrder = false;
1✔
741
    } else {
742
      lastColId = pColSchema->colId;
119✔
743
    }
744

745
    if (bind[c].num != rowNum) {
120!
746
      code = buildInvalidOperationMsg(&pBuf, "row number in each bind param should be the same");
×
747
      goto _return;
×
748
    }
749

750
    if ((!(rowNum == 1 && bind[c].is_null && *bind[c].is_null)) &&
120!
751
        bind[c].buffer_type != pColSchema->type) {  // for rowNum ==1 , connector may not set buffer_type
120!
752
      code = buildInvalidOperationMsg(&pBuf, "column type mis-match with buffer type");
×
753
      goto _return;
×
754
    }
755

756
    if (TSDB_DATA_TYPE_NCHAR == pColSchema->type) {
120✔
757
      code = convertStmtStbNcharCol2(&pBuf, pColSchema, bind + c, &ncharBind, charsetCxt);
5✔
758
      if (code) {
5!
759
        goto _return;
×
760
      }
761
      if (!taosArrayPush(ncharBinds, &ncharBind)) {
5!
762
        code = terrno;
×
763
        goto _return;
×
764
      }
765
      pBindInfos[c].bind = taosArrayGetLast(ncharBinds);
5✔
766
    } else if (TSDB_DATA_TYPE_GEOMETRY == pColSchema->type) {
115✔
767
      code = initCtxAsText();
1✔
768
      if (code) {
1!
769
        qError("geometry init failed:%s", tstrerror(code));
×
770
        goto _return;
×
771
      }
772
      uint8_t* buf = bind[c].buffer;
1✔
773
      for (int j = 0; j < bind[c].num; j++) {
5✔
774
        if (bind[c].is_null && bind[c].is_null[j]) {
4!
775
          continue;
1✔
776
        }
777
        code = checkWKB(buf, bind[c].length[j]);
3✔
778
        if (code) {
3!
779
          qError("stmt2 interlace mode geometry data[%d]:{%s},length:%d must be in WKB format", c, buf,
×
780
                 bind[c].length[j]);
781
          goto _return;
×
782
        }
783
        buf += bind[c].length[j];
3✔
784
      }
785
      pBindInfos[c].bind = bind + c;
1✔
786
    } else {
787
      pBindInfos[c].bind = bind + c;
114✔
788
    }
789

790
    pBindInfos[c].columnId = pColSchema->colId;
120✔
791
    pBindInfos[c].type = pColSchema->type;
120✔
792
    pBindInfos[c].bytes = pColSchema->bytes;
120✔
793
  }
794

795
  code = tRowBuildFromBind2(pBindInfos, boundInfo->numOfBound, colInOrder, *pTSchema, pCols, &pDataBlock->ordered, &pDataBlock->duplicateTs);
67✔
796

797
  parserDebug("stmt all %d columns bind %d rows data", boundInfo->numOfBound, rowNum);
67!
798

799
_return:
67✔
800
  if (ncharBinds) {
67✔
801
    for (int i = 0; i < TARRAY_SIZE(ncharBinds); ++i) {
6✔
802
      TAOS_STMT2_BIND* ncBind = TARRAY_DATA(ncharBinds);
5✔
803
      taosMemoryFree(ncBind[i].buffer);
5!
804
      taosMemoryFree(ncBind[i].length);
5!
805
    }
806
    taosArrayDestroy(ncharBinds);
1✔
807
  }
808

809
  return code;
67✔
810
}
811

812
static int32_t convertStmtNcharCol2(SMsgBuf* pMsgBuf, SSchema* pSchema, TAOS_STMT2_BIND* src, TAOS_STMT2_BIND* dst, void *charsetCxt) {
3✔
813
  int32_t       output = 0;
3✔
814
  const int32_t max_buf_len = pSchema->bytes - VARSTR_HEADER_SIZE;
3✔
815

816
  int32_t newBuflen = (pSchema->bytes - VARSTR_HEADER_SIZE) * src->num;
3✔
817
  // if (dst->buffer_length < newBuflen) {
818
  dst->buffer = taosMemoryRealloc(dst->buffer, newBuflen);
3!
819
  if (NULL == dst->buffer) {
3!
820
    return terrno;
×
821
  }
822
  //}
823

824
  if (NULL == dst->length) {
3!
825
    dst->length = taosMemoryRealloc(dst->length, sizeof(int32_t) * src->num);
3!
826
    if (NULL == dst->length) {
3!
827
      taosMemoryFreeClear(dst->buffer);
×
828
      return terrno;
×
829
    }
830
  }
831

832
  // dst->buffer_length = pSchema->bytes - VARSTR_HEADER_SIZE;
833
  char* src_buf = src->buffer;
3✔
834
  char* dst_buf = dst->buffer;
3✔
835
  for (int32_t i = 0; i < src->num; ++i) {
6✔
836
    if (src->is_null && src->is_null[i]) {
3!
837
      continue;
×
838
    }
839

840
    /*if (!taosMbsToUcs4(((char*)src->buffer) + src->buffer_length * i, src->length[i],
841
      (TdUcs4*)(((char*)dst->buffer) + dst->buffer_length * i), dst->buffer_length, &output)) {*/
842
    if (!taosMbsToUcs4(src_buf, src->length[i], (TdUcs4*)dst_buf, max_buf_len, &output, charsetCxt)) {
3!
843
      if (terrno == TAOS_SYSTEM_ERROR(E2BIG)) {
×
844
        return generateSyntaxErrMsg(pMsgBuf, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name);
×
845
      }
846
      char buf[512] = {0};
×
847
      snprintf(buf, tListLen(buf), "%s", strerror(terrno));
×
848
      return buildSyntaxErrMsg(pMsgBuf, buf, NULL);
×
849
    }
850

851
    dst->length[i] = output;
3✔
852
    src_buf += src->length[i];
3✔
853
    dst_buf += output;
3✔
854
  }
855

856
  dst->buffer_type = src->buffer_type;
3✔
857
  dst->is_null = src->is_null;
3✔
858
  dst->num = src->num;
3✔
859

860
  return TSDB_CODE_SUCCESS;
3✔
861
}
862

863
int32_t qBindStmtColsValue2(void* pBlock, SArray* pCols, TAOS_STMT2_BIND* bind, char* msgBuf, int32_t msgBufLen,
99✔
864
                            void* charsetCxt) {
865
  STableDataCxt*   pDataBlock = (STableDataCxt*)pBlock;
99✔
866
  SSchema*         pSchema = getTableColumnSchema(pDataBlock->pMeta);
99✔
867
  SBoundColInfo*   boundInfo = &pDataBlock->boundColsInfo;
99✔
868
  SMsgBuf          pBuf = {.buf = msgBuf, .len = msgBufLen};
99✔
869
  int32_t          rowNum = bind->num;
99✔
870
  TAOS_STMT2_BIND  ncharBind = {0};
99✔
871
  TAOS_STMT2_BIND* pBind = NULL;
99✔
872
  int32_t          code = 0;
99✔
873

874
  for (int c = 0; c < boundInfo->numOfBound; ++c) {
306✔
875
    SSchema*  pColSchema = &pSchema[boundInfo->pColIndex[c]];
207✔
876
    SColData* pCol = taosArrayGet(pCols, c);
207✔
877
    if (pCol == NULL || pColSchema == NULL) {
207!
878
      code = buildInvalidOperationMsg(&pBuf, "get column schema or column data failed");
×
879
      goto _return;
×
880
    }
881

882
    if (boundInfo->pColIndex[c] == 0) {
207✔
883
      pCol->cflag |= COL_IS_KEY;
99✔
884
    }
885

886
    if (bind[c].num != rowNum) {
207!
887
      code = buildInvalidOperationMsg(&pBuf, "row number in each bind param should be the same");
×
888
      goto _return;
×
889
    }
890

891
    if ((!(rowNum == 1 && bind[c].is_null && *bind[c].is_null)) &&
207!
892
        bind[c].buffer_type != pColSchema->type) {  // for rowNum ==1 , connector may not set buffer_type
207!
893
      code = buildInvalidOperationMsg(&pBuf, "column type mis-match with buffer type");
×
894
      goto _return;
×
895
    }
896

897
    if (TSDB_DATA_TYPE_NCHAR == pColSchema->type) {
207✔
898
      code = convertStmtNcharCol2(&pBuf, pColSchema, bind + c, &ncharBind, charsetCxt);
1✔
899
      if (code) {
1!
900
        goto _return;
×
901
      }
902
      pBind = &ncharBind;
1✔
903
    } else {
904
      pBind = bind + c;
206✔
905
    }
906

907
    code = tColDataAddValueByBind2(pCol, pBind,
207✔
908
                                   IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1,
207!
909
                                   initCtxAsText, checkWKB);
910
    if (code) {
207!
911
      goto _return;
×
912
    }
913
  }
914

915
  parserDebug("stmt2 all %d columns bind %d rows data as col format", boundInfo->numOfBound, rowNum);
99!
916

917
_return:
99✔
918

919
  taosMemoryFree(ncharBind.buffer);
99!
920
  taosMemoryFree(ncharBind.length);
99!
921

922
  return code;
99✔
923
}
924

925
int32_t qBindStmtSingleColValue2(void* pBlock, SArray* pCols, TAOS_STMT2_BIND* bind, char* msgBuf, int32_t msgBufLen,
6✔
926
                                 int32_t colIdx, int32_t rowNum, void *charsetCxt) {
927
  STableDataCxt*   pDataBlock = (STableDataCxt*)pBlock;
6✔
928
  SSchema*         pSchema = getTableColumnSchema(pDataBlock->pMeta);
6✔
929
  SBoundColInfo*   boundInfo = &pDataBlock->boundColsInfo;
6✔
930
  SMsgBuf          pBuf = {.buf = msgBuf, .len = msgBufLen};
6✔
931
  SSchema*         pColSchema = &pSchema[boundInfo->pColIndex[colIdx]];
6✔
932
  SColData*        pCol = taosArrayGet(pCols, colIdx);
6✔
933
  TAOS_STMT2_BIND  ncharBind = {0};
6✔
934
  TAOS_STMT2_BIND* pBind = NULL;
6✔
935
  int32_t          code = 0;
6✔
936

937
  if (bind->num != rowNum) {
6!
938
    return buildInvalidOperationMsg(&pBuf, "row number in each bind param should be the same");
×
939
  }
940

941
  // Column index exceeds the number of columns
942
  if (colIdx >= pCols->size && pCol == NULL) {
6!
943
    return buildInvalidOperationMsg(&pBuf, "column index exceeds the number of columns");
×
944
  }
945

946
  if (bind->buffer_type != pColSchema->type) {
6!
947
    return buildInvalidOperationMsg(&pBuf, "column type mis-match with buffer type");
×
948
  }
949

950
  if (TSDB_DATA_TYPE_NCHAR == pColSchema->type) {
6!
951
    code = convertStmtNcharCol2(&pBuf, pColSchema, bind, &ncharBind, charsetCxt);
×
952
    if (code) {
×
953
      goto _return;
×
954
    }
955
    pBind = &ncharBind;
×
956
  } else {
957
    pBind = bind;
6✔
958
  }
959

960
  code = tColDataAddValueByBind2(pCol, pBind,
6✔
961
                                 IS_VAR_DATA_TYPE(pColSchema->type) ? pColSchema->bytes - VARSTR_HEADER_SIZE : -1,
6!
962
                                 initCtxAsText, checkWKB);
963

964
  parserDebug("stmt col %d bind %d rows data", colIdx, rowNum);
6!
965

966
_return:
6✔
967

968
  taosMemoryFree(ncharBind.buffer);
6!
969
  taosMemoryFree(ncharBind.length);
6!
970

971
  return code;
6✔
972
}
973

974
int32_t qBindStmt2RowValue(void* pBlock, SArray* pCols, TAOS_STMT2_BIND* bind, char* msgBuf, int32_t msgBufLen,
2✔
975
                            STSchema** pTSchema, SBindInfo2* pBindInfos, void* charsetCxt) {
976
  STableDataCxt*   pDataBlock = (STableDataCxt*)pBlock;
2✔
977
  SSchema*         pSchema = getTableColumnSchema(pDataBlock->pMeta);
2✔
978
  SBoundColInfo*   boundInfo = &pDataBlock->boundColsInfo;
2✔
979
  SMsgBuf          pBuf = {.buf = msgBuf, .len = msgBufLen};
2✔
980
  int32_t          rowNum = bind->num;
2✔
981
  TAOS_STMT2_BIND  ncharBind = {0};
2✔
982
  TAOS_STMT2_BIND* pBind = NULL;
2✔
983
  int32_t          code = 0;
2✔
984
  int16_t          lastColId = -1;
2✔
985
  bool             colInOrder = true;
2✔
986

987
  if (NULL == pTSchema || NULL == *pTSchema) {
2!
988
    *pTSchema = tBuildTSchema(pSchema, pDataBlock->pMeta->tableInfo.numOfColumns, pDataBlock->pMeta->sversion);
1✔
989
  }
990

991
  for (int c = 0; c < boundInfo->numOfBound; ++c) {
24✔
992
    SSchema*  pColSchema = &pSchema[boundInfo->pColIndex[c]];
22✔
993
    if (pColSchema->colId <= lastColId) {
22!
994
      colInOrder = false;
×
995
    } else {
996
      lastColId = pColSchema->colId;
22✔
997
    }
998

999
    if (bind[c].num != rowNum) {
22!
1000
      code = buildInvalidOperationMsg(&pBuf, "row number in each bind param should be the same");
×
1001
      goto _return;
×
1002
    }
1003

1004
    if ((!(rowNum == 1 && bind[c].is_null && *bind[c].is_null)) &&
22!
1005
        bind[c].buffer_type != pColSchema->type) {  // for rowNum ==1 , connector may not set buffer_type
22!
1006
      code = buildInvalidOperationMsg(&pBuf, "column type mis-match with buffer type");
×
1007
      goto _return;
×
1008
    }
1009

1010
    if (TSDB_DATA_TYPE_NCHAR == pColSchema->type) {
22✔
1011
      code = convertStmtNcharCol2(&pBuf, pColSchema, bind + c, &ncharBind, charsetCxt);
2✔
1012
      if (code) {
2!
1013
        goto _return;
×
1014
      }
1015
      pBindInfos[c].bind = &ncharBind;
2✔
1016
    } else if (TSDB_DATA_TYPE_GEOMETRY == pColSchema->type) {
20✔
1017
      code = initCtxAsText();
2✔
1018
      if (code) {
2!
1019
        qError("geometry init failed:%s", tstrerror(code));
×
1020
        goto _return;
×
1021
      }
1022
      uint8_t *buf = bind[c].buffer;
2✔
1023
      for (int j = 0; j < bind[c].num; j++) {
4✔
1024
        if (bind[c].is_null && bind[c].is_null[j]) {
2!
1025
          continue;
×
1026
        }
1027
        code = checkWKB(buf, bind[c].length[j]);
2✔
1028
        if (code) {
2!
1029
          qError("stmt2 row bind geometry data[%d]:{%s},length:%d must be in WKB format", c, buf, bind[c].length[j]);
×
1030
          goto _return;
×
1031
        }
1032
        buf += bind[c].length[j];
2✔
1033
      }
1034
      pBindInfos[c].bind = bind + c;
2✔
1035
    } else {
1036
      pBindInfos[c].bind = bind + c;
18✔
1037
    }
1038

1039
    pBindInfos[c].columnId = pColSchema->colId;
22✔
1040
    pBindInfos[c].type = pColSchema->type;
22✔
1041
    pBindInfos[c].bytes = pColSchema->bytes;
22✔
1042

1043
    if (code) {
22!
1044
      goto _return;
×
1045
    }
1046
  }
1047

1048
  pDataBlock->pData->flags &= ~SUBMIT_REQ_COLUMN_DATA_FORMAT;
2✔
1049
  if (pDataBlock->pData->pCreateTbReq != NULL) {
2!
1050
    pDataBlock->pData->flags |= SUBMIT_REQ_AUTO_CREATE_TABLE;
2✔
1051
  }
1052

1053
  code = tRowBuildFromBind2(pBindInfos, boundInfo->numOfBound, colInOrder, *pTSchema, pCols, &pDataBlock->ordered,
2✔
1054
                            &pDataBlock->duplicateTs);
1055
  qDebug("stmt2 all %d columns bind %d rows data as row format", boundInfo->numOfBound, rowNum);
2!
1056

1057
_return:
2✔
1058

1059
  taosMemoryFree(ncharBind.buffer);
2!
1060
  taosMemoryFree(ncharBind.length);
2!
1061

1062
  return code;
2✔
1063
}
1064

1065
int32_t buildBoundFields(int32_t numOfBound, int16_t* boundColumns, SSchema* pSchema, int32_t* fieldNum,
7✔
1066
                         TAOS_FIELD_E** fields, uint8_t timePrec) {
1067
  if (fields != NULL) {
7✔
1068
    *fields = taosMemoryCalloc(numOfBound, sizeof(TAOS_FIELD_E));
6!
1069
    if (NULL == *fields) {
6!
1070
      return terrno;
×
1071
    }
1072

1073
    SSchema* schema = &pSchema[boundColumns[0]];
6✔
1074
    if (TSDB_DATA_TYPE_TIMESTAMP == schema->type) {
6✔
1075
      (*fields)[0].precision = timePrec;
5✔
1076
    }
1077

1078
    for (int32_t i = 0; i < numOfBound; ++i) {
28✔
1079
      schema = &pSchema[boundColumns[i]];
22✔
1080
      tstrncpy((*fields)[i].name, schema->name, 65);
22✔
1081
      (*fields)[i].type = schema->type;
22✔
1082
      (*fields)[i].bytes = calcTypeBytesFromSchemaBytes(schema->type, schema->bytes, true);
22✔
1083
    }
1084
  }
1085

1086
  *fieldNum = numOfBound;
7✔
1087

1088
  return TSDB_CODE_SUCCESS;
7✔
1089
}
1090

1091
int32_t buildStbBoundFields(SBoundColInfo boundColsInfo, SSchema* pSchema, int32_t* fieldNum, TAOS_FIELD_ALL** fields,
32✔
1092
                            STableMeta* pMeta, void* boundTags, uint8_t tbNameFlag) {
1093
  SBoundColInfo* tags = (SBoundColInfo*)boundTags;
32✔
1094
  bool           hastag = (tags != NULL) && !(tbNameFlag & IS_FIXED_TAG);
32!
1095
  bool           hasPreBindTbname =
32✔
1096
      (tbNameFlag & IS_FIXED_VALUE) == 0 && ((tbNameFlag & USING_CLAUSE) != 0 || pMeta->tableType == TSDB_NORMAL_TABLE);
32!
1097
  int32_t numOfBound = boundColsInfo.numOfBound + (hasPreBindTbname ? 1 : 0);
32✔
1098
  if (hastag) {
32✔
1099
    numOfBound += tags->mixTagsCols ? 0 : tags->numOfBound;
23✔
1100
  }
1101
  int32_t idx = 0;
32✔
1102
  if (fields != NULL) {
32!
1103
    *fields = taosMemoryCalloc(numOfBound, sizeof(TAOS_FIELD_ALL));
32!
1104
    if (NULL == *fields) {
32!
1105
      return terrno;
×
1106
    }
1107

1108
    if (hasPreBindTbname) {
32✔
1109
      (*fields)[idx].field_type = TAOS_FIELD_TBNAME;
17✔
1110
      tstrncpy((*fields)[idx].name, "tbname", sizeof((*fields)[idx].name));
17✔
1111
      (*fields)[idx].type = TSDB_DATA_TYPE_BINARY;
17✔
1112
      (*fields)[idx].bytes = TSDB_TABLE_FNAME_LEN;
17✔
1113
      idx++;
17✔
1114
    }
1115

1116
    if (hastag && tags->numOfBound > 0 && !tags->mixTagsCols) {
32✔
1117
      SSchema* tagSchema = getTableTagSchema(pMeta);
9✔
1118

1119
      for (int32_t i = 0; i < tags->numOfBound; ++i) {
40✔
1120
        (*fields)[idx].field_type = TAOS_FIELD_TAG;
31✔
1121

1122
        SSchema* schema = &tagSchema[tags->pColIndex[i]];
31✔
1123
        tstrncpy((*fields)[idx].name, schema->name, sizeof((*fields)[i].name));
31✔
1124
        (*fields)[idx].type = schema->type;
31✔
1125
        (*fields)[idx].bytes = schema->bytes;
31✔
1126
        if (TSDB_DATA_TYPE_TIMESTAMP == schema->type) {
31✔
1127
          (*fields)[idx].precision = pMeta->tableInfo.precision;
1✔
1128
        }
1129
        idx++;
31✔
1130
      }
1131
    }
1132

1133
    if (boundColsInfo.numOfBound > 0) {
32!
1134
      SSchema* schema = &pSchema[boundColsInfo.pColIndex[0]];
32✔
1135

1136
      for (int32_t i = 0; i < boundColsInfo.numOfBound; ++i) {
164✔
1137
        int16_t idxCol = boundColsInfo.pColIndex[i];
132✔
1138

1139
        if (idxCol == pMeta->tableInfo.numOfColumns + pMeta->tableInfo.numOfTags) {
132✔
1140
          (*fields)[idx].field_type = TAOS_FIELD_TBNAME;
8✔
1141
          tstrncpy((*fields)[i].name, "tbname", sizeof((*fields)[idx].name));
8✔
1142
          (*fields)[idx].type = TSDB_DATA_TYPE_BINARY;
8✔
1143
          (*fields)[idx].bytes = TSDB_TABLE_FNAME_LEN;
8✔
1144

1145
          idx++;
8✔
1146
          continue;
8✔
1147
        } else if (idxCol < pMeta->tableInfo.numOfColumns) {
124✔
1148
          (*fields)[idx].field_type = TAOS_FIELD_COL;
98✔
1149
        } else {
1150
          (*fields)[idx].field_type = TAOS_FIELD_TAG;
26✔
1151
        }
1152

1153
        schema = &pSchema[idxCol];
124✔
1154
        tstrncpy((*fields)[idx].name, schema->name, sizeof((*fields)[idx].name));
124✔
1155
        (*fields)[idx].type = schema->type;
124✔
1156
        (*fields)[idx].bytes = schema->bytes;
124✔
1157
        if (TSDB_DATA_TYPE_TIMESTAMP == schema->type) {
124✔
1158
          (*fields)[idx].precision = pMeta->tableInfo.precision;
33✔
1159
        }
1160
        idx++;
124✔
1161
      }
1162
    }
1163
  }
1164

1165
  *fieldNum = numOfBound;
32✔
1166

1167
  return TSDB_CODE_SUCCESS;
32✔
1168
}
1169

1170
int32_t qBuildStmtTagFields(void* pBlock, void* boundTags, int32_t* fieldNum, TAOS_FIELD_E** fields) {
1✔
1171
  STableDataCxt* pDataBlock = (STableDataCxt*)pBlock;
1✔
1172
  SBoundColInfo* tags = (SBoundColInfo*)boundTags;
1✔
1173
  if (NULL == tags) {
1!
1174
    return TSDB_CODE_APP_ERROR;
×
1175
  }
1176

1177
  if (pDataBlock->pMeta->tableType != TSDB_SUPER_TABLE && pDataBlock->pMeta->tableType != TSDB_CHILD_TABLE) {
1!
1178
    return TSDB_CODE_TSC_STMT_API_ERROR;
×
1179
  }
1180

1181
  SSchema* pSchema = getTableTagSchema(pDataBlock->pMeta);
1✔
1182
  if (tags->numOfBound <= 0) {
1!
1183
    *fieldNum = 0;
×
1184
    *fields = NULL;
×
1185

1186
    return TSDB_CODE_SUCCESS;
×
1187
  }
1188

1189
  CHECK_CODE(buildBoundFields(tags->numOfBound, tags->pColIndex, pSchema, fieldNum, fields, 0));
1!
1190

1191
  return TSDB_CODE_SUCCESS;
1✔
1192
}
1193

1194
int32_t qBuildStmtColFields(void* pBlock, int32_t* fieldNum, TAOS_FIELD_E** fields) {
6✔
1195
  STableDataCxt* pDataBlock = (STableDataCxt*)pBlock;
6✔
1196
  SSchema*       pSchema = getTableColumnSchema(pDataBlock->pMeta);
6✔
1197
  if (pDataBlock->boundColsInfo.numOfBound <= 0) {
6!
1198
    *fieldNum = 0;
×
1199
    if (fields != NULL) {
×
1200
      *fields = NULL;
×
1201
    }
1202

1203
    return TSDB_CODE_SUCCESS;
×
1204
  }
1205

1206
  CHECK_CODE(buildBoundFields(pDataBlock->boundColsInfo.numOfBound, pDataBlock->boundColsInfo.pColIndex, pSchema,
6!
1207
                              fieldNum, fields, pDataBlock->pMeta->tableInfo.precision));
1208

1209
  return TSDB_CODE_SUCCESS;
6✔
1210
}
1211

1212
int32_t qBuildStmtStbColFields(void* pBlock, void* boundTags, uint8_t tbNameFlag, int32_t* fieldNum,
32✔
1213
                               TAOS_FIELD_ALL** fields) {
1214
  STableDataCxt* pDataBlock = (STableDataCxt*)pBlock;
32✔
1215
  SSchema*       pSchema = getTableColumnSchema(pDataBlock->pMeta);
32✔
1216
  if (pDataBlock->boundColsInfo.numOfBound <= 0) {
32!
1217
    *fieldNum = 0;
×
1218
    if (fields != NULL) {
×
1219
      *fields = NULL;
×
1220
    }
1221

1222
    return TSDB_CODE_SUCCESS;
×
1223
  }
1224

1225
  CHECK_CODE(buildStbBoundFields(pDataBlock->boundColsInfo, pSchema, fieldNum, fields, pDataBlock->pMeta, boundTags,
32!
1226
                                 tbNameFlag));
1227

1228
  return TSDB_CODE_SUCCESS;
32✔
1229
}
1230

1231
int32_t qResetStmtColumns(SArray* pCols, bool deepClear) {
×
1232
  int32_t colNum = taosArrayGetSize(pCols);
×
1233

1234
  for (int32_t i = 0; i < colNum; ++i) {
×
1235
    SColData* pCol = (SColData*)taosArrayGet(pCols, i);
×
1236
    if (pCol == NULL) {
×
1237
      parserError("qResetStmtColumns column:%d is NULL", i);
×
1238
      return terrno;
×
1239
    }
1240
    if (deepClear) {
×
1241
      tColDataDeepClear(pCol);
×
1242
    } else {
1243
      tColDataClear(pCol);
×
1244
    }
1245
  }
1246

1247
  return TSDB_CODE_SUCCESS;
×
1248
}
1249

1250
int32_t qResetStmtDataBlock(STableDataCxt* block, bool deepClear) {
96✔
1251
  STableDataCxt* pBlock = (STableDataCxt*)block;
96✔
1252
  int32_t        colNum = taosArrayGetSize(pBlock->pData->aCol);
96✔
1253

1254
  for (int32_t i = 0; i < colNum; ++i) {
384✔
1255
    if (pBlock->pData->flags & SUBMIT_REQ_COLUMN_DATA_FORMAT) {
288✔
1256
      SColData* pCol = (SColData*)taosArrayGet(pBlock->pData->aCol, i);
287✔
1257
      if (pCol == NULL) {
287!
1258
        parserError("qResetStmtDataBlock column:%d is NULL", i);
×
1259
        return terrno;
×
1260
      }
1261
      if (deepClear) {
287✔
1262
        tColDataDeepClear(pCol);
100✔
1263
      } else {
1264
        tColDataClear(pCol);
187✔
1265
      }
1266
    } else {
1267
      pBlock->pData->aRowP = taosArrayInit(20, POINTER_BYTES);
1✔
1268
    }
1269
  }
1270

1271
  return TSDB_CODE_SUCCESS;
96✔
1272
}
1273

1274
int32_t qCloneStmtDataBlock(STableDataCxt** pDst, STableDataCxt* pSrc, bool reset) {
113✔
1275
  int32_t code = 0;
113✔
1276

1277
  *pDst = taosMemoryCalloc(1, sizeof(STableDataCxt));
113!
1278
  if (NULL == *pDst) {
113!
1279
    return terrno;
×
1280
  }
1281

1282
  STableDataCxt* pNewCxt = (STableDataCxt*)*pDst;
113✔
1283
  STableDataCxt* pCxt = (STableDataCxt*)pSrc;
113✔
1284
  pNewCxt->pSchema = NULL;
113✔
1285
  pNewCxt->pValues = NULL;
113✔
1286

1287
  if (pCxt->pMeta) {
113!
1288
    void* pNewMeta = taosMemoryMalloc(TABLE_META_SIZE(pCxt->pMeta));
113!
1289
    if (NULL == pNewMeta) {
113!
1290
      insDestroyTableDataCxt(*pDst);
×
1291
      return terrno;
×
1292
    }
1293
    memcpy(pNewMeta, pCxt->pMeta, TABLE_META_SIZE(pCxt->pMeta));
113!
1294
    pNewCxt->pMeta = pNewMeta;
113✔
1295
  }
1296

1297
  memcpy(&pNewCxt->boundColsInfo, &pCxt->boundColsInfo, sizeof(pCxt->boundColsInfo));
113✔
1298
  pNewCxt->boundColsInfo.pColIndex = NULL;
113✔
1299

1300
  if (pCxt->boundColsInfo.pColIndex) {
113!
1301
    void* pNewColIdx = taosMemoryMalloc(pCxt->boundColsInfo.numOfBound * sizeof(*pCxt->boundColsInfo.pColIndex));
113!
1302
    if (NULL == pNewColIdx) {
113!
1303
      insDestroyTableDataCxt(*pDst);
×
1304
      return terrno;
×
1305
    }
1306
    memcpy(pNewColIdx, pCxt->boundColsInfo.pColIndex,
113✔
1307
           pCxt->boundColsInfo.numOfBound * sizeof(*pCxt->boundColsInfo.pColIndex));
113✔
1308
    pNewCxt->boundColsInfo.pColIndex = pNewColIdx;
113✔
1309
  }
1310

1311
  if (pCxt->pData) {
113!
1312
    SSubmitTbData* pNewTb = (SSubmitTbData*)taosMemoryMalloc(sizeof(SSubmitTbData));
113!
1313
    if (NULL == pNewTb) {
113!
1314
      insDestroyTableDataCxt(*pDst);
×
1315
      return terrno;
×
1316
    }
1317

1318
    memcpy(pNewTb, pCxt->pData, sizeof(*pCxt->pData));
113✔
1319
    pNewTb->pCreateTbReq = NULL;
113✔
1320

1321
    pNewTb->aCol = taosArrayDup(pCxt->pData->aCol, NULL);
113✔
1322
    if (NULL == pNewTb->aCol) {
113!
1323
      insDestroyTableDataCxt(*pDst);
×
1324
      return terrno;
×
1325
    }
1326

1327
    pNewCxt->pData = pNewTb;
113✔
1328

1329
    if (reset) {
113✔
1330
      code = qResetStmtDataBlock(*pDst, true);
33✔
1331
    }
1332
  }
1333

1334
  return code;
113✔
1335
}
1336

1337
int32_t qRebuildStmtDataBlock(STableDataCxt** pDst, STableDataCxt* pSrc, uint64_t uid, uint64_t suid, int32_t vgId,
80✔
1338
                              bool rebuildCreateTb) {
1339
  int32_t code = qCloneStmtDataBlock(pDst, pSrc, false);
80✔
1340
  if (code) {
80!
1341
    return code;
×
1342
  }
1343

1344
  STableDataCxt* pBlock = (STableDataCxt*)*pDst;
80✔
1345
  if (pBlock->pMeta) {
80!
1346
    pBlock->pMeta->uid = uid;
80✔
1347
    pBlock->pMeta->vgId = vgId;
80✔
1348
    pBlock->pMeta->suid = suid;
80✔
1349
  }
1350

1351
  pBlock->pData->suid = suid;
80✔
1352
  pBlock->pData->uid = uid;
80✔
1353

1354
  if (rebuildCreateTb && NULL == pBlock->pData->pCreateTbReq) {
80!
1355
    pBlock->pData->pCreateTbReq = taosMemoryCalloc(1, sizeof(SVCreateTbReq));
54!
1356
    if (NULL == pBlock->pData->pCreateTbReq) {
54!
1357
      return terrno;
×
1358
    }
1359
  }
1360

1361
  return TSDB_CODE_SUCCESS;
80✔
1362
}
1363

1364
STableMeta* qGetTableMetaInDataBlock(STableDataCxt* pDataBlock) { return ((STableDataCxt*)pDataBlock)->pMeta; }
174✔
1365

1366
void qDestroyStmtDataBlock(STableDataCxt* pBlock) {
256✔
1367
  if (pBlock == NULL) {
256✔
1368
    return;
81✔
1369
  }
1370

1371
  STableDataCxt* pDataBlock = (STableDataCxt*)pBlock;
175✔
1372
  insDestroyTableDataCxt(pDataBlock);
175✔
1373
}
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