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

taosdata / TDengine / #3827

01 Apr 2025 11:58AM UTC coverage: 34.049% (-0.03%) from 34.075%
#3827

push

travis-ci

happyguoxy
test:alter gcda dir

148461 of 599532 branches covered (24.76%)

Branch coverage included in aggregate %.

222339 of 489477 relevant lines covered (45.42%)

762087.13 hits per line

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

66.08
/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) {
232✔
34
  *pData = taosMemoryCalloc(1, sizeof(SSubmitTbData));
232!
35
  if (NULL == *pData) {
232!
36
    return terrno;
×
37
  }
38

39
  SSubmitTbData* pNew = *pData;
232✔
40

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

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

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

65
  return TSDB_CODE_SUCCESS;
232✔
66
}
67

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

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

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

82
  if (pStmt->freeArrayFunc) {
2,171✔
83
    pStmt->freeArrayFunc(pVgDataBlocks);
2,170✔
84
  }
85
  return code;
2,170✔
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) {
232✔
110
  int32_t             code = TSDB_CODE_SUCCESS;
232✔
111
  SArray*             pVgDataBlocks = NULL;
232✔
112
  SVnodeModifyOpStmt* pStmt = (SVnodeModifyOpStmt*)pQuery->pRoot;
232✔
113

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

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

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

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

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

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

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

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

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

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

183
      isJson = true;
10✔
184
      char* tmp = taosMemoryCalloc(1, colLen + 1);
10!
185
      if (!tmp) {
10!
186
        code = terrno;
×
187
        goto end;
×
188
      }
189
      memcpy(tmp, bind[c].buffer, colLen);
10✔
190
      code = parseJsontoTagData(tmp, pTagArray, &pTag, &pBuf, charsetCxt);
10✔
191
      taosMemoryFree(tmp);
10!
192
      if (code != TSDB_CODE_SUCCESS) {
10!
193
        goto end;
×
194
      }
195
    } else {
196
      STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type};
217✔
197
      //      strcpy(val.colName, pTagSchema->name);
198
      if (pTagSchema->type == TSDB_DATA_TYPE_BINARY || pTagSchema->type == TSDB_DATA_TYPE_VARBINARY ||
217✔
199
          pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) {
128✔
200
        if (pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) {
100✔
201
          code = initCtxAsText();
11✔
202
          if (code) {
11!
203
            qError("geometry init failed:%s", tstrerror(code));
×
204
            goto end;
×
205
          }
206
          code = checkWKB(bind[c].buffer, colLen);
11✔
207
          if (code) {
11!
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;
100✔
213
        val.nData = colLen;
100✔
214
      } else if (pTagSchema->type == TSDB_DATA_TYPE_NCHAR) {
117✔
215
        int32_t output = 0;
11✔
216
        void*   p = taosMemoryCalloc(1, colLen * TSDB_NCHAR_SIZE);
11!
217
        if (p == NULL) {
11!
218
          code = terrno;
×
219
          goto end;
×
220
        }
221
        if (!taosMbsToUcs4(bind[c].buffer, colLen, (TdUcs4*)(p), colLen * TSDB_NCHAR_SIZE, &output, charsetCxt)) {
11!
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;
11✔
234
        val.nData = output;
11✔
235
      } else {
236
        memcpy(&val.i64, bind[c].buffer, colLen);
106✔
237
      }
238
      if (IS_VAR_DATA_TYPE(pTagSchema->type) && val.nData > pTagSchema->bytes) {
217!
239
        code = TSDB_CODE_PAR_VALUE_TOO_LONG;
×
240
        goto end;
×
241
      }
242
      if (NULL == taosArrayPush(pTagArray, &val)) {
217!
243
        code = terrno;
×
244
        goto end;
×
245
      }
246
    }
247
  }
248

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

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

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

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

276
  return code;
89✔
277
}
278

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

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

297
  dst->buffer_length = pSchema->bytes - VARSTR_HEADER_SIZE;
986,327✔
298

