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

taosdata / TDengine / #3533

20 Nov 2024 07:11AM UTC coverage: 58.848% (-1.9%) from 60.78%
#3533

push

travis-ci

web-flow
Merge pull request #28823 from taosdata/fix/3.0/TD-32587

fix:[TD-32587]fix stmt segmentation fault

115578 of 252434 branches covered (45.79%)

Branch coverage included in aggregate %.

1 of 4 new or added lines in 1 file covered. (25.0%)

8038 existing lines in 233 files now uncovered.

194926 of 275199 relevant lines covered (70.83%)

1494459.59 hits per line

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

79.22
/source/libs/parser/src/parTokenizer.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 "os.h"
17
#include "parToken.h"
18
#include "taosdef.h"
19
#include "thash.h"
20
#include "ttokendef.h"
21

22
// All the keywords of the SQL language are stored in a hash table
23
typedef struct SKeyword {
24
  const char* name;  // The keyword name
25
  uint16_t    type;  // type
26
  uint8_t     len;   // length
27
} SKeyword;
28

29
// clang-format off
30
// keywords in sql string
31
static SKeyword keywordTable[] = {
32
    {"ACCOUNT",              TK_ACCOUNT},
33
    {"ACCOUNTS",             TK_ACCOUNTS},
34
    {"ADD",                  TK_ADD},
35
    {"AGGREGATE",            TK_AGGREGATE},
36
    {"ALL",                  TK_ALL},
37
    {"ALTER",                TK_ALTER},
38
    {"ANALYZE",              TK_ANALYZE},
39
    {"AND",                  TK_AND},
40
    {"ANTI",                 TK_ANTI},
41
    {"ANODE",                TK_ANODE},
42
    {"ANODES",               TK_ANODES},
43
    {"ANOMALY_WINDOW",       TK_ANOMALY_WINDOW},
44
//    {"ANY",                  TK_ANY},
45
    {"APPS",                 TK_APPS},
46
    {"AS",                   TK_AS},
47
    {"ASC",                  TK_ASC},
48
    {"ASOF",                 TK_ASOF},
49
    {"AT_ONCE",              TK_AT_ONCE},
50
    {"BALANCE",              TK_BALANCE},
51
    {"BATCH_SCAN",           TK_BATCH_SCAN},
52
    {"BETWEEN",              TK_BETWEEN},
53
    {"BIGINT",               TK_BIGINT},
54
    {"BINARY",               TK_BINARY},
55
    {"BNODE",                TK_BNODE},
56
    {"BNODES",               TK_BNODES},
57
    {"BOOL",                 TK_BOOL},
58
    {"BOTH",                 TK_BOTH},
59
    {"BUFFER",               TK_BUFFER},
60
    {"BUFSIZE",              TK_BUFSIZE},
61
    {"BY",                   TK_BY},
62
    {"CACHE",                TK_CACHE},
63
    {"CACHEMODEL",           TK_CACHEMODEL},
64
    {"CACHESIZE",            TK_CACHESIZE},
65
    {"CASE",                 TK_CASE},
66
    {"CAST",                 TK_CAST},
67
    {"CHILD",                TK_CHILD},
68
    {"CLIENT_VERSION",       TK_CLIENT_VERSION},
69
    {"CLUSTER",              TK_CLUSTER},
70
    {"COLUMN",               TK_COLUMN},
71
    {"COMMENT",              TK_COMMENT},
72
    {"COMP",                 TK_COMP},
73
    {"COMPACT",              TK_COMPACT},
74
    {"COMPACTS",             TK_COMPACTS},
75
    {"CONNECTION",           TK_CONNECTION},
76
    {"CONNECTIONS",          TK_CONNECTIONS},
77
    {"CONNS",                TK_CONNS},
78
    {"CONSUMER",             TK_CONSUMER},
79
    {"CONSUMERS",            TK_CONSUMERS},
80
    {"CONTAINS",             TK_CONTAINS},
81
    {"COUNT",                TK_COUNT},
82
    {"COUNT_WINDOW",         TK_COUNT_WINDOW},
83
    {"CREATE",               TK_CREATE},
84
    {"CREATEDB",             TK_CREATEDB},
85
    {"CURRENT_USER",         TK_CURRENT_USER},
86
    {"DATABASE",             TK_DATABASE},
87
    {"DATABASES",            TK_DATABASES},
88
    {"DBS",                  TK_DBS},
89
    {"DELETE",               TK_DELETE},
90
    {"DELETE_MARK",          TK_DELETE_MARK},
91
    {"DESC",                 TK_DESC},
92
    {"DESCRIBE",             TK_DESCRIBE},
93
    {"DISTINCT",             TK_DISTINCT},
94
    {"DISTRIBUTED",          TK_DISTRIBUTED},
95
    {"DNODE",                TK_DNODE},
96
    {"DNODES",               TK_DNODES},
97
    {"DOUBLE",               TK_DOUBLE},
98
    {"DROP",                 TK_DROP},
99
    {"DURATION",             TK_DURATION},
100
    {"ELSE",                 TK_ELSE},
101
    {"ENABLE",               TK_ENABLE},
102
    {"ENCRYPTIONS",          TK_ENCRYPTIONS},
103
    {"ENCRYPT_ALGORITHM",    TK_ENCRYPT_ALGORITHM},
104
    {"ENCRYPT_KEY",          TK_ENCRYPT_KEY},
105
    {"END",                  TK_END},
106
    {"EXISTS",               TK_EXISTS},
107
    {"EXPIRED",              TK_EXPIRED},
108
    {"EXPLAIN",              TK_EXPLAIN},
109
    {"EVENT_WINDOW",         TK_EVENT_WINDOW},
110
    {"EVERY",                TK_EVERY},
111
    {"FILE",                 TK_FILE},
112
    {"FILL",                 TK_FILL},
113
    {"FILL_HISTORY",         TK_FILL_HISTORY},
114
    {"FIRST",                TK_FIRST},
115
    {"FLOAT",                TK_FLOAT},
116
    {"FLUSH",                TK_FLUSH},
117
    {"FROM",                 TK_FROM},
118
    {"FOR",                  TK_FOR},
119
    {"FORCE",                TK_FORCE},
120
    {"FULL",                 TK_FULL},
121
    {"FUNCTION",             TK_FUNCTION},
122
    {"FUNCTIONS",            TK_FUNCTIONS},
123
    {"GEOMETRY",             TK_GEOMETRY},
124
    {"GRANT",                TK_GRANT},
125
    {"GRANTS",               TK_GRANTS},
126
    {"FULL",                 TK_FULL},
127
    {"LOGS",                 TK_LOGS},
128
    {"MACHINES",             TK_MACHINES},
129
    {"GROUP",                TK_GROUP},
130
    {"HASH_JOIN",            TK_HASH_JOIN},    
131
    {"HAVING",               TK_HAVING},
132
    {"HOST",                 TK_HOST},
133
    {"IF",                   TK_IF},
134
    {"IGNORE",               TK_IGNORE},
135
    {"IMPORT",               TK_IMPORT},
136
    {"IN",                   TK_IN},
137
    {"INDEX",                TK_INDEX},
138
    {"INDEXES",              TK_INDEXES},
139
    {"INNER",                TK_INNER},
140
    {"INSERT",               TK_INSERT},
141
    {"INT",                  TK_INT},
142
    {"INTEGER",              TK_INTEGER},
143
    {"INTERVAL",             TK_INTERVAL},
144
    {"INTO",                 TK_INTO},
145
    {"IS",                   TK_IS},
146
    {"JLIMIT",               TK_JLIMIT},
147
    {"JOIN",                 TK_JOIN},
148
    {"JSON",                 TK_JSON},
149
    {"KEEP",                 TK_KEEP},
150
    {"KEY",                  TK_KEY},
151
    {"KILL",                 TK_KILL},
152
    {"LANGUAGE",             TK_LANGUAGE},
153
    {"LAST",                 TK_LAST},
154
    {"LAST_ROW",             TK_LAST_ROW},
155
    {"LEADER",               TK_LEADER},
156
    {"LEADING",              TK_LEADING},
157
    {"LEFT",                 TK_LEFT},
158
    {"LICENCES",             TK_LICENCES},
159
    {"LIKE",                 TK_LIKE},
160
    {"LIMIT",                TK_LIMIT},
161
    {"LINEAR",               TK_LINEAR},
162
    {"LOCAL",                TK_LOCAL},
163
    {"MATCH",                TK_MATCH},
164
    {"MAXROWS",              TK_MAXROWS},
165
    {"MAX_DELAY",            TK_MAX_DELAY},
166
    {"BWLIMIT",              TK_BWLIMIT},
167
    {"MERGE",                TK_MERGE},
168
    {"META",                 TK_META},
169
    {"ONLY",                 TK_ONLY},
170
    {"MINROWS",              TK_MINROWS},
171
    {"MINUS",                TK_MINUS},
172
    {"MNODE",                TK_MNODE},
173
    {"MNODES",               TK_MNODES},
174
    {"MODIFY",               TK_MODIFY},
175
    {"MODULES",              TK_MODULES},
176
    {"NORMAL",               TK_NORMAL},
177
    {"NCHAR",                TK_NCHAR},
178
    {"NEXT",                 TK_NEXT},
179
    {"NMATCH",               TK_NMATCH},
180
    {"NONE",                 TK_NONE},
181
    {"NOT",                  TK_NOT},
182
    {"NOW",                  TK_NOW},
183
    {"NO_BATCH_SCAN",        TK_NO_BATCH_SCAN},
184
    {"NULL",                 TK_NULL},
185
    {"NULL_F",               TK_NULL_F},
186
    {"NULLS",                TK_NULLS},
187
    {"OFFSET",               TK_OFFSET},
188
    {"ON",                   TK_ON},
189
    {"OR",                   TK_OR},
190
    {"ORDER",                TK_ORDER},
191
    {"OUTER",                TK_OUTER},
192
    {"OUTPUTTYPE",           TK_OUTPUTTYPE},
193
    {"PAGES",                TK_PAGES},
194
    {"PAGESIZE",             TK_PAGESIZE},
195
    {"PARA_TABLES_SORT",     TK_PARA_TABLES_SORT},
196
    {"PARTITION",            TK_PARTITION},
197
    {"PARTITION_FIRST",      TK_PARTITION_FIRST},
198
    {"PASS",                 TK_PASS},
199
    {"PORT",                 TK_PORT},
200
    {"POSITION",             TK_POSITION},
201
    {"PPS",                  TK_PPS},
202
    {"PRIMARY",              TK_PRIMARY},
203
    {"PRECISION",            TK_PRECISION},
204
    {"PREV",                 TK_PREV},
205
    {"PRIVILEGES",           TK_PRIVILEGES},
206
    {"QNODE",                TK_QNODE},
207
    {"QNODES",               TK_QNODES},
208
    {"QTIME",                TK_QTIME},
209
    {"QUERIES",              TK_QUERIES},
210
    {"QUERY",                TK_QUERY},
211
    {"PI",                   TK_PI},
212
    {"RAND",                 TK_RAND},
213
    {"RANGE",                TK_RANGE},
214
    {"RATIO",                TK_RATIO},
215
    {"PAUSE",                TK_PAUSE},
216
    {"READ",                 TK_READ},
217
    {"RECURSIVE",            TK_RECURSIVE},
218
    {"REDISTRIBUTE",         TK_REDISTRIBUTE},
219
    {"RENAME",               TK_RENAME},
220
    {"REPLACE",              TK_REPLACE},
221
    {"REPLICA",              TK_REPLICA},
222
    {"RESET",                TK_RESET},
223
    {"RESUME",               TK_RESUME},
224
    {"RESTORE",              TK_RESTORE},
225
    {"RETENTIONS",           TK_RETENTIONS},
226
    {"REVOKE",               TK_REVOKE},
227
    {"RIGHT",                TK_RIGHT},
228
    {"ROLLUP",               TK_ROLLUP},
229
    {"SCHEMALESS",           TK_SCHEMALESS},
230
    {"SCORES",               TK_SCORES},
231
    {"SELECT",               TK_SELECT},
232
    {"SEMI",                 TK_SEMI},
233
    {"SERVER_STATUS",        TK_SERVER_STATUS},
234
    {"SERVER_VERSION",       TK_SERVER_VERSION},
235
    {"SESSION",              TK_SESSION},
236
    {"SET",                  TK_SET},
237
    {"SHOW",                 TK_SHOW},
238
    {"SINGLE_STABLE",        TK_SINGLE_STABLE},
239
    {"SKIP_TSMA",            TK_SKIP_TSMA},
240
    {"SLIDING",              TK_SLIDING},
241
    {"SLIMIT",               TK_SLIMIT},
242
    {"SMA",                  TK_SMA},
243
    {"SMALLDATA_TS_SORT",    TK_SMALLDATA_TS_SORT},
244
    {"SMALLINT",             TK_SMALLINT},
245
    {"SNODE",                TK_SNODE},
246
    {"SNODES",               TK_SNODES},
247
    {"SORT_FOR_GROUP",       TK_SORT_FOR_GROUP},
248
    {"SOFFSET",              TK_SOFFSET},
249
    {"SPLIT",                TK_SPLIT},
250
    {"STABLE",               TK_STABLE},
251
    {"STABLES",              TK_STABLES},
252
    {"START",                TK_START},
253
    {"STATE",                TK_STATE},
254
    {"STATE_WINDOW",         TK_STATE_WINDOW},
255
    {"STORAGE",              TK_STORAGE},
256
    {"STREAM",               TK_STREAM},
257
    {"STREAMS",              TK_STREAMS},
258
    {"STRICT",               TK_STRICT},
259
    {"STT_TRIGGER",          TK_STT_TRIGGER},
260
    {"SUBSCRIBE",            TK_SUBSCRIBE},
261
    {"SUBSCRIPTIONS",        TK_SUBSCRIPTIONS},
262
    {"SUBSTR",               TK_SUBSTR},
263
    {"SUBSTRING",            TK_SUBSTRING},
264
    {"SUBTABLE",             TK_SUBTABLE},
265
    {"SYSINFO",              TK_SYSINFO},
266
    {"SYSTEM",               TK_SYSTEM},
267
    {"TABLE",                TK_TABLE},
268
    {"TABLES",               TK_TABLES},
269
    {"TABLE_PREFIX",         TK_TABLE_PREFIX},
270
    {"TABLE_SUFFIX",         TK_TABLE_SUFFIX},
271
    {"TAG",                  TK_TAG},
272
    {"TAGS",                 TK_TAGS},
273
    {"TBNAME",               TK_TBNAME},
274
    {"THEN",                 TK_THEN},
275
    {"TIMESTAMP",            TK_TIMESTAMP},
276
    {"TIMEZONE",             TK_TIMEZONE},
277
    {"TINYINT",              TK_TINYINT},
278
    {"TO",                   TK_TO},
279
    {"TODAY",                TK_TODAY},
280
    {"TOPIC",                TK_TOPIC},
281
    {"TOPICS",               TK_TOPICS},
282
    {"TRAILING",             TK_TRAILING},
283
    {"TRANSACTION",          TK_TRANSACTION},
284
    {"TRANSACTIONS",         TK_TRANSACTIONS},
285
    {"TRIGGER",              TK_TRIGGER},
286
    {"TRIM",                 TK_TRIM},
287
    {"TSDB_PAGESIZE",        TK_TSDB_PAGESIZE},
288
    {"TSERIES",              TK_TSERIES},
289
    {"TSMA",                 TK_TSMA},
290
    {"TSMAS",                TK_TSMAS},
291
    {"TTL",                  TK_TTL},
292
    {"UNION",                TK_UNION},
293
    {"UNSAFE",               TK_UNSAFE},
294
    {"UNSIGNED",             TK_UNSIGNED},
295
    {"UNTREATED",            TK_UNTREATED},
296
    {"UPDATE",               TK_UPDATE},
297
    {"USE",                  TK_USE},
298
    {"USER",                 TK_USER},
299
    {"USERS",                TK_USERS},
300
    {"USING",                TK_USING},
301
    {"VALUE",                TK_VALUE},
302
    {"VALUE_F",              TK_VALUE_F},
303
    {"VALUES",               TK_VALUES},
304
    {"VARCHAR",              TK_VARCHAR},
305
    {"VARIABLES",            TK_VARIABLES},
306
    {"VERBOSE",              TK_VERBOSE},
307
    {"VGROUP",               TK_VGROUP},
308
    {"VGROUPS",              TK_VGROUPS},
309
    {"VIEW",                 TK_VIEW},
310
    {"VIEWS",                TK_VIEWS},
311
    {"VNODE",                TK_VNODE},
312
    {"VNODES",               TK_VNODES},
313
    {"WAL_FSYNC_PERIOD",     TK_WAL_FSYNC_PERIOD},
314
    {"WAL_LEVEL",            TK_WAL_LEVEL},
315
    {"WAL_RETENTION_PERIOD", TK_WAL_RETENTION_PERIOD},
316
    {"WAL_RETENTION_SIZE",   TK_WAL_RETENTION_SIZE},
317
    {"WAL_ROLL_PERIOD",      TK_WAL_ROLL_PERIOD},
318
    {"WAL_SEGMENT_SIZE",     TK_WAL_SEGMENT_SIZE},
319
    {"WATERMARK",            TK_WATERMARK},
320
    {"WHEN",                 TK_WHEN},
321
    {"WHERE",                TK_WHERE},
322
    {"WINDOW",               TK_WINDOW},    
323
    {"WINDOW_CLOSE",         TK_WINDOW_CLOSE},
324
    {"WINDOW_OFFSET",        TK_WINDOW_OFFSET},
325
    {"WITH",                 TK_WITH},
326
    {"WRITE",                TK_WRITE},
327
    {"_C0",                  TK_ROWTS},
328
    {"_IROWTS",              TK_IROWTS},
329
    {"_ISFILLED",            TK_ISFILLED},
330
    {"_QDURATION",           TK_QDURATION},
331
    {"_QEND",                TK_QEND},
332
    {"_QSTART",              TK_QSTART},
333
    {"_ROWTS",               TK_ROWTS},
334
    {"_TAGS",                TK_QTAGS},
335
    {"_WDURATION",           TK_WDURATION},
336
    {"_WEND",                TK_WEND},
337
    {"_WSTART",              TK_WSTART},
338
    {"_FLOW",                TK_FLOW},
339
    {"_FHIGH",               TK_FHIGH},
340
    {"_FROWTS",              TK_FROWTS},
341
    {"ALIVE",                TK_ALIVE},
342
    {"VARBINARY",            TK_VARBINARY},
343
    {"S3_CHUNKPAGES",        TK_S3_CHUNKPAGES},
344
    {"S3_KEEPLOCAL",         TK_S3_KEEPLOCAL},
345
    {"S3_COMPACT",           TK_S3_COMPACT},
346
    {"S3MIGRATE",            TK_S3MIGRATE},
347
    {"KEEP_TIME_OFFSET",     TK_KEEP_TIME_OFFSET},
348
    {"ARBGROUPS",            TK_ARBGROUPS},
349
    {"IS_IMPORT",            TK_IS_IMPORT},
350
    {"FORCE_WINDOW_CLOSE",   TK_FORCE_WINDOW_CLOSE},
351
};
352
// clang-format on
353

