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

taosdata / TDengine / #3535

23 Nov 2024 02:07AM UTC coverage: 60.85% (+0.03%) from 60.825%
#3535

push

travis-ci

web-flow
Merge pull request #28893 from taosdata/doc/internal

refact: rename taos lib name

120252 of 252737 branches covered (47.58%)

Branch coverage included in aggregate %.

201187 of 275508 relevant lines covered (73.02%)

15886166.19 hits per line

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

80.43
/source/libs/parser/src/parInsertSql.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 "parInsertUtil.h"
18
#include "parToken.h"
19
#include "scalar.h"
20
#include "tglobal.h"
21
#include "ttime.h"
22

23
typedef struct SInsertParseContext {
24
  SParseContext* pComCxt;
25
  SMsgBuf        msg;
26
  char           tmpTokenBuf[TSDB_MAX_BYTES_PER_ROW];
27
  SBoundColInfo  tags;  // for stmt
28
  bool           missCache;
29
  bool           usingDuplicateTable;
30
  bool           forceUpdate;
31
  bool           needTableTagVal;
32
  bool           needRequest;  // whether or not request server
33
  bool           isStmtBind;   // whether is stmt bind
34
} SInsertParseContext;
35

36
typedef int32_t (*_row_append_fn_t)(SMsgBuf* pMsgBuf, const void* value, int32_t len, void* param);
37

38
static uint8_t TRUE_VALUE = (uint8_t)TSDB_TRUE;
39
static uint8_t FALSE_VALUE = (uint8_t)TSDB_FALSE;
40

41
static FORCE_INLINE bool isNullValue(int8_t dataType, SToken* pToken) {
42
  return TK_NULL == pToken->type ||
1,652,520,939✔
43
         (TK_NK_STRING == pToken->type && !IS_STR_DATA_TYPE(dataType) && IS_NULL_STR(pToken->z, pToken->n));
1,640,053,296!
44
}
45

46
static FORCE_INLINE int32_t toDouble(SToken* pToken, double* value, char** endPtr) {
47
  errno = 0;
48
  *value = taosStr2Double(pToken->z, endPtr);
49

50
  // not a valid integer number, return error
51
  if ((*endPtr - pToken->z) != pToken->n) {
52
    return TK_NK_ILLEGAL;
53
  }
54

55
  return pToken->type;
56
}
57

58
static int32_t skipInsertInto(const char** pSql, SMsgBuf* pMsg) {
9,578,696✔
59
  SToken token;
60
  NEXT_TOKEN(*pSql, token);
9,578,696✔
61
  if (TK_INSERT != token.type && TK_IMPORT != token.type) {
9,596,094!
62
    return buildSyntaxErrMsg(pMsg, "keyword INSERT is expected", token.z);
×
63
  }
64
  NEXT_TOKEN(*pSql, token);
9,596,094✔
65
  if (TK_INTO != token.type) {
9,597,639!
66
    return buildSyntaxErrMsg(pMsg, "keyword INTO is expected", token.z);
×
67
  }
68
  return TSDB_CODE_SUCCESS;
9,598,464✔
69
}
70

71
static int32_t skipParentheses(SInsertParseContext* pCxt, const char** pSql) {
515,798✔
72
  SToken  token;
73
  int32_t expectRightParenthesis = 1;
515,798✔
74
  while (1) {
75
    NEXT_TOKEN(*pSql, token);
10,129,535✔
76
    if (TK_NK_LP == token.type) {
10,129,536!
77
      ++expectRightParenthesis;
×
78
    } else if (TK_NK_RP == token.type && 0 == --expectRightParenthesis) {
10,129,536!
79
      break;
515,799✔
80
    }
81
    if (0 == token.n) {
9,613,737!
82
      return buildSyntaxErrMsg(&pCxt->msg, ") expected", NULL);
×
83
    }
84
  }
85
  return TSDB_CODE_SUCCESS;
515,799✔
86
}
87

88
static int32_t skipTableOptions(SInsertParseContext* pCxt, const char** pSql) {
4✔
89
  do {
×
90
    int32_t index = 0;
4✔
91
    SToken  token;
92
    NEXT_TOKEN_KEEP_SQL(*pSql, token, index);
4✔
93
    if (TK_TTL == token.type || TK_COMMENT == token.type) {
4!
94
      *pSql += index;
×
95
      NEXT_TOKEN_WITH_PREV(*pSql, token);
×
96
    } else {
97
      break;
98
    }
99
  } while (1);
100
  return TSDB_CODE_SUCCESS;
4✔
101
}
102

103
// pSql -> stb_name [(tag1_name, ...)] TAGS (tag1_value, ...)
104
static int32_t ignoreUsingClause(SInsertParseContext* pCxt, const char** pSql) {
4✔
105
  int32_t code = TSDB_CODE_SUCCESS;
4✔
106
  SToken  token;
107
  NEXT_TOKEN(*pSql, token);
4✔
108

109
  NEXT_TOKEN(*pSql, token);
4✔
110
  if (TK_NK_LP == token.type) {
4✔
111
    code = skipParentheses(pCxt, pSql);
2✔
112
    if (TSDB_CODE_SUCCESS == code) {
2!
113
      NEXT_TOKEN(*pSql, token);
2✔
114
    }
115
  }
116

117
  // pSql -> TAGS (tag1_value, ...)
118
  if (TSDB_CODE_SUCCESS == code) {
4!
119
    if (TK_TAGS != token.type) {
4!
120
      code = buildSyntaxErrMsg(&pCxt->msg, "TAGS is expected", token.z);
×
121
    } else {
122
      NEXT_TOKEN(*pSql, token);
4✔
123
    }
124
  }
125
  if (TSDB_CODE_SUCCESS == code) {
4!
126
    if (TK_NK_LP != token.type) {
4!
127
      code = buildSyntaxErrMsg(&pCxt->msg, "( is expected", token.z);
×
128
    } else {
129
      code = skipParentheses(pCxt, pSql);
4✔
130
    }
131
  }
132

133
  if (TSDB_CODE_SUCCESS == code) {
4!
134
    code = skipTableOptions(pCxt, pSql);
4✔
135
  }
136

137
  return code;
4✔
138
}
139

140
static int32_t parseDuplicateUsingClause(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, bool* pDuplicate) {
59,649✔
141
  int32_t code = TSDB_CODE_SUCCESS;
59,649✔
142
  *pDuplicate = false;
59,649✔
143

144
  char tbFName[TSDB_TABLE_FNAME_LEN];
145
  code = tNameExtractFullName(&pStmt->targetTableName, tbFName);
59,649✔
146
  if (TSDB_CODE_SUCCESS != code) {
59,649!
147
    return code;
×
148
  }
149
  STableMeta** pMeta = taosHashGet(pStmt->pSubTableHashObj, tbFName, strlen(tbFName));
59,649✔
150
  if (NULL != pMeta) {
59,649✔
151
    *pDuplicate = true;
4✔
152
    code = ignoreUsingClause(pCxt, &pStmt->pSql);
4✔
153
    if (TSDB_CODE_SUCCESS == code) {
4!
154
      return cloneTableMeta(*pMeta, &pStmt->pTableMeta);
4✔
155
    }
156
  }
157

158
  return code;
59,645✔
159
}
160

161
typedef enum { BOUND_TAGS, BOUND_COLUMNS, BOUND_ALL_AND_TBNAME } EBoundColumnsType;
162

163
static int32_t getTbnameSchemaIndex(STableMeta* pTableMeta) {
2,617,383✔
164
  return pTableMeta->tableInfo.numOfTags + pTableMeta->tableInfo.numOfColumns;
2,617,383✔
165
}
166

167
// pStmt->pSql -> field1_name, ...)
168
static int32_t parseBoundColumns(SInsertParseContext* pCxt, const char** pSql, EBoundColumnsType boundColsType,
516,408✔
169
                                 STableMeta* pTableMeta, SBoundColInfo* pBoundInfo) {
170
  SSchema* pSchema = NULL;
516,408✔
171
  if (boundColsType == BOUND_TAGS) {
516,408✔
172
    pSchema = getTableTagSchema(pTableMeta);
466✔
173
  } else if (boundColsType == BOUND_COLUMNS) {
515,942✔
174
    pSchema = getTableColumnSchema(pTableMeta);
505,385✔
175
  } else {
176
    pSchema = pTableMeta->schema;
10,557✔
177
    if (pBoundInfo->numOfCols != getTbnameSchemaIndex(pTableMeta) + 1) {
10,557!
178
      return TSDB_CODE_PAR_INTERNAL_ERROR;
×
179
    }
180
  }
181
  int32_t tbnameSchemaIndex = getTbnameSchemaIndex(pTableMeta);
516,407✔
182

183
  bool* pUseCols = taosMemoryCalloc(pBoundInfo->numOfCols, sizeof(bool));
516,407✔
184
  if (NULL == pUseCols) {
516,410!
185
    return terrno;
×
186
  }
187

188
  pBoundInfo->numOfBound = 0;
516,410✔
189
  pBoundInfo->hasBoundCols = true;
516,410✔
190

191
  bool    hasPK = pTableMeta->tableInfo.numOfPKs;
516,410✔
192
  int16_t numOfBoundPKs = 0;
516,410✔
193
  int16_t lastColIdx = -1;  // last column found
516,410✔
194
  int32_t code = TSDB_CODE_SUCCESS;
516,410✔
195
  while (TSDB_CODE_SUCCESS == code) {
10,132,847✔
196
    SToken token;
197
    NEXT_TOKEN(*pSql, token);
10,132,833✔
198

199
    if (TK_NK_RP == token.type) {
10,132,836✔
200
      break;
516,406✔
201
    }
202

203
    char tmpTokenBuf[TSDB_COL_NAME_LEN + 2] = {0};  // used for deleting Escape character backstick(`)
9,616,430✔
204
    strncpy(tmpTokenBuf, token.z, token.n);
9,616,430✔
205
    token.z = tmpTokenBuf;
9,616,430✔
206
    token.n = strdequote(token.z);
9,616,430✔
207

208
    if (boundColsType == BOUND_ALL_AND_TBNAME && token.n == strlen("tbname") && (strcasecmp(token.z, "tbname") == 0)) {
9,616,438✔
209
      pBoundInfo->pColIndex[pBoundInfo->numOfBound] = tbnameSchemaIndex;
10,556✔
210
      pUseCols[tbnameSchemaIndex] = true;
10,556✔
211
      ++pBoundInfo->numOfBound;
10,556✔
212
      continue;
10,556✔
213
    }
214
    int16_t t = lastColIdx + 1;
9,605,882✔
215
    int16_t end = (boundColsType == BOUND_ALL_AND_TBNAME) ? (pBoundInfo->numOfCols - 1) : pBoundInfo->numOfCols;
9,605,882✔
216
    int16_t index = insFindCol(&token, t, end, pSchema);
9,605,882✔
217
    if (index < 0 && t > 0) {
9,605,871!
218
      index = insFindCol(&token, 0, t, pSchema);
28,693✔
219
    }
220
    if (index < 0) {
9,605,877✔
221
      code = generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_INVALID_COLUMN, token.z);
4✔
222
    } else if (pUseCols[index]) {
9,605,873!
223
      code = buildSyntaxErrMsg(&pCxt->msg, "duplicated column name", token.z);
×
224
    } else {
225
      lastColIdx = index;
9,605,873✔
226
      pUseCols[index] = true;
9,605,873✔
227
      pBoundInfo->pColIndex[pBoundInfo->numOfBound] = index;
9,605,873✔
228
      ++pBoundInfo->numOfBound;
9,605,873✔
229
      if (hasPK && (pSchema[index].flags & COL_IS_KEY)) ++numOfBoundPKs;
9,605,873✔
230
    }
231
  }
232

233
  if (TSDB_CODE_SUCCESS == code && (BOUND_TAGS != boundColsType)) {
516,420✔
234
    if (!pUseCols[0]) {
515,941✔
235
      code = buildInvalidOperationMsg(&pCxt->msg, "Primary timestamp column should not be null");
23✔
236
    }
237
    if (numOfBoundPKs != pTableMeta->tableInfo.numOfPKs) {
515,941✔
238
      code = buildInvalidOperationMsg(&pCxt->msg, "Primary key column should not be none");
18✔
239
    }
240
  }
241
  if (TSDB_CODE_SUCCESS == code && (BOUND_ALL_AND_TBNAME == boundColsType) && !pUseCols[tbnameSchemaIndex]) {
516,420✔
242
    code = buildInvalidOperationMsg(&pCxt->msg, "tbname column should not be null");
1✔
243
  }
244
  taosMemoryFree(pUseCols);
516,420✔
245

246
  return code;
516,408✔
247
}
248

249
static int32_t parseTimestampOrInterval(const char** end, SToken* pToken, int16_t timePrec, int64_t* ts, int64_t* interval,
369,413,965✔
250
                                    SMsgBuf* pMsgBuf, bool* isTs) {
251
  if (pToken->type == TK_NOW) {
369,413,965✔
252
    *isTs = true;
23,167,958✔
253
    *ts = taosGetTimestamp(timePrec);
46,335,918✔
254
  } else if (pToken->type == TK_TODAY) {
346,246,007✔
255
    *isTs = true;
568✔
256
    *ts = taosGetTimestampToday(timePrec);
1,136✔
257
  } else if (pToken->type == TK_NK_INTEGER) {
346,245,439✔
258
    *isTs = true;
336,032,179✔
259
    if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, ts)) {
336,032,179✔
260
      return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
8✔
261
    }
262
  } else if (pToken->type == TK_NK_VARIABLE) {
10,213,260✔
263
    char unit = 0;
10,173,052✔
264
    *isTs = false;
10,173,052✔
265
    if (parseAbsoluteDuration(pToken->z, pToken->n, interval, &unit, timePrec) != TSDB_CODE_SUCCESS) {
10,173,052✔
266
      return TSDB_CODE_TSC_INVALID_OPERATION;
73✔
267
    }
268
  } else {  // parse the RFC-3339/ISO-8601 timestamp format string
269
    *isTs = true;
40,208✔
270
    if (taosParseTime(pToken->z, ts, pToken->n, timePrec, tsDaylight) != TSDB_CODE_SUCCESS) {
40,208!
271
      if ((pToken->n == 0) ||
2,106,454✔
272
          (pToken->type != TK_NK_STRING && pToken->type != TK_NK_HEX && pToken->type != TK_NK_BIN)) {
146,800✔
273
        return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
1,959,900✔
274
      }
275
      if (IS_NOW_STR(pToken->z, pToken->n)) {
146,554!
276
        *isTs = true;
73✔
277
        *ts = taosGetTimestamp(timePrec);
146!
278
      } else if (IS_TODAY_STR(pToken->z, pToken->n)) {
146,481!
279
        *isTs = true;
73✔
280
        *ts = taosGetTimestampToday(timePrec);
146!
281
      } else if (TSDB_CODE_SUCCESS == toIntegerPure(pToken->z, pToken->n, 10, ts)) {
146,408✔
282
        *isTs = true;
145,192✔
283
      } else {
284
        return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
1,216✔
285
      }
286
    }
287
  }
288

289
  return TSDB_CODE_SUCCESS;
369,215,496✔
290
}
291

292
static int parseTime(const char** end, SToken* pToken, int16_t timePrec, int64_t* time, SMsgBuf* pMsgBuf) {
359,525,527✔
293
  int32_t     index = 0, i = 0;
359,525,527✔
294
  int64_t     interval = 0, tempInterval = 0;
359,525,527✔
295
  int64_t     ts = 0, tempTs = 0;
359,525,527✔
296
  bool        firstIsTS = false, secondIsTs = false;
359,525,527✔
297
  const char* pTokenEnd = *end;
359,525,527✔
298

299
  if (TSDB_CODE_SUCCESS !=
359,209,901!
300
      parseTimestampOrInterval(&pTokenEnd, pToken, timePrec, &ts, &interval, pMsgBuf, &firstIsTS)) {
359,525,527✔
301
    return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
×
302
  }
303

304
  if (firstIsTS) {
360,148,305✔
305
    *time = ts;
359,609,462✔
306
  }
307

308
  for (int k = pToken->n; pToken->z[k] != '\0'; k++) {
360,672,768!
309
    if (pToken->z[k] == ' ' || pToken->z[k] == '\t') continue;
361,038,769!
310
    if (pToken->z[k] == '(') {  // for insert NOW()/TODAY()
360,547,653✔
311
      if (pToken->z[k + 1] == ')') {
33,347✔
312
        *end = pTokenEnd = &pToken->z[k + 2];
33,196✔
313
        ++k;
33,196✔
314
        continue;
33,196✔
315
      } else {
316
        char nc = pToken->z[k + 1];
151✔
317
        while (nc == ' ' || nc == '\t' || nc == '\n' || nc == '\r' || nc == '\f') {
302!
318
          nc = pToken->z[(++k) + 1];
151✔
319
        }
320
        if (nc == ')') {
151!
321
          *end = pTokenEnd = &pToken->z[k + 2];
151✔
322
          ++k;
151✔
323
          continue;
151✔
324
        }
325
      }
326
    }
327
    if (pToken->z[k] == ',') {
360,514,306✔
328
      *end = pTokenEnd;
333,403,890✔
329
      if (!firstIsTS) {
333,403,890!
330
        return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
×
331
      }
332
      *time = ts;
333,403,890✔
333
      return TSDB_CODE_SUCCESS;
333,403,890✔
334
    }
335
    break;
27,110,416✔
336
  }
337

338
  while (pTokenEnd[i] != '\0') {
26,805,975✔
339
    if (pTokenEnd[i] == ' ' || pTokenEnd[i] == '\t') {
25,993,977!
340
      i++;
61,560✔
341
      continue;
61,560✔
342
    } else if (pTokenEnd[i] == ',' || pTokenEnd[i] == ')') {
25,932,417✔
343
      *end = pTokenEnd + i;
15,758,728✔
344
      if (!firstIsTS) {
15,758,728!
345
        return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
×
346
      }
347
      *time = ts;
15,758,728✔
348
      return TSDB_CODE_SUCCESS;
15,758,728✔
349
    } else {
350
      break;
351
    }
352
  }
353
  pTokenEnd = pTokenEnd + i;
10,985,687✔
354

355
  index = 0;
10,985,687✔
356
  SToken token = tStrGetToken(pTokenEnd, &index, false, NULL);
10,985,687✔
357

358
  if (token.type == TK_NK_MINUS || token.type == TK_NK_PLUS) {
10,183,547✔
359
    pTokenEnd += index;
10,173,215✔
360
    index = 0;
10,173,215✔
361
    SToken valueToken = tStrGetToken(pTokenEnd, &index, false, NULL);
10,173,215✔
362
    pTokenEnd += index;
10,173,215✔
363
    char tmpTokenBuf[TSDB_MAX_BYTES_PER_ROW];
364
    if (TK_NK_STRING == valueToken.type) {
10,173,215✔
365
      if (valueToken.n >= TSDB_MAX_BYTES_PER_ROW) {
1!
366
        return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", valueToken.z);
10,173,139✔
367
      }
368
      int32_t len = trimString(valueToken.z, valueToken.n, tmpTokenBuf, TSDB_MAX_BYTES_PER_ROW);
1✔
369
      valueToken.z = tmpTokenBuf;
1✔
370
      valueToken.n = len;
1✔
371
    }
372

373
    if (TSDB_CODE_SUCCESS !=
10,173,215✔
374
        parseTimestampOrInterval(&pTokenEnd, &valueToken, timePrec, &tempTs, &tempInterval, pMsgBuf, &secondIsTs)) {
10,173,215✔
375
      return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
73✔
376
    }
377

378
    if (valueToken.n < 2) {
10,173,142✔
379
      return buildSyntaxErrMsg(pMsgBuf, "value expected in timestamp", token.z);
154✔
380
    }
381

382
    if (secondIsTs) {
10,172,988✔
383
      // not support operator between tow timestamp, such as today() + now()
384
      if (firstIsTS) {
15✔
385
        return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
11✔
386
      }
387
      ts = tempTs;
4✔
388
    } else {
389
      // not support operator between tow interval, such as 2h + 3s
390
      if (!firstIsTS) {
10,172,973✔
391
        return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
2✔
392
      }
393
      interval = tempInterval;
10,172,971✔
394
    }
395
    if (token.type == TK_NK_MINUS) {
10,172,975✔
396
      // not support interval - ts,such as 2h - today()
397
      if (secondIsTs) {
15,387✔
398
        return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
2✔
399
      }
400
      *time = ts - interval;
15,385✔
401
    } else {
402
      *time = ts + interval;
10,157,588✔
403
    }
404

405
    for (int k = valueToken.n; valueToken.z[k] != '\0'; k++) {
10,225,741✔
406
      if (valueToken.z[k] == ' ' || valueToken.z[k] == '\t') continue;
10,225,665!
407
      if (valueToken.z[k] == '(' && valueToken.z[k + 1] == ')') {  // for insert NOW()/TODAY()
10,172,897!
408
        *end = pTokenEnd = &valueToken.z[k + 2];
×
409
        k++;
×
410
        continue;
×
411
      }
412
      if (valueToken.z[k] == ',' || valueToken.z[k] == ')') {
10,172,897✔
413
        *end = pTokenEnd;
10,172,894✔
414
        return TSDB_CODE_SUCCESS;
10,172,894✔
415
      }
416
      return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z);
3✔
417
    }
418
  }
419

420
  *end = pTokenEnd;
10,408✔
421
  return TSDB_CODE_SUCCESS;
10,408✔
422
}
423

424
// need to call geosFreeBuffer(*output) later
425
static int parseGeometry(SToken* pToken, unsigned char** output, size_t* size) {
11,059✔
426
  int32_t code = TSDB_CODE_FAILED;
11,059✔
427

428
  //[ToDo] support to parse WKB as well as WKT
429
  if (pToken->type == TK_NK_STRING) {
11,059✔
430
    code = initCtxGeomFromText();
10,118✔
431
    if (code != TSDB_CODE_SUCCESS) {
10,118!
432
      return code;
×
433
    }
434

435
    code = doGeomFromText(pToken->z, output, size);
10,118✔
436
    if (code != TSDB_CODE_SUCCESS) {
10,118✔
437
      return code;
1,507✔
438
    }
439
  }
440

441
  return code;
9,552✔
442
}
443

444
static int32_t parseVarbinary(SToken* pToken, uint8_t** pData, uint32_t* nData, int32_t bytes) {
10,665,844✔
445
  if (pToken->type != TK_NK_STRING) {
10,665,844✔
446
    return TSDB_CODE_PAR_INVALID_VARBINARY;
959✔
447
  }
448

449
  if (isHex(pToken->z + 1, pToken->n - 2)) {
10,664,885✔
450
    if (!isValidateHex(pToken->z + 1, pToken->n - 2)) {
4,989✔
451
      return TSDB_CODE_PAR_INVALID_VARBINARY;
35✔
452
    }
453

454
    void*    data = NULL;
4,956✔
455
    uint32_t size = 0;
4,956✔
456
    if (taosHex2Ascii(pToken->z + 1, pToken->n - 2, &data, &size) < 0) {
4,956!
457
      return TSDB_CODE_OUT_OF_MEMORY;
×
458
    }
459

460
    if (size + VARSTR_HEADER_SIZE > bytes) {
4,956✔
461
      taosMemoryFree(data);
2✔
462
      return TSDB_CODE_PAR_VALUE_TOO_LONG;
2✔
463
    }
464
    *pData = data;
4,954✔
465
    *nData = size;
4,954✔
466
  } else {
467
    *pData = taosMemoryCalloc(1, pToken->n);
10,659,896✔
468
    if (!pData) return terrno;
10,659,896!
469
    int32_t len = trimString(pToken->z, pToken->n, *pData, pToken->n);
10,659,896✔
470
    *nData = len;
10,659,896✔
471

472
    if (*nData + VARSTR_HEADER_SIZE > bytes) {
10,659,896!
473
      return TSDB_CODE_PAR_VALUE_TOO_LONG;
×
474
    }
475
  }
476
  return TSDB_CODE_SUCCESS;
10,664,850✔
477
}
478

