clientSmlLine.c 18.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "clientSml.h"

// comma ,
X
Xiaoyu Wang 已提交
24 25
// #define IS_SLASH_COMMA(sql) (*(sql) == COMMA && *((sql)-1) == SLASH)
#define IS_COMMA(sql) (*(sql) == COMMA && *((sql)-1) != SLASH)
26
// space
X
Xiaoyu Wang 已提交
27 28
// #define IS_SLASH_SPACE(sql) (*(sql) == SPACE && *((sql)-1) == SLASH)
#define IS_SPACE(sql) (*(sql) == SPACE && *((sql)-1) != SLASH)
29
// equal =
X
Xiaoyu Wang 已提交
30 31
// #define IS_SLASH_EQUAL(sql) (*(sql) == EQUAL && *((sql)-1) == SLASH)
#define IS_EQUAL(sql) (*(sql) == EQUAL && *((sql)-1) != SLASH)
32
// quote "
X
Xiaoyu Wang 已提交
33 34
// #define IS_SLASH_QUOTE(sql) (*(sql) == QUOTE && *((sql)-1) == SLASH)
#define IS_QUOTE(sql) (*(sql) == QUOTE && *((sql)-1) != SLASH)
35
// SLASH
X
Xiaoyu Wang 已提交
36
// #define IS_SLASH_SLASH(sql) (*(sql) == SLASH && *((sql)-1) == SLASH)
37

X
Xiaoyu Wang 已提交
38 39 40 41
#define IS_SLASH_LETTER(sql)                                                                           \
  (*((sql)-1) == SLASH && (*(sql) == COMMA || *(sql) == SPACE || *(sql) == EQUAL || *(sql) == QUOTE || \
                           *(sql) == SLASH))  //  (IS_SLASH_COMMA(sql) || IS_SLASH_SPACE(sql) || IS_SLASH_EQUAL(sql) ||
                                              //  IS_SLASH_QUOTE(sql) || IS_SLASH_SLASH(sql))
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56

#define MOVE_FORWARD_ONE(sql, len) (memmove((void *)((sql)-1), (sql), len))

#define PROCESS_SLASH(key, keyLen)           \
  for (int i = 1; i < keyLen; ++i) {         \
    if (IS_SLASH_LETTER(key + i)) {          \
      MOVE_FORWARD_ONE(key + i, keyLen - i); \
      i--;                                   \
      keyLen--;                              \
    }                                        \
  }

#define BINARY_ADD_LEN 2  // "binary"   2 means " "
#define NCHAR_ADD_LEN  3  // L"nchar"   3 means L" "

X
Xiaoyu Wang 已提交
57
uint8_t smlPrecisionConvert[7] = {TSDB_TIME_PRECISION_NANO,    TSDB_TIME_PRECISION_HOURS, TSDB_TIME_PRECISION_MINUTES,
58 59 60 61 62 63
                                  TSDB_TIME_PRECISION_SECONDS, TSDB_TIME_PRECISION_MILLI, TSDB_TIME_PRECISION_MICRO,
                                  TSDB_TIME_PRECISION_NANO};

static int64_t smlParseInfluxTime(SSmlHandle *info, const char *data, int32_t len) {
  uint8_t toPrecision = info->currSTableMeta ? info->currSTableMeta->tableInfo.precision : TSDB_TIME_PRECISION_NANO;

X
Xiaoyu Wang 已提交
64 65
  if (unlikely(len == 0 || (len == 1 && data[0] == '0'))) {
    return taosGetTimestampNs() / smlFactorNS[toPrecision];
66 67 68 69 70 71 72 73 74 75 76 77
  }

  uint8_t fromPrecision = smlPrecisionConvert[info->precision];

  int64_t ts = smlGetTimeValue(data, len, fromPrecision, toPrecision);
  if (unlikely(ts == -1)) {
    smlBuildInvalidDataMsg(&info->msgBuf, "invalid timestamp", data);
    return -1;
  }
  return ts;
}