354
static const char isIdChar[] = {
355
    /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
356
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */
357
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */
358
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */
359
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */
360
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */
361
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */
362
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x */
363
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */
364
};
365

366
static void* keywordHashTable = NULL;
367

368
static int32_t doInitKeywordsTable(void) {
1,602✔
369
  int numOfEntries = tListLen(keywordTable);
1,602✔
370

371
  keywordHashTable = taosHashInit(numOfEntries, MurmurHash3_32, true, false);
1,602✔
372
  for (int32_t i = 0; i < numOfEntries; i++) {
511,038✔
373
    keywordTable[i].len = (uint8_t)strlen(keywordTable[i].name);
509,436✔
374
    void*   ptr = &keywordTable[i];
509,436✔
375
    int32_t code = taosHashPut(keywordHashTable, keywordTable[i].name, keywordTable[i].len, (void*)&ptr, POINTER_BYTES);
509,436✔
376
    if (TSDB_CODE_SUCCESS != code) {
509,436!
377
      taosHashCleanup(keywordHashTable);
×
378
      return code;
×
379
    }
380
  }
381
  return TSDB_CODE_SUCCESS;
1,602✔
382
}
383

384
static int32_t tKeywordCode(const char* z, int n) {
50,183,541✔
385
  char key[512] = {0};
50,183,541✔
386
  if (n > tListLen(key)) {  // too long token, can not be any other token type
50,183,541!
387
    return TK_NK_ID;
×
388
  }
389

390
  for (int32_t j = 0; j < n; ++j) {
297,028,347✔
391
    if (z[j] >= 'a' && z[j] <= 'z') {
246,844,806!
392
      key[j] = (char)(z[j] & 0xDF);  // to uppercase and set the null-terminated
225,632,654✔
393
    } else {
394
      key[j] = z[j];
21,212,152✔
395
    }
396
  }
397

398
  if (keywordHashTable == NULL) {
50,183,541!
399
    return TK_NK_ILLEGAL;
×
400
  }
401

402
  SKeyword** pKey = (SKeyword**)taosHashGet(keywordHashTable, key, n);
50,183,541✔
403
  return (pKey != NULL) ? (*pKey)->type : TK_NK_ID;
50,184,205✔
404
}
405