479
static int32_t parseTagToken(const char** end, SToken* pToken, SSchema* pSchema, int16_t timePrec, STagVal* val,
410,474✔
480
                             SMsgBuf* pMsgBuf) {
481
  int64_t  iv;
482
  uint64_t uv;
483
  char*    endptr = NULL;
410,474✔
484
  int32_t  code = TSDB_CODE_SUCCESS;
410,474✔
485

486
#if 0
487
  if (isNullValue(pSchema->type, pToken)) {
488
    if (TSDB_DATA_TYPE_TIMESTAMP == pSchema->type && PRIMARYKEY_TIMESTAMP_COL_ID == pSchema->colId) {
489
      return buildSyntaxErrMsg(pMsgBuf, "Primary timestamp column can not be null", pToken->z);
490
    }
491

492
    return TSDB_CODE_SUCCESS;
493
  }
494
#endif
495

496
  //  strcpy(val->colName, pSchema->name);
497
  val->cid = pSchema->colId;
410,474✔
498
  val->type = pSchema->type;
410,474✔
499

500
  switch (pSchema->type) {
410,474!
501
    case TSDB_DATA_TYPE_BOOL: {
20,937✔
502
      if ((pToken->type == TK_NK_BOOL || pToken->type == TK_NK_STRING) && (pToken->n != 0)) {
20,937✔
503
        if (IS_TRUE_STR(pToken->z, pToken->n)) {
12,902!
504
          *(int8_t*)(&val->i64) = TRUE_VALUE;
11,281✔
505
        } else if (IS_FALSE_STR(pToken->z, pToken->n)) {
1,621!
506
          *(int8_t*)(&val->i64) = FALSE_VALUE;
752✔
507
        } else if (TSDB_CODE_SUCCESS == toDoubleEx(pToken->z, pToken->n, pToken->type, (double*)&iv)) {
869✔
508
          *(int8_t*)(&val->i64) = (*(double*)&iv == 0 ? FALSE_VALUE : TRUE_VALUE);
355✔
509
        } else {
510
          return buildSyntaxErrMsg(pMsgBuf, "invalid bool data", pToken->z);
514✔
511
        }
512
      } else if (pToken->type == TK_NK_INTEGER) {
8,035✔
513
        *(int8_t*)(&val->i64) = ((taosStr2Int64(pToken->z, NULL, 10) == 0) ? FALSE_VALUE : TRUE_VALUE);
7,597✔
514
      } else if (pToken->type == TK_NK_FLOAT) {
438✔
515
        *(int8_t*)(&val->i64) = ((taosStr2Double(pToken->z, NULL) == 0) ? FALSE_VALUE : TRUE_VALUE);
140✔
516
      } else if ((pToken->type == TK_NK_HEX || pToken->type == TK_NK_BIN) &&
436!
517
                 (TSDB_CODE_SUCCESS == toDoubleEx(pToken->z, pToken->n, pToken->type, (double*)&iv))) {
138✔
518
        *(int8_t*)(&val->i64) = (*(double*)&iv == 0 ? FALSE_VALUE : TRUE_VALUE);
138✔
519
      } else {
520
        return buildSyntaxErrMsg(pMsgBuf, "invalid bool data", pToken->z);
160✔
521
      }
522
      break;
20,263✔
523
    }
524

525
    case TSDB_DATA_TYPE_TINYINT: {
15,219✔
526
      code = toIntegerEx(pToken->z, pToken->n, pToken->type, &iv);
15,219✔
527
      if (TSDB_CODE_SUCCESS != code) {
15,220✔
528
        return buildSyntaxErrMsg(pMsgBuf, "invalid tinyint data", pToken->z);
767✔
529
      } else if (!IS_VALID_TINYINT(iv)) {
14,453✔
530
        return buildSyntaxErrMsg(pMsgBuf, "tinyint data overflow", pToken->z);
28✔
531
      }
532

533
      *(int8_t*)(&val->i64) = iv;
14,425✔
534
      break;
14,425✔
535
    }
536

537
    case TSDB_DATA_TYPE_UTINYINT: {
6,644✔
538
      code = toUIntegerEx(pToken->z, pToken->n, pToken->type, &uv);
6,644✔
539
      if (TSDB_CODE_SUCCESS != code) {
6,644✔
540
        return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned tinyint data", pToken->z);
854✔
541
      } else if (uv > UINT8_MAX) {
5,790✔
542
        return buildSyntaxErrMsg(pMsgBuf, "unsigned tinyint data overflow", pToken->z);
10✔
543
      }
544
      *(uint8_t*)(&val->i64) = uv;
5,780✔
545
      break;
5,780✔
546
    }
547

548
    case TSDB_DATA_TYPE_SMALLINT: {
16,808✔
549
      code = toIntegerEx(pToken->z, pToken->n, pToken->type, &iv);
16,808✔
550
      if (TSDB_CODE_SUCCESS != code) {
16,808✔
551
        return buildSyntaxErrMsg(pMsgBuf, "invalid smallint data", pToken->z);
767✔
552
      } else if (!IS_VALID_SMALLINT(iv)) {
16,041✔
553
        return buildSyntaxErrMsg(pMsgBuf, "smallint data overflow", pToken->z);
28✔
554
      }
555
      *(int16_t*)(&val->i64) = iv;
16,013✔
556
      break;
16,013✔
557
    }
558

559
    case TSDB_DATA_TYPE_USMALLINT: {
6,705✔
560
      code = toUIntegerEx(pToken->z, pToken->n, pToken->type, &uv);
6,705✔
561
      if (TSDB_CODE_SUCCESS != code) {
6,705✔
562
        return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned smallint data", pToken->z);
854✔
563
      } else if (uv > UINT16_MAX) {
5,851✔
564
        return buildSyntaxErrMsg(pMsgBuf, "unsigned smallint data overflow", pToken->z);
10✔
565
      }
566
      *(uint16_t*)(&val->i64) = uv;
5,841✔
567
      break;
5,841✔
568
    }
569

570
    case TSDB_DATA_TYPE_INT: {
104,410✔
571
      code = toIntegerEx(pToken->z, pToken->n, pToken->type, &iv);
104,410✔
572
      if (TSDB_CODE_SUCCESS != code) {
104,422✔
573
        return buildSyntaxErrMsg(pMsgBuf, "invalid int data", pToken->z);
769✔
574
      } else if (!IS_VALID_INT(iv)) {
103,653✔
575
        return buildSyntaxErrMsg(pMsgBuf, "int data overflow", pToken->z);
26✔
576
      }
577
      *(int32_t*)(&val->i64) = iv;
103,627✔
578
      break;
103,627✔
579
    }
580

581
    case TSDB_DATA_TYPE_UINT: {
6,497✔
582
      code = toUIntegerEx(pToken->z, pToken->n, pToken->type, &uv);
6,497✔
583
      if (TSDB_CODE_SUCCESS != code) {
6,497✔
584
        return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned int data", pToken->z);
874✔
585
      } else if (uv > UINT32_MAX) {
5,623✔
586
        return buildSyntaxErrMsg(pMsgBuf, "unsigned int data overflow", pToken->z);
11✔
587
      }
588
      *(uint32_t*)(&val->i64) = uv;
5,612✔
589
      break;
5,612✔
590
    }
591

592
    case TSDB_DATA_TYPE_BIGINT: {
38,479✔
593
      code = toIntegerEx(pToken->z, pToken->n, pToken->type, &iv);
38,479✔
594
      if (TSDB_CODE_SUCCESS != code) {
38,479✔
595
        return buildSyntaxErrMsg(pMsgBuf, "invalid bigint data", pToken->z);
796✔
596
      }
597
      val->i64 = iv;
37,683✔
598
      break;
37,683✔
599
    }
600

601
    case TSDB_DATA_TYPE_UBIGINT: {
6,233✔
602
      code = toUIntegerEx(pToken->z, pToken->n, pToken->type, &uv);
6,233✔
603
      if (TSDB_CODE_SUCCESS != code) {
6,233✔
604
        return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned bigint data", pToken->z);
868✔
605
      }
606
      *(uint64_t*)(&val->i64) = uv;
5,365✔
607
      break;
5,365✔
608
    }
609

610
    case TSDB_DATA_TYPE_FLOAT: {
13,247✔
611
      double dv;
612
      code = toDoubleEx(pToken->z, pToken->n, pToken->type, &dv);
13,247✔
613
      if (TSDB_CODE_SUCCESS != code) {
13,247✔
614
        return buildSyntaxErrMsg(pMsgBuf, "illegal float data", pToken->z);
784✔
615
      }
616
      if (dv > FLT_MAX || dv < -FLT_MAX || isinf(dv) || isnan(dv)) {
12,477!
617
        return buildSyntaxErrMsg(pMsgBuf, "illegal float data", pToken->z);
14✔
618
      }
619
      *(float*)(&val->i64) = dv;
12,463✔
620
      break;
12,463✔
621
    }
622

623
    case TSDB_DATA_TYPE_DOUBLE: {
39,683✔
624
      double dv;
625
      code = toDoubleEx(pToken->z, pToken->n, pToken->type, &dv);
39,683✔
626
      if (TSDB_CODE_SUCCESS != code) {
39,683✔
627
        return buildSyntaxErrMsg(pMsgBuf, "illegal float data", pToken->z);
781✔
628
      }
629
      if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || isinf(dv) || isnan(dv)) {
38,902!
630
        return buildSyntaxErrMsg(pMsgBuf, "illegal double data", pToken->z);
×
631
      }
632

633
      *(double*)(&val->i64) = dv;
38,902✔
634
      break;
38,902✔
635
    }
636

637
    case TSDB_DATA_TYPE_BINARY: {
69,843✔
638
      // Too long values will raise the invalid sql error message
639
      if (pToken->n + VARSTR_HEADER_SIZE > pSchema->bytes) {
69,843✔
640
        return generateSyntaxErrMsg(pMsgBuf, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name);
291✔
641
      }
642
      val->pData = taosStrdup(pToken->z);
69,552✔
643
      if (!val->pData) {
69,551!
644
        return terrno;
×
645
      }
646
      val->nData = pToken->n;
69,552✔
647
      break;
69,552✔
648
    }
649
    case TSDB_DATA_TYPE_VARBINARY: {
3,436✔
650
      code = parseVarbinary(pToken, &val->pData, &val->nData, pSchema->bytes);
3,436✔
651
      if (code != TSDB_CODE_SUCCESS) {
3,436✔
652
        return generateSyntaxErrMsg(pMsgBuf, code, pSchema->name);
454✔
653
      }
654
      break;
2,982✔
655
    }
656
    case TSDB_DATA_TYPE_GEOMETRY: {
3,068✔
657
      unsigned char* output = NULL;
3,068✔
658
      size_t         size = 0;
3,068✔
659

660
      code = parseGeometry(pToken, &output, &size);
3,068✔
661
      if (code != TSDB_CODE_SUCCESS) {
3,068✔
662
        code = buildSyntaxErrMsg(pMsgBuf, getGeosErrMsg(code), pToken->z);
1,182✔
663
      } else if (size + VARSTR_HEADER_SIZE > pSchema->bytes) {
1,886!
664
        // Too long values will raise the invalid sql error message
665
        code = generateSyntaxErrMsg(pMsgBuf, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name);
×
666
      } else {
667
        val->pData = taosMemoryMalloc(size);
1,886✔
668
        if (NULL == val->pData) {
1,886!
669
          code = terrno;
×
670
        } else {
671
          memcpy(val->pData, output, size);
1,886✔
672
          val->nData = size;
1,886✔
673
        }
674
      }
675

676
      geosFreeBuffer(output);
3,068✔
677
      break;
3,068✔
678
    }
679

680
    case TSDB_DATA_TYPE_NCHAR: {
46,151✔
681
      int32_t output = 0;
46,151✔
682
      int64_t realLen = pToken->n << 2;
46,151✔
683
      if (realLen > pSchema->bytes - VARSTR_HEADER_SIZE) realLen = pSchema->bytes - VARSTR_HEADER_SIZE;
46,151✔
684
      void* p = taosMemoryMalloc(realLen);
46,151✔
685
      if (p == NULL) {
46,151!
686
        return terrno;
267✔
687
      }
688
      if (!taosMbsToUcs4(pToken->z, pToken->n, (TdUcs4*)(p), realLen, &output)) {
46,151✔
689
        if (terrno == TAOS_SYSTEM_ERROR(E2BIG)) {
267!
690
          taosMemoryFree(p);
267✔
691
          return generateSyntaxErrMsg(pMsgBuf, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name);
267✔
692
        }
693
        char buf[512] = {0};
×
694
        snprintf(buf, tListLen(buf), " taosMbsToUcs4 error:%s", strerror(terrno));
×
695
        taosMemoryFree(p);
×
696
        return buildSyntaxErrMsg(pMsgBuf, buf, pToken->z);
×
697
      }
698
      val->pData = p;
45,884✔
699
      val->nData = output;
45,884✔
700
      break;
45,884✔
701
    }
702
    case TSDB_DATA_TYPE_TIMESTAMP: {
13,116✔
703
      if (parseTime(end, pToken, timePrec, &iv, pMsgBuf) != TSDB_CODE_SUCCESS) {
13,116✔
704
        return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp", pToken->z);
924✔
705
      }
706

707
      val->i64 = iv;
12,192✔
708
      break;
12,192✔
709
    }
710
  }
711

712
  return code;
399,650✔
713
}
714

715
// input pStmt->pSql:  [(tag1_name, ...)] TAGS (tag1_value, ...) ...
716
// output pStmt->pSql: TAGS (tag1_value, ...) ...
717
static int32_t parseBoundTagsClause(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
59,624✔
718
  int32_t code = insInitBoundColsInfo(getNumOfTags(pStmt->pTableMeta), &pCxt->tags);
59,624✔
719
  if (TSDB_CODE_SUCCESS != code) {
59,624!
720
    return code;
×
721
  }
722

723
  SToken  token;
724
  int32_t index = 0;
59,624✔
725
  NEXT_TOKEN_KEEP_SQL(pStmt->pSql, token, index);
59,624✔
726
  if (TK_NK_LP != token.type) {
59,624✔
727
    return TSDB_CODE_SUCCESS;
59,158✔
728
  }
729

730
  pStmt->pSql += index;
466✔
731
  return parseBoundColumns(pCxt, &pStmt->pSql, BOUND_TAGS, pStmt->pTableMeta, &pCxt->tags);
466✔
732
}
733

734
int32_t parseTagValue(SMsgBuf* pMsgBuf, const char** pSql, uint8_t precision, SSchema* pTagSchema, SToken* pToken,
413,494✔
735
                      SArray* pTagName, SArray* pTagVals, STag** pTag) {
736
  bool isNull = isNullValue(pTagSchema->type, pToken);
413,494✔
737
  if (!isNull && pTagName) {
413,494✔
738
    if (NULL == taosArrayPush(pTagName, pTagSchema->name)) {
811,259!
739
      return terrno;
×
740
    }
741
  }
742

743
  if (pTagSchema->type == TSDB_DATA_TYPE_JSON) {
413,473✔
744
    if (pToken->n > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) {
1,094✔
745
      return buildSyntaxErrMsg(pMsgBuf, "json string too long than 4095", pToken->z);
4✔
746
    }
747

748
    if (isNull) {
1,090✔
749
      return tTagNew(pTagVals, 1, true, pTag);
68✔
750
    } else {
751
      return parseJsontoTagData(pToken->z, pTagVals, pTag, pMsgBuf);
1,022✔
752
    }
753
  }
754

755
  if (isNull) return 0;
412,379✔
756

757
  STagVal val = {0};
410,482✔
758
  int32_t code = parseTagToken(pSql, pToken, pTagSchema, precision, &val, pMsgBuf);
410,482✔
759
  if (TSDB_CODE_SUCCESS == code) {
410,487✔
760
    if (NULL == taosArrayPush(pTagVals, &val)) {
398,456!
761
      code = terrno;
×
762
    }
763
  }
764

765
  return code;
410,483✔
766
}
767

768
static int32_t buildCreateTbReq(SVnodeModifyOpStmt* pStmt, STag* pTag, SArray* pTagName) {
55,206✔
769
  if (pStmt->pCreateTblReq) {
55,206!
770
    tdDestroySVCreateTbReq(pStmt->pCreateTblReq);
×
771
    taosMemoryFreeClear(pStmt->pCreateTblReq);
×
772
  }
773
  pStmt->pCreateTblReq = taosMemoryCalloc(1, sizeof(SVCreateTbReq));
55,206✔
774
  if (NULL == pStmt->pCreateTblReq) {
55,206!
775
    return terrno;
×
776
  }
777
  return insBuildCreateTbReq(pStmt->pCreateTblReq, pStmt->targetTableName.tname, pTag, pStmt->pTableMeta->suid,
55,206✔
778
                             pStmt->usingTableName.tname, pTagName, pStmt->pTableMeta->tableInfo.numOfTags,
55,206✔
779
                             TSDB_DEFAULT_TABLE_TTL);
780
}
781

782
int32_t checkAndTrimValue(SToken* pToken, char* tmpTokenBuf, SMsgBuf* pMsgBuf, int8_t type) {
1,657,265,467✔
783
  if (pToken->type == TK_NK_QUESTION) {
1,657,265,467!
784
    return buildInvalidOperationMsg(pMsgBuf, "insert into super table syntax is not supported for stmt");
×
785
  }
786
  if ((pToken->type != TK_NOW && pToken->type != TK_TODAY && pToken->type != TK_NK_INTEGER &&
1,657,265,467!
787
       pToken->type != TK_NK_STRING && pToken->type != TK_NK_FLOAT && pToken->type != TK_NK_BOOL &&
330,912,740✔
788
       pToken->type != TK_NULL && pToken->type != TK_NK_HEX && pToken->type != TK_NK_OCT && pToken->type != TK_NK_BIN &&
19,708,168!
789
       pToken->type != TK_NK_VARIABLE) ||
3,914✔
790
      (pToken->n == 0) || (pToken->type == TK_NK_RP)) {
1,657,261,569!
791
    return buildSyntaxErrMsg(pMsgBuf, "invalid data or symbol", pToken->z);
×
792
  }
793

794
  // Remove quotation marks
795
  if (TK_NK_STRING == pToken->type && type != TSDB_DATA_TYPE_VARBINARY) {
1,663,357,832✔
796
    if (pToken->n >= TSDB_MAX_BYTES_PER_ROW) {
143,420,159!
797
      return buildSyntaxErrMsg(pMsgBuf, "too long string", pToken->z);
×
798
    }
799

800
    int32_t len = trimString(pToken->z, pToken->n, tmpTokenBuf, TSDB_MAX_BYTES_PER_ROW);
143,420,159✔
801
    pToken->z = tmpTokenBuf;
144,166,336✔
802
    pToken->n = len;
144,166,336✔
803
  }
804

805
  return TSDB_CODE_SUCCESS;
1,664,104,009✔
806
}
807

808
typedef struct SRewriteTagCondCxt {
809
  SArray* pTagVals;
810
  SArray* pTagName;
811
  int32_t code;
812
} SRewriteTagCondCxt;
813

814
static int32_t rewriteTagCondColumnImpl(STagVal* pVal, SNode** pNode) {
11✔
815
  SValueNode* pValue = NULL;
11✔
816
  int32_t     code = nodesMakeNode(QUERY_NODE_VALUE, (SNode**)&pValue);
11✔
817
  if (NULL == pValue) {
11!
818
    return code;
×
819
  }
820

821
  pValue->node.resType = ((SColumnNode*)*pNode)->node.resType;
11✔
822
  nodesDestroyNode(*pNode);
11✔
823
  *pNode = (SNode*)pValue;
11✔
824

825
  switch (pVal->type) {
11!
826
    case TSDB_DATA_TYPE_BOOL:
×
827
      pValue->datum.b = *(int8_t*)(&pVal->i64);
×
828
      *(bool*)&pValue->typeData = pValue->datum.b;
×
829
      break;
×
830
    case TSDB_DATA_TYPE_TINYINT:
×
831
      pValue->datum.i = *(int8_t*)(&pVal->i64);
×
832
      *(int8_t*)&pValue->typeData = pValue->datum.i;
×
833
      break;
×
834
    case TSDB_DATA_TYPE_SMALLINT:
×
835
      pValue->datum.i = *(int16_t*)(&pVal->i64);
×
836
      *(int16_t*)&pValue->typeData = pValue->datum.i;
×
837
      break;
×
838
    case TSDB_DATA_TYPE_INT:
6✔
839
      pValue->datum.i = *(int32_t*)(&pVal->i64);
6✔
840
      *(int32_t*)&pValue->typeData = pValue->datum.i;
6✔
841
      break;
6✔
842
    case TSDB_DATA_TYPE_BIGINT:
×
843
      pValue->datum.i = pVal->i64;
×
844
      pValue->typeData = pValue->datum.i;
×
845
      break;
×
846
    case TSDB_DATA_TYPE_FLOAT:
×
847
      pValue->datum.d = *(float*)(&pVal->i64);
×
848
      *(float*)&pValue->typeData = pValue->datum.d;
×
849
      break;
×
850
    case TSDB_DATA_TYPE_DOUBLE:
×
851
      pValue->datum.d = *(double*)(&pVal->i64);
×
852
      *(double*)&pValue->typeData = pValue->datum.d;
×
853
      break;
×
854
    case TSDB_DATA_TYPE_VARCHAR:
5✔
855
    case TSDB_DATA_TYPE_VARBINARY:
856
    case TSDB_DATA_TYPE_NCHAR:
857
      pValue->datum.p = taosMemoryCalloc(1, pVal->nData + VARSTR_HEADER_SIZE);
5✔
858
      if (NULL == pValue->datum.p) {
5!
859
        return terrno;
×
860
      }
861
      varDataSetLen(pValue->datum.p, pVal->nData);
5✔
862
      memcpy(varDataVal(pValue->datum.p), pVal->pData, pVal->nData);
5✔
863
      break;
5✔
864
    case TSDB_DATA_TYPE_TIMESTAMP:
×
865
      pValue->datum.i = pVal->i64;
×
866
      pValue->typeData = pValue->datum.i;
×
867
      break;
×
868
    case TSDB_DATA_TYPE_UTINYINT:
×
869
      pValue->datum.i = *(uint8_t*)(&pVal->i64);
×
870
      *(uint8_t*)&pValue->typeData = pValue->datum.i;
×
871
      break;
×
872
    case TSDB_DATA_TYPE_USMALLINT:
×
873
      pValue->datum.i = *(uint16_t*)(&pVal->i64);
×
874
      *(uint16_t*)&pValue->typeData = pValue->datum.i;
×
875
      break;
×
876
    case TSDB_DATA_TYPE_UINT:
×
877
      pValue->datum.i = *(uint32_t*)(&pVal->i64);
×
878
      *(uint32_t*)&pValue->typeData = pValue->datum.i;
×
879
      break;
×
880
    case TSDB_DATA_TYPE_UBIGINT:
×
881
      pValue->datum.i = *(uint64_t*)(&pVal->i64);
×
882
      *(uint64_t*)&pValue->typeData = pValue->datum.i;
×
883
      break;
×
884
    case TSDB_DATA_TYPE_JSON:
×
885
    case TSDB_DATA_TYPE_DECIMAL:
886
    case TSDB_DATA_TYPE_BLOB:
887
    case TSDB_DATA_TYPE_MEDIUMBLOB:
888
    default:
889
      return TSDB_CODE_FAILED;
×
890
  }
891
  return TSDB_CODE_SUCCESS;
11✔
892
}
893