299
  for (int32_t i = 0; i < src->num; ++i) {
1,982,953✔
300
    if (src->is_null && src->is_null[i]) {
986,157✔
301
      continue;
50,464✔
302
    }
303

304
    if (!taosMbsToUcs4(((char*)src->buffer) + src->buffer_length * i, src->length[i],
947,914✔
305
                       (TdUcs4*)(((char*)dst->buffer) + dst->buffer_length * i), dst->buffer_length, &output, charsetCxt)) {
935,693✔
306
      if (terrno == TAOS_SYSTEM_ERROR(E2BIG)) {
1,752!
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;
946,162✔
315
  }
316

317
  dst->buffer_type = src->buffer_type;
996,796✔
318
  dst->is_null = src->is_null;
996,796✔
319
  dst->num = src->num;
996,796✔
320

321
  return TSDB_CODE_SUCCESS;
996,796✔
322
}
323

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

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

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

350
    if (bind[c].num != rowNum) {
133,778!
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)) &&
133,778✔
356
        bind[c].buffer_type != pColSchema->type) {  // for rowNum ==1 , connector may not set buffer_type
133,761!
357
      code = buildInvalidOperationMsg(&pBuf, "column type mis-match with buffer type");
×
358
      goto _return;
×
359
    }
360

361
    if (TSDB_DATA_TYPE_NCHAR == pColSchema->type) {
133,778!
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;
133,778✔
369
    }
370

371
    pBindInfos[c].columnId = pColSchema->colId;
133,778✔
372
    pBindInfos[c].bind = pBind;
133,778✔
373
    pBindInfos[c].type = pColSchema->type;
133,778✔
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);
33,994✔
382

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

385
_return:
34,014✔
386

387
  taosMemoryFree(ncharBind.buffer);
34,014!
388
  taosMemoryFree(ncharBind.length);
34,023!
389

390
  return code;
34,008✔
391
}
392

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

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

407
    if (bind[c].num != rowNum) {
10,218,147!
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)) &&
10,637,447✔
413
        bind[c].buffer_type != pColSchema->type) {  // for rowNum ==1 , connector may not set buffer_type
10,045,193!
414
      code = buildInvalidOperationMsg(&pBuf, "column type mis-match with buffer type");
×
415
      goto _return;
×
416
    }
417

418
    if (TSDB_DATA_TYPE_NCHAR == pColSchema->type) {
10,637,447✔
419
      code = convertStmtNcharCol(&pBuf, pColSchema, bind + c, &ncharBind, charsetCxt);
962,513✔
420
      if (code) {
966,277!
421
        goto _return;
×
422
      }
423
      pBind = &ncharBind;
966,277✔
424
    } else {
425
      pBind = bind + c;
9,674,934✔
426
    }
427

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

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

438
_return:
885,356✔
439

440
  taosMemoryFree(ncharBind.buffer);
885,357!
441
  taosMemoryFree(ncharBind.length);
973,451!
442

443
  return code;
985,979✔
444
}
445

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

458
  if (bind->num != rowNum) {
140!
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) {
140!
464
    return buildInvalidOperationMsg(&pBuf, "column index exceeds the number of columns");
×
465
  }
466

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

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

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

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

487
_return:
140✔
488

489
  taosMemoryFree(ncharBind.buffer);
140!
490
  taosMemoryFree(ncharBind.length);
140!
491

492
  return code;
140✔
493
}
494

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

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

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

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

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

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

530
    SSchema* pTagSchema = &pSchema[tags->pColIndex[c]];
282✔
531
    int32_t  colLen = pTagSchema->bytes;
282✔
532
    if (IS_VAR_DATA_TYPE(pTagSchema->type)) {
282!
533
      if (!bind[c].length) {
122!
534
        code = buildInvalidOperationMsg(&pBuf, "var tag length is null");
×
535
        goto end;
×
536
      }
537
      colLen = bind[c].length[0];
122✔
538
      if ((colLen + VARSTR_HEADER_SIZE) > pTagSchema->bytes) {
122!
539
        code = buildInvalidOperationMsg(&pBuf, "tag length is too big");
×
540
        goto end;
×
541
      }
542
    }