wmmhello's avatar
wmmhello 已提交
78
int32_t smlParseValue(SSmlKv *pVal, SSmlMsgBuf *msg) {
X
Xiaoyu Wang 已提交
79
  if (pVal->value[0] == '"') {  // binary
wmmhello's avatar
wmmhello 已提交
80 81 82 83 84 85 86 87
    if (pVal->length >= 2 && pVal->value[pVal->length - 1] == '"') {
      pVal->type = TSDB_DATA_TYPE_BINARY;
      pVal->length -= BINARY_ADD_LEN;
      if (pVal->length > TSDB_MAX_BINARY_LEN - VARSTR_HEADER_SIZE) {
        return TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN;
      }
      pVal->value += (BINARY_ADD_LEN - 1);
      return TSDB_CODE_SUCCESS;
88
    }
wmmhello's avatar
wmmhello 已提交
89
    return TSDB_CODE_TSC_INVALID_VALUE;
90
  }
wmmhello's avatar
wmmhello 已提交
91

X
Xiaoyu Wang 已提交
92 93
  if (pVal->value[0] == 'l' || pVal->value[0] == 'L') {  // nchar
    if (pVal->value[1] == '"' && pVal->value[pVal->length - 1] == '"' && pVal->length >= 3) {
wmmhello's avatar
wmmhello 已提交
94 95 96 97 98 99 100
      pVal->type = TSDB_DATA_TYPE_NCHAR;
      pVal->length -= NCHAR_ADD_LEN;
      if (pVal->length > (TSDB_MAX_NCHAR_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) {
        return TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN;
      }
      pVal->value += (NCHAR_ADD_LEN - 1);
      return TSDB_CODE_SUCCESS;
101
    }
wmmhello's avatar
wmmhello 已提交
102
    return TSDB_CODE_TSC_INVALID_VALUE;
103 104
  }

X
Xiaoyu Wang 已提交
105 106 107 108
  if (pVal->value[0] == 't' || pVal->value[0] == 'T') {
    if (pVal->length == 1 ||
        (pVal->length == 4 && (pVal->value[1] == 'r' || pVal->value[1] == 'R') &&
         (pVal->value[2] == 'u' || pVal->value[2] == 'U') && (pVal->value[3] == 'e' || pVal->value[3] == 'E'))) {
wmmhello's avatar
wmmhello 已提交
109 110 111 112 113 114
      pVal->i = TSDB_TRUE;
      pVal->type = TSDB_DATA_TYPE_BOOL;
      pVal->length = (int16_t)tDataTypes[pVal->type].bytes;
      return TSDB_CODE_SUCCESS;
    }
    return TSDB_CODE_TSC_INVALID_VALUE;
115
  }
wmmhello's avatar
wmmhello 已提交
116

X
Xiaoyu Wang 已提交
117 118 119 120 121
  if (pVal->value[0] == 'f' || pVal->value[0] == 'F') {
    if (pVal->length == 1 ||
        (pVal->length == 5 && (pVal->value[1] == 'a' || pVal->value[1] == 'A') &&
         (pVal->value[2] == 'l' || pVal->value[2] == 'L') && (pVal->value[3] == 's' || pVal->value[3] == 'S') &&
         (pVal->value[4] == 'e' || pVal->value[4] == 'E'))) {
wmmhello's avatar
wmmhello 已提交
122 123 124 125 126 127 128 129
      pVal->i = TSDB_FALSE;
      pVal->type = TSDB_DATA_TYPE_BOOL;
      pVal->length = (int16_t)tDataTypes[pVal->type].bytes;
      return TSDB_CODE_SUCCESS;
    }
    return TSDB_CODE_TSC_INVALID_VALUE;
  }

130 131 132 133 134 135 136 137 138
  // number
  if (smlParseNumber(pVal, msg)) {
    pVal->length = (int16_t)tDataTypes[pVal->type].bytes;
    return TSDB_CODE_SUCCESS;
  }

  return TSDB_CODE_TSC_INVALID_VALUE;
}

X
Xiaoyu Wang 已提交
139 140 141
static int32_t smlParseTagKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLineInfo *currElement, bool isSameMeasure,
                             bool isSameCTable) {
  if (isSameCTable) {
142 143 144 145 146
    return TSDB_CODE_SUCCESS;
  }

  int     cnt = 0;
  SArray *preLineKV = info->preLineTagKV;
X
Xiaoyu Wang 已提交
147 148 149 150
  if (info->dataFormat) {
    if (unlikely(!isSameMeasure)) {
      SSmlSTableMeta **tmp =
          (SSmlSTableMeta **)taosHashGet(info->superTables, currElement->measure, currElement->measureLen);
151

152
      SSmlSTableMeta *sMeta = NULL;
X
Xiaoyu Wang 已提交
153 154 155
      if (unlikely(tmp == NULL)) {
        STableMeta *pTableMeta = smlGetMeta(info, currElement->measure, currElement->measureLen);
        if (pTableMeta == NULL) {
156
          info->dataFormat = false;
X
Xiaoyu Wang 已提交
157
          info->reRun = true;
158 159
          return TSDB_CODE_SUCCESS;
        }
160
        sMeta = smlBuildSTableMeta(info->dataFormat);
wmmhello's avatar
wmmhello 已提交
161
        sMeta->tableMeta = pTableMeta;
162
        taosHashPut(info->superTables, currElement->measure, currElement->measureLen, &sMeta, POINTER_BYTES);
163 164 165 166 167
        for(int i = pTableMeta->tableInfo.numOfColumns; i < pTableMeta->tableInfo.numOfTags + pTableMeta->tableInfo.numOfColumns; i++){
          SSchema *tag = pTableMeta->schema + i;
          SSmlKv kv = {.key = tag->name, .keyLen = strlen(tag->name), .type = tag->type, .length = (tag->bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE };
          taosArrayPush(sMeta->tags, &kv);
        }
168
        tmp = &sMeta;
169
      }
170 171
      info->currSTableMeta = (*tmp)->tableMeta;
      info->maxTagKVs = (*tmp)->tags;
172 173
    }
  }
X
Xiaoyu Wang 已提交
174
  taosArrayClear(preLineKV);
175 176 177 178 179 180 181 182 183

  while (*sql < sqlEnd) {
    if (unlikely(IS_SPACE(*sql))) {
      break;
    }

    bool hasSlash = false;
    // parse key
    const char *key = *sql;
X
Xiaoyu Wang 已提交
184
    size_t      keyLen = 0;
185 186 187 188 189 190 191 192 193 194
    while (*sql < sqlEnd) {
      if (unlikely(IS_COMMA(*sql))) {
        smlBuildInvalidDataMsg(&info->msgBuf, "invalid data", *sql);
        return TSDB_CODE_SML_INVALID_DATA;
      }
      if (unlikely(IS_EQUAL(*sql))) {
        keyLen = *sql - key;
        (*sql)++;
        break;
      }
X
Xiaoyu Wang 已提交
195
      if (!hasSlash) {
196 197 198 199
        hasSlash = (*(*sql) == SLASH);
      }
      (*sql)++;
    }
X
Xiaoyu Wang 已提交
200
    if (unlikely(hasSlash)) {
201 202 203 204 205 206 207 208 209 210
      PROCESS_SLASH(key, keyLen)
    }

    if (unlikely(IS_INVALID_COL_LEN(keyLen))) {
      smlBuildInvalidDataMsg(&info->msgBuf, "invalid key or key is too long than 64", key);
      return TSDB_CODE_TSC_INVALID_COLUMN_LENGTH;
    }

    // parse value
    const char *value = *sql;
X
Xiaoyu Wang 已提交
211
    size_t      valueLen = 0;
212 213 214 215 216
    hasSlash = false;
    while (*sql < sqlEnd) {
      // parse value
      if (unlikely(IS_SPACE(*sql) || IS_COMMA(*sql))) {
        break;
X
Xiaoyu Wang 已提交
217
      } else if (unlikely(IS_EQUAL(*sql))) {
218 219 220 221
        smlBuildInvalidDataMsg(&info->msgBuf, "invalid data", *sql);
        return TSDB_CODE_SML_INVALID_DATA;
      }

X
Xiaoyu Wang 已提交
222
      if (!hasSlash) {
223 224 225 226 227 228 229 230 231 232 233 234
        hasSlash = (*(*sql) == SLASH);
      }

      (*sql)++;
    }
    valueLen = *sql - value;

    if (unlikely(valueLen == 0)) {
      smlBuildInvalidDataMsg(&info->msgBuf, "invalid value", value);
      return TSDB_CODE_SML_INVALID_DATA;
    }

X
Xiaoyu Wang 已提交
235
    if (unlikely(hasSlash)) {
236 237 238 239 240 241 242
      PROCESS_SLASH(value, valueLen)
    }

    if (unlikely(valueLen > (TSDB_MAX_NCHAR_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE)) {
      return TSDB_CODE_PAR_INVALID_VAR_COLUMN_LEN;
    }

wmmhello's avatar
wmmhello 已提交
243
    SSmlKv kv = {.key = key, .keyLen = keyLen, .type = TSDB_DATA_TYPE_NCHAR, .value = value, .length = valueLen};
X
Xiaoyu Wang 已提交
244 245
    if (info->dataFormat) {
      if (unlikely(cnt + 1 > info->currSTableMeta->tableInfo.numOfTags)) {
246
        info->dataFormat = false;
X
Xiaoyu Wang 已提交
247
        info->reRun = true;
248 249 250
        return TSDB_CODE_SUCCESS;
      }

251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
      if (unlikely(cnt >= taosArrayGetSize(info->maxTagKVs))) {
        info->dataFormat = false;
        info->reRun = true;
        return TSDB_CODE_SUCCESS;
      }
      SSmlKv *maxKV = (SSmlKv *)taosArrayGet(info->maxTagKVs, cnt);

      if (unlikely(!IS_SAME_KEY)) {
        info->dataFormat = false;
        info->reRun = true;
        return TSDB_CODE_SUCCESS;
      }

      if (unlikely(kv.length > maxKV->length)) {
        maxKV->length = kv.length;
        info->needModifySchema = true;
267 268
      }
    }
wmmhello's avatar
wmmhello 已提交
269
    taosArrayPush(preLineKV, &kv);
270 271

    cnt++;
X
Xiaoyu Wang 已提交
272
    if (IS_SPACE(*sql)) {
273 274 275 276 277
      break;
    }
    (*sql)++;
  }

X
Xiaoyu Wang 已提交
278
  void *oneTable = taosHashGet(info->childTables, currElement->measure, currElement->measureTagsLen);
279 280 281 282 283 284 285 286 287 288 289
  if ((oneTable != NULL)) {
    return TSDB_CODE_SUCCESS;
  }

  SSmlTableInfo *tinfo = smlBuildTableInfo(1, currElement->measure, currElement->measureLen);
  if (unlikely(!tinfo)) {
    return TSDB_CODE_OUT_OF_MEMORY;
  }
  tinfo->tags = taosArrayDup(preLineKV, NULL);

  smlSetCTableName(tinfo);
wmmhello's avatar
wmmhello 已提交
290
  tinfo->uid = info->uid++;
X
Xiaoyu Wang 已提交
291
  if (info->dataFormat) {
292 293
    info->currSTableMeta->uid = tinfo->uid;
    tinfo->tableDataCtx = smlInitTableDataCtx(info->pQuery, info->currSTableMeta);
X
Xiaoyu Wang 已提交
294
    if (tinfo->tableDataCtx == NULL) {
295 296 297 298 299
      smlBuildInvalidDataMsg(&info->msgBuf, "smlInitTableDataCtx error", NULL);
      return TSDB_CODE_SML_INVALID_DATA;
    }
  }

300
  taosHashPut(info->childTables, currElement->measure, currElement->measureTagsLen, &tinfo, POINTER_BYTES);
301 302 303 304

  return TSDB_CODE_SUCCESS;
}

X
Xiaoyu Wang 已提交
305 306
static int32_t smlParseColKv(SSmlHandle *info, char **sql, char *sqlEnd, SSmlLineInfo *currElement, bool isSameMeasure,
                             bool isSameCTable) {
307
  int     cnt = 0;
X
Xiaoyu Wang 已提交
308 309 310 311
  if (info->dataFormat) {
    if (unlikely(!isSameCTable)) {
      SSmlTableInfo **oneTable =
          (SSmlTableInfo **)taosHashGet(info->childTables, currElement->measure, currElement->measureTagsLen);
312 313 314 315
      if (unlikely(oneTable == NULL)) {
        smlBuildInvalidDataMsg(&info->msgBuf, "child table should inside", currElement->measure);
        return TSDB_CODE_SML_INVALID_DATA;
      }
316
      info->currTableDataCtx = (*oneTable)->tableDataCtx;
317 318
    }

X
Xiaoyu Wang 已提交
319 320 321 322 323 324
    if (unlikely(!isSameMeasure)) {
      SSmlSTableMeta **tmp =
          (SSmlSTableMeta **)taosHashGet(info->superTables, currElement->measure, currElement->measureLen);
      if (unlikely(tmp == NULL)) {
        STableMeta *pTableMeta = smlGetMeta(info, currElement->measure, currElement->measureLen);
        if (pTableMeta == NULL) {
325
          info->dataFormat = false;
X
Xiaoyu Wang 已提交
326
          info->reRun = true;
327 328
          return TSDB_CODE_SUCCESS;
        }
329 330 331 332 333 334 335 336 337 338 339 340 341 342
        *tmp = smlBuildSTableMeta(info->dataFormat);
        (*tmp)->tableMeta = pTableMeta;
        taosHashPut(info->superTables, currElement->measure, currElement->measureLen, tmp, POINTER_BYTES);

        for(int i = 0; i < pTableMeta->tableInfo.numOfColumns; i++){
          SSchema *tag = pTableMeta->schema + i;
          SSmlKv kv = {.key = tag->name, .keyLen = strlen(tag->name), .type = tag->type };
          if(tag->type == TSDB_DATA_TYPE_NCHAR){
            kv.length = (tag->bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE;
          }else if(tag->type == TSDB_DATA_TYPE_BINARY){
            kv.length = tag->bytes - VARSTR_HEADER_SIZE;
          }
          taosArrayPush((*tmp)->cols, &kv);
        }
343
      }
344
      info->currSTableMeta = (*tmp)->tableMeta;
345
      info->masColKVs = (*tmp)->cols;
346 347 348 349 350 351 352 353 354 355 356
    }
  }

  while (*sql < sqlEnd) {
    if (unlikely(IS_SPACE(*sql))) {
      break;
    }

    bool hasSlash = false;
    // parse key
    const char *key = *sql;
X
Xiaoyu Wang 已提交
357
    size_t      keyLen = 0;
358 359 360 361 362 363 364 365 366 367
    while (*sql < sqlEnd) {
      if (unlikely(IS_COMMA(*sql))) {
        smlBuildInvalidDataMsg(&info->msgBuf, "invalid data", *sql);
        return TSDB_CODE_SML_INVALID_DATA;
      }
      if (unlikely(IS_EQUAL(*sql))) {
        keyLen = *sql - key;
        (*sql)++;
        break;
      }
X
Xiaoyu Wang 已提交
368
      if (!hasSlash) {
369 370 371 372
        hasSlash = (*(*sql) == SLASH);
      }
      (*sql)++;
    }
X
Xiaoyu Wang 已提交
373
    if (unlikely(hasSlash)) {
374 375 376 377 378 379 380 381 382 383
      PROCESS_SLASH(key, keyLen)
    }

    if (unlikely(IS_INVALID_COL_LEN(keyLen))) {
      smlBuildInvalidDataMsg(&info->msgBuf, "invalid key or key is too long than 64", key);
      return TSDB_CODE_TSC_INVALID_COLUMN_LENGTH;
    }

    // parse value
    const char *value = *sql;
X
Xiaoyu Wang 已提交
384 385 386
    size_t      valueLen = 0;
    hasSlash = false;
    bool isInQuote = false;
387 388
    while (*sql < sqlEnd) {
      // parse value
wmmhello's avatar
wmmhello 已提交
389
      if (unlikely(IS_QUOTE(*sql))) {
390 391 392 393
        isInQuote = !isInQuote;
        (*sql)++;
        continue;
      }
X
Xiaoyu Wang 已提交
394
      if (!isInQuote) {
395 396 397 398 399 400 401
        if (unlikely(IS_SPACE(*sql) || IS_COMMA(*sql))) {
          break;
        } else if (unlikely(IS_EQUAL(*sql))) {
          smlBuildInvalidDataMsg(&info->msgBuf, "invalid data", *sql);
          return TSDB_CODE_SML_INVALID_DATA;
        }
      }
X
Xiaoyu Wang 已提交
402
      if (!hasSlash) {
403 404 405 406 407 408 409 410 411 412 413 414 415 416 417
        hasSlash = (*(*sql) == SLASH);
      }

      (*sql)++;
    }
    valueLen = *sql - value;

    if (unlikely(isInQuote)) {
      smlBuildInvalidDataMsg(&info->msgBuf, "only one quote", value);
      return TSDB_CODE_SML_INVALID_DATA;
    }
    if (unlikely(valueLen == 0)) {
      smlBuildInvalidDataMsg(&info->msgBuf, "invalid value", value);
      return TSDB_CODE_SML_INVALID_DATA;
    }
X
Xiaoyu Wang 已提交
418
    if (unlikely(hasSlash)) {
419 420 421
      PROCESS_SLASH(value, valueLen)
    }

X
Xiaoyu Wang 已提交
422
    SSmlKv  kv = {.key = key, .keyLen = keyLen, .value = value, .length = valueLen};
423 424
    int32_t ret = smlParseValue(&kv, &info->msgBuf);
    if (ret != TSDB_CODE_SUCCESS) {
wmmhello's avatar
wmmhello 已提交
425
      smlBuildInvalidDataMsg(&info->msgBuf, "smlParseValue error", value);
426 427 428
      return ret;
    }

X
Xiaoyu Wang 已提交
429 430 431
    if (info->dataFormat) {
      // cnt begin 0, add ts so + 2
      if (unlikely(cnt + 2 > info->currSTableMeta->tableInfo.numOfColumns)) {
432
        info->dataFormat = false;
X
Xiaoyu Wang 已提交
433
        info->reRun = true;
434 435 436 437 438 439 440
        return TSDB_CODE_SUCCESS;
      }
      // bind data
      ret = smlBuildCol(info->currTableDataCtx, info->currSTableMeta->schema, &kv, cnt + 1);
      if (unlikely(ret != TSDB_CODE_SUCCESS)) {
        uError("smlBuildCol error, retry");
        info->dataFormat = false;
X
Xiaoyu Wang 已提交
441
        info->reRun = true;
442 443
        return TSDB_CODE_SUCCESS;
      }
444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459
      if (cnt >= taosArrayGetSize(info->masColKVs)) {
        info->dataFormat = false;
        info->reRun = true;
        return TSDB_CODE_SUCCESS;
      }
      SSmlKv *maxKV = (SSmlKv *)taosArrayGet(info->masColKVs, cnt);
      if (kv.type != maxKV->type) {
        info->dataFormat = false;
        info->reRun = true;
        return TSDB_CODE_SUCCESS;
      }
      if (unlikely(!IS_SAME_KEY)) {
        info->dataFormat = false;
        info->reRun = true;
        return TSDB_CODE_SUCCESS;
      }
460

461 462 463
      if (unlikely(IS_VAR_DATA_TYPE(kv.type) && kv.length > maxKV->length)) {
        maxKV->length = kv.length;
        info->needModifySchema = true;
464
      }
X
Xiaoyu Wang 已提交
465 466
    } else {
      if (currElement->colArray == NULL) {
X
Xiaoyu Wang 已提交
467
        currElement->colArray = taosArrayInit_s(sizeof(SSmlKv), 1);
468
      }
X
Xiaoyu Wang 已提交
469
      taosArrayPush(currElement->colArray, &kv);  // reserve for timestamp
470 471 472
    }

    cnt++;
X
Xiaoyu Wang 已提交
473
    if (IS_SPACE(*sql)) {
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510
      break;
    }
    (*sql)++;
  }

  return TSDB_CODE_SUCCESS;
}

int32_t smlParseInfluxString(SSmlHandle *info, char *sql, char *sqlEnd, SSmlLineInfo *elements) {
  if (!sql) return TSDB_CODE_SML_INVALID_DATA;
  JUMP_SPACE(sql, sqlEnd)
  if (unlikely(*sql == COMMA)) return TSDB_CODE_SML_INVALID_DATA;
  elements->measure = sql;

  // parse measure
  while (sql < sqlEnd) {
    if (unlikely((sql != elements->measure) && IS_SLASH_LETTER(sql))) {
      MOVE_FORWARD_ONE(sql, sqlEnd - sql);
      sqlEnd--;
      continue;
    }
    if (unlikely(IS_COMMA(sql))) {
      break;
    }

    if (unlikely(IS_SPACE(sql))) {
      break;
    }
    sql++;
  }
  elements->measureLen = sql - elements->measure;
  if (unlikely(IS_INVALID_TABLE_LEN(elements->measureLen))) {
    smlBuildInvalidDataMsg(&info->msgBuf, "measure is empty or too large than 192", NULL);
    return TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH;
  }

  // to get measureTagsLen before
X
Xiaoyu Wang 已提交
511 512
  const char *tmp = sql;
  while (tmp < sqlEnd) {
513 514 515 516 517 518 519 520 521
    if (unlikely(IS_SPACE(tmp))) {
      break;
    }
    tmp++;
  }
  elements->measureTagsLen = tmp - elements->measure;

  bool isSameCTable = false;
  bool isSameMeasure = false;
X
Xiaoyu Wang 已提交
522
  if (IS_SAME_CHILD_TABLE) {
523 524
    isSameCTable = true;
    isSameMeasure = true;
X
Xiaoyu Wang 已提交
525
  } else if (info->dataFormat) {
526 527 528 529 530 531 532
    isSameMeasure = IS_SAME_SUPER_TABLE;
  }
  // parse tag
  if (*sql == COMMA) sql++;
  elements->tags = sql;

  int ret = smlParseTagKv(info, &sql, sqlEnd, elements, isSameMeasure, isSameCTable);
X
Xiaoyu Wang 已提交
533
  if (unlikely(ret != TSDB_CODE_SUCCESS)) {
534 535
    return ret;
  }
X
Xiaoyu Wang 已提交
536
  if (unlikely(info->reRun)) {
537 538 539 540 541 542 543 544 545 546 547
    return TSDB_CODE_SUCCESS;
  }

  sql = elements->measure + elements->measureTagsLen;
  elements->tagsLen = sql - elements->tags;

  // parse cols
  JUMP_SPACE(sql, sqlEnd)
  elements->cols = sql;

  ret = smlParseColKv(info, &sql, sqlEnd, elements, isSameMeasure, isSameCTable);
X
Xiaoyu Wang 已提交
548
  if (unlikely(ret != TSDB_CODE_SUCCESS)) {
549 550 551
    return ret;
  }

X
Xiaoyu Wang 已提交
552
  if (unlikely(info->reRun)) {
553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
    return TSDB_CODE_SUCCESS;
  }

  elements->colsLen = sql - elements->cols;
  if (unlikely(elements->colsLen == 0)) {
    smlBuildInvalidDataMsg(&info->msgBuf, "cols is empty", NULL);
    return TSDB_CODE_SML_INVALID_DATA;
  }

  // parse timestamp
  JUMP_SPACE(sql, sqlEnd)
  elements->timestamp = sql;
  while (sql < sqlEnd) {
    if (unlikely(isspace(*sql))) {
      break;
    }
    sql++;
  }
  elements->timestampLen = sql - elements->timestamp;

  int64_t ts = smlParseInfluxTime(info, elements->timestamp, elements->timestampLen);
  if (unlikely(ts <= 0)) {
    uError("SML:0x%" PRIx64 " smlParseTS error:%" PRId64, info->id, ts);
    return TSDB_CODE_INVALID_TIMESTAMP;
  }
  // add ts to
X
Xiaoyu Wang 已提交
579 580 581 582 583 584
  SSmlKv kv = {.key = TS,
               .keyLen = TS_LEN,
               .type = TSDB_DATA_TYPE_TIMESTAMP,
               .i = ts,
               .length = (size_t)tDataTypes[TSDB_DATA_TYPE_TIMESTAMP].bytes};
  if (info->dataFormat) {
585 586
    smlBuildCol(info->currTableDataCtx, info->currSTableMeta->schema, &kv, 0);
    smlBuildRow(info->currTableDataCtx);
wmmhello's avatar
wmmhello 已提交
587
    clearColValArray(info->currTableDataCtx->pValues);
X
Xiaoyu Wang 已提交
588
  } else {
589 590 591 592 593 594
    taosArraySet(elements->colArray, 0, &kv);
  }
  info->preLine = *elements;

  return ret;
}