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

taosdata / TDengine / #3858

17 Apr 2025 01:40PM UTC coverage: 62.968% (+0.5%) from 62.513%
#3858

push

travis-ci

web-flow
docs(opc): add perssit data support (#30783)

156194 of 316378 branches covered (49.37%)

Branch coverage included in aggregate %.

242021 of 316027 relevant lines covered (76.58%)

19473613.85 hits per line

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

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

379
static const char isIdChar[] = {
380
    /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
381
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */
382
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */
383
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */
384
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */
385
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */
386
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */
387
    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x */
388
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */
389
};
390

391
static void* keywordHashTable = NULL;
392

393
static int32_t doInitKeywordsTable(void) {
18,153✔
394
  int numOfEntries = tListLen(keywordTable);
18,153✔
395

396
  keywordHashTable = taosHashInit(numOfEntries, MurmurHash3_32, true, false);
18,153✔
397
  for (int32_t i = 0; i < numOfEntries; i++) {
6,244,632✔
398
    keywordTable[i].len = (uint8_t)strlen(keywordTable[i].name);
6,226,479✔
399
    void*   ptr = &keywordTable[i];
6,226,479✔
400
    int32_t code = taosHashPut(keywordHashTable, keywordTable[i].name, keywordTable[i].len, (void*)&ptr, POINTER_BYTES);
6,226,479✔
401
    if (TSDB_CODE_SUCCESS != code) {
6,226,479!
402
      taosHashCleanup(keywordHashTable);
×
403
      return code;
×
404
    }
405
  }
406
  return TSDB_CODE_SUCCESS;
18,153✔
407
}
408

409
static int32_t tKeywordCode(const char* z, int n) {
308,567,492✔
410
  char key[512] = {0};
308,567,492✔
411
  if (n > tListLen(key)) {  // too long token, can not be any other token type
308,567,492!
412
    return TK_NK_ID;
×
413
  }
414

415
  for (int32_t j = 0; j < n; ++j) {
2,093,006,273✔
416
    if (z[j] >= 'a' && z[j] <= 'z') {
1,784,438,781!
417
      key[j] = (char)(z[j] & 0xDF);  // to uppercase and set the null-terminated
1,593,116,777✔
418
    } else {
419
      key[j] = z[j];
191,322,004✔
420
    }
421
  }
422

423
  if (keywordHashTable == NULL) {
308,567,492!
424
    return TK_NK_ILLEGAL;
×
425
  }
426

427
  SKeyword** pKey = (SKeyword**)taosHashGet(keywordHashTable, key, n);
308,567,492✔
428
  return (pKey != NULL) ? (*pKey)->type : TK_NK_ID;
296,648,024✔
429
}
430

431
/*
432
 * Return the length of the token that begins at z[0].
433
 * Store the token type in *type before returning.
434
 */
435
uint32_t tGetToken(const char* z, uint32_t* tokenId) {
2,147,483,647✔
436
  uint32_t i;
437
  switch (*z) {
2,147,483,647!
438
    case ' ':
32,236,145✔
439
    case '\t':
440
    case '\n':
441
    case '\f':
442
    case '\r': {
443
      for (i = 1; isspace(z[i]); i++) {
35,897,687✔
444
      }
445
      *tokenId = TK_NK_SPACE;
32,236,145✔
446
      return i;
32,236,145✔
447
    }
448
    case ':': {
118✔
449
      *tokenId = TK_NK_COLON;
118✔
450
      return 1;
118✔
451
    }
452
    case '-': {
996,546,110✔
453
      if (z[1] == '-') {
996,546,110✔
454
        for (i = 2; z[i] && z[i] != '\n'; i++) {
4,358!
455
        }
456
        *tokenId = TK_NK_COMMENT;
198✔
457
        return i;
198✔
458
      } else if (z[1] == '>') {
996,545,912✔
459
        *tokenId = TK_NK_ARROW;
1,041✔
460
        return 2;
1,041✔
461
      }
462
      *tokenId = TK_NK_MINUS;
996,544,871✔
463
      return 1;
996,544,871✔
464
    }
465
    case '(': {
1,007,846,860✔
466
      *tokenId = TK_NK_LP;
1,007,846,860✔
467
      return 1;
1,007,846,860✔
468
    }
469
    case ')': {
1,004,846,982✔
470
      *tokenId = TK_NK_RP;
1,004,846,982✔
471
      return 1;
1,004,846,982✔
472
    }
473
    case ';': {
1,604,630✔
474
      *tokenId = TK_NK_SEMI;
1,604,630✔
475
      return 1;
1,604,630✔
476
    }
477
    case '+': {
10,640,785✔
478
      *tokenId = TK_NK_PLUS;
10,640,785✔
479
      return 1;
10,640,785✔
480
    }
481
    case '*': {
508,390✔
482
      *tokenId = TK_NK_STAR;
508,390✔
483
      return 1;
508,390✔
484
    }
485
    case '/': {
60,026✔
486
      if (z[1] != '*' || z[2] == 0) {
60,026!
487
        *tokenId = TK_NK_SLASH;
27,738✔
488
        return 1;
27,738✔
489
      }
490
      bool isHint = false;
32,288✔
491
      if (z[2] == '+') {
32,288✔
492
        isHint = true;
32,260✔
493
      }
494
      for (i = 3; z[i] && (z[i] != '/' || z[i - 1] != '*'); i++) {
709,068!
495
      }
496
      if (z[i]) i++;
32,288!
497
      *tokenId = isHint ? TK_NK_HINT : TK_NK_COMMENT;
32,288✔
498
      return i;
32,288✔
499
    }
500
    case '%': {
1,160✔
501
      *tokenId = TK_NK_REM;
1,160✔
502
      return 1;
1,160✔
503
    }
504
    case '=': {
315,627✔
505
      *tokenId = TK_NK_EQ;
315,627✔
506
      return 1 + (z[1] == '=');
315,627✔
507
    }
508
    case '<': {
443,904✔
509
      if (z[1] == '=') {
443,904✔
510
        *tokenId = TK_NK_LE;
91,241✔
511
        return 2;
91,241✔
512
      } else if (z[1] == '>') {
352,663✔
513
        *tokenId = TK_NK_NE;
3,613✔
514
        return 2;
3,613✔
515
      } else if (z[1] == '<') {
349,050!
516
        *tokenId = TK_NK_LSHIFT;
×
517
        return 2;
×
518
      } else {
519
        *tokenId = TK_NK_LT;
349,050✔
520
        return 1;
349,050✔
521
      }
522
    }
523
    case '>': {
429,505✔
524
      if (z[1] == '=') {
429,505✔
525
        *tokenId = TK_NK_GE;
398,928✔
526
        return 2;
398,928✔
527
      } else if (z[1] == '>') {
30,577!
528
        *tokenId = TK_NK_RSHIFT;
×
529
        return 2;
×
530
      } else {
531
        *tokenId = TK_NK_GT;
30,577✔
532
        return 1;
30,577✔
533
      }
534
    }
535
    case '!': {
18,429✔
536
      if (z[1] != '=') {
18,429✔
537
        *tokenId = TK_NK_ILLEGAL;
582✔
538
        return 2;
582✔
539
      } else {
540
        *tokenId = TK_NK_NE;
17,847✔
541
        return 2;
17,847✔
542
      }
543
    }
544
    case '|': {
47✔
545
      if (z[1] != '|') {
47!
546
        *tokenId = TK_NK_BITOR;
47✔
547
        return 1;
47✔
548
      } else {
549
        *tokenId = TK_NK_CONCAT;
×
550
        return 2;
×
551
      }
552
    }
553
    case ',': {
2,147,483,647✔
554
      *tokenId = TK_NK_COMMA;
2,147,483,647✔
555
      return 1;
2,147,483,647✔
556
    }
557
    case '&': {
225✔
558
      *tokenId = TK_NK_BITAND;
225✔
559
      return 1;
225✔
560
    }
561
    case '~': {
×
562
      *tokenId = TK_NK_BITNOT;
×
563
      return 1;
×
564
    }
565
    case '?': {
188,841✔
566
      *tokenId = TK_NK_QUESTION;
188,841✔
567
      return 1;
188,841✔
568
    }
569
    case '`':
177,246,587✔
570
    case '\'':
571
    case '"': {
572
      int  delim = z[0];
177,246,587✔
573
      bool strEnd = false;
177,246,587✔
574
      for (i = 1; z[i]; i++) {
2,147,483,647!
575
        if (delim != '`' && z[i] == '\\') {  // ignore the escaped character that follows this backslash
2,147,483,647✔
576
          i++;
5,326✔
577
          continue;
5,326✔
578
        }
579

580
        if (z[i] == delim) {
2,147,483,647✔
581
          if (z[i + 1] == delim) {
180,733,933✔
582
            i++;
8✔
583
          } else {
584
            strEnd = true;
180,733,925✔
585
            break;
180,733,925✔
586
          }
587
        }
588
      }
589

590
      if (z[i]) i++;
177,246,587!
591

592
      if (strEnd) {
177,246,587!
593
        *tokenId = (delim == '`') ? TK_NK_ID : TK_NK_STRING;
180,547,925✔
594
        return i;
180,547,925✔
595
      }
596

597
      break;
×
598
    }
599
    case '.': {
2,311,034✔
600
      /*
601
       * handle the the float number with out integer part
602
       * .123
603
       * .123e4
604
       */
605
      if (isdigit(z[1])) {
2,311,034✔
606
        for (i = 2; isdigit(z[i]); i++) {
15,930✔
607
        }
608

609
        if ((z[i] == 'e' || z[i] == 'E') &&
15,898!
610
            (isdigit(z[i + 1]) || ((z[i + 1] == '+' || z[i + 1] == '-') && isdigit(z[i + 2])))) {
×
611
          i += 2;
×
612
          while (isdigit(z[i])) {
×
613
            i++;
×
614
          }
615
        }
616

617
        *tokenId = TK_NK_FLOAT;
15,898✔
618
        return i;
15,898✔
619
      } else {
620
        *tokenId = TK_NK_DOT;
2,295,136✔
621
        return 1;
2,295,136✔
622
      }
623
    }
624

625
    case '0': {
32,467,114✔
626
      char next = z[1];
32,467,114✔
627

628
      if (next == 'b') {  // bin number
32,467,114✔
629
        *tokenId = TK_NK_BIN;
166✔
630
        for (i = 2; (z[i] == '0' || z[i] == '1'); ++i) {
497✔
631
        }
632

633
        if (i == 2) {
166!
634
          break;
×
635
        }
636

637
        return i;
166✔
638
      } else if (next == 'x') {  // hex number
32,466,948✔
639
        *tokenId = TK_NK_HEX;
157✔
640
        for (i = 2; isxdigit(z[i]) != 0; ++i) {
472✔
641
        }
642

643
        if (i == 2) {
157!
644
          break;
×
645
        }
646

647
        return i;
157✔
648
      }
649
    }
650
    case '1':
651
    case '2':
652
    case '3':
653
    case '4':
654
    case '5':
655
    case '6':
656
    case '7':
657
    case '8':
658
    case '9': {
659
      *tokenId = TK_NK_INTEGER;
2,147,483,647✔
660
      for (i = 1; isdigit(z[i]); i++) {
2,147,483,647✔
661
      }
662

663
      /* here is the 1u/1a/2s/3m/9y */
664
      if ((z[i] == 'b' || z[i] == 'u' || z[i] == 'a' || z[i] == 's' || z[i] == 'm' || z[i] == 'h' || z[i] == 'd' ||
2,147,483,647!
665
           z[i] == 'n' || z[i] == 'y' || z[i] == 'w' || z[i] == 'B' || z[i] == 'U' || z[i] == 'A' || z[i] == 'S' ||
2,147,483,647!
666
           z[i] == 'M' || z[i] == 'H' || z[i] == 'D' || z[i] == 'N' || z[i] == 'Y' || z[i] == 'W') &&
2,147,483,647!
667
          (isIdChar[(uint8_t)z[i + 1]] == 0)) {
×
668
        *tokenId = TK_NK_VARIABLE;
10,332,597✔
669
        i += 1;
10,332,597✔
670
        return i;
10,332,597✔
671
      }
672

673
      int32_t seg = 1;
2,147,483,647✔
674
      while (z[i] == '.' && isdigit(z[i + 1])) {
2,147,483,647!
675
        i += 2;
1,028,805,690✔
676
        while (isdigit(z[i])) {
2,147,483,647✔
677
          i++;
2,147,483,647✔
678
        }
679
        *tokenId = TK_NK_FLOAT;
1,028,805,690✔
680
        seg++;
1,028,805,690✔
681
      }
682

683
      if (seg == 4) {  // ip address
2,147,483,647✔
684
        *tokenId = TK_NK_IPTOKEN;
11✔
685
        return i;
11✔
686
      } else if (seg > 2) {
2,147,483,647!
687
        break;
×
688
      }
689

690
      // support float with no decimal part after the decimal point
691
      if (z[i] == '.' && seg == 1) {
2,147,483,647!
692
        *tokenId = TK_NK_FLOAT;
23,647✔
693
        i++;
23,647✔
694
      }
695
      if ((z[i] == 'e' || z[i] == 'E') &&
2,147,483,647!
696
          (isdigit(z[i + 1]) || ((z[i + 1] == '+' || z[i + 1] == '-') && isdigit(z[i + 2])))) {
×
697
        i += 2;
235,538✔
698
        while (isdigit(z[i])) {
683,672✔
699
          i++;
448,134✔
700
        }
701
        *tokenId = TK_NK_FLOAT;
235,538✔
702
      }
703
      return i;
2,147,483,647✔
704
    }
705
    // case '[': {
706
    //   for (i = 1; z[i] && z[i - 1] != ']'; i++) {
707
    //   }
708
    //   *tokenId = TK_NK_ID;
709
    //   return i;
710
    // }
711
    case 'T':
61,572,742✔
712
    case 't':
713
    case 'F':
714
    case 'f': {
715
      bool hasNonAsciiChars = false;
61,572,742✔
716
      for (i = 1;; i++) {
263,409,386✔
717
        if ((z[i] & 0x80) != 0) {
263,409,386!
718
          // utf-8 characters
719
          // currently, we support using utf-8 characters only in alias
720
          hasNonAsciiChars = true;
×
721
        } else if (isIdChar[(uint8_t)z[i]]) {
263,409,386✔
722
        } else {
723
          break;
61,572,742✔
724
        }
725
      }
726
      if (hasNonAsciiChars) {
61,572,742!
727
        *tokenId = TK_NK_ALIAS;  // must be alias
×
728
        return i;
×
729
      }
730
      if (IS_TRUE_STR(z, i) || IS_FALSE_STR(z, i)) {
61,572,742!
731
        *tokenId = TK_NK_BOOL;
50,340,612✔
732
        return i;
50,340,612✔
733
      }
734
      *tokenId = tKeywordCode(z, i);
11,232,130✔
735
      return i;
11,323,009✔
736
    }
737
    default: {
296,724,750✔
738
      if ((*z & 0x80) == 0 && !isIdChar[(uint8_t)*z]) {
296,724,750✔
739
        break;
1,243,859✔
740
      }
741
      bool hasNonAsciiChars = false;
295,480,891✔
742
      for (i = 1;; i++) {
1,717,714,006✔
743
        if ((z[i] & 0x80) != 0) {
1,717,714,006✔
744
          hasNonAsciiChars = true;
857✔
745
        } else if (isIdChar[(uint8_t)z[i]]) {
1,717,713,149✔
746
        } else {
747
          break;
295,480,891✔
748
        }
749
      }
750
      if (hasNonAsciiChars) {
295,480,891✔
751
        *tokenId = TK_NK_ALIAS;
159✔
752
        return i;
159✔
753
      }
754
      *tokenId = tKeywordCode(z, i);
295,480,732✔
755
      return i;
285,255,512✔
756
    }
757
  }
758

759
  *tokenId = TK_NK_ILLEGAL;
×
760
  return 0;
×
761
}
762

763
SToken tStrGetToken(const char* str, int32_t* i, bool isPrevOptr, bool* pIgnoreComma) {
2,147,483,647✔
764
  SToken t0 = {0};
2,147,483,647✔
765

766
  // here we reach the end of sql string, null-terminated string
767
  if (str[*i] == 0) {
2,147,483,647✔
768
    t0.n = 0;
17,626,790✔
769
    return t0;
17,626,790✔
770
  }
771

772
  // IGNORE TK_NK_SPACE, TK_NK_COMMA, and specified tokens
773
  while (1) {
774
    *i += t0.n;
2,147,483,647✔
775

776
    int32_t numOfComma = 0;
2,147,483,647✔
777
    char    t = str[*i];
2,147,483,647✔
778
    while (t == ' ' || t == '\n' || t == '\r' || t == '\t' || t == '\f' || t == ',') {
2,147,483,647!
779
      if (t == ',' && (++numOfComma > 1)) {  // comma only allowed once
570,125,494✔
780
        t0.n = 0;
1✔
781
        return t0;
1✔
782
      }
783

784
      if (NULL != pIgnoreComma && t == ',') {
570,125,493!
785
        *pIgnoreComma = true;
×
786
      }
787

788
      t = str[++(*i)];
570,125,493✔
789
    }
790

791
    t0.n = tGetToken(&str[*i], &t0.type);
2,147,483,647✔
792
    break;
2,147,483,647✔
793

794
    // not support user specfied ignored symbol list
795
#if 0
796
    bool ignore = false;
797
    for (uint32_t k = 0; k < numOfIgnoreToken; k++) {
798
      if (t0.type == ignoreTokenTypes[k]) {
799
        ignore = true;
800
        break;
801
      }
802
    }
803

804
    if (!ignore) {
805
      break;
806
    }
807
#endif
808
  }
809

810
  if (t0.type == TK_NK_SEMI) {
2,147,483,647✔
811
    t0.n = 0;
1,022,094✔
812
    t0.type = 0;
1,022,094✔
813
    return t0;
1,022,094✔
814
  }
815

816
  uint32_t type = 0;
2,147,483,647✔
817
  int32_t  len;
818

819
  // support parse the 'db.tbl' format, notes: There should be no space on either side of the dot!
820
  if ('.' == str[*i + t0.n]) {
2,147,483,647✔
821
    len = tGetToken(&str[*i + t0.n + 1], &type);
26,219,651✔
822

823
    // only id、string and ? are valid
824
    if (((TK_NK_STRING != t0.type) && (TK_NK_ID != t0.type)) ||
26,046,297!
825
        ((TK_NK_STRING != type) && (TK_NK_ID != type) && (TK_NK_QUESTION != type))) {
26,048,642!
826
      t0.type = TK_NK_ILLEGAL;
32✔
827
      t0.n = 0;
32✔
828

829
      return t0;
32✔
830
    }
831

832
    // check the table name is '?', db.?asf is not valid.
833
    if (TK_NK_QUESTION == type) {
26,046,265✔
834
      (void)tGetToken(&str[*i + t0.n + 2], &type);
119✔
835
      if (TK_NK_SPACE != type) {
119✔
836
        t0.type = TK_NK_ILLEGAL;
12✔
837
        t0.n = 0;
12✔
838
        return t0;
12✔
839
      }
840
    }
841

842
    t0.n += len + 1;
26,046,253✔
843

844
  } else {
845
    // support parse the -/+number format
846
    if ((isPrevOptr) && (t0.type == TK_NK_MINUS || t0.type == TK_NK_PLUS)) {
2,147,483,647!
847
      len = tGetToken(&str[*i + t0.n], &type);
722,792,221✔
848
      if (type == TK_NK_INTEGER || type == TK_NK_FLOAT || type == TK_NK_BIN || type == TK_NK_HEX) {
1,076,593,717!
849
        t0.type = type;
1,057,401,249✔
850
        t0.n += len;
1,057,401,249✔
851
      }
852
    }
853
  }
854

855
  t0.z = (char*)str + (*i);
2,147,483,647✔
856
  *i += t0.n;
2,147,483,647✔
857

858
  return t0;
2,147,483,647✔
859
}
860

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

863
int32_t taosInitKeywordsTable() { return doInitKeywordsTable(); }
18,153✔
864

865
void taosCleanupKeywordsTable() {
17,927✔
866
  void* m = keywordHashTable;
17,927✔
867
  if (m != NULL && atomic_val_compare_exchange_ptr(&keywordHashTable, m, 0) == m) {
17,927!
868
    taosHashCleanup(m);
17,926✔
869
  }
870
}
17,927✔
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