894
static int32_t rewriteTagCondColumn(SArray* pTagVals, SArray* pTagName, SNode** pNode) {
11✔
895
  SColumnNode* pCol = (SColumnNode*)*pNode;
11✔
896
  int32_t      ntags = taosArrayGetSize(pTagName);
11✔
897
  for (int32_t i = 0; i < ntags; ++i) {
11!
898
    char* pTagColName = taosArrayGet(pTagName, i);
11✔
899
    if (0 == strcmp(pTagColName, pCol->colName)) {
11!
900
      return rewriteTagCondColumnImpl(taosArrayGet(pTagVals, i), pNode);
11✔
901
    }
902
  }
903
  return TSDB_CODE_PAR_PERMISSION_DENIED;
×
904
}
905

906
static EDealRes rewriteTagCond(SNode** pNode, void* pContext) {
33✔
907
  if (QUERY_NODE_COLUMN == nodeType(*pNode)) {
33✔
908
    SRewriteTagCondCxt* pCxt = pContext;
11✔
909
    pCxt->code = rewriteTagCondColumn(pCxt->pTagVals, pCxt->pTagName, pNode);
11✔
910
    return (TSDB_CODE_SUCCESS == pCxt->code ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR);
11!
911
  }
912
  return DEAL_RES_CONTINUE;
22✔
913
}
914

915
static int32_t setTagVal(SArray* pTagVals, SArray* pTagName, SNode* pCond) {
11✔
916
  SRewriteTagCondCxt cxt = {.code = TSDB_CODE_SUCCESS, .pTagVals = pTagVals, .pTagName = pTagName};
11✔
917
  nodesRewriteExpr(&pCond, rewriteTagCond, &cxt);
11✔
918
  return cxt.code;
11✔
919
}
920

921
static int32_t checkTagCondResult(SNode* pResult) {
11✔
922
  return (QUERY_NODE_VALUE == nodeType(pResult) && ((SValueNode*)pResult)->datum.b) ? TSDB_CODE_SUCCESS
11✔
923
                                                                                    : TSDB_CODE_PAR_PERMISSION_DENIED;
22!
924
}
925

926
static int32_t checkSubtablePrivilege(SArray* pTagVals, SArray* pTagName, SNode** pCond) {
11✔
927
  int32_t code = setTagVal(pTagVals, pTagName, *pCond);
11✔
928
  if (TSDB_CODE_SUCCESS == code) {
11!
929
    code = scalarCalculateConstants(*pCond, pCond);
11✔
930
  }
931
  if (TSDB_CODE_SUCCESS == code) {
11!
932
    code = checkTagCondResult(*pCond);
11✔
933
  }
934
  NODES_DESTORY_NODE(*pCond);
11✔
935
  return code;
11✔
936
}
937

938
// pSql -> tag1_value, ...)
939
static int32_t parseTagsClauseImpl(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
59,624✔
940
  int32_t  code = TSDB_CODE_SUCCESS;
59,624✔
941
  SSchema* pSchema = getTableTagSchema(pStmt->pTableMeta);
59,624✔
942
  SArray*  pTagVals = NULL;
59,624✔
943
  SArray*  pTagName = NULL;
59,624✔
944
  uint8_t  precision = pStmt->pTableMeta->tableInfo.precision;
59,624✔
945
  SToken   token;
946
  bool     isParseBindParam = false;
59,624✔
947
  bool     isJson = false;
59,624✔
948
  STag*    pTag = NULL;
59,624✔
949

950
  if (!(pTagVals = taosArrayInit(pCxt->tags.numOfBound, sizeof(STagVal))) ||
119,248!
951
      !(pTagName = taosArrayInit(pCxt->tags.numOfBound, TSDB_COL_NAME_LEN))) {
59,624✔
952
    code = terrno;
×
953
    goto _exit;
×
954
  }
955

956
  for (int i = 0; TSDB_CODE_SUCCESS == code && i < pCxt->tags.numOfBound; ++i) {
161,859✔
957
    NEXT_TOKEN_WITH_PREV(pStmt->pSql, token);
102,235✔
958

959
    if (token.type == TK_NK_QUESTION) {
102,237✔
960
      isParseBindParam = true;
23✔
961
      if (NULL == pCxt->pComCxt->pStmtCb) {
23!
962
        code = buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", token.z);
×
963
        break;
×
964
      }
965

966
      continue;
23✔
967
    }
968

969
    if (isParseBindParam) {
102,214!
970
      code = buildInvalidOperationMsg(&pCxt->msg, "no mix usage for ? and tag values");
×
971
      break;
×
972
    }
973

974
    SSchema* pTagSchema = &pSchema[pCxt->tags.pColIndex[i]];
102,214✔
975
    isJson = pTagSchema->type == TSDB_DATA_TYPE_JSON;
102,214✔
976
    code = checkAndTrimValue(&token, pCxt->tmpTokenBuf, &pCxt->msg, pTagSchema->type);
102,214✔
977
    if (TSDB_CODE_SUCCESS == code && TK_NK_VARIABLE == token.type) {
102,214!
978
      code = buildSyntaxErrMsg(&pCxt->msg, "not expected tags values ", token.z);
×
979
    }
980
    if (TSDB_CODE_SUCCESS == code) {
102,214✔
981
      code = parseTagValue(&pCxt->msg, &pStmt->pSql, precision, pTagSchema, &token, pTagName, pTagVals, &pTag);
101,364✔
982
    }
983
  }
984

985
  if (TSDB_CODE_SUCCESS == code && NULL != pStmt->pTagCond) {
59,624✔
986
    code = checkSubtablePrivilege(pTagVals, pTagName, &pStmt->pTagCond);
7✔
987
  }
988

989
  if (TSDB_CODE_SUCCESS == code && !isParseBindParam && !isJson) {
59,624✔
990
    code = tTagNew(pTagVals, 1, false, &pTag);
54,936✔
991
  }
992

993
  if (TSDB_CODE_SUCCESS == code && !isParseBindParam) {
59,624✔
994
    code = buildCreateTbReq(pStmt, pTag, pTagName);
55,206✔
995
    pTag = NULL;
55,206✔
996
  }
997

998
_exit:
4,418✔
999
  for (int32_t i = 0; i < taosArrayGetSize(pTagVals); ++i) {
157,181✔
1000
    STagVal* p = (STagVal*)TARRAY_GET_ELEM(pTagVals, i);
97,557✔
1001
    if (IS_VAR_DATA_TYPE(p->type)) {
97,557!
1002
      taosMemoryFreeClear(p->pData);
30,506✔
1003
    }
1004
  }
1005
  taosArrayDestroy(pTagVals);
59,623✔
1006
  taosArrayDestroy(pTagName);
59,624✔
1007
  tTagFree(pTag);
59,624✔
1008
  return code;
59,624✔
1009
}
1010

1011
// input pStmt->pSql:  TAGS (tag1_value, ...) [table_options] ...
1012
// output pStmt->pSql: [table_options] ...
1013
static int32_t parseTagsClause(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
59,624✔
1014
  SToken token;
1015
  NEXT_TOKEN(pStmt->pSql, token);
59,624✔
1016
  if (TK_TAGS != token.type) {
59,624!
1017
    return buildSyntaxErrMsg(&pCxt->msg, "TAGS is expected", token.z);
×
1018
  }
1019

1020
  NEXT_TOKEN(pStmt->pSql, token);
59,624✔
1021
  if (TK_NK_LP != token.type) {
59,624!
1022
    return buildSyntaxErrMsg(&pCxt->msg, "( is expected", token.z);
×
1023
  }
1024

1025
  int32_t code = parseTagsClauseImpl(pCxt, pStmt);
59,624✔
1026
  if (TSDB_CODE_SUCCESS == code) {
59,624✔
1027
    NEXT_VALID_TOKEN(pStmt->pSql, token);
84,101✔
1028
    if (TK_NK_COMMA == token.type) {
55,214✔
1029
      code = generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_TAGS_NOT_MATCHED);
62✔
1030
    } else if (TK_NK_RP != token.type) {
55,152✔
1031
      code = buildSyntaxErrMsg(&pCxt->msg, ") is expected", token.z);
247✔
1032
    }
1033
  }
1034
  return code;
59,624✔
1035
}
1036

1037
static int32_t storeChildTableMeta(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
59,624✔
1038
  pStmt->pTableMeta->suid = pStmt->pTableMeta->uid;
59,624✔
1039
  pStmt->pTableMeta->uid = pStmt->totalTbNum;
59,624✔
1040
  pStmt->pTableMeta->tableType = TSDB_CHILD_TABLE;
59,624✔
1041

1042
  STableMeta* pBackup = NULL;
59,624✔
1043
  if (TSDB_CODE_SUCCESS != cloneTableMeta(pStmt->pTableMeta, &pBackup)) {
59,624!
1044
    return TSDB_CODE_OUT_OF_MEMORY;
×
1045
  }
1046

1047
  char    tbFName[TSDB_TABLE_FNAME_LEN];
1048
  int32_t code = tNameExtractFullName(&pStmt->targetTableName, tbFName);
59,624✔
1049
  if (TSDB_CODE_SUCCESS != code) {
59,624!
1050
    taosMemoryFree(pBackup);
×
1051
    return code;
×
1052
  }
1053
  code = taosHashPut(pStmt->pSubTableHashObj, tbFName, strlen(tbFName), &pBackup, POINTER_BYTES);
59,624✔
1054
  if (TSDB_CODE_SUCCESS != code) {
59,624!
1055
    taosMemoryFree(pBackup);
×
1056
  }
1057
  return code;
59,624✔
1058
}
1059

1060
static int32_t parseTableOptions(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
54,923✔
1061
  do {
18✔
1062
    int32_t index = 0;
54,923✔
1063
    SToken  token;
1064
    NEXT_TOKEN_KEEP_SQL(pStmt->pSql, token, index);
54,923✔
1065
    if (TK_TTL == token.type) {
54,923✔
1066
      pStmt->pSql += index;
18✔
1067
      NEXT_TOKEN_WITH_PREV(pStmt->pSql, token);
18✔
1068
      if (TK_NK_INTEGER != token.type) {
18!
1069
        return buildSyntaxErrMsg(&pCxt->msg, "Invalid option ttl", token.z);
4✔
1070
      }
1071
      pStmt->pCreateTblReq->ttl = taosStr2Int32(token.z, NULL, 10);
18✔
1072
      if (pStmt->pCreateTblReq->ttl < 0) {
18✔
1073
        return buildSyntaxErrMsg(&pCxt->msg, "Invalid option ttl", token.z);
4✔
1074
      }
1075
    } else if (TK_COMMENT == token.type) {
54,905✔
1076
      pStmt->pSql += index;
4✔
1077
      NEXT_TOKEN(pStmt->pSql, token);
4✔
1078
      if (TK_NK_STRING != token.type) {
4!
1079
        return buildSyntaxErrMsg(&pCxt->msg, "Invalid option comment", token.z);
×
1080
      }
1081
      if (token.n >= TSDB_TB_COMMENT_LEN) {
4!
1082
        return buildSyntaxErrMsg(&pCxt->msg, "comment too long", token.z);
×
1083
      }
1084
      int32_t len = trimString(token.z, token.n, pCxt->tmpTokenBuf, TSDB_TB_COMMENT_LEN);
4✔
1085
      pStmt->pCreateTblReq->comment = taosStrndup(pCxt->tmpTokenBuf, len);
4✔
1086
      if (NULL == pStmt->pCreateTblReq->comment) {
4!
1087
        return terrno;
×
1088
      }
1089
      pStmt->pCreateTblReq->commentLen = len;
4✔
1090
    } else {
1091
      break;
54,901✔
1092
    }
1093
  } while (1);
1094
  return TSDB_CODE_SUCCESS;
54,901✔
1095
}
1096

1097
// input pStmt->pSql:
1098
//   1. [(tag1_name, ...)] ...
1099
//   2. VALUES ... | FILE ...
1100
// output pStmt->pSql:
1101
//   1. [(field1_name, ...)]
1102
//   2. VALUES ... | FILE ...
1103
static int32_t parseUsingClauseBottom(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
9,666,426✔
1104
  if (!pStmt->usingTableProcessing || pCxt->usingDuplicateTable) {
9,666,426✔
1105
    return TSDB_CODE_SUCCESS;
9,606,802✔
1106
  }
1107

1108
  int32_t code = parseBoundTagsClause(pCxt, pStmt);
59,624✔
1109
  if (TSDB_CODE_SUCCESS == code) {
59,624!
1110
    code = parseTagsClause(pCxt, pStmt);
59,624✔
1111
  }
1112
  if (TSDB_CODE_SUCCESS == code) {
59,624✔
1113
    code = parseTableOptions(pCxt, pStmt);
54,905✔
1114
  }
1115

1116
  return code;
59,624✔
1117
}
1118

1119
static void setUserAuthInfo(SParseContext* pCxt, SName* pTbName, SUserAuthInfo* pInfo) {
9,687,942✔
1120
  snprintf(pInfo->user, sizeof(pInfo->user), "%s", pCxt->pUser);
9,687,942✔
1121
  memcpy(&pInfo->tbName, pTbName, sizeof(SName));
9,687,942✔
1122
  pInfo->type = AUTH_TYPE_WRITE;
9,687,942✔
1123
}
9,687,942✔
1124

1125
static int32_t checkAuth(SParseContext* pCxt, SName* pTbName, bool* pMissCache, SNode** pTagCond) {
9,689,628✔
1126
  int32_t       code = TSDB_CODE_SUCCESS;
9,689,628✔
1127
  SUserAuthInfo authInfo = {0};
9,689,628✔
1128
  setUserAuthInfo(pCxt, pTbName, &authInfo);
9,689,628✔
1129
  SUserAuthRes authRes = {0};
9,693,071✔
1130
  bool         exists = true;
9,693,071✔
1131
  if (pCxt->async) {
9,693,071!
1132
    code = catalogChkAuthFromCache(pCxt->pCatalog, &authInfo, &authRes, &exists);
9,699,088✔
1133
  } else {
1134
    SRequestConnInfo conn = {.pTrans = pCxt->pTransporter,
×
1135
                             .requestId = pCxt->requestId,
×
1136
                             .requestObjRefId = pCxt->requestRid,
×
1137
                             .mgmtEps = pCxt->mgmtEpSet};
1138
    code = catalogChkAuth(pCxt->pCatalog, &conn, &authInfo, &authRes);
×
1139
  }
1140
  if (TSDB_CODE_SUCCESS == code) {
9,665,244!
1141
    if (!exists) {
9,665,633✔
1142
      *pMissCache = true;
421✔
1143
    } else if (!authRes.pass[AUTH_RES_BASIC]) {
9,665,212✔
1144
      code = TSDB_CODE_PAR_PERMISSION_DENIED;
52✔
1145
    } else if (NULL != authRes.pCond[AUTH_RES_BASIC]) {
9,665,160✔
1146
      *pTagCond = authRes.pCond[AUTH_RES_BASIC];
11✔
1147
    }
1148
  }
1149
  return code;
9,665,244✔
1150
}
1151

1152
static int32_t getTableMeta(SInsertParseContext* pCxt, SName* pTbName, STableMeta** pTableMeta, bool* pMissCache,
59,502✔
1153
                            bool bUsingTable) {
1154
  SParseContext* pComCxt = pCxt->pComCxt;
59,502✔
1155
  int32_t        code = TSDB_CODE_SUCCESS;
59,502✔
1156
  if (pComCxt->async) {
59,502✔
1157
    if (bUsingTable) {
59,467!
1158
      code = catalogGetCachedSTableMeta(pComCxt->pCatalog, pTbName, pTableMeta);
59,467✔
1159
    } else {
1160
      code = catalogGetCachedTableMeta(pComCxt->pCatalog, pTbName, pTableMeta);
×
1161
    }
1162
  } else {
1163
    SRequestConnInfo conn = {.pTrans = pComCxt->pTransporter,
35✔
1164
                             .requestId = pComCxt->requestId,
35✔
1165
                             .requestObjRefId = pComCxt->requestRid,
35✔
1166
                             .mgmtEps = pComCxt->mgmtEpSet};
1167
    if (bUsingTable) {
35✔
1168
      code = catalogGetSTableMeta(pComCxt->pCatalog, &conn, pTbName, pTableMeta);
24✔
1169
    } else {
1170
      code = catalogGetTableMeta(pComCxt->pCatalog, &conn, pTbName, pTableMeta);
11✔
1171
    }
1172
  }
1173
  if (TSDB_CODE_SUCCESS == code) {
59,502!
1174
    if (NULL == *pTableMeta) {
59,502✔
1175
      *pMissCache = true;
11✔
1176
    } else if (bUsingTable && TSDB_SUPER_TABLE != (*pTableMeta)->tableType) {
59,491!
1177
      code = buildInvalidOperationMsg(&pCxt->msg, "create table only from super table is allowed");
×
1178
    }
1179
  }
1180
  return code;
59,502✔
1181
}
1182

1183
static int32_t getTargetTableVgroup(SParseContext* pCxt, SVnodeModifyOpStmt* pStmt, bool isStb, bool* pMissCache) {
59,490✔
1184
  int32_t     code = TSDB_CODE_SUCCESS;
59,490✔
1185
  SVgroupInfo vg;
1186
  bool        exists = true;
59,490✔
1187
  if (pCxt->async) {
59,490✔
1188
    code = catalogGetCachedTableHashVgroup(pCxt->pCatalog, &pStmt->targetTableName, &vg, &exists);
59,456✔
1189
  } else {
1190
    SRequestConnInfo conn = {.pTrans = pCxt->pTransporter,
34✔
1191
                             .requestId = pCxt->requestId,
34✔
1192
                             .requestObjRefId = pCxt->requestRid,
34✔
1193
                             .mgmtEps = pCxt->mgmtEpSet};
1194
    code = catalogGetTableHashVgroup(pCxt->pCatalog, &conn, &pStmt->targetTableName, &vg);
34✔
1195
  }
1196
  if (TSDB_CODE_SUCCESS == code) {
59,490!
1197
    if (exists) {
59,490✔
1198
      if (isStb) {
59,474✔
1199
        pStmt->pTableMeta->vgId = vg.vgId;
59,464✔
1200
      }
1201
      code = taosHashPut(pStmt->pVgroupsHashObj, (const char*)&vg.vgId, sizeof(vg.vgId), (char*)&vg, sizeof(vg));
59,474✔
1202
    }
1203
    *pMissCache = !exists;
59,490✔
1204
  }
1205
  return code;
59,490✔
1206
}
1207

1208
static int32_t getTargetTableMetaAndVgroup(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, bool* pMissCache) {
9,601,796✔
1209
  SParseContext* pComCxt = pCxt->pComCxt;
9,601,796✔
1210
  int32_t        code = TSDB_CODE_SUCCESS;
9,601,796✔
1211
  if (pComCxt->async) {
9,601,796!
1212
    {
1213
      SVgroupInfo vg;
1214
      code = catalogGetCachedTableVgMeta(pComCxt->pCatalog, &pStmt->targetTableName, &vg, &pStmt->pTableMeta);
9,604,625✔
1215
      if (TSDB_CODE_SUCCESS == code) {
9,630,605✔
1216
        if (NULL != pStmt->pTableMeta) {
9,630,520✔
1217
          if (pStmt->pTableMeta->tableType == TSDB_SUPER_TABLE) {
9,599,888✔
1218
            pStmt->stbSyntax = true;
10,608✔
1219
          } else {
1220
            code = taosHashPut(pStmt->pVgroupsHashObj, (const char*)&vg.vgId, sizeof(vg.vgId), (char*)&vg, sizeof(vg));
9,589,280✔
1221
          }
1222
        }
1223
        *pMissCache = (NULL == pStmt->pTableMeta);
9,630,539✔
1224
      }
1225
    }
1226
  } else {
1227
    bool bUsingTable = false;
×
1228
    code = getTableMeta(pCxt, &pStmt->targetTableName, &pStmt->pTableMeta, pMissCache, bUsingTable);
×
1229
    if (TSDB_CODE_SUCCESS == code && !pCxt->missCache) {
11!
1230
      if (TSDB_SUPER_TABLE == pStmt->pTableMeta->tableType) {
11✔
1231
        pStmt->stbSyntax = true;
1✔
1232
      }
1233
      if (!pStmt->stbSyntax) {
11✔
1234
        code = getTargetTableVgroup(pCxt->pComCxt, pStmt, false, &pCxt->missCache);
10✔
1235
      }
1236
    }
1237
  }
1238
  return code;
9,628,574✔
1239
}
1240

1241
static int32_t collectUseTable(const SName* pName, SHashObj* pTable) {
19,948✔
1242
  char    fullName[TSDB_TABLE_FNAME_LEN];
1243
  int32_t code = tNameExtractFullName(pName, fullName);
19,948✔
1244
  if (TSDB_CODE_SUCCESS != code) {
19,948!
1245
    return code;
×
1246
  }
1247
  return taosHashPut(pTable, fullName, strlen(fullName), pName, sizeof(SName));
19,948✔
1248
}
1249

1250
static int32_t collectUseDatabase(const SName* pName, SHashObj* pDbs) {
10,592✔
1251
  char dbFName[TSDB_DB_FNAME_LEN] = {0};
10,592✔
1252
  (void)tNameGetFullDbName(pName, dbFName);
10,592✔
1253
  return taosHashPut(pDbs, dbFName, strlen(dbFName), dbFName, sizeof(dbFName));
10,592✔
1254
}
1255

1256
static int32_t getTargetTableSchema(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
9,637,877✔
1257
  if (pCxt->forceUpdate) {
9,637,877✔
1258
    pCxt->missCache = true;
345✔
1259
    return TSDB_CODE_SUCCESS;
345✔
1260
  }
1261
  SNode*  pTagCond = NULL;
9,637,532✔
1262
  int32_t code = checkAuth(pCxt->pComCxt, &pStmt->targetTableName, &pCxt->missCache, &pTagCond);
9,637,532✔
1263
  if (TSDB_CODE_SUCCESS == code && !pCxt->missCache) {
9,605,520!
1264
    code = getTargetTableMetaAndVgroup(pCxt, pStmt, &pCxt->missCache);
9,605,977✔
1265
  }
1266
  if (TSDB_CODE_SUCCESS == code && !pCxt->missCache) {
9,626,561!
1267
    if (TSDB_SUPER_TABLE != pStmt->pTableMeta->tableType) {
9,597,208✔
1268
      pCxt->needTableTagVal = (NULL != pTagCond);
9,584,777✔
1269
      pCxt->missCache = (NULL != pTagCond);
9,584,777✔
1270
    } else {
1271
      pStmt->pTagCond = NULL;
12,431✔
1272
      code = nodesCloneNode(pTagCond, &pStmt->pTagCond);
12,431✔
1273
    }
1274
  }
1275
  nodesDestroyNode(pTagCond);
9,624,739✔
1276

1277
  if (TSDB_CODE_SUCCESS == code && !pCxt->pComCxt->async) {
9,623,705!
1278
    code = collectUseDatabase(&pStmt->targetTableName, pStmt->pDbFNameHashObj);
11✔
1279
    if (TSDB_CODE_SUCCESS == code) {
11!
1280
      code = collectUseTable(&pStmt->targetTableName, pStmt->pTableNameHashObj);
11✔
1281
    }
1282
  }
1283
  return code;
9,625,414✔
1284
}
1285