406
/*
407
 * Return the length of the token that begins at z[0].
408
 * Store the token type in *type before returning.
409
 */
410
uint32_t tGetToken(const char* z, uint32_t* tokenId) {
976,930,436✔
411
  uint32_t i;
412
  switch (*z) {
976,930,436!
413
    case ' ':
10,777,428✔
414
    case '\t':
415
    case '\n':
416
    case '\f':
417
    case '\r': {
418
      for (i = 1; isspace(z[i]); i++) {
11,548,575✔
419
      }
420
      *tokenId = TK_NK_SPACE;
10,777,428✔
421
      return i;
10,777,428✔
422
    }
423
    case ':': {
30✔
424
      *tokenId = TK_NK_COLON;
30✔
425
      return 1;
30✔
426
    }
427
    case '-': {
37,795,062✔
428
      if (z[1] == '-') {
37,795,062✔
429
        for (i = 2; z[i] && z[i] != '\n'; i++) {
2,855!
430
        }
431
        *tokenId = TK_NK_COMMENT;
131✔
432
        return i;
131✔
433
      } else if (z[1] == '>') {
37,794,931✔
434
        *tokenId = TK_NK_ARROW;
743✔
435
        return 2;
743✔
436
      }
437
      *tokenId = TK_NK_MINUS;
37,794,188✔
438
      return 1;
37,794,188✔
439
    }
440
    case '(': {
58,416,435✔
441
      *tokenId = TK_NK_LP;
58,416,435✔
442
      return 1;
58,416,435✔
443
    }
444
    case ')': {
58,219,814✔
445
      *tokenId = TK_NK_RP;
58,219,814✔
446
      return 1;
58,219,814✔
447
    }
448
    case ';': {
523,904✔
449
      *tokenId = TK_NK_SEMI;
523,904✔
450
      return 1;
523,904✔
451
    }
452
    case '+': {
301,896✔
453
      *tokenId = TK_NK_PLUS;
301,896✔
454
      return 1;
301,896✔
455
    }
456
    case '*': {
78,962✔
457
      *tokenId = TK_NK_STAR;
78,962✔
458
      return 1;
78,962✔
459
    }
460
    case '/': {
14,313✔
461
      if (z[1] != '*' || z[2] == 0) {
14,313!
462
        *tokenId = TK_NK_SLASH;
3,531✔
463
        return 1;
3,531✔
464
      }
465
      bool isHint = false;
10,782✔
466
      if (z[2] == '+') {
10,782!
467
        isHint = true;
10,782✔
468
      }
469
      for (i = 3; z[i] && (z[i] != '/' || z[i - 1] != '*'); i++) {
237,076!
470
      }
471
      if (z[i]) i++;
10,782!
472
      *tokenId = isHint ? TK_NK_HINT : TK_NK_COMMENT;
10,782!
473
      return i;
10,782✔
474
    }
475
    case '%': {
380✔
476
      *tokenId = TK_NK_REM;
380✔
477
      return 1;
380✔
478
    }
479
    case '=': {
67,112✔
480
      *tokenId = TK_NK_EQ;
67,112✔
481
      return 1 + (z[1] == '=');
67,112✔
482
    }
483
    case '<': {
24,811✔
484
      if (z[1] == '=') {
24,811✔
485
        *tokenId = TK_NK_LE;
12,715✔
486
        return 2;
12,715✔
487
      } else if (z[1] == '>') {
12,096✔
488
        *tokenId = TK_NK_NE;
2,502✔
489
        return 2;
2,502✔
490
      } else if (z[1] == '<') {
9,594!
491
        *tokenId = TK_NK_LSHIFT;
×
492
        return 2;
×
493
      } else {
494
        *tokenId = TK_NK_LT;
9,594✔
495
        return 1;
9,594✔
496
      }
497
    }
498
    case '>': {
18,102✔
499
      if (z[1] == '=') {
18,102✔
500
        *tokenId = TK_NK_GE;
10,001✔
501
        return 2;
10,001✔
502
      } else if (z[1] == '>') {
8,101!
503
        *tokenId = TK_NK_RSHIFT;
×
504
        return 2;
×
505
      } else {
506
        *tokenId = TK_NK_GT;
8,101✔
507
        return 1;
8,101✔
508
      }
509
    }
510
    case '!': {
4,665✔
511
      if (z[1] != '=') {
4,665✔
512
        *tokenId = TK_NK_ILLEGAL;
549✔
513
        return 2;
549✔
514
      } else {
515
        *tokenId = TK_NK_NE;
4,116✔
516
        return 2;
4,116✔
517
      }
518
    }
519
    case '|': {
44✔
520
      if (z[1] != '|') {
44✔
521
        *tokenId = TK_NK_BITOR;
22✔
522
        return 1;
22✔
523
      } else {
524
        *tokenId = TK_NK_CONCAT;
22✔
525
        return 2;
22✔
526
      }
527
    }
528
    case ',': {
364,557,416✔
529
      *tokenId = TK_NK_COMMA;
364,557,416✔
530
      return 1;
364,557,416✔
531
    }
532
    case '&': {
69✔
533
      *tokenId = TK_NK_BITAND;
69✔
534
      return 1;
69✔
535
    }
536
    case '~': {
×
537
      *tokenId = TK_NK_BITNOT;
×
538
      return 1;
×
539
    }
540
    case '?': {
472✔
541
      *tokenId = TK_NK_QUESTION;
472✔
542
      return 1;
472✔
543
    }
544
    case '`':
65,905,315✔
545
    case '\'':
546
    case '"': {
547
      int  delim = z[0];
65,905,315✔
548
      bool strEnd = false;
65,905,315✔
549
      for (i = 1; z[i]; i++) {
2,147,483,647✔
550
        if (delim != '`' && z[i] == '\\') {  // ignore the escaped character that follows this backslash
2,147,483,647✔
551
          i++;
5,187✔
552
          continue;
5,187✔
553
        }
554

555
        if (z[i] == delim) {
2,147,483,647✔
556
          if (z[i + 1] == delim) {
61,152,448✔
557
            i++;
5✔
558
          } else {
559
            strEnd = true;
61,152,443✔
560
            break;
61,152,443✔
561
          }
562
        }
563
      }
564

565
      if (z[i]) i++;
65,905,315✔
566

567
      if (strEnd) {
65,905,315✔
568
        *tokenId = (delim == '`') ? TK_NK_ID : TK_NK_STRING;
61,667,975✔
569
        return i;
61,667,975✔
570
      }
571

572
      break;
4,237,340✔
573
    }
574
    case '.': {
609,450✔
575
      /*
576
       * handle the the float number with out integer part
577
       * .123
578
       * .123e4
579
       */
580
      if (isdigit(z[1])) {
609,450✔
581
        for (i = 2; isdigit(z[i]); i++) {
12✔
582
        }
583

584
        if ((z[i] == 'e' || z[i] == 'E') &&
4!
585
            (isdigit(z[i + 1]) || ((z[i + 1] == '+' || z[i + 1] == '-') && isdigit(z[i + 2])))) {
×
586
          i += 2;
×
587
          while (isdigit(z[i])) {
×
588
            i++;
×
589
          }
590
        }
591

592
        *tokenId = TK_NK_FLOAT;
4✔
593
        return i;
4✔
594
      } else {
595
        *tokenId = TK_NK_DOT;
609,446✔
596
        return 1;
609,446✔
597
      }
598
    }
599

600
    case '0': {
24,048,199✔
601
      char next = z[1];
24,048,199✔
602

603
      if (next == 'b') {  // bin number
24,048,199✔
604
        *tokenId = TK_NK_BIN;
153✔
605
        for (i = 2; (z[i] == '0' || z[i] == '1'); ++i) {
451✔
606
        }
607

608
        if (i == 2) {
153!
609
          break;
×
610
        }
611

612
        return i;
153✔
613
      } else if (next == 'x') {  // hex number
24,048,046✔
614
        *tokenId = TK_NK_HEX;
143✔
615
        for (i = 2; isxdigit(z[i]) != 0; ++i) {
425✔
616
        }
617

618
        if (i == 2) {
143!
UNCOV
619
          break;
×
620
        }
621

622
        return i;
143✔
623
      }
624
    }
625
    case '1':
626
    case '2':
627
    case '3':
628
    case '4':
629
    case '5':
630
    case '6':
631
    case '7':
632
    case '8':
633
    case '9': {
634
      *tokenId = TK_NK_INTEGER;
320,823,917✔
635
      for (i = 1; isdigit(z[i]); i++) {
2,085,663,816✔
636
      }
637

638
      /* here is the 1u/1a/2s/3m/9y */
639
      if ((z[i] == 'b' || z[i] == 'u' || z[i] == 'a' || z[i] == 's' || z[i] == 'm' || z[i] == 'h' || z[i] == 'd' ||
320,823,917!
640
           z[i] == 'n' || z[i] == 'y' || z[i] == 'w' || z[i] == 'B' || z[i] == 'U' || z[i] == 'A' || z[i] == 'S' ||
352,733,164!
641
           z[i] == 'M' || z[i] == 'H' || z[i] == 'D' || z[i] == 'N' || z[i] == 'Y' || z[i] == 'W') &&
352,892,595!
642
          (isIdChar[(uint8_t)z[i + 1]] == 0)) {
×
643
        *tokenId = TK_NK_VARIABLE;
101,575✔
644
        i += 1;
101,575✔
645
        return i;
101,575✔
646
      }
647

648
      int32_t seg = 1;
320,722,342✔
649
      while (z[i] == '.' && isdigit(z[i + 1])) {
394,265,102!
650
        i += 2;
73,542,760✔
651
        while (isdigit(z[i])) {
346,261,631✔
652
          i++;
272,718,871✔
653
        }
654
        *tokenId = TK_NK_FLOAT;
73,542,760✔
655
        seg++;
73,542,760✔
656
      }
657

658
      if (seg == 4) {  // ip address
320,722,342!
659
        *tokenId = TK_NK_IPTOKEN;
×
660
        return i;
×
661
      } else if (seg > 2) {
320,722,342!
662
        break;
×
663
      }
664

665
      // support float with no decimal part after the decimal point
666
      if (z[i] == '.' && seg == 1) {
320,722,342!
UNCOV
667
        *tokenId = TK_NK_FLOAT;
×
UNCOV
668
        i++;
×
669
      }
670
      if ((z[i] == 'e' || z[i] == 'E') &&
320,722,342!
671
          (isdigit(z[i + 1]) || ((z[i + 1] == '+' || z[i + 1] == '-') && isdigit(z[i + 2])))) {
×
672
        i += 2;
32,718✔
673
        while (isdigit(z[i])) {
96,030✔
674
          i++;
63,312✔
675
        }
676
        *tokenId = TK_NK_FLOAT;
32,718✔
677
      }
678
      return i;
320,722,342✔
679
    }
680
    // case '[': {
681
    //   for (i = 1; z[i] && z[i - 1] != ']'; i++) {
682
    //   }
683
    //   *tokenId = TK_NK_ID;
684
    //   return i;
685
    // }
686
    case 'T':
10,631,931✔
687
    case 't':
688
    case 'F':
689
    case 'f': {
690
      bool hasNonAsciiChars = false;
10,631,931✔
691
      for (i = 1;; i++) {
44,408,556✔
692
        if ((z[i] & 0x80) != 0) {
44,408,556!
693
          // utf-8 characters
694
          // currently, we support using utf-8 characters only in alias
695
          hasNonAsciiChars = true;
×
696
        } else if (isIdChar[(uint8_t)z[i]]) {
44,408,556✔
697
        } else {
698
          break;
10,631,931✔
699
        }
700
      }
701
      if (hasNonAsciiChars) {
10,631,931!
702
        *tokenId = TK_NK_ALIAS;  // must be alias
×
703
        return i;
×
704
      }
705
      if (IS_TRUE_STR(z, i) || IS_FALSE_STR(z, i)) {
10,631,931!
706
        *tokenId = TK_NK_BOOL;
7,917,278✔
707
        return i;
7,917,278✔
708
      }
709
      *tokenId = tKeywordCode(z, i);
2,714,653✔
710
      return i;
2,698,007✔
711
    }
712
    default: {
48,158,612✔
713
      if ((*z & 0x80) == 0 && !isIdChar[(uint8_t)*z]) {
48,158,612✔
714
        break;
673,473✔
715
      }
716
      bool hasNonAsciiChars = false;
47,485,139✔
717
      for (i = 1;; i++) {
235,971,907✔
718
        if ((z[i] & 0x80) != 0) {
235,971,907✔
719
          hasNonAsciiChars = true;
268✔
720
        } else if (isIdChar[(uint8_t)z[i]]) {
235,971,639✔
721
        } else {
722
          break;
47,485,139✔
723
        }
724
      }
725
      if (hasNonAsciiChars) {
47,485,139✔
726
        *tokenId = TK_NK_ALIAS;
49✔
727
        return i;
49✔
728
      }
729
      *tokenId = tKeywordCode(z, i);
47,485,090✔
730
      return i;
47,486,289✔
731
    }
732
  }
733

734
  *tokenId = TK_NK_ILLEGAL;
4,910,813✔
735
  return 0;
4,910,813✔
736
}
737