543
    if (NULL == taosArrayPush(tagName, pTagSchema->name)) {
564!
544
      code = terrno;
×
545
      goto end;
×
546
    }
547
    if (pTagSchema->type == TSDB_DATA_TYPE_JSON) {
282!
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};
282✔
567
      //      strcpy(val.colName, pTagSchema->name);
568
      if (pTagSchema->type == TSDB_DATA_TYPE_BINARY || pTagSchema->type == TSDB_DATA_TYPE_VARBINARY ||
282!
569
          pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) {
171✔
570
        if (pTagSchema->type == TSDB_DATA_TYPE_GEOMETRY) {
118✔
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;
117✔
583
        val.nData = colLen;
117✔
584
      } else if (pTagSchema->type == TSDB_DATA_TYPE_NCHAR) {
164✔
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);
160✔
607
      }
608
      if (IS_VAR_DATA_TYPE(pTagSchema->type) && val.nData > pTagSchema->bytes) {
281!
609
        code = TSDB_CODE_PAR_VALUE_TOO_LONG;
×
610
        goto end;
×
611
      }
612
      if (NULL == taosArrayPush(pTagArray, &val)) {
281!
613
        code = terrno;
×
614
        goto end;
×
615
      }
616
    }
617
  }
618

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

623
  if (pCreateTbReq){
131✔
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) {
94✔
631
    pDataBlock->pData->pCreateTbReq = taosMemoryCalloc(1, sizeof(SVCreateTbReq));
9!
632
    if (NULL == pDataBlock->pData->pCreateTbReq) {
9!
633
      code = terrno;
×
634
      goto end;
×
635
    }
636
  } else {
637
    SVCreateTbReq* tmp = pDataBlock->pData->pCreateTbReq;
85✔
638
    taosMemoryFreeClear(tmp->name);
85!
639
    taosMemoryFreeClear(tmp->ctb.pTag);
85!
640
    taosMemoryFreeClear(tmp->ctb.stbName);
85!
641
    taosArrayDestroy(tmp->ctb.tagName);
85✔
642
    tmp->ctb.tagName = NULL;
85✔
643
  }
644

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

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

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

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

724
  for (int c = 0; c < boundInfo->numOfBound; ++c) {
2,696✔
725
    if (TSDB_DATA_TYPE_NCHAR == pSchema[boundInfo->pColIndex[c]].type) {
2,127✔
726
      ncharColNums++;
5✔
727
    }
728
  }
729
  if (ncharColNums > 0) {
569✔
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) {
2,696✔
738
    SSchema* pColSchema = &pSchema[boundInfo->pColIndex[c]];
2,127✔
739
    if (pColSchema->colId <= lastColId) {
2,127✔
740
      colInOrder = false;
1✔
741
    } else {
742
      lastColId = pColSchema->colId;
2,126✔
743
    }
744

745
    if (bind[c].num != rowNum) {
2,127!
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)) &&
2,127!
751
        bind[c].buffer_type != pColSchema->type) {  // for rowNum ==1 , connector may not set buffer_type
2,127!
752
      code = buildInvalidOperationMsg(&pBuf, "column type mis-match with buffer type");
×
753
      goto _return;
×
754
    }
755

756
    if (TSDB_DATA_TYPE_NCHAR == pColSchema->type) {
2,127✔
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) {
2,122✔
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;
2,121✔
788
    }
789

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

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

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

799
_return:
567✔
800
  if (ncharBinds) {
567✔
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;
568✔
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,
119✔
864
                            void* charsetCxt) {
865
  STableDataCxt*   pDataBlock = (STableDataCxt*)pBlock;
119✔
866
  SSchema*         pSchema = getTableColumnSchema(pDataBlock->pMeta);
119✔
867
  SBoundColInfo*   boundInfo = &pDataBlock->boundColsInfo;
119✔
868
  SMsgBuf          pBuf = {.buf = msgBuf, .len = msgBufLen};
119✔
869
  int32_t          rowNum = bind->num;
119✔
870
  TAOS_STMT2_BIND  ncharBind = {0};
119✔
871
  TAOS_STMT2_BIND* pBind = NULL;
119✔
872
  int32_t          code = 0;
119✔
873

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

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

886
    if (bind[c].num != rowNum) {
287!
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)) &&
287!
892
        bind[c].buffer_type != pColSchema->type) {  // for rowNum ==1 , connector may not set buffer_type
287!
893
      code = buildInvalidOperationMsg(&pBuf, "column type mis-match with buffer type");
×
894
      goto _return;
×
895
    }