1286
static int32_t preParseUsingTableName(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SToken* pTbName) {
59,645✔
1287
  return insCreateSName(&pStmt->usingTableName, pTbName, pCxt->pComCxt->acctId, pCxt->pComCxt->db, &pCxt->msg);
59,645✔
1288
}
1289

1290
static int32_t getUsingTableSchema(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
59,644✔
1291
  if (pCxt->forceUpdate) {
59,644✔
1292
    pCxt->missCache = true;
142✔
1293
    return TSDB_CODE_SUCCESS;
142✔
1294
  }
1295

1296
  int32_t code = checkAuth(pCxt->pComCxt, &pStmt->usingTableName, &pCxt->missCache, &pStmt->pTagCond);
59,502✔
1297
  if (TSDB_CODE_SUCCESS == code && !pCxt->missCache) {
59,502✔
1298
    bool bUsingTable = true;
59,491✔
1299
    code = getTableMeta(pCxt, &pStmt->usingTableName, &pStmt->pTableMeta, &pCxt->missCache, bUsingTable);
59,491✔
1300
  }
1301
  if (TSDB_CODE_SUCCESS == code && !pCxt->missCache) {
59,502✔
1302
    code = getTargetTableVgroup(pCxt->pComCxt, pStmt, true, &pCxt->missCache);
59,480✔
1303
  }
1304
  if (TSDB_CODE_SUCCESS == code && !pCxt->pComCxt->async) {
59,502✔
1305
    code = collectUseDatabase(&pStmt->usingTableName, pStmt->pDbFNameHashObj);
24✔
1306
    if (TSDB_CODE_SUCCESS == code) {
24!
1307
      code = collectUseTable(&pStmt->usingTableName, pStmt->pTableNameHashObj);
24✔
1308
    }
1309
  }
1310
  return code;
59,502✔
1311
}
1312

1313
static int32_t parseUsingTableNameImpl(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
59,645✔
1314
  SToken token;
1315
  NEXT_TOKEN(pStmt->pSql, token);
59,645✔
1316
  int32_t code = preParseUsingTableName(pCxt, pStmt, &token);
59,645✔
1317
  if (TSDB_CODE_SUCCESS == code) {
59,645✔
1318
    code = getUsingTableSchema(pCxt, pStmt);
59,644✔
1319
  }
1320
  if (TSDB_CODE_SUCCESS == code && !pCxt->missCache) {
59,645✔
1321
    code = storeChildTableMeta(pCxt, pStmt);
59,464✔
1322
  }
1323
  return code;
59,645✔
1324
}
1325

1326
// input pStmt->pSql:
1327
//   1(care). [USING stb_name [(tag1_name, ...)] TAGS (tag1_value, ...) [table_options]] ...
1328
//   2. VALUES ... | FILE ...
1329
// output pStmt->pSql:
1330
//   1. [(tag1_name, ...)] TAGS (tag1_value, ...) [table_options]] ...
1331
//   2. VALUES ... | FILE ...
1332
static int32_t parseUsingTableName(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
9,698,237✔
1333
  SToken  token;
1334
  int32_t index = 0;
9,698,237✔
1335
  NEXT_TOKEN_KEEP_SQL(pStmt->pSql, token, index);
9,698,237✔
1336
  if (TK_USING != token.type) {
9,702,036✔
1337
    return getTargetTableSchema(pCxt, pStmt);
9,643,006✔
1338
  }
1339

1340
  pStmt->usingTableProcessing = true;
59,030✔
1341
  // pStmt->pSql -> stb_name [(tag1_name, ...)
1342
  pStmt->pSql += index;
59,030✔
1343
  int32_t code = parseDuplicateUsingClause(pCxt, pStmt, &pCxt->usingDuplicateTable);
59,030✔
1344
  if (TSDB_CODE_SUCCESS == code && !pCxt->usingDuplicateTable) {
59,649!
1345
    return parseUsingTableNameImpl(pCxt, pStmt);
59,645✔
1346
  }
1347
  return code;
4✔
1348
}
1349

1350
static int32_t preParseTargetTableName(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SToken* pTbName) {
9,671,737✔
1351
  int32_t code = insCreateSName(&pStmt->targetTableName, pTbName, pCxt->pComCxt->acctId, pCxt->pComCxt->db, &pCxt->msg);
9,671,737✔
1352
  if (TSDB_CODE_SUCCESS == code) {
9,691,076!
1353
    if (IS_SYS_DBNAME(pStmt->targetTableName.dbname)) {
9,695,376!
1354
      return TSDB_CODE_PAR_SYSTABLE_NOT_ALLOWED;
×
1355
    }
1356
  }
1357

1358
  return code;
9,691,076✔
1359
}
1360

1361
// input pStmt->pSql:
1362
//   1(care). [(field1_name, ...)] ...
1363
//   2. [ USING ... ] ...
1364
//   3. VALUES ... | FILE ...
1365
// output pStmt->pSql:
1366
//   1. [ USING ... ] ...
1367
//   2. VALUES ... | FILE ...
1368
static int32_t preParseBoundColumnsClause(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
9,687,985✔
1369
  SToken  token;
1370
  int32_t index = 0;
9,687,985✔
1371
  NEXT_TOKEN_KEEP_SQL(pStmt->pSql, token, index);
9,687,985✔
1372
  if (TK_NK_LP != token.type) {
9,702,036✔
1373
    return TSDB_CODE_SUCCESS;
9,186,946✔
1374
  }
1375

1376
  // pStmt->pSql -> field1_name, ...)
1377
  pStmt->pSql += index;
515,090✔
1378
  pStmt->pBoundCols = pStmt->pSql;
515,090✔
1379
  return skipParentheses(pCxt, &pStmt->pSql);
515,090✔
1380
}
1381

1382
static int32_t getTableDataCxt(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, STableDataCxt** pTableCxt) {
9,660,324✔
1383
  if (pCxt->pComCxt->async) {
9,660,324!
1384
    return insGetTableDataCxt(pStmt->pTableBlockHashObj, &pStmt->pTableMeta->uid, sizeof(pStmt->pTableMeta->uid),
9,681,280✔
1385
                              pStmt->pTableMeta, &pStmt->pCreateTblReq, pTableCxt, false, false);
9,663,655✔
1386
  }
1387

1388
  char    tbFName[TSDB_TABLE_FNAME_LEN];
1389
  int32_t code = tNameExtractFullName(&pStmt->targetTableName, tbFName);
×
1390
  if (TSDB_CODE_SUCCESS != code) {
34!
1391
    return code;
×
1392
  }
1393
  if (pStmt->usingTableProcessing) {
34✔
1394
    pStmt->pTableMeta->uid = 0;
24✔
1395
  }
1396
  return insGetTableDataCxt(pStmt->pTableBlockHashObj, tbFName, strlen(tbFName), pStmt->pTableMeta,
34✔
1397
                            &pStmt->pCreateTblReq, pTableCxt, NULL != pCxt->pComCxt->pStmtCb, false);
34✔
1398
}
1399

1400
static int32_t parseBoundColumnsClause(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, STableDataCxt* pTableCxt) {
9,675,914✔
1401
  SToken  token;
1402
  int32_t index = 0;
9,675,914✔
1403
  NEXT_TOKEN_KEEP_SQL(pStmt->pSql, token, index);
9,675,914✔
1404
  if (TK_NK_LP == token.type) {
9,679,651✔
1405
    pStmt->pSql += index;
170✔
1406
    if (NULL != pStmt->pBoundCols) {
170✔
1407
      return buildSyntaxErrMsg(&pCxt->msg, "keyword VALUES or FILE is expected", token.z);
3✔
1408
    }
1409
    // pStmt->pSql -> field1_name, ...)
1410
    return parseBoundColumns(pCxt, &pStmt->pSql, BOUND_COLUMNS, pStmt->pTableMeta, &pTableCxt->boundColsInfo);
167✔
1411
  }
1412

1413
  if (NULL != pStmt->pBoundCols) {
9,679,481✔
1414
    return parseBoundColumns(pCxt, &pStmt->pBoundCols, BOUND_COLUMNS, pStmt->pTableMeta, &pTableCxt->boundColsInfo);
505,218✔
1415
  } else if (pTableCxt->boundColsInfo.hasBoundCols) {
9,174,263✔
1416
    insResetBoundColsInfo(&pTableCxt->boundColsInfo);
22✔
1417
  }
1418

1419
  return TSDB_CODE_SUCCESS;
9,173,933✔
1420
}
1421

1422
int32_t initTableColSubmitData(STableDataCxt* pTableCxt) {
11,700,588✔
1423
  if (0 == (pTableCxt->pData->flags & SUBMIT_REQ_COLUMN_DATA_FORMAT)) {
11,700,588!
1424
    return TSDB_CODE_SUCCESS;
11,704,115✔
1425
  }
1426

1427
  for (int32_t i = 0; i < pTableCxt->boundColsInfo.numOfBound; ++i) {
×
1428
    SSchema*  pSchema = &pTableCxt->pMeta->schema[pTableCxt->boundColsInfo.pColIndex[i]];
925✔
1429
    SColData* pCol = taosArrayReserve(pTableCxt->pData->aCol, 1);
925✔
1430
    if (NULL == pCol) {
925!
1431
      return terrno;
×
1432
    }
1433
    tColDataInit(pCol, pSchema->colId, pSchema->type, pSchema->flags);
925✔
1434
  }
1435

1436
  return TSDB_CODE_SUCCESS;
×
1437
}
1438

1439
// input pStmt->pSql:
1440
//   1. [(tag1_name, ...)] ...
1441
//   2. VALUES ... | FILE ...
1442
// output pStmt->pSql: VALUES ... | FILE ...
1443
static int32_t parseSchemaClauseBottom(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt,
9,664,129✔
1444
                                       STableDataCxt** pTableCxt) {
1445
  int32_t code = parseUsingClauseBottom(pCxt, pStmt);
9,664,129✔
1446
  if (TSDB_CODE_SUCCESS == code) {
9,667,521✔
1447
    code = getTableDataCxt(pCxt, pStmt, pTableCxt);
9,664,731✔
1448
  }
1449
  if (TSDB_CODE_SUCCESS == code) {
9,682,133✔
1450
    code = parseBoundColumnsClause(pCxt, pStmt, *pTableCxt);
9,679,901✔
1451
  }
1452
  if (TSDB_CODE_SUCCESS == code) {
9,681,342✔
1453
    code = initTableColSubmitData(*pTableCxt);
9,679,334✔
1454
  }
1455
  return code;
9,682,095✔
1456
}
1457

1458
// input pStmt->pSql: [(field1_name, ...)] [ USING ... ] VALUES ... | FILE ...
1459
// output pStmt->pSql:
1460
//   1. [(tag1_name, ...)] ...
1461
//   2. VALUES ... | FILE ...
1462
static int32_t parseSchemaClauseTop(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SToken* pTbName) {
9,671,364✔
1463
  int32_t code = preParseTargetTableName(pCxt, pStmt, pTbName);
9,671,364✔
1464
  if (TSDB_CODE_SUCCESS == code) {
9,696,458!
1465
    // option: [(field1_name, ...)]
1466
    code = preParseBoundColumnsClause(pCxt, pStmt);
9,697,355✔
1467
  }
1468
  if (TSDB_CODE_SUCCESS == code) {
9,701,887!
1469
    // option: [USING stb_name]
1470
    code = parseUsingTableName(pCxt, pStmt);
9,702,932✔
1471
  }
1472
  return code;
9,682,055✔
1473
}
1474

1475
static int32_t parseValueTokenImpl(SInsertParseContext* pCxt, const char** pSql, SToken* pToken, SSchema* pSchema,
1,628,368,855✔
1476
                                   int16_t timePrec, SColVal* pVal) {
1477
  switch (pSchema->type) {
1,628,368,855!
1478
    case TSDB_DATA_TYPE_BOOL: {
41,062,475✔
1479
      if ((pToken->type == TK_NK_BOOL || pToken->type == TK_NK_STRING) && (pToken->n != 0)) {
41,062,475✔
1480
        if (IS_TRUE_STR(pToken->z, pToken->n)) {
32,926,593!
1481
          pVal->value.val = TRUE_VALUE;
19,994,502✔
1482
        } else if (IS_FALSE_STR(pToken->z, pToken->n)) {
12,932,091!
1483
          pVal->value.val = FALSE_VALUE;
13,268,711✔
1484
        } else if (TSDB_CODE_SUCCESS == toDoubleEx(pToken->z, pToken->n, pToken->type, (double*)&pVal->value.val)) {
✔
1485
          *(int8_t*)(&pVal->value.val) = (*(double*)&pVal->value.val == 0 ? FALSE_VALUE : TRUE_VALUE);
389✔
1486
        } else {
1487
          return buildSyntaxErrMsg(&pCxt->msg, "invalid bool data", pToken->z);
510✔
1488
        }
1489
      } else if (pToken->type == TK_NK_INTEGER) {
8,135,882✔
1490
        pVal->value.val = ((taosStr2Int64(pToken->z, NULL, 10) == 0) ? FALSE_VALUE : TRUE_VALUE);
8,132,635✔
1491
      } else if (pToken->type == TK_NK_FLOAT) {
3,247✔
1492
        pVal->value.val = ((taosStr2Double(pToken->z, NULL) == 0) ? FALSE_VALUE : TRUE_VALUE);
154✔
1493
      } else if ((pToken->type == TK_NK_HEX || pToken->type == TK_NK_BIN) &&
3,245!
1494
                 (TSDB_CODE_SUCCESS == toDoubleEx(pToken->z, pToken->n, pToken->type, (double*)&pVal->value.val))) {
2,878✔
1495
        *(int8_t*)(&pVal->value.val) = (*(double*)&pVal->value.val == 0 ? FALSE_VALUE : TRUE_VALUE);
152✔
1496
      } else {
1497
        return buildSyntaxErrMsg(&pCxt->msg, "invalid bool data", pToken->z);
215✔
1498
      }
1499
      break;
41,395,477✔
1500
    }
1501
    case TSDB_DATA_TYPE_TINYINT: {
45,621,147✔
1502
      int32_t code = toIntegerEx(pToken->z, pToken->n, pToken->type, &pVal->value.val);
45,621,147✔
1503
      if (TSDB_CODE_SUCCESS != code) {
45,676,127✔
1504
        return buildSyntaxErrMsg(&pCxt->msg, "invalid tinyint data", pToken->z);
812✔
1505
      } else if (!IS_VALID_TINYINT(pVal->value.val)) {
45,675,315!
1506
        return buildSyntaxErrMsg(&pCxt->msg, "tinyint data overflow", pToken->z);
×
1507
      }
1508
      break;
45,698,296✔
1509
    }
1510
    case TSDB_DATA_TYPE_UTINYINT: {
38,722,072✔
1511
      int32_t code = toUIntegerEx(pToken->z, pToken->n, pToken->type, &pVal->value.val);
38,722,072✔
1512
      if (TSDB_CODE_SUCCESS != code) {
38,753,592✔
1513
        return buildSyntaxErrMsg(&pCxt->msg, "invalid unsigned tinyint data", pToken->z);
2,152✔
1514
      } else if (pVal->value.val > UINT8_MAX) {
38,751,440✔
1515
        return buildSyntaxErrMsg(&pCxt->msg, "unsigned tinyint data overflow", pToken->z);
11✔
1516
      }
1517
      break;
38,751,429✔
1518
    }
1519
    case TSDB_DATA_TYPE_SMALLINT: {
45,504,975✔
1520
      int32_t code = toIntegerEx(pToken->z, pToken->n, pToken->type, &pVal->value.val);
45,504,975✔
1521
      if (TSDB_CODE_SUCCESS != code) {
45,603,937✔
1522
        return buildSyntaxErrMsg(&pCxt->msg, "invalid smallint data", pToken->z);
812✔
1523
      } else if (!IS_VALID_SMALLINT(pVal->value.val)) {
45,603,125!
1524
        return buildSyntaxErrMsg(&pCxt->msg, "smallint data overflow", pToken->z);
7,022✔
1525
      }
1526
      break;
45,596,103✔
1527
    }
1528
    case TSDB_DATA_TYPE_USMALLINT: {
38,603,447✔
1529
      int32_t code = toUIntegerEx(pToken->z, pToken->n, pToken->type, &pVal->value.val);
38,603,447✔
1530
      if (TSDB_CODE_SUCCESS != code) {
38,677,382!
1531
        return buildSyntaxErrMsg(&pCxt->msg, "invalid unsigned smallint data", pToken->z);
×
1532
      } else if (pVal->value.val > UINT16_MAX) {
38,691,070✔
1533
        return buildSyntaxErrMsg(&pCxt->msg, "unsigned smallint data overflow", pToken->z);
11✔
1534
      }
1535
      break;
38,691,059✔
1536
    }
1537
    case TSDB_DATA_TYPE_INT: {
520,410,811✔
1538
      int32_t code = toIntegerEx(pToken->z, pToken->n, pToken->type, &pVal->value.val);
520,410,811✔
1539
      if (TSDB_CODE_SUCCESS != code) {
534,884,742✔
1540
        return buildSyntaxErrMsg(&pCxt->msg, "invalid int data", pToken->z);
812✔
1541
      } else if (!IS_VALID_INT(pVal->value.val)) {
534,883,930!
1542
        return buildSyntaxErrMsg(&pCxt->msg, "int data overflow", pToken->z);
×
1543
      }
1544
      break;
536,658,253✔
1545
    }
1546
    case TSDB_DATA_TYPE_UINT: {
38,679,850✔
1547
      int32_t code = toUIntegerEx(pToken->z, pToken->n, pToken->type, &pVal->value.val);
38,679,850✔
1548
      if (TSDB_CODE_SUCCESS != code) {
38,766,129✔
1549
        return buildSyntaxErrMsg(&pCxt->msg, "invalid unsigned int data", pToken->z);
22,604✔
1550
      } else if (pVal->value.val > UINT32_MAX) {
38,743,525✔
1551
        return buildSyntaxErrMsg(&pCxt->msg, "unsigned int data overflow", pToken->z);
13✔
1552
      }
1553
      break;
38,743,512✔
1554
    }
1555
    case TSDB_DATA_TYPE_BIGINT: {
267,603,612✔
1556
      int32_t code = toIntegerEx(pToken->z, pToken->n, pToken->type, &pVal->value.val);
267,603,612✔
1557
      if (TSDB_CODE_SUCCESS != code) {
272,433,151✔
1558
        return buildSyntaxErrMsg(&pCxt->msg, "invalid bigint data", pToken->z);
284,431✔
1559
      }
1560
      break;
272,148,720✔
1561
    }
1562
    case TSDB_DATA_TYPE_UBIGINT: {
38,703,644✔
1563
      int32_t code = toUIntegerEx(pToken->z, pToken->n, pToken->type, &pVal->value.val);
38,703,644✔
1564
      if (TSDB_CODE_SUCCESS != code) {
38,786,462!
1565
        return buildSyntaxErrMsg(&pCxt->msg, "invalid unsigned bigint data", pToken->z);
×
1566
      }
1567
      break;
38,790,494✔
1568
    }
1569
    case TSDB_DATA_TYPE_FLOAT: {
91,081,173✔
1570
      double  dv;
1571
      int32_t code = toDoubleEx(pToken->z, pToken->n, pToken->type, &dv);
91,081,173✔
1572
      if (TSDB_CODE_SUCCESS != code) {
91,950,295✔
1573
        return buildSyntaxErrMsg(&pCxt->msg, "illegal float data", pToken->z);
825✔
1574
      }
1575
      if (dv > FLT_MAX || dv < -FLT_MAX || isinf(dv) || isnan(dv)) {
91,949,485!
1576
        return buildSyntaxErrMsg(&pCxt->msg, "illegal float data", pToken->z);
×
1577
      }
1578
      float f = dv;
91,995,682✔
1579
      memcpy(&pVal->value.val, &f, sizeof(f));
91,995,682✔
1580
      break;
91,995,682✔
1581
    }
1582
    case TSDB_DATA_TYPE_DOUBLE: {
65,322,490✔
1583
      double  dv;
1584
      int32_t code = toDoubleEx(pToken->z, pToken->n, pToken->type, &dv);
65,322,490✔
1585
      if (TSDB_CODE_SUCCESS != code) {
65,691,140!
1586
        return buildSyntaxErrMsg(&pCxt->msg, "illegal float data", pToken->z);
×
1587
      }
1588
      if (isinf(dv) || isnan(dv)) {
65,715,238!
1589
        return buildSyntaxErrMsg(&pCxt->msg, "illegal double data", pToken->z);
5,921✔
1590
      }
1591
      pVal->value.val = *(int64_t*)&dv;
65,709,317✔
1592
      break;
65,709,317✔
1593
    }
1594
    case TSDB_DATA_TYPE_BINARY: {
69,358,337✔
1595
      // Too long values will raise the invalid sql error message
1596
      if (pToken->n + VARSTR_HEADER_SIZE > pSchema->bytes) {
69,358,337✔
1597
        return generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name);
40✔
1598
      }
1599
      pVal->value.pData = taosMemoryMalloc(pToken->n);
69,358,297✔
1600
      if (NULL == pVal->value.pData) {
69,337,570!
1601
        return terrno;
×
1602
      }
1603
      memcpy(pVal->value.pData, pToken->z, pToken->n);
69,342,510✔
1604
      pVal->value.nData = pToken->n;
69,342,510✔
1605
      break;
69,342,510✔
1606
    }
1607
    case TSDB_DATA_TYPE_VARBINARY: {
10,662,408✔
1608
      int32_t code = parseVarbinary(pToken, &pVal->value.pData, &pVal->value.nData, pSchema->bytes);
10,662,408✔
1609
      if (code != TSDB_CODE_SUCCESS) {
10,662,408✔
1610
        return generateSyntaxErrMsg(&pCxt->msg, code, pSchema->name);
540✔
1611
      }
1612
      break;
10,661,868✔
1613
    }
1614
    case TSDB_DATA_TYPE_NCHAR: {
59,070,866✔
1615
      // if the converted output len is over than pColumnModel->bytes, return error: 'Argument list too long'
1616
      int32_t len = 0;
59,070,866✔
1617
      int64_t realLen = pToken->n << 2;
59,070,866✔
1618
      if (realLen > pSchema->bytes - VARSTR_HEADER_SIZE) realLen = pSchema->bytes - VARSTR_HEADER_SIZE;
59,070,866✔
1619
      char* pUcs4 = taosMemoryMalloc(realLen);
59,070,866✔
1620
      if (NULL == pUcs4) {
59,064,477!
1621
        return terrno;
20✔
1622
      }
1623
      if (!taosMbsToUcs4(pToken->z, pToken->n, (TdUcs4*)pUcs4, realLen, &len)) {
59,064,477✔
1624
        taosMemoryFree(pUcs4);
4,415✔
1625
        if (terrno == TAOS_SYSTEM_ERROR(E2BIG)) {
20!
1626
          return generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name);
20✔
1627
        }
1628
        char buf[512] = {0};
×
1629
        snprintf(buf, tListLen(buf), "%s", strerror(terrno));
×
1630
        return buildSyntaxErrMsg(&pCxt->msg, buf, pToken->z);
×
1631
      }
1632
      pVal->value.pData = pUcs4;
59,254,062✔
1633
      pVal->value.nData = len;
59,254,062✔
1634
      break;
59,254,062✔
1635
    }