738
SToken tStrGetToken(const char* str, int32_t* i, bool isPrevOptr, bool* pIgnoreComma) {
515,944,170✔
739
  SToken t0 = {0};
515,944,170✔
740

741
  // here we reach the end of sql string, null-terminated string
742
  if (str[*i] == 0) {
515,944,170✔
743
    t0.n = 0;
858,009✔
744
    return t0;
858,009✔
745
  }
746

747
  // IGNORE TK_NK_SPACE, TK_NK_COMMA, and specified tokens
748
  while (1) {
749
    *i += t0.n;
515,086,161✔
750

751
    int32_t numOfComma = 0;
515,086,161✔
752
    char    t = str[*i];
515,086,161✔
753
    while (t == ' ' || t == '\n' || t == '\r' || t == '\t' || t == '\f' || t == ',') {
723,863,904!
754
      if (t == ',' && (++numOfComma > 1)) {  // comma only allowed once
208,777,744✔
755
        t0.n = 0;
1✔
756
        return t0;
1✔
757
      }
758

759
      if (NULL != pIgnoreComma && t == ',') {
208,777,743!
760
        *pIgnoreComma = true;
×
761
      }
762

763
      t = str[++(*i)];
208,777,743✔
764
    }
765

766
    t0.n = tGetToken(&str[*i], &t0.type);
515,086,160✔
767
    break;
508,432,179✔
768

769
    // not support user specfied ignored symbol list
770
#if 0
771
    bool ignore = false;
772
    for (uint32_t k = 0; k < numOfIgnoreToken; k++) {
773
      if (t0.type == ignoreTokenTypes[k]) {
774
        ignore = true;
775
        break;
776
      }
777
    }
778

779
    if (!ignore) {
780
      break;
781
    }
782
#endif
783
  }
784

785
  if (t0.type == TK_NK_SEMI) {
508,432,179✔
786
    t0.n = 0;
461,957✔
787
    t0.type = 0;
461,957✔
788
    return t0;
461,957✔
789
  }
790

791
  uint32_t type = 0;
507,970,222✔
792
  int32_t  len;
793

794
  // support parse the 'db.tbl' format, notes: There should be no space on either side of the dot!
795
  if ('.' == str[*i + t0.n]) {
507,970,222✔
796
    len = tGetToken(&str[*i + t0.n + 1], &type);
1,281,510✔
797

798
    // only id、string and ? are valid
799
    if (((TK_NK_STRING != t0.type) && (TK_NK_ID != t0.type)) ||
1,281,504✔
800
        ((TK_NK_STRING != type) && (TK_NK_ID != type) && (TK_NK_QUESTION != type))) {
1,281,503!
801
      t0.type = TK_NK_ILLEGAL;
8✔
802
      t0.n = 0;
8✔
803

804
      return t0;
8✔
805
    }
806

807
    // check the table name is '?', db.?asf is not valid.
808
    if (TK_NK_QUESTION == type) {
1,281,496!
809
      (void)tGetToken(&str[*i + t0.n + 2], &type);
×
810
      if (TK_NK_SPACE != type) {
×
811
        t0.type = TK_NK_ILLEGAL;
×
812
        t0.n = 0;
×
813
        return t0;
×
814
      }
815
    }
816

817
    t0.n += len + 1;
1,281,496✔
818

819
  } else {
820
    // support parse the -/+number format
821
    if ((isPrevOptr) && (t0.type == TK_NK_MINUS || t0.type == TK_NK_PLUS)) {
506,688,712!
822
      len = tGetToken(&str[*i + t0.n], &type);
16,384,654✔
823
      if (type == TK_NK_INTEGER || type == TK_NK_FLOAT || type == TK_NK_BIN || type == TK_NK_HEX) {
38,085,906!
824
        t0.type = type;
38,131,303✔
825
        t0.n += len;
38,131,303✔
826
      }
827
    }
828
  }
829

830
  t0.z = (char*)str + (*i);
529,671,460✔
831
  *i += t0.n;
529,671,460✔
832

833
  return t0;
529,671,460✔
834
}
835

836
bool taosIsKeyWordToken(const char* z, int32_t len) { return (tKeywordCode((char*)z, len) != TK_NK_ID); }
×
837

838
int32_t taosInitKeywordsTable() { return doInitKeywordsTable(); }
1,602✔
839

840
void taosCleanupKeywordsTable() {
1,602✔
841
  void* m = keywordHashTable;
1,602✔
842
  if (m != NULL && atomic_val_compare_exchange_ptr(&keywordHashTable, m, 0) == m) {
1,602!
843
    taosHashCleanup(m);
1,602✔
844
  }
845
}
1,602✔
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