896

897
    if (TSDB_DATA_TYPE_NCHAR == pColSchema->type) {
287✔
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;
286✔
905
    }
906

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

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

917
_return:
119✔
918

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

922
  return code;
119✔
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,
117✔
1066
                         TAOS_FIELD_E** fields, uint8_t timePrec) {
1067
  if (fields != NULL) {
117✔
1068
    *fields = taosMemoryCalloc(numOfBound, sizeof(TAOS_FIELD_E));
116!
1069
    if (NULL == *fields) {
116!
1070
      return terrno;
×
1071
    }
1072

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

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

1086
  *fieldNum = numOfBound;
117✔
1087

1088
  return TSDB_CODE_SUCCESS;
117✔
1089
}
1090

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

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

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

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

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

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

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

1139
        if (idxCol == pMeta->tableInfo.numOfColumns + pMeta->tableInfo.numOfTags) {
136✔
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) {
128✔
1148
          (*fields)[idx].field_type = TAOS_FIELD_COL;
102✔
1149
        } else {
1150
          (*fields)[idx].field_type = TAOS_FIELD_TAG;
26✔
1151
        }
1152

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

1165
  *fieldNum = numOfBound;
33✔
1166

1167
  return TSDB_CODE_SUCCESS;
33✔
1168
}
1169

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

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

1181
  SSchema* pSchema = getTableTagSchema(pDataBlock->pMeta);
11✔
1182
  if (tags->numOfBound <= 0) {
11!
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));
11!
1190

1191
  return TSDB_CODE_SUCCESS;
11✔
1192
}
1193

1194
int32_t qBuildStmtColFields(void* pBlock, int32_t* fieldNum, TAOS_FIELD_E** fields) {
106✔
1195
  STableDataCxt* pDataBlock = (STableDataCxt*)pBlock;
106✔
1196
  SSchema*       pSchema = getTableColumnSchema(pDataBlock->pMeta);
106✔
1197
  if (pDataBlock->boundColsInfo.numOfBound <= 0) {
106!
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,
106!
1207
                              fieldNum, fields, pDataBlock->pMeta->tableInfo.precision));
1208

1209
  return TSDB_CODE_SUCCESS;
106✔
1210
}
1211

1212
int32_t qBuildStmtStbColFields(void* pBlock, void* boundTags, uint8_t tbNameFlag, int32_t* fieldNum,
33✔
1213
                               TAOS_FIELD_ALL** fields) {
1214
  STableDataCxt* pDataBlock = (STableDataCxt*)pBlock;
33✔
1215
  SSchema*       pSchema = getTableColumnSchema(pDataBlock->pMeta);
33✔
1216
  if (pDataBlock->boundColsInfo.numOfBound <= 0) {
33!
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,
33!
1226
                                 tbNameFlag));
1227

1228
  return TSDB_CODE_SUCCESS;
33✔
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) {
289✔
1251
  STableDataCxt* pBlock = (STableDataCxt*)block;
289✔
1252
  int32_t        colNum = taosArrayGetSize(pBlock->pData->aCol);
289✔
1253

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

1271
  return TSDB_CODE_SUCCESS;
289✔
1272
}
1273

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

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

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

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

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

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

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

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

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

1327
    pNewCxt->pData = pNewTb;
224✔
1328

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

1334
  return code;
223✔
1335
}
1336

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

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

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

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

1361
  return TSDB_CODE_SUCCESS;
166✔
1362
}
1363

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

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

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