1636
    case TSDB_DATA_TYPE_JSON: {
×
1637
      if (pToken->n > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) {
×
1638
        return buildSyntaxErrMsg(&pCxt->msg, "json string too long than 4095", pToken->z);
×
1639
      }
1640
      pVal->value.pData = taosMemoryMalloc(pToken->n);
×
1641
      if (NULL == pVal->value.pData) {
×
1642
        return terrno;
×
1643
      }
1644
      memcpy(pVal->value.pData, pToken->z, pToken->n);
×
1645
      pVal->value.nData = pToken->n;
×
1646
      break;
×
1647
    }
1648
    case TSDB_DATA_TYPE_GEOMETRY: {
7,991✔
1649
      int32_t        code = TSDB_CODE_FAILED;
7,991✔
1650
      unsigned char* output = NULL;
7,991✔
1651
      size_t         size = 0;
7,991✔
1652

1653
      code = parseGeometry(pToken, &output, &size);
7,991✔
1654
      if (code != TSDB_CODE_SUCCESS) {
7,991✔
1655
        code = buildSyntaxErrMsg(&pCxt->msg, getGeosErrMsg(code), pToken->z);
1,266✔
1656
      }
1657
      // Too long values will raise the invalid sql error message
1658
      else if (size + VARSTR_HEADER_SIZE > pSchema->bytes) {
6,725!
1659
        code = generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_VALUE_TOO_LONG, pSchema->name);
×
1660
      } else {
1661
        pVal->value.pData = taosMemoryMalloc(size);
6,725✔
1662
        if (NULL == pVal->value.pData) {
6,725!
1663
          code = terrno;
×
1664
        } else {
1665
          memcpy(pVal->value.pData, output, size);
6,725✔
1666
          pVal->value.nData = size;
6,725✔
1667
        }
1668
      }
1669

1670
      geosFreeBuffer(output);
7,991✔
1671
      if (code != TSDB_CODE_SUCCESS) {
7,991✔
1672
        return code;
1,266✔
1673
      }
1674

1675
      break;
6,725✔
1676
    }
1677
    case TSDB_DATA_TYPE_TIMESTAMP: {
352,607,790✔
1678
      if (parseTime(pSql, pToken, timePrec, &pVal->value.val, &pCxt->msg) != TSDB_CODE_SUCCESS) {
352,607,790!
1679
        return buildSyntaxErrMsg(&pCxt->msg, "invalid timestamp", pToken->z);
×
1680
      }
1681
      break;
358,969,514✔
1682
    }
1683
    default:
×
1684
      return TSDB_CODE_FAILED;
×
1685
  }
1686

1687
  pVal->flag = CV_FLAG_VALUE;
1,752,413,021✔
1688
  return TSDB_CODE_SUCCESS;
1,752,413,021✔
1689
}
1690

1691
static int32_t parseValueToken(SInsertParseContext* pCxt, const char** pSql, SToken* pToken, SSchema* pSchema,
1,654,907,375✔
1692
                               int16_t timePrec, SColVal* pVal) {
1693
  int32_t code = checkAndTrimValue(pToken, pCxt->tmpTokenBuf, &pCxt->msg, pSchema->type);
1,654,907,375✔
1694
  if (TSDB_CODE_SUCCESS == code && isNullValue(pSchema->type, pToken)) {
2,147,483,647✔
1695
    if (TSDB_DATA_TYPE_TIMESTAMP == pSchema->type && PRIMARYKEY_TIMESTAMP_COL_ID == pSchema->colId) {
21,886,818✔
1696
      return buildSyntaxErrMsg(&pCxt->msg, "Primary timestamp column should not be null", pToken->z);
1✔
1697
    }
1698

1699
    pVal->flag = CV_FLAG_NULL;
21,886,817✔
1700
    return TSDB_CODE_SUCCESS;
21,886,817✔
1701
  }
1702

1703
  if (TSDB_CODE_SUCCESS == code) {
1,629,227,089!
1704
    if (pToken->n == 0 && IS_NUMERIC_TYPE(pSchema->type)) {
1,630,146,650!
1705
      return buildSyntaxErrMsg(&pCxt->msg, "invalid numeric data", pToken->z);
59✔
1706
    }
1707
    code = parseValueTokenImpl(pCxt, pSql, pToken, pSchema, timePrec, pVal);
1,630,146,591✔
1708
  }
1709

1710
  return code;
1,658,605,100✔
1711
}
1712

1713
static void clearColValArray(SArray* pCols) {
333,221,683✔
1714
  int32_t num = taosArrayGetSize(pCols);
333,221,683✔
1715
  for (int32_t i = 0; i < num; ++i) {
2,110,735,458✔
1716
    SColVal* pCol = taosArrayGet(pCols, i);
1,778,198,625✔
1717
    if (IS_VAR_DATA_TYPE(pCol->value.type)) {
1,777,390,784!
1718
      taosMemoryFreeClear(pCol->value.pData);
146,005,069✔
1719
    }
1720
  }
1721
}
332,536,833✔
1722

1723
typedef struct SStbRowsDataContext {
1724
  SName stbName;
1725

1726
  STableMeta*   pStbMeta;
1727
  SNode*        pTagCond;
1728
  SBoundColInfo boundColsInfo;
1729

1730
  // the following fields are for each stb row
1731
  SArray*        aTagVals;
1732
  SArray*        aColVals;
1733
  SArray*        aTagNames;
1734
  SName          ctbName;
1735
  STag*          pTag;
1736
  STableMeta*    pCtbMeta;
1737
  SVCreateTbReq* pCreateCtbReq;
1738
  bool           hasTimestampTag;
1739
  bool           isJsonTag;
1740
} SStbRowsDataContext;
1741

1742
typedef union SRowsDataContext {
1743
  STableDataCxt*       pTableDataCxt;
1744
  SStbRowsDataContext* pStbRowsCxt;
1745
} SRowsDataContext;
1746

1747
int32_t parseTbnameToken(SMsgBuf* pMsgBuf, char* tname, SToken* pToken, bool* pFoundCtbName) {
2,029,495✔
1748
  *pFoundCtbName = false;
2,029,495!
1749

1750
  if (isNullValue(TSDB_DATA_TYPE_BINARY, pToken)) {
2,029,495!
1751
    return buildInvalidOperationMsg(pMsgBuf, "tbname can not be null value");
×
1752
  }
1753

1754
  if (pToken->n > 0) {
2,029,495✔
1755
    if (pToken->n <= TSDB_TABLE_NAME_LEN - 1) {
2,029,494!
1756
      for (int i = 0; i < pToken->n; ++i) {
19,289,324✔
1757
        if (pToken->z[i] == '.') {
17,259,831✔
1758
          return buildInvalidOperationMsg(pMsgBuf, "tbname can not contain '.'");
1✔
1759
        } else {
1760
          tname[i] = pToken->z[i];
17,259,830✔
1761
        }
1762
      }
1763
      tname[pToken->n] = '\0';
2,029,493✔
1764
      *pFoundCtbName = true;
2,029,493✔
1765
    } else {
1766
      return buildInvalidOperationMsg(pMsgBuf, "tbname is too long");
×
1767
    }
1768
  } else {
1769
    return buildInvalidOperationMsg(pMsgBuf, "tbname can not be empty");
1✔
1770
  }
1771
  return TSDB_CODE_SUCCESS;
2,029,493✔
1772
}
1773

1774
static int32_t processCtbTagsAfterCtbName(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt,
2,024,788✔
1775
                                          SStbRowsDataContext* pStbRowsCxt, bool ctbFirst, const SToken* tagTokens,
1776
                                          SSchema* const* tagSchemas, int numOfTagTokens) {
1777
  int32_t code = TSDB_CODE_SUCCESS;
2,024,788✔
1778
  uint8_t precision = pStmt->pTableMeta->tableInfo.precision;
2,024,788✔
1779

1780
  if (code == TSDB_CODE_SUCCESS && ctbFirst) {
2,024,788!
1781
    for (int32_t i = 0; code == TSDB_CODE_SUCCESS && i < numOfTagTokens; ++i) {
18,972✔
1782
      SToken*  pTagToken = (SToken*)(tagTokens + i);
8,288✔
1783
      SSchema* pTagSchema = tagSchemas[i];
8,288✔
1784
      code = checkAndTrimValue(pTagToken, pCxt->tmpTokenBuf, &pCxt->msg, pTagSchema->type);
8,288✔
1785
      if (code == TSDB_CODE_SUCCESS && TK_NK_VARIABLE == pTagToken->type) {
8,288!
1786
        code = buildInvalidOperationMsg(&pCxt->msg, "not expected tag");
×
1787
      }
1788

1789
      if (code == TSDB_CODE_SUCCESS) {
8,288✔
1790
        code = parseTagValue(&pCxt->msg, NULL, precision, pTagSchema, pTagToken, pStbRowsCxt->aTagNames,
8,047✔
1791
                             pStbRowsCxt->aTagVals, &pStbRowsCxt->pTag);
1792
      }
1793
    }
1794
    if (code == TSDB_CODE_SUCCESS && !pStbRowsCxt->isJsonTag) {
10,684!
1795
      code = tTagNew(pStbRowsCxt->aTagVals, 1, false, &pStbRowsCxt->pTag);
9,356✔
1796
    }
1797
  }
1798

1799
  if (code == TSDB_CODE_SUCCESS && pStbRowsCxt->pTagCond) {
2,024,788!
1800
    code = checkSubtablePrivilege(pStbRowsCxt->aTagVals, pStbRowsCxt->aTagNames, &pStbRowsCxt->pTagCond);
×
1801
  }
1802
  return code;
2,024,788✔
1803
}
1804

1805
static int32_t doGetStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, const char** ppSql,
2,029,520✔
1806
                                 SStbRowsDataContext* pStbRowsCxt, SToken* pToken, const SBoundColInfo* pCols,
1807
                                 const SSchema* pSchemas, SToken* tagTokens, SSchema** tagSchemas, int* pNumOfTagTokens,
1808
                                 bool* bFoundTbName) {
1809
  int32_t code = TSDB_CODE_SUCCESS;
2,029,520✔
1810
  SArray* pTagNames = pStbRowsCxt->aTagNames;
2,029,520✔
1811
  SArray* pTagVals = pStbRowsCxt->aTagVals;
2,029,520✔
1812
  bool    canParseTagsAfter = !pStbRowsCxt->pTagCond && !pStbRowsCxt->hasTimestampTag;
2,029,520!
1813
  int32_t numOfCols = getNumOfColumns(pStbRowsCxt->pStbMeta);
2,029,520✔
1814
  int32_t tbnameIdx = getTbnameSchemaIndex(pStbRowsCxt->pStbMeta);
2,029,520✔
1815
  uint8_t precision = getTableInfo(pStbRowsCxt->pStbMeta).precision;
2,029,520✔
1816
  for (int i = 0; i < pCols->numOfBound && (code) == TSDB_CODE_SUCCESS; ++i) {
10,224,021✔
1817
    const char* pTmpSql = *ppSql;
8,194,501✔
1818
    bool        ignoreComma = false;
8,194,501✔
1819
    NEXT_TOKEN_WITH_PREV_EXT(*ppSql, *pToken, &ignoreComma);
8,194,501✔
1820

1821
    if (ignoreComma) {
8,194,501!
1822
      code = buildSyntaxErrMsg(&pCxt->msg, "invalid data or symbol", pTmpSql);
×
1823
      break;
×
1824
    }
1825

1826
    if (TK_NK_RP == pToken->type) {
8,194,501!
1827
      code = generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_INVALID_COLUMNS_NUM);
×
1828
      break;
×
1829
    }
1830

1831
    if (TK_NK_QUESTION == pToken->type) {
8,194,501!
1832
      pCxt->isStmtBind = true;
×
1833
      if (pCols->pColIndex[i] == tbnameIdx) {
×
1834
        *bFoundTbName = true;
×
1835
      }
1836
      if (NULL == pCxt->pComCxt->pStmtCb) {
×
1837
        code = buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", pToken->z);
×
1838
        break;
×
1839
      }
1840
    } else {
1841
      if (pCols->pColIndex[i] < numOfCols) {
8,194,501✔
1842
        const SSchema* pSchema = &pSchemas[pCols->pColIndex[i]];
6,147,026✔
1843
        SColVal*       pVal = taosArrayGet(pStbRowsCxt->aColVals, pCols->pColIndex[i]);
6,147,026✔
1844
        code = parseValueToken(pCxt, ppSql, pToken, (SSchema*)pSchema, precision, pVal);
6,147,026✔
1845
        if (TK_NK_VARIABLE == pToken->type) {
6,147,026!
1846
          code = buildInvalidOperationMsg(&pCxt->msg, "not expected row value");
×
1847
        }
1848
      } else if (pCols->pColIndex[i] < tbnameIdx) {
2,047,475✔
1849
        const SSchema* pTagSchema = &pSchemas[pCols->pColIndex[i]];
17,956✔
1850
        if (canParseTagsAfter) {
17,956✔
1851
          tagTokens[(*pNumOfTagTokens)] = *pToken;
17,064✔
1852
          tagSchemas[(*pNumOfTagTokens)] = (SSchema*)pTagSchema;
17,064✔
1853
          ++(*pNumOfTagTokens);
17,064✔
1854
        } else {
1855
          code = checkAndTrimValue(pToken, pCxt->tmpTokenBuf, &pCxt->msg, pTagSchema->type);
892✔
1856
          if (code == TSDB_CODE_SUCCESS && TK_NK_VARIABLE == pToken->type) {
892!
1857
            code = buildInvalidOperationMsg(&pCxt->msg, "not expected row value");
×
1858
          }
1859
          if (code == TSDB_CODE_SUCCESS) {
892✔
1860
            code = parseTagValue(&pCxt->msg, ppSql, precision, (SSchema*)pTagSchema, pToken, pTagNames, pTagVals,
854✔
1861
                                 &pStbRowsCxt->pTag);
1862
          }
1863
        }
1864
      } else if (pCols->pColIndex[i] == tbnameIdx) {
2,029,519!
1865
        code = checkAndTrimValue(pToken, pCxt->tmpTokenBuf, &pCxt->msg, TSDB_DATA_TYPE_BINARY);
2,029,519✔
1866
        if (TK_NK_VARIABLE == pToken->type) {
2,029,519!
1867
          code = buildInvalidOperationMsg(&pCxt->msg, "not expected tbname");
×
1868
        }
1869

1870
        if (code == TSDB_CODE_SUCCESS) {
2,029,519✔
1871
          code = parseTbnameToken(&pCxt->msg, pStbRowsCxt->ctbName.tname, pToken, bFoundTbName);
2,029,495✔
1872
        }
1873
      }
1874
    }
1875

1876
    if (code == TSDB_CODE_SUCCESS && i < pCols->numOfBound - 1) {
8,194,501✔
1877
      NEXT_VALID_TOKEN(*ppSql, *pToken);
6,168,102✔
1878
      if (TK_NK_COMMA != pToken->type) {
6,166,218✔
1879
        code = buildSyntaxErrMsg(&pCxt->msg, ", expected", pToken->z);
1,237✔
1880
      }
1881
    }
1882
  }
1883
  return code;
2,029,520✔
1884
}
1885

1886
static int32_t getStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, const char** ppSql,
2,029,520✔
1887
                               SStbRowsDataContext* pStbRowsCxt, bool* pGotRow, SToken* pToken, bool* pCtbFirst) {
1888
  SBoundColInfo* pCols = &pStbRowsCxt->boundColsInfo;
2,029,520✔
1889
  SSchema*       pSchemas = getTableColumnSchema(pStbRowsCxt->pStbMeta);
2,029,520✔
1890

1891
  bool        bFoundTbName = false;
2,029,520✔
1892
  const char* pOrigSql = *ppSql;
2,029,520✔
1893

1894
  int32_t  code = TSDB_CODE_SUCCESS;
2,029,520✔
1895
  SToken   tagTokens[TSDB_MAX_TAGS] = {0};
2,029,520✔
1896
  SSchema* tagSchemas[TSDB_MAX_TAGS] = {0};
2,029,520✔
1897
  int      numOfTagTokens = 0;
2,029,520✔
1898

1899
  code = doGetStbRowValues(pCxt, pStmt, ppSql, pStbRowsCxt, pToken, pCols, pSchemas, tagTokens, tagSchemas,
2,029,520✔
1900
                           &numOfTagTokens, &bFoundTbName);
1901

1902
  if (code == TSDB_CODE_SUCCESS && !bFoundTbName) {
2,029,520!
1903
    code = buildSyntaxErrMsg(&pCxt->msg, "tbname value expected", pOrigSql);
×
1904
  }
1905

1906
  if (code == TSDB_CODE_SUCCESS && pStbRowsCxt->ctbName.tname[0] == '\0') {
2,029,520!
1907
    *pGotRow = true;
×
1908
    return TSDB_CODE_TSC_STMT_TBNAME_ERROR;
×
1909
  }
1910

1911
  bool ctbFirst = true;
2,029,520✔
1912
  char ctbFName[TSDB_TABLE_FNAME_LEN];
1913
  if (code == TSDB_CODE_SUCCESS) {
2,029,520✔
1914
    code = tNameExtractFullName(&pStbRowsCxt->ctbName, ctbFName);
2,024,788✔
1915
  }
1916
  if (TSDB_CODE_SUCCESS == code) {
2,029,520✔
1917
    STableMeta** pCtbMeta = taosHashGet(pStmt->pSubTableHashObj, ctbFName, strlen(ctbFName));
2,024,788✔
1918
    ctbFirst = (pCtbMeta == NULL);
2,024,788✔
1919
    if (!ctbFirst) {
2,024,788✔
1920
      pStbRowsCxt->pCtbMeta->uid = (*pCtbMeta)->uid;
2,014,104✔
1921
      pStbRowsCxt->pCtbMeta->vgId = (*pCtbMeta)->vgId;
2,014,104✔
1922
    }
1923
    *pCtbFirst = ctbFirst;
2,024,788✔
1924
  }
1925

1926
  if (code == TSDB_CODE_SUCCESS) {
2,029,520✔
1927
    code = processCtbTagsAfterCtbName(pCxt, pStmt, pStbRowsCxt, ctbFirst, tagTokens, tagSchemas, numOfTagTokens);
2,024,788✔
1928
  }
1929

1930
  if (code == TSDB_CODE_SUCCESS) {
2,029,520✔
1931
    *pGotRow = true;
2,023,460✔
1932
  }
1933
  return code;
2,029,520✔
1934
}
1935

1936
static int32_t processCtbAutoCreationAndCtbMeta(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt,
9,356✔
1937
                                                SStbRowsDataContext* pStbRowsCxt) {
1938
  int32_t code = TSDB_CODE_SUCCESS;
9,356✔
1939

1940
  pStbRowsCxt->pCreateCtbReq = taosMemoryCalloc(1, sizeof(SVCreateTbReq));
9,356✔
1941
  if (pStbRowsCxt->pCreateCtbReq == NULL) {
9,356!
1942
    code = terrno;
×
1943
  }
1944
  if (code == TSDB_CODE_SUCCESS) {
9,356!
1945
    code = insBuildCreateTbReq(pStbRowsCxt->pCreateCtbReq, pStbRowsCxt->ctbName.tname, pStbRowsCxt->pTag,
9,356✔
1946
                               pStbRowsCxt->pStbMeta->uid, pStbRowsCxt->stbName.tname, pStbRowsCxt->aTagNames,
9,356✔
1947
                               getNumOfTags(pStbRowsCxt->pStbMeta), TSDB_DEFAULT_TABLE_TTL);
9,356✔
1948
    pStbRowsCxt->pTag = NULL;
9,356✔
1949
  }
1950

1951
  if (code == TSDB_CODE_SUCCESS) {
9,356!
1952
    char ctbFName[TSDB_TABLE_FNAME_LEN];
1953
    code = tNameExtractFullName(&pStbRowsCxt->ctbName, ctbFName);
9,356✔
1954
    SVgroupInfo      vg;
1955
    SRequestConnInfo conn = {.pTrans = pCxt->pComCxt->pTransporter,
9,356✔
1956
                             .requestId = pCxt->pComCxt->requestId,
9,356✔
1957
                             .requestObjRefId = pCxt->pComCxt->requestRid,
9,356✔
1958
                             .mgmtEps = pCxt->pComCxt->mgmtEpSet};
9,356✔
1959
    if (TSDB_CODE_SUCCESS == code) {
9,356!
1960
      code = catalogGetTableHashVgroup(pCxt->pComCxt->pCatalog, &conn, &pStbRowsCxt->ctbName, &vg);
9,356✔
1961
    }
1962
    if (code == TSDB_CODE_SUCCESS) {
9,356!
1963
      code = taosHashPut(pStmt->pVgroupsHashObj, (const char*)(&vg.vgId), sizeof(vg.vgId), &vg, sizeof(vg));
9,356✔
1964
    }
1965
    STableMeta* pBackup = NULL;
9,356✔
1966
    if (TSDB_CODE_SUCCESS == code) {
9,356!
1967
      pStbRowsCxt->pCtbMeta->uid = taosHashGetSize(pStmt->pSubTableHashObj) + 1;
9,356✔
1968
      pStbRowsCxt->pCtbMeta->vgId = vg.vgId;
9,356✔
1969

1970
      code = cloneTableMeta(pStbRowsCxt->pCtbMeta, &pBackup);
9,356✔
1971
    }
1972
    if (TSDB_CODE_SUCCESS == code) {
9,356!
1973
      code = taosHashPut(pStmt->pSubTableHashObj, ctbFName, strlen(ctbFName), &pBackup, POINTER_BYTES);
9,356✔
1974
    }
1975
    if (TSDB_CODE_SUCCESS == code) {
9,356!
1976
      code = collectUseTable(&pStbRowsCxt->ctbName, pStmt->pTableNameHashObj);
9,356✔
1977
    }
1978
  }
1979
  return code;
9,356✔
1980
}
1981

1982
static void clearStbRowsDataContext(SStbRowsDataContext* pStbRowsCxt) {
2,034,017✔
1983
  if (pStbRowsCxt == NULL) return;
2,034,017!
1984

1985
  taosArrayClear(pStbRowsCxt->aTagNames);
2,034,017✔
1986
  for (int i = 0; i < taosArrayGetSize(pStbRowsCxt->aTagVals); ++i) {
2,041,211✔
1987
    STagVal* p = (STagVal*)taosArrayGet(pStbRowsCxt->aTagVals, i);
7,194✔
1988
    if (IS_VAR_DATA_TYPE(p->type)) {
7,194!
1989
      taosMemoryFreeClear(p->pData);
3,128!
1990
    }
1991
  }
1992
  taosArrayClear(pStbRowsCxt->aTagVals);
2,034,017✔
1993

1994
  clearColValArray(pStbRowsCxt->aColVals);
2,034,017✔
1995

1996
  tTagFree(pStbRowsCxt->pTag);
2,034,017✔
1997
  pStbRowsCxt->pTag = NULL;
2,034,017✔
1998
  tdDestroySVCreateTbReq(pStbRowsCxt->pCreateCtbReq);
2,034,017!
1999
  taosMemoryFreeClear(pStbRowsCxt->pCreateCtbReq);
2,034,017!
2000
}
2001

2002
static int32_t parseStbBoundInfo(SVnodeModifyOpStmt* pStmt, SStbRowsDataContext* pStbRowsCxt,
×
2003
                                 STableDataCxt** ppTableDataCxt) {
2004
  char    tbFName[TSDB_TABLE_FNAME_LEN];
2005
  int32_t code = tNameExtractFullName(&pStmt->targetTableName, tbFName);
×
2006
  if (TSDB_CODE_SUCCESS != code) {
×
2007
    return code;
×
2008
  }
2009
  if (pStmt->usingTableProcessing) {
×
2010
    pStmt->pTableMeta->uid = 0;
×
2011
  }
2012

2013
  code = insGetTableDataCxt(pStmt->pTableBlockHashObj, tbFName, strlen(tbFName), pStmt->pTableMeta,
×
2014
                            &pStmt->pCreateTblReq, ppTableDataCxt, false, true);
2015
  if (code != TSDB_CODE_SUCCESS) {
×
2016
    return code;
×
2017
  }
2018

2019
  insDestroyBoundColInfo(&((*ppTableDataCxt)->boundColsInfo));
×
2020
  (*ppTableDataCxt)->boundColsInfo = pStbRowsCxt->boundColsInfo;
×
2021
  (*ppTableDataCxt)->boundColsInfo.numOfCols = pStbRowsCxt->boundColsInfo.numOfBound;
×
2022
  (*ppTableDataCxt)->boundColsInfo.numOfBound = pStbRowsCxt->boundColsInfo.numOfBound;
×
2023
  (*ppTableDataCxt)->boundColsInfo.hasBoundCols = pStbRowsCxt->boundColsInfo.hasBoundCols;
×
2024
  (*ppTableDataCxt)->boundColsInfo.pColIndex = taosMemoryCalloc(pStbRowsCxt->boundColsInfo.numOfBound, sizeof(int16_t));
×
2025
  if (NULL == (*ppTableDataCxt)->boundColsInfo.pColIndex) {
×
2026
    return terrno;
×
2027
  }
2028
  (void)memcpy((*ppTableDataCxt)->boundColsInfo.pColIndex, pStbRowsCxt->boundColsInfo.pColIndex,
×
2029
               sizeof(int16_t) * pStmt->pStbRowsCxt->boundColsInfo.numOfBound);
×
2030
  return TSDB_CODE_SUCCESS;
×
2031
}
2032

2033
static int32_t parseOneStbRow(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, const char** ppSql,
2,029,520✔
2034
                              SStbRowsDataContext* pStbRowsCxt, bool* pGotRow, SToken* pToken,
2035
                              STableDataCxt** ppTableDataCxt) {
2036
  bool    bFirstTable = false;
2,029,520✔
2037
  int32_t code = getStbRowValues(pCxt, pStmt, ppSql, pStbRowsCxt, pGotRow, pToken, &bFirstTable);
2,029,520✔
2038

2039
  if (code == TSDB_CODE_TSC_STMT_TBNAME_ERROR && *pGotRow) {
2,029,520!
2040
    return parseStbBoundInfo(pStmt, pStbRowsCxt, ppTableDataCxt);
×
2041
  }
2042

2043
  if (code != TSDB_CODE_SUCCESS || !*pGotRow) {
2,029,520!
2044
    return code;
6,060✔
2045
  }
2046

2047
  if (code == TSDB_CODE_SUCCESS && bFirstTable) {
2,023,460!
2048
    code = processCtbAutoCreationAndCtbMeta(pCxt, pStmt, pStbRowsCxt);
9,356✔
2049
  }
2050
  if (code == TSDB_CODE_SUCCESS) {
2,023,460!
2051
    code =
2052
        insGetTableDataCxt(pStmt->pTableBlockHashObj, &pStbRowsCxt->pCtbMeta->uid, sizeof(pStbRowsCxt->pCtbMeta->uid),
2,023,460✔
2053
                           pStbRowsCxt->pCtbMeta, &pStbRowsCxt->pCreateCtbReq, ppTableDataCxt, false, true);
2054
  }
2055
  if (code == TSDB_CODE_SUCCESS) {
2,023,460!
2056
    code = initTableColSubmitData(*ppTableDataCxt);
2,023,460✔
2057
  }
2058
  if (code == TSDB_CODE_SUCCESS) {
2,023,460!
2059
    SRow** pRow = taosArrayReserve((*ppTableDataCxt)->pData->aRowP, 1);
2,023,460✔
2060
    code = tRowBuild(pStbRowsCxt->aColVals, (*ppTableDataCxt)->pSchema, pRow);
2,023,460✔
2061
    if (TSDB_CODE_SUCCESS == code) {
2,023,460✔
2062
      SRowKey key;
2063
      tRowGetKey(*pRow, &key);
2,023,448✔
2064
      insCheckTableDataOrder(*ppTableDataCxt, &key);
2,023,448✔
2065
    }
2066
  }
2067

2068
  if (code == TSDB_CODE_SUCCESS) {
2,023,460✔
2069
    *pGotRow = true;
2,023,448✔
2070
  }
2071

2072
  clearStbRowsDataContext(pStbRowsCxt);
2,023,460✔
2073

2074
  return code;
2,023,460✔
2075
}
2076

2077
static int parseOneRow(SInsertParseContext* pCxt, const char** pSql, STableDataCxt* pTableCxt, bool* pGotRow,
337,110,227✔
2078
                       SToken* pToken) {
2079
  SBoundColInfo* pCols = &pTableCxt->boundColsInfo;
337,110,227✔
2080
  SSchema*       pSchemas = getTableColumnSchema(pTableCxt->pMeta);
337,110,227✔
2081

2082
  int32_t code = TSDB_CODE_SUCCESS;
335,099,565✔
2083
  // 1. set the parsed value from sql string
2084
  for (int i = 0; i < pCols->numOfBound && TSDB_CODE_SUCCESS == code; ++i) {
1,936,943,646!
2085
    const char* pOrigSql = *pSql;
1,614,139,928✔
2086
    bool        ignoreComma = false;
1,614,139,928✔
2087
    NEXT_TOKEN_WITH_PREV_EXT(*pSql, *pToken, &ignoreComma);
1,614,139,928✔
2088
    if (ignoreComma) {
1,763,403,338!
2089
      code = buildSyntaxErrMsg(&pCxt->msg, "invalid data or symbol", pOrigSql);
×
2090
      break;
8✔
2091
    }
2092

2093
    SSchema* pSchema = &pSchemas[pCols->pColIndex[i]];
1,763,403,338✔
2094
    SColVal* pVal = taosArrayGet(pTableCxt->pValues, pCols->pColIndex[i]);
1,763,403,338✔
2095

2096
    if (pToken->type == TK_NK_QUESTION) {
1,731,750,385!
2097
      pCxt->isStmtBind = true;
×
2098
      if (NULL == pCxt->pComCxt->pStmtCb) {
×
2099
        code = buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", pToken->z);
4✔
2100
        break;
4✔
2101
      }
2102
    } else {
2103
      if (TK_NK_RP == pToken->type) {
1,734,394,138✔
2104
        code = generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_INVALID_COLUMNS_NUM);
2✔
2105
        break;
2✔
2106
      }
2107

2108
      if (pCxt->isStmtBind) {
1,734,394,136✔
2109
        code = buildInvalidOperationMsg(&pCxt->msg, "stmt bind param does not support normal value in sql");
2✔
2110
        break;
2✔
2111
      }
2112

2113
      if (TSDB_CODE_SUCCESS == code) {
1,734,394,134✔
2114
        code = parseValueToken(pCxt, pSql, pToken, pSchema, getTableInfo(pTableCxt->pMeta).precision, pVal);
1,698,818,461✔
2115
      }
2116
    }
2117

2118
    if (TSDB_CODE_SUCCESS == code && i < pCols->numOfBound - 1) {
1,636,868,989✔
2119
      NEXT_VALID_TOKEN(*pSql, *pToken);
1,343,602,441!
2120
      if (TK_NK_COMMA != pToken->type) {
1,320,892,567✔
2121
        code = buildSyntaxErrMsg(&pCxt->msg, ", expected", pToken->z);
770✔
2122
      }
2123
    }
2124
  }
2125

2126
  if (TSDB_CODE_SUCCESS == code && !pCxt->isStmtBind) {
322,803,726!
2127
    SRow** pRow = taosArrayReserve(pTableCxt->pData->aRowP, 1);
331,318,526✔
2128
    code = tRowBuild(pTableCxt->pValues, pTableCxt->pSchema, pRow);
327,739,592✔
2129
    if (TSDB_CODE_SUCCESS == code) {
331,529,100✔
2130
      SRowKey key;
2131
      tRowGetKey(*pRow, &key);
331,346,714✔
2132
      insCheckTableDataOrder(pTableCxt, &key);
330,780,393✔
2133
    }
2134
  }
2135

2136
  if (TSDB_CODE_SUCCESS == code && !pCxt->isStmtBind) {
323,808,011!
2137
    *pGotRow = true;
332,654,259✔
2138
  }
2139

2140
  clearColValArray(pTableCxt->pValues);
323,808,011✔
2141

2142
  return code;
325,107,713✔
2143
}
2144

2145
// pSql -> (field1_value, ...) [(field1_value2, ...) ...]
2146
static int32_t parseValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SRowsDataContext rowsDataCxt,
9,677,190✔
2147
                           int32_t* pNumOfRows, SToken* pToken) {
2148
  int32_t code = TSDB_CODE_SUCCESS;
9,677,190✔
2149

2150
  (*pNumOfRows) = 0;
9,677,190✔
2151
  while (TSDB_CODE_SUCCESS == code) {
316,826,490!
2152
    int32_t index = 0;
316,895,700✔
2153
    NEXT_TOKEN_KEEP_SQL(pStmt->pSql, *pToken, index);
316,895,700✔
2154
    if (TK_NK_LP != pToken->type) {
330,824,597✔
2155
      break;
9,673,614✔
2156
    }
2157
    pStmt->pSql += index;
321,150,983✔
2158

2159
    bool gotRow = false;
321,150,983✔
2160
    if (TSDB_CODE_SUCCESS == code) {
321,150,983!
2161
      if (!pStmt->stbSyntax) {
321,800,244✔
2162
        code = parseOneRow(pCxt, &pStmt->pSql, rowsDataCxt.pTableDataCxt, &gotRow, pToken);
321,000,673✔
2163
      } else {
2164
        STableDataCxt* pTableDataCxt = NULL;
799,571✔
2165
        code = parseOneStbRow(pCxt, pStmt, &pStmt->pSql, rowsDataCxt.pStbRowsCxt, &gotRow, pToken, &pTableDataCxt);
799,571✔
2166
      }
2167
    }
2168

2169
    if (TSDB_CODE_SUCCESS == code) {
305,985,202!
2170
      NEXT_VALID_TOKEN(pStmt->pSql, *pToken);
308,524,187✔
2171
      if (TK_NK_COMMA == pToken->type) {
306,800,937✔
2172
        code = generateSyntaxErrMsg(&pCxt->msg, TSDB_CODE_PAR_INVALID_COLUMNS_NUM);
12✔
2173
      } else if (TK_NK_RP != pToken->type) {
306,800,925✔
2174
        code = buildSyntaxErrMsg(&pCxt->msg, ") expected", pToken->z);
603✔
2175
      }
2176
    }
2177

2178
    if (TSDB_CODE_SUCCESS == code && gotRow) {
307,149,300!
2179
      (*pNumOfRows)++;
307,072,411✔
2180
    }
2181
  }
2182

2183
  if (TSDB_CODE_SUCCESS == code && 0 == (*pNumOfRows) &&
9,604,404!
2184
      (!TSDB_QUERY_HAS_TYPE(pStmt->insertType, TSDB_QUERY_TYPE_STMT_INSERT))) {
32!
2185
    code = buildSyntaxErrMsg(&pCxt->msg, "no any data points", NULL);
×
2186
  }
2187
  return code;
9,690,908✔
2188
}
2189

2190
// VALUES (field1_value, ...) [(field1_value2, ...) ...]
2191
static int32_t parseValuesClause(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SRowsDataContext rowsDataContext,
9,682,719✔
2192
                                 SToken* pToken) {
2193
  int32_t numOfRows = 0;
9,682,719✔
2194
  int32_t code = parseValues(pCxt, pStmt, rowsDataContext, &numOfRows, pToken);
9,682,719✔
2195
  if (TSDB_CODE_SUCCESS == code) {
9,688,879✔
2196
    pStmt->totalRowsNum += numOfRows;
9,668,941✔
2197
    pStmt->totalTbNum += 1;
9,668,941✔
2198
    TSDB_QUERY_SET_TYPE(pStmt->insertType, TSDB_QUERY_TYPE_INSERT);
9,668,941✔
2199
  }
2200
  return code;
9,688,879✔
2201
}
2202

2203
static int32_t parseCsvFile(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SRowsDataContext rowsDataCxt,
173✔
2204
                            int32_t* pNumOfRows) {
2205
  int32_t code = TSDB_CODE_SUCCESS;
173✔
2206
  (*pNumOfRows) = 0;
173✔
2207
  char*   pLine = NULL;
173✔
2208
  int64_t readLen = 0;
173✔
2209
  bool    firstLine = (pStmt->fileProcessing == false);
173✔
2210
  pStmt->fileProcessing = false;
173✔
2211
  while (TSDB_CODE_SUCCESS == code && (readLen = taosGetLineFile(pStmt->fp, &pLine)) != -1) {
20,210,219✔
2212
    if (('\r' == pLine[readLen - 1]) || ('\n' == pLine[readLen - 1])) {
20,210,066!
2213
      pLine[--readLen] = '\0';
20,210,066✔
2214
    }
2215

2216
    if (readLen == 0) {
20,210,066!
2217
      firstLine = false;
×
2218
      continue;
120✔
2219
    }
2220

2221
    bool gotRow = false;
20,210,066✔
2222
    if (TSDB_CODE_SUCCESS == code) {
20,210,066!
2223
      SToken token;
2224
      (void)strtolower(pLine, pLine);
20,210,066✔
2225
      const char* pRow = pLine;
20,210,066✔
2226
      if (!pStmt->stbSyntax) {
20,210,066✔
2227
        code = parseOneRow(pCxt, (const char**)&pRow, rowsDataCxt.pTableDataCxt, &gotRow, &token);
18,191,130✔
2228
      } else {
2229
        STableDataCxt* pTableDataCxt = NULL;
2,018,936✔
2230
        code =
2231
            parseOneStbRow(pCxt, pStmt, (const char**)&pRow, rowsDataCxt.pStbRowsCxt, &gotRow, &token, &pTableDataCxt);
2,018,936✔
2232
        if (code == TSDB_CODE_SUCCESS) {
2,018,936✔
2233
          SStbRowsDataContext* pStbRowsCxt = rowsDataCxt.pStbRowsCxt;
2,018,912✔
2234
          void*                pData = pTableDataCxt;
2,018,912✔
2235
          code = taosHashPut(pStmt->pTableCxtHashObj, &pStbRowsCxt->pCtbMeta->uid, sizeof(pStbRowsCxt->pCtbMeta->uid),
2,018,912✔
2236
                             &pData, POINTER_BYTES);
2237
          if (TSDB_CODE_SUCCESS != code) {
2,018,912!
2238
            break;
×
2239
          }
2240
        }
2241
      }
2242
      if (code && firstLine) {
20,210,066✔
2243
        firstLine = false;
120✔
2244
        code = 0;
120✔
2245
        continue;
120✔
2246
      }
2247
    }
2248

2249
    if (TSDB_CODE_SUCCESS == code && gotRow) {
20,209,946!
2250
      (*pNumOfRows)++;
20,209,904✔
2251
    }
2252

2253
    if (TSDB_CODE_SUCCESS == code && (*pNumOfRows) >= tsMaxInsertBatchRows) {
20,209,946✔
2254
      pStmt->fileProcessing = true;
20✔
2255
      break;
20✔
2256
    }
2257

2258
    firstLine = false;
20,209,926✔
2259
  }
2260
  taosMemoryFree(pLine);
173✔
2261

2262
  parserDebug("0x%" PRIx64 " %d rows have been parsed", pCxt->pComCxt->requestId, *pNumOfRows);
173✔
2263

2264
  if (TSDB_CODE_SUCCESS == code && 0 == (*pNumOfRows) && 0 == pStmt->totalRowsNum &&
173!
2265
      (!TSDB_QUERY_HAS_TYPE(pStmt->insertType, TSDB_QUERY_TYPE_STMT_INSERT)) && !pStmt->fileProcessing) {
×
2266
    code = buildSyntaxErrMsg(&pCxt->msg, "no any data points", NULL);
×
2267
  }
2268
  return code;
173✔
2269
}
2270

2271
static int32_t parseDataFromFileImpl(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt,
173✔
2272
                                     SRowsDataContext rowsDataCxt) {
2273
  // init only for file
2274
  if (NULL == pStmt->pTableCxtHashObj) {
173✔
2275
    pStmt->pTableCxtHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
124✔
2276
    if (!pStmt->pTableCxtHashObj) {
124!
2277
      return terrno;
×
2278
    }
2279
  }
2280
  int32_t numOfRows = 0;
173✔
2281
  int32_t code = parseCsvFile(pCxt, pStmt, rowsDataCxt, &numOfRows);
173✔
2282
  if (TSDB_CODE_SUCCESS == code) {
173✔
2283
    pStmt->totalRowsNum += numOfRows;
131✔
2284
    pStmt->totalTbNum += 1;
131✔
2285
    TSDB_QUERY_SET_TYPE(pStmt->insertType, TSDB_QUERY_TYPE_FILE_INSERT);
131✔
2286
    if (rowsDataCxt.pTableDataCxt && rowsDataCxt.pTableDataCxt->pData) {
131!
2287
      rowsDataCxt.pTableDataCxt->pData->flags |= SUBMIT_REQ_FROM_FILE;
102✔
2288
    }
2289
    if (!pStmt->fileProcessing) {
131✔
2290
      code = taosCloseFile(&pStmt->fp);
111✔
2291
      if (TSDB_CODE_SUCCESS != code) {
111!
2292
        parserWarn("0x%" PRIx64 " failed to close file.", pCxt->pComCxt->requestId);
×
2293
      }
2294
    } else {
2295
      parserDebug("0x%" PRIx64 " insert from csv. File is too large, do it in batches.", pCxt->pComCxt->requestId);
20!
2296
    }
2297
    if (pStmt->insertType != TSDB_QUERY_TYPE_FILE_INSERT) {
131!
2298
      return buildSyntaxErrMsg(&pCxt->msg, "keyword VALUES or FILE is exclusive", NULL);
×
2299
    }
2300
  } else {
2301
    return buildInvalidOperationMsg(&pCxt->msg, tstrerror(code));
42✔
2302
  }
2303

2304
  // just record pTableCxt whose data come from file
2305
  if (!pStmt->stbSyntax && numOfRows > 0) {
131✔
2306
    void* pData = rowsDataCxt.pTableDataCxt;
93✔
2307
    code = taosHashPut(pStmt->pTableCxtHashObj, &pStmt->pTableMeta->uid, sizeof(pStmt->pTableMeta->uid), &pData,
93✔
2308
                       POINTER_BYTES);
2309
  }
2310

2311
  return code;
131✔
2312
}
2313

2314
static int32_t parseDataFromFile(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SToken* pFilePath,
153✔
2315
                                 SRowsDataContext rowsDataCxt) {
2316
  char filePathStr[PATH_MAX + 16] = {0};
153✔
2317
  if (TK_NK_STRING == pFilePath->type) {
153!
2318
    (void)trimString(pFilePath->z, pFilePath->n, filePathStr, sizeof(filePathStr));
153✔
2319
    if (strlen(filePathStr) >= PATH_MAX) {
153!
2320
      return buildSyntaxErrMsg(&pCxt->msg, "file path is too long, max length is 4096", pFilePath->z);
×
2321
    }
2322
  } else {
2323
    if (pFilePath->n >= PATH_MAX) {
×
2324
      return buildSyntaxErrMsg(&pCxt->msg, "file path is too long, max length is 4096", pFilePath->z);
×
2325
    }
2326
    strncpy(filePathStr, pFilePath->z, pFilePath->n);
×
2327
  }
2328
  pStmt->fp = taosOpenFile(filePathStr, TD_FILE_READ | TD_FILE_STREAM);
153✔
2329
  if (NULL == pStmt->fp) {
153!
2330
    return terrno;
×
2331
  }
2332

2333
  return parseDataFromFileImpl(pCxt, pStmt, rowsDataCxt);
153✔
2334
}
2335

2336
static int32_t parseFileClause(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SRowsDataContext rowsDataCxt,
153✔
2337
                               SToken* pToken) {
2338
  if (tsUseAdapter) {
153!
2339
    return buildInvalidOperationMsg(&pCxt->msg, "proxy mode does not support csv loading");
×
2340
  }
2341

2342
  NEXT_TOKEN(pStmt->pSql, *pToken);
153✔
2343
  if (0 == pToken->n || (TK_NK_STRING != pToken->type && TK_NK_ID != pToken->type)) {
153!
2344
    return buildSyntaxErrMsg(&pCxt->msg, "file path is required following keyword FILE", pToken->z);
×
2345
  }
2346
  return parseDataFromFile(pCxt, pStmt, pToken, rowsDataCxt);
153✔
2347
}
2348

2349
// VALUES (field1_value, ...) [(field1_value2, ...) ...] | FILE csv_file_path
2350
static int32_t parseDataClause(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SRowsDataContext rowsDataCxt) {
9,676,695✔
2351
  SToken token;
2352
  NEXT_TOKEN(pStmt->pSql, token);
9,676,695✔
2353
  switch (token.type) {
9,693,735!
2354
    case TK_VALUES:
9,695,191✔
2355
      if (TSDB_QUERY_HAS_TYPE(pStmt->insertType, TSDB_QUERY_TYPE_FILE_INSERT)) {
9,695,191✔
2356
        return buildSyntaxErrMsg(&pCxt->msg, "keyword VALUES or FILE is exclusive", token.z);
1✔
2357
      }
2358
      return parseValuesClause(pCxt, pStmt, rowsDataCxt, &token);
9,695,190✔
2359
    case TK_FILE:
×
2360
      return parseFileClause(pCxt, pStmt, rowsDataCxt, &token);
×
2361
    default:
×
2362
      break;
×
2363
  }
2364
  return buildSyntaxErrMsg(&pCxt->msg, "keyword VALUES or FILE is expected", token.z);
×
2365
}
2366

2367
static void destroyStbRowsDataContext(SStbRowsDataContext* pStbRowsCxt) {
19,250,187✔
2368
  if (pStbRowsCxt == NULL) return;
19,250,187✔
2369
  clearStbRowsDataContext(pStbRowsCxt);
6,430✔
2370
  taosArrayDestroy(pStbRowsCxt->aColVals);
10,557✔
2371
  pStbRowsCxt->aColVals = NULL;
10,557✔
2372
  taosArrayDestroy(pStbRowsCxt->aTagVals);
10,557✔
2373
  pStbRowsCxt->aTagVals = NULL;
10,557✔
2374
  taosArrayDestroy(pStbRowsCxt->aTagNames);
10,557✔
2375
  pStbRowsCxt->aTagNames = NULL;
10,557✔
2376
  insDestroyBoundColInfo(&pStbRowsCxt->boundColsInfo);
10,557✔
2377
  tTagFree(pStbRowsCxt->pTag);
10,557✔
2378
  pStbRowsCxt->pTag = NULL;
10,557✔
2379
  taosMemoryFreeClear(pStbRowsCxt->pCtbMeta);
10,557!
2380
  tdDestroySVCreateTbReq(pStbRowsCxt->pCreateCtbReq);
10,557!
2381
  taosMemoryFreeClear(pStbRowsCxt->pCreateCtbReq);
10,557!
2382
}
2383

2384
static int32_t constructStbRowsDataContext(SVnodeModifyOpStmt* pStmt, SStbRowsDataContext** ppStbRowsCxt) {
10,557✔
2385
  SStbRowsDataContext* pStbRowsCxt = taosMemoryCalloc(1, sizeof(SStbRowsDataContext));
10,557✔
2386
  if (!pStbRowsCxt) {
10,557!
2387
    return terrno;
×
2388
  }
2389
  tNameAssign(&pStbRowsCxt->stbName, &pStmt->targetTableName);
10,557✔
2390
  int32_t code = collectUseTable(&pStbRowsCxt->stbName, pStmt->pTableNameHashObj);
10,557✔
2391
  if (TSDB_CODE_SUCCESS == code) {
10,557!
2392
    code = collectUseDatabase(&pStbRowsCxt->stbName, pStmt->pDbFNameHashObj);
10,557✔
2393
  }
2394
  if (TSDB_CODE_SUCCESS == code) {
10,557!
2395
    pStbRowsCxt->ctbName.type = TSDB_TABLE_NAME_T;
10,557✔
2396
    pStbRowsCxt->ctbName.acctId = pStbRowsCxt->stbName.acctId;
10,557✔
2397
    memcpy(pStbRowsCxt->ctbName.dbname, pStbRowsCxt->stbName.dbname, sizeof(pStbRowsCxt->stbName.dbname));
10,557✔
2398

2399
    pStbRowsCxt->pTagCond = pStmt->pTagCond;
10,557✔
2400
    pStbRowsCxt->pStbMeta = pStmt->pTableMeta;
10,557✔
2401

2402
    code = cloneTableMeta(pStbRowsCxt->pStbMeta, &pStbRowsCxt->pCtbMeta);
10,557✔
2403
  }
2404
  if (TSDB_CODE_SUCCESS == code) {
10,557!
2405
    pStbRowsCxt->pCtbMeta->tableType = TSDB_CHILD_TABLE;
10,557✔
2406
    pStbRowsCxt->pCtbMeta->suid = pStbRowsCxt->pStbMeta->uid;
10,557✔
2407

2408
    pStbRowsCxt->aTagNames = taosArrayInit(8, TSDB_COL_NAME_LEN);
10,557✔
2409
    if (!pStbRowsCxt->aTagNames) {
10,557!
2410
      code = terrno;
×
2411
    }
2412
  }
2413
  if (TSDB_CODE_SUCCESS == code) {
10,557!
2414
    pStbRowsCxt->aTagVals = taosArrayInit(8, sizeof(STagVal));
10,557✔
2415
    if (!pStbRowsCxt->aTagVals) {
10,557!
2416
      code = terrno;
×
2417
    }
2418
  }
2419
  if (TSDB_CODE_SUCCESS == code) {
10,557!
2420
    // col values and bound cols info of STableDataContext is not used
2421
    pStbRowsCxt->aColVals = taosArrayInit(getNumOfColumns(pStbRowsCxt->pStbMeta), sizeof(SColVal));
10,557✔
2422
    if (!pStbRowsCxt->aColVals) code = terrno;
10,557!
2423
  }
2424
  if (TSDB_CODE_SUCCESS == code) {
10,557!
2425
    code = insInitColValues(pStbRowsCxt->pStbMeta, pStbRowsCxt->aColVals);
10,557✔
2426
  }
2427
  if (TSDB_CODE_SUCCESS == code) {
10,557!
2428
    STableComInfo tblInfo = getTableInfo(pStmt->pTableMeta);
10,557✔
2429
    code = insInitBoundColsInfo(tblInfo.numOfColumns + tblInfo.numOfTags + 1, &pStbRowsCxt->boundColsInfo);
10,557✔
2430
  }
2431
  if (TSDB_CODE_SUCCESS == code) {
10,557!
2432
    *ppStbRowsCxt = pStbRowsCxt;
10,557✔
2433
  } else {
2434
    clearStbRowsDataContext(pStbRowsCxt);
×
2435
  }
2436
  return code;
10,557✔
2437
}
2438

2439
static int32_t parseInsertStbClauseBottom(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
10,619✔
2440
  int32_t code = TSDB_CODE_SUCCESS;
10,619✔
2441
  if (!pStmt->pBoundCols) {
10,619✔
2442
    return buildSyntaxErrMsg(&pCxt->msg, "(...tbname, ts...) bounded cols is expected for supertable insertion",
62✔
2443
                             pStmt->pSql);
2444
  }
2445

2446
  SStbRowsDataContext* pStbRowsCxt = NULL;
10,557✔
2447
  code = constructStbRowsDataContext(pStmt, &pStbRowsCxt);
10,557✔
2448

2449
  if (code == TSDB_CODE_SUCCESS) {
10,557!
2450
    code = parseBoundColumns(pCxt, &pStmt->pBoundCols, BOUND_ALL_AND_TBNAME, pStmt->pTableMeta,
10,557✔
2451
                             &pStbRowsCxt->boundColsInfo);
10,557✔
2452
    pStbRowsCxt->hasTimestampTag = false;
10,557✔
2453
    for (int32_t i = 0; i < pStbRowsCxt->boundColsInfo.numOfBound; ++i) {
71,457✔
2454
      int16_t schemaIndex = pStbRowsCxt->boundColsInfo.pColIndex[i];
60,900✔
2455
      if (schemaIndex != getTbnameSchemaIndex(pStmt->pTableMeta) && schemaIndex >= getNumOfColumns(pStmt->pTableMeta)) {
60,900✔
2456
        if (pStmt->pTableMeta->schema[schemaIndex].type == TSDB_DATA_TYPE_TIMESTAMP) {
19,373✔
2457
          pStbRowsCxt->hasTimestampTag = true;
1,158✔
2458
        }
2459
        if (pStmt->pTableMeta->schema[schemaIndex].type == TSDB_DATA_TYPE_JSON) {
19,373!
2460
          pStbRowsCxt->isJsonTag = true;
×
2461
        }
2462
      }
2463
    }
2464
    pStmt->pStbRowsCxt = pStbRowsCxt;
10,557✔
2465
  }
2466

2467
  if (code == TSDB_CODE_SUCCESS) {
10,557✔
2468
    SRowsDataContext rowsDataCxt;
2469
    rowsDataCxt.pStbRowsCxt = pStbRowsCxt;
10,543✔
2470
    code = parseDataClause(pCxt, pStmt, rowsDataCxt);
10,543✔
2471
  }
2472

2473
  return code;
10,557✔
2474
}
2475

2476
// input pStmt->pSql:
2477
//   1. [(tag1_name, ...)] ...
2478
//   2. VALUES ... | FILE ...
2479
static int32_t parseInsertTableClauseBottom(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
9,679,631✔
2480
  if (!pStmt->stbSyntax) {
9,679,631✔
2481
    STableDataCxt*   pTableCxt = NULL;
9,671,485✔
2482
    int32_t          code = parseSchemaClauseBottom(pCxt, pStmt, &pTableCxt);
9,671,485✔
2483
    SRowsDataContext rowsDataCxt;
2484
    rowsDataCxt.pTableDataCxt = pTableCxt;
9,678,782✔
2485
    if (TSDB_CODE_SUCCESS == code) {
9,678,782✔
2486
      code = parseDataClause(pCxt, pStmt, rowsDataCxt);
9,675,583✔
2487
    }
2488
    return code;
9,661,487✔
2489
  } else {
2490
    int32_t code = parseInsertStbClauseBottom(pCxt, pStmt);
8,146✔
2491
    return code;
10,619✔
2492
  }
2493
}
2494

2495
static void resetEnvPreTable(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
9,677,735✔
2496
  insDestroyBoundColInfo(&pCxt->tags);
9,677,735✔
2497
  taosMemoryFreeClear(pStmt->pTableMeta);
9,676,810✔
2498
  nodesDestroyNode(pStmt->pTagCond);
9,676,810✔
2499
  taosArrayDestroy(pStmt->pTableTag);
9,676,634✔
2500
  tdDestroySVCreateTbReq(pStmt->pCreateTblReq);
9,673,415!
2501
  taosMemoryFreeClear(pStmt->pCreateTblReq);
9,673,415!
2502
  pCxt->missCache = false;
9,673,415✔
2503
  pCxt->usingDuplicateTable = false;
9,673,415✔
2504
  pStmt->pBoundCols = NULL;
9,673,415✔
2505
  pStmt->usingTableProcessing = false;
9,673,415✔
2506
  pStmt->fileProcessing = false;
9,673,415✔
2507
  pStmt->usingTableName.type = 0;
9,673,415✔
2508

2509
  destroyStbRowsDataContext(pStmt->pStbRowsCxt);
9,673,415✔
2510
  taosMemoryFreeClear(pStmt->pStbRowsCxt);
9,673,210✔
2511
  pStmt->stbSyntax = false;
9,673,210✔
2512
}
9,673,210✔
2513

2514
// input pStmt->pSql: [(field1_name, ...)] [ USING ... ] VALUES ... | FILE ...
2515
static int32_t parseInsertTableClause(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SToken* pTbName) {
9,681,240✔
2516
  resetEnvPreTable(pCxt, pStmt);
9,681,240✔
2517
  int32_t code = parseSchemaClauseTop(pCxt, pStmt, pTbName);
9,673,294✔
2518
  if (TSDB_CODE_SUCCESS == code && !pCxt->missCache) {
9,679,440!
2519
    code = parseInsertTableClauseBottom(pCxt, pStmt);
9,651,858✔
2520
  }
2521

2522
  return code;
9,670,592✔
2523
}
2524

2525
static int32_t checkTableClauseFirstToken(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SToken* pTbName,
19,227,121✔
2526
                                          bool* pHasData) {
2527
  // no data in the sql string anymore.
2528
  if (0 == pTbName->n) {
19,227,121✔
2529
    if (0 != pTbName->type && '\0' != pStmt->pSql[0]) {
9,543,533!
2530
      return buildSyntaxErrMsg(&pCxt->msg, "invalid table name", pTbName->z);
×
2531
    }
2532

2533
    if (0 == pStmt->totalRowsNum && (!TSDB_QUERY_HAS_TYPE(pStmt->insertType, TSDB_QUERY_TYPE_STMT_INSERT))) {
9,543,533!
2534
      return buildInvalidOperationMsg(&pCxt->msg, "no data in sql");
×
2535
    }
2536

2537
    *pHasData = false;
9,543,533✔
2538
    return TSDB_CODE_SUCCESS;
9,543,533✔
2539
  }
2540

2541
  if (TSDB_QUERY_HAS_TYPE(pStmt->insertType, TSDB_QUERY_TYPE_STMT_INSERT) && pStmt->totalTbNum > 0) {
9,683,588!
2542
    return buildInvalidOperationMsg(&pCxt->msg, "single table allowed in one stmt");
×
2543
  }
2544

2545
  if (TK_NK_QUESTION == pTbName->type) {
9,683,588✔
2546
    pCxt->isStmtBind = true;
28✔
2547
    if (NULL == pCxt->pComCxt->pStmtCb) {
28!
2548
      return buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", pTbName->z);
×
2549
    }
2550

2551
    char*   tbName = NULL;
28✔
2552
    int32_t code = (*pCxt->pComCxt->pStmtCb->getTbNameFn)(pCxt->pComCxt->pStmtCb->pStmt, &tbName);
28✔
2553
    if (TSDB_CODE_SUCCESS == code) {
28!
2554
      pTbName->z = tbName;
28✔
2555
      pTbName->n = strlen(tbName);
28✔
2556
    } else {
2557
      return code;
×
2558
    }
2559
  }
2560

2561
  if (TK_NK_ID != pTbName->type && TK_NK_STRING != pTbName->type && TK_NK_QUESTION != pTbName->type) {
9,683,588!
2562
    return buildSyntaxErrMsg(&pCxt->msg, "table_name is expected", pTbName->z);
×
2563
  }
2564

2565
  // db.? situation,ensure that the only thing following the '.' mark is '?'
2566
  char* tbNameAfterDbName = strnchr(pTbName->z, '.', pTbName->n, true);
9,683,588✔
2567
  if ((tbNameAfterDbName != NULL) && (*(tbNameAfterDbName + 1) == '?')) {
9,682,981!
2568
    char* tbName = NULL;
×
2569
    if (NULL == pCxt->pComCxt->pStmtCb) {
×
2570
      return buildSyntaxErrMsg(&pCxt->msg, "? only used in stmt", pTbName->z);
×
2571
    }
2572
    int32_t code = (*pCxt->pComCxt->pStmtCb->getTbNameFn)(pCxt->pComCxt->pStmtCb->pStmt, &tbName);
×
2573
    if (code != TSDB_CODE_SUCCESS) {
×
2574
      return code;
×
2575
    }
2576
    pTbName->z = tbName;
×
2577
    pTbName->n = strlen(tbName);
×
2578
  }
2579

2580
  if (pCxt->isStmtBind) {
9,682,981✔
2581
    if (TK_NK_ID == pTbName->type || (tbNameAfterDbName != NULL && *(tbNameAfterDbName + 1) != '?')) {
35!
2582
      // In SQL statements, the table name has already been specified.
2583
      parserWarn("0x%" PRIx64 " table name is specified in sql, ignore the table name in bind param",
7!
2584
                 pCxt->pComCxt->requestId);
2585
    }
2586
  }
2587

2588
  *pHasData = true;
9,681,550✔
2589
  return TSDB_CODE_SUCCESS;
9,681,550✔
2590
}
2591

2592
static int32_t setStmtInfo(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
32✔
2593
  SBoundColInfo* tags = taosMemoryMalloc(sizeof(pCxt->tags));
32✔
2594
  if (NULL == tags) {
32!
2595
    return terrno;
×
2596
  }
2597
  memcpy(tags, &pCxt->tags, sizeof(pCxt->tags));
32✔
2598

2599
  SStmtCallback* pStmtCb = pCxt->pComCxt->pStmtCb;
32✔
2600
  int32_t        code = (*pStmtCb->setInfoFn)(pStmtCb->pStmt, pStmt->pTableMeta, tags, &pStmt->targetTableName,
32✔
2601
                                       pStmt->usingTableProcessing, pStmt->pVgroupsHashObj, pStmt->pTableBlockHashObj,
32✔
2602
                                       pStmt->usingTableName.tname);
32✔
2603

2604
  memset(&pCxt->tags, 0, sizeof(pCxt->tags));
32✔
2605
  pStmt->pVgroupsHashObj = NULL;
32✔
2606
  pStmt->pTableBlockHashObj = NULL;
32✔
2607
  return code;
32✔
2608
}
2609

2610
static int32_t parseInsertBodyBottom(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
9,543,075✔
2611
  if (TSDB_QUERY_HAS_TYPE(pStmt->insertType, TSDB_QUERY_TYPE_STMT_INSERT)) {
9,543,075✔
2612
    return setStmtInfo(pCxt, pStmt);
32✔
2613
  }
2614

2615
  // release old array alloced by merge
2616
  pStmt->freeArrayFunc(pStmt->pVgDataBlocks);
9,543,043✔
2617
  pStmt->pVgDataBlocks = NULL;
9,533,392✔
2618

2619
  bool fileOnly = (pStmt->insertType == TSDB_QUERY_TYPE_FILE_INSERT);
9,533,392✔
2620
  if (fileOnly) {
9,533,392!
2621
    // none data, skip merge & buildvgdata
2622
    if (0 == taosHashGetSize(pStmt->pTableCxtHashObj)) {
✔
2623
      pCxt->needRequest = false;
10✔
2624
      return TSDB_CODE_SUCCESS;
10✔
2625
    }
2626
  }
2627

2628
  // merge according to vgId
2629
  int32_t code = insMergeTableDataCxt(fileOnly ? pStmt->pTableCxtHashObj : pStmt->pTableBlockHashObj,
9,538,142✔
2630
                                      &pStmt->pVgDataBlocks, pStmt->fileProcessing);
9,538,142✔
2631
  // clear tmp hashobj only
2632
  taosHashClear(pStmt->pTableCxtHashObj);
9,534,018✔
2633

2634
  if (TSDB_CODE_SUCCESS == code) {
9,533,302!
2635
    code = insBuildVgDataBlocks(pStmt->pVgroupsHashObj, pStmt->pVgDataBlocks, &pStmt->pDataBlocks, false);
9,535,081✔
2636
  }
2637

2638
  return code;
9,528,135✔
2639
}
2640

2641
// tb_name
2642
//     [USING stb_name [(tag1_name, ...)] TAGS (tag1_value, ...)]
2643
//     [(field1_name, ...)]
2644
//     VALUES (field1_value, ...) [(field1_value2, ...) ...] | FILE csv_file_path
2645
// [...];
2646
static int32_t parseInsertBody(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
9,627,261✔
2647
  SToken  token;
2648
  int32_t code = TSDB_CODE_SUCCESS;
9,627,261✔
2649
  bool    hasData = true;
9,627,261✔
2650
  // for each table
2651
  while (TSDB_CODE_SUCCESS == code && hasData && !pCxt->missCache && !pStmt->fileProcessing) {
28,817,517!
2652
    // pStmt->pSql -> tb_name ...
2653
    NEXT_TOKEN(pStmt->pSql, token);
19,224,581✔
2654
    code = checkTableClauseFirstToken(pCxt, pStmt, &token, &hasData);
19,256,895✔
2655
    if (TSDB_CODE_SUCCESS == code && hasData) {
19,210,101!
2656
      code = parseInsertTableClause(pCxt, pStmt, &token);
9,684,206✔
2657
    }
2658
  }
2659

2660
  if (TSDB_CODE_SUCCESS == code && !pCxt->missCache) {
9,592,936✔
2661
    code = parseInsertBodyBottom(pCxt, pStmt);
9,549,409✔
2662
  }
2663
  return code;
9,571,477✔
2664
}
2665

2666
static void destroySubTableHashElem(void* p) { taosMemoryFree(*(STableMeta**)p); }
68,980✔
2667

2668
static int32_t createVnodeModifOpStmt(SInsertParseContext* pCxt, bool reentry, SNode** pOutput) {
9,579,732✔
2669
  SVnodeModifyOpStmt* pStmt = NULL;
9,579,732✔
2670
  int32_t             code = nodesMakeNode(QUERY_NODE_VNODE_MODIFY_STMT, (SNode**)&pStmt);
9,579,732✔
2671
  if (NULL == pStmt) {
9,585,095!
2672
    return code;
×
2673
  }
2674

2675
  if (pCxt->pComCxt->pStmtCb) {
9,585,095✔
2676
    TSDB_QUERY_SET_TYPE(pStmt->insertType, TSDB_QUERY_TYPE_STMT_INSERT);
35✔
2677
  }
2678
  pStmt->pSql = pCxt->pComCxt->pSql;
9,585,095✔
2679

2680
  pStmt->freeHashFunc = insDestroyTableDataCxtHashMap;
9,585,095✔
2681
  pStmt->freeArrayFunc = insDestroyVgroupDataCxtList;
9,585,095✔
2682
  pStmt->freeStbRowsCxtFunc = destroyStbRowsDataContext;
9,585,095✔
2683

2684
  if (!reentry) {
9,585,095!
2685
    pStmt->pVgroupsHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
9,585,132✔
2686
    if (pCxt->pComCxt->pStmtCb) {
9,577,871✔
2687
      pStmt->pTableBlockHashObj =
35✔
2688
          taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
35✔
2689
    } else {
2690
      pStmt->pTableBlockHashObj =
9,576,360✔
2691
          taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_NO_LOCK);
9,577,836✔
2692
    }
2693
  }
2694
  pStmt->pSubTableHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, HASH_NO_LOCK);
9,576,358✔
2695
  pStmt->pTableNameHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, HASH_NO_LOCK);
9,577,381✔
2696
  pStmt->pDbFNameHashObj = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, HASH_NO_LOCK);
9,577,383✔
2697
  if ((!reentry && (NULL == pStmt->pVgroupsHashObj || NULL == pStmt->pTableBlockHashObj)) ||
9,576,409!
2698
      NULL == pStmt->pSubTableHashObj || NULL == pStmt->pTableNameHashObj || NULL == pStmt->pDbFNameHashObj) {
9,575,711!
2699
    nodesDestroyNode((SNode*)pStmt);
×
2700
    return TSDB_CODE_OUT_OF_MEMORY;
×
2701
  }
2702

2703
  taosHashSetFreeFp(pStmt->pSubTableHashObj, destroySubTableHashElem);
9,577,098✔
2704

2705
  *pOutput = (SNode*)pStmt;
9,574,822✔
2706
  return TSDB_CODE_SUCCESS;
9,574,822✔
2707
}
2708

2709
static int32_t createInsertQuery(SInsertParseContext* pCxt, SQuery** pOutput) {
9,589,557✔
2710
  SQuery* pQuery = NULL;
9,589,557✔
2711
  int32_t code = nodesMakeNode(QUERY_NODE_QUERY, (SNode**)&pQuery);
9,589,557✔
2712
  if (NULL == pQuery) {
9,583,180!
2713
    return code;
×
2714
  }
2715

2716
  pQuery->execMode = QUERY_EXEC_MODE_SCHEDULE;
9,583,180✔
2717
  pQuery->haveResultSet = false;
9,583,180✔
2718
  pQuery->msgType = TDMT_VND_SUBMIT;
9,583,180✔
2719

2720
  code = createVnodeModifOpStmt(pCxt, false, &pQuery->pRoot);
9,583,180✔
2721
  if (TSDB_CODE_SUCCESS == code) {
9,574,340✔
2722
    *pOutput = pQuery;
9,574,007✔
2723
  } else {
2724
    nodesDestroyNode((SNode*)pQuery);
333✔
2725
  }
2726
  return code;
9,575,346✔
2727
}
2728

2729
static int32_t checkAuthFromMetaData(const SArray* pUsers, SNode** pTagCond) {
32,299✔
2730
  if (1 != taosArrayGetSize(pUsers)) {
32,299!
2731
    return TSDB_CODE_FAILED;
×
2732
  }
2733

2734
  SMetaRes* pRes = taosArrayGet(pUsers, 0);
32,299✔
2735
  if (TSDB_CODE_SUCCESS == pRes->code) {
32,300✔
2736
    SUserAuthRes* pAuth = pRes->pRes;
32,298✔
2737
    pRes->code = nodesCloneNode(pAuth->pCond[AUTH_RES_BASIC], pTagCond);
32,298✔
2738
    if (TSDB_CODE_SUCCESS == pRes->code) {
32,297!
2739
      return pAuth->pass[AUTH_RES_BASIC] ? TSDB_CODE_SUCCESS : TSDB_CODE_PAR_PERMISSION_DENIED;
32,297✔
2740
    }
2741
  }
2742
  return pRes->code;
2✔
2743
}
2744

2745
static int32_t getTableMetaFromMetaData(const SArray* pTables, STableMeta** pMeta) {
32,293✔
2746
  if (1 != taosArrayGetSize(pTables)) {
32,293!
2747
    return TSDB_CODE_FAILED;
×
2748
  }
2749

2750
  taosMemoryFreeClear(*pMeta);
32,293✔
2751
  SMetaRes* pRes = taosArrayGet(pTables, 0);
32,293✔
2752
  if (TSDB_CODE_SUCCESS == pRes->code) {
32,292✔
2753
    *pMeta = tableMetaDup((const STableMeta*)pRes->pRes);
31,762✔
2754
    if (NULL == *pMeta) {
31,762!
2755
      return TSDB_CODE_OUT_OF_MEMORY;
×
2756
    }
2757
  }
2758
  return pRes->code;
32,292✔
2759
}
2760

2761
static int32_t addTableVgroupFromMetaData(const SArray* pTables, SVnodeModifyOpStmt* pStmt, bool isStb) {
31,752✔
2762
  if (1 != taosArrayGetSize(pTables)) {
31,752!
2763
    return TSDB_CODE_FAILED;
×
2764
  }
2765

2766
  SMetaRes* pRes = taosArrayGet(pTables, 0);
31,752✔
2767
  if (TSDB_CODE_SUCCESS != pRes->code) {
31,752!
2768
    return pRes->code;
×
2769
  }
2770

2771
  SVgroupInfo* pVg = pRes->pRes;
31,752✔
2772
  if (isStb) {
31,752✔
2773
    pStmt->pTableMeta->vgId = pVg->vgId;
160✔
2774
  }
2775
  return taosHashPut(pStmt->pVgroupsHashObj, (const char*)&pVg->vgId, sizeof(pVg->vgId), (char*)pVg,
31,752✔
2776
                     sizeof(SVgroupInfo));
2777
}
2778

2779
static int32_t buildTagNameFromMeta(STableMeta* pMeta, SArray** pTagName) {
4✔
2780
  *pTagName = taosArrayInit(pMeta->tableInfo.numOfTags, TSDB_COL_NAME_LEN);
4✔
2781
  if (NULL == *pTagName) {
4!
2782
    return terrno;
×
2783
  }
2784
  SSchema* pSchema = getTableTagSchema(pMeta);
4✔
2785
  int32_t  code = 0;
4✔
2786
  for (int32_t i = 0; i < pMeta->tableInfo.numOfTags; ++i) {
12✔
2787
    if (NULL == taosArrayPush(*pTagName, pSchema[i].name)) {
16!
2788
      code = terrno;
×
2789
      taosArrayDestroy(*pTagName);
×
2790
      *pTagName = NULL;
×
2791
      break;
×
2792
    }
2793
  }
2794
  return code;
4✔
2795
}
2796

2797
static int32_t checkSubtablePrivilegeForTable(const SArray* pTables, SVnodeModifyOpStmt* pStmt) {
10✔
2798
  if (1 != taosArrayGetSize(pTables)) {
10✔
2799
    return TSDB_CODE_FAILED;
6✔
2800
  }
2801

2802
  SMetaRes* pRes = taosArrayGet(pTables, 0);
4✔
2803
  if (TSDB_CODE_SUCCESS != pRes->code) {
4!
2804
    return pRes->code;
×
2805
  }
2806

2807
  SArray* pTagName = NULL;
4✔
2808
  int32_t code = buildTagNameFromMeta(pStmt->pTableMeta, &pTagName);
4✔
2809
  if (TSDB_CODE_SUCCESS == code) {
4!
2810
    code = checkSubtablePrivilege((SArray*)pRes->pRes, pTagName, &pStmt->pTagCond);
4✔
2811
  }
2812
  taosArrayDestroy(pTagName);
4✔
2813
  return code;
4✔
2814
}
2815

2816
static int32_t processTableSchemaFromMetaData(SInsertParseContext* pCxt, const SMetaData* pMetaData,
31,752✔
2817
                                              SVnodeModifyOpStmt* pStmt, bool isStb) {
2818
  int32_t code = TSDB_CODE_SUCCESS;
31,752✔
2819
  if (!isStb && TSDB_SUPER_TABLE == pStmt->pTableMeta->tableType) {
31,752!
2820
    code = buildInvalidOperationMsg(&pCxt->msg, "insert data into super table is not supported");
×
2821
  }
2822
  if (TSDB_CODE_SUCCESS == code && isStb) {
31,752!
2823
    code = storeChildTableMeta(pCxt, pStmt);
160✔
2824
  }
2825
  if (TSDB_CODE_SUCCESS == code) {
31,752!
2826
    code = addTableVgroupFromMetaData(pMetaData->pTableHash, pStmt, isStb);
31,752✔
2827
  }
2828
  if (TSDB_CODE_SUCCESS == code && !isStb && NULL != pStmt->pTagCond) {
31,754!
2829
    code = checkSubtablePrivilegeForTable(pMetaData->pTableTag, pStmt);
10✔
2830
  }
2831
  return code;
31,754✔
2832
}
2833

2834
static void destoryTablesReq(void* p) {
64,595✔
2835
  STablesReq* pRes = (STablesReq*)p;
64,595✔
2836
  taosArrayDestroy(pRes->pTables);
64,595✔
2837
}
64,599✔
2838

2839
static void clearCatalogReq(SCatalogReq* pCatalogReq) {
32,300✔
2840
  if (NULL == pCatalogReq) {
32,300!
2841
    return;
×
2842
  }
2843

2844
  taosArrayDestroyEx(pCatalogReq->pTableMeta, destoryTablesReq);
32,300✔
2845
  pCatalogReq->pTableMeta = NULL;
32,300✔
2846
  taosArrayDestroyEx(pCatalogReq->pTableHash, destoryTablesReq);
32,300✔
2847
  pCatalogReq->pTableHash = NULL;
32,300✔
2848
  taosArrayDestroy(pCatalogReq->pUser);
32,300✔
2849
  pCatalogReq->pUser = NULL;
32,300✔
2850
  taosArrayDestroy(pCatalogReq->pTableTag);
32,300✔
2851
  pCatalogReq->pTableTag = NULL;
32,299✔
2852
}
2853

2854
static int32_t setVnodeModifOpStmt(SInsertParseContext* pCxt, SCatalogReq* pCatalogReq, const SMetaData* pMetaData,
32,300✔
2855
                                   SVnodeModifyOpStmt* pStmt) {
2856
  clearCatalogReq(pCatalogReq);
32,300✔
2857
  int32_t code = checkAuthFromMetaData(pMetaData->pUser, &pStmt->pTagCond);
32,299✔
2858
  if (code == TSDB_CODE_SUCCESS) {
32,299✔
2859
    code = getTableMetaFromMetaData(pMetaData->pTableMeta, &pStmt->pTableMeta);
32,293✔
2860
  }
2861
  if (code == TSDB_CODE_SUCCESS) {
32,298✔
2862
    if (pStmt->pTableMeta->tableType == TSDB_SUPER_TABLE && !pStmt->usingTableProcessing) {
31,762✔
2863
      pStmt->stbSyntax = true;
10✔
2864
    }
2865
    if (!pStmt->stbSyntax) {
31,762✔
2866
      if (pStmt->usingTableProcessing) {
31,752✔
2867
        return processTableSchemaFromMetaData(pCxt, pMetaData, pStmt, true);
160✔
2868
      }
2869
      return processTableSchemaFromMetaData(pCxt, pMetaData, pStmt, false);
31,592✔
2870
    }
2871
  }
2872
  return code;
546✔
2873
}
2874

2875
static int32_t resetVnodeModifOpStmt(SInsertParseContext* pCxt, SQuery* pQuery) {
×
2876
  nodesDestroyNode(pQuery->pRoot);
×
2877

2878
  int32_t code = createVnodeModifOpStmt(pCxt, true, &pQuery->pRoot);
×
2879
  if (TSDB_CODE_SUCCESS == code) {
×
2880
    SVnodeModifyOpStmt* pStmt = (SVnodeModifyOpStmt*)pQuery->pRoot;
×
2881

2882
    code = (*pCxt->pComCxt->pStmtCb->getExecInfoFn)(pCxt->pComCxt->pStmtCb->pStmt, &pStmt->pVgroupsHashObj,
×
2883
                                                    &pStmt->pTableBlockHashObj);
2884
    if (TSDB_CODE_SUCCESS == code) {
×
2885
      if (NULL == pStmt->pVgroupsHashObj) {
×
2886
        pStmt->pVgroupsHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK);
×
2887
      }
2888
      if (NULL == pStmt->pTableBlockHashObj) {
×
2889
        pStmt->pTableBlockHashObj =
×
2890
            taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
×
2891
      }
2892
      if (NULL == pStmt->pVgroupsHashObj || NULL == pStmt->pTableBlockHashObj) {
×
2893
        code = TSDB_CODE_OUT_OF_MEMORY;
×
2894
      }
2895
    }
2896
  }
2897

2898
  return code;
×
2899
}
2900

2901
static int32_t initInsertQuery(SInsertParseContext* pCxt, SCatalogReq* pCatalogReq, const SMetaData* pMetaData,
9,623,229✔
2902
                               SQuery** pQuery) {
2903
  if (NULL == *pQuery) {
9,623,229✔
2904
    return createInsertQuery(pCxt, pQuery);
9,593,495✔
2905
  }
2906

2907
  if (NULL != pCxt->pComCxt->pStmtCb) {
29,734!
2908
    return resetVnodeModifOpStmt(pCxt, *pQuery);
×
2909
  }
2910

2911
  SVnodeModifyOpStmt* pStmt = (SVnodeModifyOpStmt*)(*pQuery)->pRoot;
29,734✔
2912

2913
  if (!pStmt->fileProcessing) {
29,734!
2914
    return setVnodeModifOpStmt(pCxt, pCatalogReq, pMetaData, pStmt);
32,300✔
2915
  }
2916

2917
  return TSDB_CODE_SUCCESS;
×
2918
}
2919

2920
static int32_t setRefreshMeta(SQuery* pQuery) {
9,504,954✔
2921
  SVnodeModifyOpStmt* pStmt = (SVnodeModifyOpStmt*)pQuery->pRoot;
9,504,954✔
2922
  int32_t             code = 0;
9,504,954✔
2923

2924
  if (taosHashGetSize(pStmt->pTableNameHashObj) > 0) {
9,504,954✔
2925
    taosArrayDestroy(pQuery->pTableList);
4,084✔
2926
    pQuery->pTableList = taosArrayInit(taosHashGetSize(pStmt->pTableNameHashObj), sizeof(SName));
4,084✔
2927
    if (!pQuery->pTableList) {
4,084!
2928
      code = terrno;
×
2929
    } else {
2930
      SName* pTable = taosHashIterate(pStmt->pTableNameHashObj, NULL);
4,084✔
2931
      while (NULL != pTable) {
17,333✔
2932
        if (NULL == taosArrayPush(pQuery->pTableList, pTable)) {
26,498!
2933
          code = terrno;
×
2934
          taosHashCancelIterate(pStmt->pTableNameHashObj, pTable);
×
2935
          break;
×
2936
        }
2937
        pTable = taosHashIterate(pStmt->pTableNameHashObj, pTable);
13,249✔
2938
      }
2939
    }
2940
  }
2941

2942
  if (TSDB_CODE_SUCCESS == code && taosHashGetSize(pStmt->pDbFNameHashObj) > 0) {
9,460,183!
2943
    taosArrayDestroy(pQuery->pDbList);
4,084✔
2944
    pQuery->pDbList = taosArrayInit(taosHashGetSize(pStmt->pDbFNameHashObj), TSDB_DB_FNAME_LEN);
4,084✔
2945
    if (!pQuery->pDbList) {
4,084!
2946
      code = terrno;
×
2947
    } else {
2948
      char* pDb = taosHashIterate(pStmt->pDbFNameHashObj, NULL);
4,084✔
2949
      while (NULL != pDb) {
6,408✔
2950
        if (NULL == taosArrayPush(pQuery->pDbList, pDb)) {
8,172!
2951
          code = terrno;
×
2952
          taosHashCancelIterate(pStmt->pDbFNameHashObj, pDb);
×
2953
          break;
×
2954
        }
2955
        pDb = taosHashIterate(pStmt->pDbFNameHashObj, pDb);
4,086✔
2956
      }
2957
    }
2958
  }
2959

2960
  return code;
9,447,590✔
2961
}
2962

2963
// INSERT INTO
2964
//   tb_name
2965
//       [USING stb_name [(tag1_name, ...)] TAGS (tag1_value, ...) [table_options]]
2966
//       [(field1_name, ...)]
2967
//       VALUES (field1_value, ...) [(field1_value2, ...) ...] | FILE csv_file_path
2968
//   [...];
2969
static int32_t parseInsertSqlFromStart(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
9,576,480✔
2970
  int32_t code = skipInsertInto(&pStmt->pSql, &pCxt->msg);
9,576,480✔
2971
  if (TSDB_CODE_SUCCESS == code) {
9,597,921!
2972
    code = parseInsertBody(pCxt, pStmt);
9,598,170✔
2973
  }
2974
  return code;
9,532,577✔
2975
}
2976

2977
static int32_t parseInsertSqlFromCsv(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
20✔
2978
  int32_t          code = TSDB_CODE_SUCCESS;
20✔
2979
  SRowsDataContext rowsDataCxt;
2980

2981
  if (!pStmt->stbSyntax) {
20✔
2982
    STableDataCxt* pTableCxt = NULL;
18✔
2983
    code = getTableDataCxt(pCxt, pStmt, &pTableCxt);
18✔
2984
    rowsDataCxt.pTableDataCxt = pTableCxt;
18✔
2985
  } else {
2986
    rowsDataCxt.pStbRowsCxt = pStmt->pStbRowsCxt;
2✔
2987
  }
2988
  if (TSDB_CODE_SUCCESS == code) {
20!
2989
    code = parseDataFromFileImpl(pCxt, pStmt, rowsDataCxt);
20✔
2990
  }
2991

2992
  if (TSDB_CODE_SUCCESS == code) {
20!
2993
    if (pStmt->fileProcessing) {
20!
2994
      code = parseInsertBodyBottom(pCxt, pStmt);
×
2995
    } else {
2996
      code = parseInsertBody(pCxt, pStmt);
20✔
2997
    }
2998
  }
2999

3000
  return code;
20✔
3001
}
3002

3003
static int32_t parseInsertSqlFromTable(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
31,757✔
3004
  int32_t code = parseInsertTableClauseBottom(pCxt, pStmt);
31,757✔
3005
  if (TSDB_CODE_SUCCESS == code) {
31,754✔
3006
    code = parseInsertBody(pCxt, pStmt);
31,579✔
3007
  }
3008
  return code;
31,758✔
3009
}
3010

3011
static int32_t parseInsertSqlImpl(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt) {
9,608,884✔
3012
  if (pStmt->pSql == pCxt->pComCxt->pSql || NULL != pCxt->pComCxt->pStmtCb) {
9,608,884!
3013
    return parseInsertSqlFromStart(pCxt, pStmt);
9,577,107✔
3014
  }
3015

3016
  if (pStmt->fileProcessing) {
31,777✔
3017
    return parseInsertSqlFromCsv(pCxt, pStmt);
20✔
3018
  }
3019

3020
  return parseInsertSqlFromTable(pCxt, pStmt);
31,757✔
3021
}
3022

3023
static int32_t buildInsertTableReq(SName* pName, SArray** pTables) {
65,428✔
3024
  *pTables = taosArrayInit(1, sizeof(SName));
65,428✔
3025
  if (NULL == *pTables) {
65,423!
3026
    return terrno;
×
3027
  }
3028

3029
  if (NULL == taosArrayPush(*pTables, pName)) {
130,847!
3030
    taosArrayDestroy(*pTables);
×
3031
    *pTables = NULL;
×
3032
    return terrno;
×
3033
  }
3034
  return TSDB_CODE_SUCCESS;
65,424✔
3035
}
3036

3037
static int32_t buildInsertDbReq(SName* pName, SArray** pDbs) {
65,421✔
3038
  if (NULL == *pDbs) {
65,421!
3039
    *pDbs = taosArrayInit(1, sizeof(STablesReq));
65,421✔
3040
    if (NULL == *pDbs) {
65,426!
3041
      return terrno;
×
3042
    }
3043
  }
3044

3045
  STablesReq req = {0};
65,426✔
3046
  (void)tNameGetFullDbName(pName, req.dbFName);
65,426✔
3047
  int32_t code = buildInsertTableReq(pName, &req.pTables);
65,426✔
3048
  if (TSDB_CODE_SUCCESS == code && NULL == taosArrayPush(*pDbs, &req)) {
130,842!
3049
    code = TSDB_CODE_OUT_OF_MEMORY;
×
3050
  }
3051

3052
  return code;
65,421✔
3053
}
3054

3055
static int32_t buildInsertUserAuthReq(const char* pUser, SName* pName, SArray** pUserAuth) {
32,708✔
3056
  *pUserAuth = taosArrayInit(1, sizeof(SUserAuthInfo));
32,708✔
3057
  if (NULL == *pUserAuth) {
32,713!
3058
    return terrno;
×
3059
  }
3060

3061
  SUserAuthInfo userAuth = {.type = AUTH_TYPE_WRITE};
32,713✔
3062
  snprintf(userAuth.user, sizeof(userAuth.user), "%s", pUser);
32,713✔
3063
  memcpy(&userAuth.tbName, pName, sizeof(SName));
32,713✔
3064
  if (NULL == taosArrayPush(*pUserAuth, &userAuth)) {
65,425!
3065
    taosArrayDestroy(*pUserAuth);
×
3066
    *pUserAuth = NULL;
×
3067
    return terrno;
×
3068
  }
3069

3070
  return TSDB_CODE_SUCCESS;
32,712✔
3071
}
3072

3073
static int32_t buildInsertTableTagReq(SName* pName, SArray** pTables) { return buildInsertTableReq(pName, pTables); }
4✔
3074

3075
static int32_t buildInsertCatalogReq(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, SCatalogReq* pCatalogReq) {
32,709✔
3076
  int32_t code = buildInsertUserAuthReq(
32,709✔
3077
      pCxt->pComCxt->pUser, (0 == pStmt->usingTableName.type ? &pStmt->targetTableName : &pStmt->usingTableName),
65,418✔
3078
      &pCatalogReq->pUser);
3079
  if (TSDB_CODE_SUCCESS == code && pCxt->needTableTagVal) {
32,712!
3080
    code = buildInsertTableTagReq(&pStmt->targetTableName, &pCatalogReq->pTableTag);
4✔
3081
  }
3082
  if (TSDB_CODE_SUCCESS == code) {
32,712!
3083
    if (0 == pStmt->usingTableName.type) {
32,712✔
3084
      code = buildInsertDbReq(&pStmt->targetTableName, &pCatalogReq->pTableMeta);
32,541✔
3085
    } else {
3086
      code = buildInsertDbReq(&pStmt->usingTableName, &pCatalogReq->pTableMeta);
171✔
3087
    }
3088
  }
3089
  if (TSDB_CODE_SUCCESS == code) {
32,711!
3090
    code = buildInsertDbReq(&pStmt->targetTableName, &pCatalogReq->pTableHash);
32,711✔
3091
  }
3092
  return code;
32,712✔
3093
}
3094

3095
static int32_t setNextStageInfo(SInsertParseContext* pCxt, SQuery* pQuery, SCatalogReq* pCatalogReq) {
9,540,423✔
3096
  SVnodeModifyOpStmt* pStmt = (SVnodeModifyOpStmt*)pQuery->pRoot;
9,540,423✔
3097
  if (pCxt->missCache) {
9,540,423✔
3098
    parserDebug("0x%" PRIx64 " %d rows of %d tables have been inserted before cache miss", pCxt->pComCxt->requestId,
32,712✔
3099
                pStmt->totalRowsNum, pStmt->totalTbNum);
3100

3101
    pQuery->execStage = QUERY_EXEC_STAGE_PARSE;
32,712✔
3102
    return buildInsertCatalogReq(pCxt, pStmt, pCatalogReq);
32,712✔
3103
  }
3104

3105
  parserDebug("0x%" PRIx64 " %d rows of %d tables have been inserted", pCxt->pComCxt->requestId, pStmt->totalRowsNum,
9,507,711✔
3106
              pStmt->totalTbNum);
3107

3108
  pQuery->execStage = QUERY_EXEC_STAGE_SCHEDULE;
9,507,068✔
3109
  return TSDB_CODE_SUCCESS;
9,507,068✔
3110
}
3111

3112
int32_t parseInsertSql(SParseContext* pCxt, SQuery** pQuery, SCatalogReq* pCatalogReq, const SMetaData* pMetaData) {
9,621,349✔
3113
  SInsertParseContext context = {.pComCxt = pCxt,
19,242,698✔
3114
                                 .msg = {.buf = pCxt->pMsg, .len = pCxt->msgLen},
9,621,349✔
3115
                                 .missCache = false,
3116
                                 .usingDuplicateTable = false,
3117
                                 .needRequest = true,
3118
                                 .forceUpdate = (NULL != pCatalogReq ? pCatalogReq->forceUpdate : false),
9,621,349!
3119
                                 .isStmtBind = pCxt->isStmtBind};
9,621,349✔
3120

3121
  int32_t             code = initInsertQuery(&context, pCatalogReq, pMetaData, pQuery);
9,621,349✔
3122
  SVnodeModifyOpStmt* pStmt = (SVnodeModifyOpStmt*)((*pQuery)->pRoot);
9,609,797✔
3123
  if (TSDB_CODE_SUCCESS == code) {
9,609,797✔
3124
    code = parseInsertSqlImpl(&context, pStmt);
9,609,506✔
3125
  }
3126
  if (TSDB_CODE_SUCCESS == code) {
9,561,325✔
3127
    code = setNextStageInfo(&context, *pQuery, pCatalogReq);
9,545,622✔
3128
  }
3129
  if ((TSDB_CODE_SUCCESS == code || NEED_CLIENT_HANDLE_ERROR(code)) &&
9,559,393!
3130
      QUERY_EXEC_STAGE_SCHEDULE == (*pQuery)->execStage) {
9,534,967✔
3131
    code = setRefreshMeta(*pQuery);
9,506,869✔
3132
  }
3133

3134
  insDestroyBoundColInfo(&context.tags);
9,499,870✔
3135
  // if no data to insert, set emptyMode to avoid request server
3136
  if (!context.needRequest) {
9,499,201✔
3137
    (*pQuery)->execMode = QUERY_EXEC_MODE_EMPTY_RESULT;
10✔
3138
  }
3139
  return code;
9,499,201✔
3140
}
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