PluginProbe
SQLite Database Integration / 3.1.0
SQLite Database Integration v3.1.0
3.1.0 3.0.2 3.0.1 trunk 2.1.13 2.1.14 2.1.15 2.1.16 2.2.0 2.2.1 2.2.10 2.2.11 2.2.12 2.2.13 2.2.14 2.2.15 2.2.16 2.2.17 2.2.18 2.2.19 2.2.2 2.2.20 2.2.21 2.2.22 2.2.23 All 33 releases
sqlite-database-integration / wp-includes / database / mysql / class-wp-mysql-lexer.php

class-wp-mysql-lexer.php in SQLite Database Integration 3.1.0, at wp-includes/database/mysql/class-wp-mysql-lexer.php

3,105 lines 151.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * MySQL lexer.
5 *
6 * An exhaustive lexer for the MySQL SQL dialect with multi-version support.
7 * It scans the provided SQL input payload and generates MySQL token objects.
8 * The lexer is intended to cover 100% of the MySQL SQL syntax for all MySQL
9 * versions starting from 5.7. It's likely to support older versions as well.
10 *
11 * The lexer is implemented with zero dependencies, it doesn't require any PHP
12 * extensions, and it doesn't use PCRE or any other regular expression engines.
13 *
14 * This lexer is based on the MySQL Workbench lexer grammar.
15 * See:
16 * https://github.com/mysql/mysql-workbench/blob/8.0.38/library/parsers/grammars/MySQLLexer.g4
17 * https://github.com/mysql/mysql-workbench/blob/8.0.38/library/parsers/grammars/predefined.tokens
18 * https://github.com/mysql/mysql-workbench/blob/8.0.38/library/parsers/mysql/MySQLBaseLexer.cpp
19 *
20 * @access private
21 */
22 class WP_MySQL_Lexer {
23 /**
24 * The SQL modes that affect the lexer behavior.
25 *
26 * These values are intended to be used in a bitmask. See "$this->sql_modes".
27 * The list of the SQL modes is not exhaustive. Only the ones that influence
28 * the lexer behavior are included in this list.
29 *
30 * See:
31 * https://dev.mysql.com/doc/refman/8.4/en/sql-mode.html
32 */
33 const SQL_MODE_HIGH_NOT_PRECEDENCE = 1;
34 const SQL_MODE_PIPES_AS_CONCAT = 2;
35 const SQL_MODE_IGNORE_SPACE = 4;
36 const SQL_MODE_NO_BACKSLASH_ESCAPES = 8;
37 const SQL_MODE_ANSI_QUOTES = 16;
38
39 /**
40 * Character masks for frequently used character classes.
41 *
42 * These are intended to be used with "strspn()" and "strcspn()" functions
43 * for fast character class matching in the SQL payload.
44 */
45 const WHITESPACE_MASK = " \t\n\r\f\v";
46 const DIGIT_MASK = '0123456789';
47 const HEX_DIGIT_MASK = '0123456789abcdefABCDEF';
48
49 /**
50 * Tokens from the MySQL Workbench "predefined.tokens" list.
51 *
52 * This list preserves the token names and IDs from the MySQL Workbench
53 * "predefined.tokens" list, adding some tokens missing from the list.
54 *
55 * See:
56 * https://github.com/mysql/mysql-workbench/blob/8.0.38/library/parsers/grammars/predefined.tokens
57 */
58 const ACCESSIBLE_SYMBOL = 1;
59 const ACCOUNT_SYMBOL = 2;
60 const ACTION_SYMBOL = 3;
61 const ADD_SYMBOL = 4;
62 const ADDDATE_SYMBOL = 5;
63 const AFTER_SYMBOL = 6;
64 const AGAINST_SYMBOL = 7;
65 const AGGREGATE_SYMBOL = 8;
66 const ALGORITHM_SYMBOL = 9;
67 const ALL_SYMBOL = 10;
68 const ALTER_SYMBOL = 11;
69 const ALWAYS_SYMBOL = 12;
70 const ANALYSE_SYMBOL = 13;
71 const ANALYZE_SYMBOL = 14;
72 const AND_SYMBOL = 15;
73 const ANY_SYMBOL = 16;
74 const AS_SYMBOL = 17;
75 const ASC_SYMBOL = 18;
76 const ASCII_SYMBOL = 19;
77 const ASENSITIVE_SYMBOL = 20;
78 const AT_SYMBOL = 21;
79 const AUTHORS_SYMBOL = 22;
80 const AUTOEXTEND_SIZE_SYMBOL = 23;
81 const AUTO_INCREMENT_SYMBOL = 24;
82 const AVG_ROW_LENGTH_SYMBOL = 25;
83 const AVG_SYMBOL = 26;
84 const BACKUP_SYMBOL = 27;
85 const BEFORE_SYMBOL = 28;
86 const BEGIN_SYMBOL = 29;
87 const BETWEEN_SYMBOL = 30;
88 const BIGINT_SYMBOL = 31;
89 const BINARY_SYMBOL = 32;
90 const BINLOG_SYMBOL = 33;
91 const BIN_NUM_SYMBOL = 34;
92 const BIT_AND_SYMBOL = 35;
93 const BIT_OR_SYMBOL = 36;
94 const BIT_SYMBOL = 37;
95 const BIT_XOR_SYMBOL = 38;
96 const BLOB_SYMBOL = 39;
97 const BLOCK_SYMBOL = 40;
98 const BOOLEAN_SYMBOL = 41;
99 const BOOL_SYMBOL = 42;
100 const BOTH_SYMBOL = 43;
101 const BTREE_SYMBOL = 44;
102 const BY_SYMBOL = 45;
103 const BYTE_SYMBOL = 46;
104 const CACHE_SYMBOL = 47;
105 const CALL_SYMBOL = 48;
106 const CASCADE_SYMBOL = 49;
107 const CASCADED_SYMBOL = 50;
108 const CASE_SYMBOL = 51;
109 const CAST_SYMBOL = 52;
110 const CATALOG_NAME_SYMBOL = 53;
111 const CHAIN_SYMBOL = 54;
112 const CHANGE_SYMBOL = 55;
113 const CHANGED_SYMBOL = 56;
114 const CHANNEL_SYMBOL = 57;
115 const CHARSET_SYMBOL = 58;
116 const CHARACTER_SYMBOL = 59;
117 const CHAR_SYMBOL = 60;
118 const CHECKSUM_SYMBOL = 61;
119 const CHECK_SYMBOL = 62;
120 const CIPHER_SYMBOL = 63;
121 const CLASS_ORIGIN_SYMBOL = 64;
122 const CLIENT_SYMBOL = 65;
123 const CLOSE_SYMBOL = 66;
124 const COALESCE_SYMBOL = 67;
125 const CODE_SYMBOL = 68;
126 const COLLATE_SYMBOL = 69;
127 const COLLATION_SYMBOL = 70;
128 const COLUMNS_SYMBOL = 71;
129 const COLUMN_SYMBOL = 72;
130 const COLUMN_NAME_SYMBOL = 73;
131 const COLUMN_FORMAT_SYMBOL = 74;
132 const COMMENT_SYMBOL = 75;
133 const COMMITTED_SYMBOL = 76;
134 const COMMIT_SYMBOL = 77;
135 const COMPACT_SYMBOL = 78;
136 const COMPLETION_SYMBOL = 79;
137 const COMPRESSED_SYMBOL = 80;
138 const COMPRESSION_SYMBOL = 81;
139 const CONCURRENT_SYMBOL = 82;
140 const CONDITION_SYMBOL = 83;
141 const CONNECTION_SYMBOL = 84;
142 const CONSISTENT_SYMBOL = 85;
143 const CONSTRAINT_SYMBOL = 86;
144 const CONSTRAINT_CATALOG_SYMBOL = 87;
145 const CONSTRAINT_NAME_SYMBOL = 88;
146 const CONSTRAINT_SCHEMA_SYMBOL = 89;
147 const CONTAINS_SYMBOL = 90;
148 const CONTEXT_SYMBOL = 91;
149 const CONTINUE_SYMBOL = 92;
150 const CONTRIBUTORS_SYMBOL = 93;
151 const CONVERT_SYMBOL = 94;
152 const COUNT_SYMBOL = 95;
153 const CPU_SYMBOL = 96;
154 const CREATE_SYMBOL = 97;
155 const CROSS_SYMBOL = 98;
156 const CUBE_SYMBOL = 99;
157 const CURDATE_SYMBOL = 100;
158 const CURRENT_SYMBOL = 101;
159 const CURRENT_DATE_SYMBOL = 102;
160 const CURRENT_TIME_SYMBOL = 103;
161 const CURRENT_TIMESTAMP_SYMBOL = 104;
162 const CURRENT_USER_SYMBOL = 105;
163 const CURSOR_SYMBOL = 106;
164 const CURSOR_NAME_SYMBOL = 107;
165 const CURTIME_SYMBOL = 108;
166 const DATABASE_SYMBOL = 109;
167 const DATABASES_SYMBOL = 110;
168 const DATAFILE_SYMBOL = 111;
169 const DATA_SYMBOL = 112;
170 const DATETIME_SYMBOL = 113;
171 const DATE_ADD_SYMBOL = 114;
172 const DATE_SUB_SYMBOL = 115;
173 const DATE_SYMBOL = 116;
174 const DAYOFMONTH_SYMBOL = 117;
175 const DAY_HOUR_SYMBOL = 118;
176 const DAY_MICROSECOND_SYMBOL = 119;
177 const DAY_MINUTE_SYMBOL = 120;
178 const DAY_SECOND_SYMBOL = 121;
179 const DAY_SYMBOL = 122;
180 const DEALLOCATE_SYMBOL = 123;
181 const DEC_SYMBOL = 124;
182 const DECIMAL_NUM_SYMBOL = 125;
183 const DECIMAL_SYMBOL = 126;
184 const DECLARE_SYMBOL = 127;
185 const DEFAULT_SYMBOL = 128;
186 const DEFAULT_AUTH_SYMBOL = 129;
187 const DEFINER_SYMBOL = 130;
188 const DELAYED_SYMBOL = 131;
189 const DELAY_KEY_WRITE_SYMBOL = 132;
190 const DELETE_SYMBOL = 133;
191 const DESC_SYMBOL = 134;
192 const DESCRIBE_SYMBOL = 135;
193 const DES_KEY_FILE_SYMBOL = 136;
194 const DETERMINISTIC_SYMBOL = 137;
195 const DIAGNOSTICS_SYMBOL = 138;
196 const DIRECTORY_SYMBOL = 139;
197 const DISABLE_SYMBOL = 140;
198 const DISCARD_SYMBOL = 141;
199 const DISK_SYMBOL = 142;
200 const DISTINCT_SYMBOL = 143;
201 const DISTINCTROW_SYMBOL = 144;
202 const DIV_SYMBOL = 145;
203 const DOUBLE_SYMBOL = 146;
204 const DO_SYMBOL = 147;
205 const DROP_SYMBOL = 148;
206 const DUAL_SYMBOL = 149;
207 const DUMPFILE_SYMBOL = 150;
208 const DUPLICATE_SYMBOL = 151;
209 const DYNAMIC_SYMBOL = 152;
210 const EACH_SYMBOL = 153;
211 const ELSE_SYMBOL = 154;
212 const ELSEIF_SYMBOL = 155;
213 const ENABLE_SYMBOL = 156;
214 const ENCLOSED_SYMBOL = 157;
215 const ENCRYPTION_SYMBOL = 158;
216 const END_SYMBOL = 159;
217 const ENDS_SYMBOL = 160;
218 const END_OF_INPUT_SYMBOL = 161; // defined in "predefined.tokens", but not used
219 const ENGINES_SYMBOL = 162;
220 const ENGINE_SYMBOL = 163;
221 const ENUM_SYMBOL = 164;
222 const ERROR_SYMBOL = 165;
223 const ERRORS_SYMBOL = 166;
224 const ESCAPED_SYMBOL = 167;
225 const ESCAPE_SYMBOL = 168;
226 const EVENTS_SYMBOL = 169;
227 const EVENT_SYMBOL = 170;
228 const EVERY_SYMBOL = 171;
229 const EXCHANGE_SYMBOL = 172;
230 const EXECUTE_SYMBOL = 173;
231 const EXISTS_SYMBOL = 174;
232 const EXIT_SYMBOL = 175;
233 const EXPANSION_SYMBOL = 176;
234 const EXPIRE_SYMBOL = 177;
235 const EXPLAIN_SYMBOL = 178;
236 const EXPORT_SYMBOL = 179;
237 const EXTENDED_SYMBOL = 180;
238 const EXTENT_SIZE_SYMBOL = 181;
239 const EXTRACT_SYMBOL = 182;
240 const FALSE_SYMBOL = 183;
241 const FAST_SYMBOL = 184;
242 const FAULTS_SYMBOL = 185;
243 const FETCH_SYMBOL = 186;
244 const FIELDS_SYMBOL = 187;
245 const FILE_SYMBOL = 188;
246 const FILE_BLOCK_SIZE_SYMBOL = 189;
247 const FILTER_SYMBOL = 190;
248 const FIRST_SYMBOL = 191;
249 const FIXED_SYMBOL = 192;
250 const FLOAT4_SYMBOL = 193;
251 const FLOAT8_SYMBOL = 194;
252 const FLOAT_SYMBOL = 195;
253 const FLUSH_SYMBOL = 196;
254 const FOLLOWS_SYMBOL = 197;
255 const FORCE_SYMBOL = 198;
256 const FOREIGN_SYMBOL = 199;
257 const FOR_SYMBOL = 200;
258 const FORMAT_SYMBOL = 201;
259 const FOUND_SYMBOL = 202;
260 const FROM_SYMBOL = 203;
261 const FULL_SYMBOL = 204;
262 const FULLTEXT_SYMBOL = 205;
263 const FUNCTION_SYMBOL = 206;
264 const GET_SYMBOL = 207;
265 const GENERAL_SYMBOL = 208;
266 const GENERATED_SYMBOL = 209;
267 const GROUP_REPLICATION_SYMBOL = 210;
268 const GEOMETRYCOLLECTION_SYMBOL = 211;
269 const GEOMETRY_SYMBOL = 212;
270 const GET_FORMAT_SYMBOL = 213;
271 const GLOBAL_SYMBOL = 214;
272 const GRANT_SYMBOL = 215;
273 const GRANTS_SYMBOL = 216;
274 const GROUP_SYMBOL = 217;
275 const GROUP_CONCAT_SYMBOL = 218;
276 const HANDLER_SYMBOL = 219;
277 const HASH_SYMBOL = 220;
278 const HAVING_SYMBOL = 221;
279 const HELP_SYMBOL = 222;
280 const HIGH_PRIORITY_SYMBOL = 223;
281 const HOST_SYMBOL = 224;
282 const HOSTS_SYMBOL = 225;
283 const HOUR_MICROSECOND_SYMBOL = 226;
284 const HOUR_MINUTE_SYMBOL = 227;
285 const HOUR_SECOND_SYMBOL = 228;
286 const HOUR_SYMBOL = 229;
287 const IDENTIFIED_SYMBOL = 230;
288 const IF_SYMBOL = 231;
289 const IGNORE_SYMBOL = 232;
290 const IGNORE_SERVER_IDS_SYMBOL = 233;
291 const IMPORT_SYMBOL = 234;
292 const INDEXES_SYMBOL = 235;
293 const INDEX_SYMBOL = 236;
294 const INFILE_SYMBOL = 237;
295 const INITIAL_SIZE_SYMBOL = 238;
296 const INNER_SYMBOL = 239;
297 const INOUT_SYMBOL = 240;
298 const INSENSITIVE_SYMBOL = 241;
299 const INSERT_SYMBOL = 242;
300 const INSERT_METHOD_SYMBOL = 243;
301 const INSTANCE_SYMBOL = 244;
302 const INSTALL_SYMBOL = 245;
303 const INTEGER_SYMBOL = 246;
304 const INTERVAL_SYMBOL = 247;
305 const INTO_SYMBOL = 248;
306 const INT_SYMBOL = 249;
307 const INVOKER_SYMBOL = 250;
308 const IN_SYMBOL = 251;
309 const IO_AFTER_GTIDS_SYMBOL = 252;
310 const IO_BEFORE_GTIDS_SYMBOL = 253;
311 const IO_THREAD_SYMBOL = 254;
312 const IO_SYMBOL = 255;
313 const IPC_SYMBOL = 256;
314 const IS_SYMBOL = 257;
315 const ISOLATION_SYMBOL = 258;
316 const ISSUER_SYMBOL = 259;
317 const ITERATE_SYMBOL = 260;
318 const JOIN_SYMBOL = 261;
319 const JSON_SYMBOL = 262;
320 const KEYS_SYMBOL = 263;
321 const KEY_BLOCK_SIZE_SYMBOL = 264;
322 const KEY_SYMBOL = 265;
323 const KILL_SYMBOL = 266;
324 const LANGUAGE_SYMBOL = 267;
325 const LAST_SYMBOL = 268;
326 const LEADING_SYMBOL = 269;
327 const LEAVES_SYMBOL = 270;
328 const LEAVE_SYMBOL = 271;
329 const LEFT_SYMBOL = 272;
330 const LESS_SYMBOL = 273;
331 const LEVEL_SYMBOL = 274;
332 const LIKE_SYMBOL = 275;
333 const LIMIT_SYMBOL = 276;
334 const LINEAR_SYMBOL = 277;
335 const LINES_SYMBOL = 278;
336 const LINESTRING_SYMBOL = 279;
337 const LIST_SYMBOL = 280;
338 const LOAD_SYMBOL = 281;
339 const LOCALTIME_SYMBOL = 282;
340 const LOCALTIMESTAMP_SYMBOL = 283;
341 const LOCAL_SYMBOL = 284;
342 const LOCATOR_SYMBOL = 285;
343 const LOCKS_SYMBOL = 286;
344 const LOCK_SYMBOL = 287;
345 const LOGFILE_SYMBOL = 288;
346 const LOGS_SYMBOL = 289;
347 const LONGBLOB_SYMBOL = 290;
348 const LONGTEXT_SYMBOL = 291;
349 const LONG_NUM_SYMBOL = 292;
350 const LONG_SYMBOL = 293;
351 const LOOP_SYMBOL = 294;
352 const LOW_PRIORITY_SYMBOL = 295;
353 const MASTER_AUTO_POSITION_SYMBOL = 296;
354 const MASTER_BIND_SYMBOL = 297;
355 const MASTER_CONNECT_RETRY_SYMBOL = 298;
356 const MASTER_DELAY_SYMBOL = 299;
357 const MASTER_HOST_SYMBOL = 300;
358 const MASTER_LOG_FILE_SYMBOL = 301;
359 const MASTER_LOG_POS_SYMBOL = 302;
360 const MASTER_PASSWORD_SYMBOL = 303;
361 const MASTER_PORT_SYMBOL = 304;
362 const MASTER_RETRY_COUNT_SYMBOL = 305;
363 const MASTER_SERVER_ID_SYMBOL = 306;
364 const MASTER_SSL_CAPATH_SYMBOL = 307;
365 const MASTER_SSL_CA_SYMBOL = 308;
366 const MASTER_SSL_CERT_SYMBOL = 309;
367 const MASTER_SSL_CIPHER_SYMBOL = 310;
368 const MASTER_SSL_CRL_SYMBOL = 311;
369 const MASTER_SSL_CRLPATH_SYMBOL = 312;
370 const MASTER_SSL_KEY_SYMBOL = 313;
371 const MASTER_SSL_SYMBOL = 314;
372 const MASTER_SSL_VERIFY_SERVER_CERT_SYMBOL = 315;
373 const MASTER_SYMBOL = 316;
374 const MASTER_TLS_VERSION_SYMBOL = 317;
375 const MASTER_USER_SYMBOL = 318;
376 const MASTER_HEARTBEAT_PERIOD_SYMBOL = 319;
377 const MATCH_SYMBOL = 320;
378 const MAX_CONNECTIONS_PER_HOUR_SYMBOL = 321;
379 const MAX_QUERIES_PER_HOUR_SYMBOL = 322;
380 const MAX_ROWS_SYMBOL = 323;
381 const MAX_SIZE_SYMBOL = 324;
382 const MAX_STATEMENT_TIME_SYMBOL = 325;
383 const MAX_SYMBOL = 326;
384 const MAX_UPDATES_PER_HOUR_SYMBOL = 327;
385 const MAX_USER_CONNECTIONS_SYMBOL = 328;
386 const MAXVALUE_SYMBOL = 329;
387 const MEDIUMBLOB_SYMBOL = 330;
388 const MEDIUMINT_SYMBOL = 331;
389 const MEDIUMTEXT_SYMBOL = 332;
390 const MEDIUM_SYMBOL = 333;
391 const MEMORY_SYMBOL = 334;
392 const MERGE_SYMBOL = 335;
393 const MESSAGE_TEXT_SYMBOL = 336;
394 const MICROSECOND_SYMBOL = 337;
395 const MID_SYMBOL = 338;
396 const MIDDLEINT_SYMBOL = 339;
397 const MIGRATE_SYMBOL = 340;
398 const MINUTE_MICROSECOND_SYMBOL = 341;
399 const MINUTE_SECOND_SYMBOL = 342;
400 const MINUTE_SYMBOL = 343;
401 const MIN_ROWS_SYMBOL = 344;
402 const MIN_SYMBOL = 345;
403 const MODE_SYMBOL = 346;
404 const MODIFIES_SYMBOL = 347;
405 const MODIFY_SYMBOL = 348;
406 const MOD_SYMBOL = 349;
407 const MONTH_SYMBOL = 350;
408 const MULTILINESTRING_SYMBOL = 351;
409 const MULTIPOINT_SYMBOL = 352;
410 const MULTIPOLYGON_SYMBOL = 353;
411 const MUTEX_SYMBOL = 354;
412 const MYSQL_ERRNO_SYMBOL = 355;
413 const NAMES_SYMBOL = 356;
414 const NAME_SYMBOL = 357;
415 const NATIONAL_SYMBOL = 358;
416 const NATURAL_SYMBOL = 359;
417 const NCHAR_STRING_SYMBOL = 360;
418 const NCHAR_SYMBOL = 361;
419 const NDB_SYMBOL = 362;
420 const NDBCLUSTER_SYMBOL = 363;
421 const NEG_SYMBOL = 364;
422 const NEVER_SYMBOL = 365;
423 const NEW_SYMBOL = 366;
424 const NEXT_SYMBOL = 367;
425 const NODEGROUP_SYMBOL = 368;
426 const NONE_SYMBOL = 369;
427 const NONBLOCKING_SYMBOL = 370;
428 const NOT_SYMBOL = 371;
429 const NOW_SYMBOL = 372;
430 const NO_SYMBOL = 373;
431 const NO_WAIT_SYMBOL = 374;
432 const NO_WRITE_TO_BINLOG_SYMBOL = 375;
433 const NULL_SYMBOL = 376;
434 const NUMBER_SYMBOL = 377;
435 const NUMERIC_SYMBOL = 378;
436 const NVARCHAR_SYMBOL = 379;
437 const OFFLINE_SYMBOL = 380;
438 const OFFSET_SYMBOL = 381;
439 const OLD_PASSWORD_SYMBOL = 382;
440 const ON_SYMBOL = 383;
441 const ONE_SYMBOL = 384;
442 const ONLINE_SYMBOL = 385;
443 const ONLY_SYMBOL = 386;
444 const OPEN_SYMBOL = 387;
445 const OPTIMIZE_SYMBOL = 388;
446 const OPTIMIZER_COSTS_SYMBOL = 389;
447 const OPTIONS_SYMBOL = 390;
448 const OPTION_SYMBOL = 391;
449 const OPTIONALLY_SYMBOL = 392;
450 const ORDER_SYMBOL = 393;
451 const OR_SYMBOL = 394;
452 const OUTER_SYMBOL = 395;
453 const OUTFILE_SYMBOL = 396;
454 const OUT_SYMBOL = 397;
455 const OWNER_SYMBOL = 398;
456 const PACK_KEYS_SYMBOL = 399;
457 const PAGE_SYMBOL = 400;
458 const PARSER_SYMBOL = 401;
459 const PARTIAL_SYMBOL = 402;
460 const PARTITIONING_SYMBOL = 403;
461 const PARTITIONS_SYMBOL = 404;
462 const PARTITION_SYMBOL = 405;
463 const PASSWORD_SYMBOL = 406;
464 const PHASE_SYMBOL = 407;
465 const PLUGINS_SYMBOL = 408;
466 const PLUGIN_DIR_SYMBOL = 409;
467 const PLUGIN_SYMBOL = 410;
468 const POINT_SYMBOL = 411;
469 const POLYGON_SYMBOL = 412;
470 const PORT_SYMBOL = 413;
471 const POSITION_SYMBOL = 414;
472 const PRECEDES_SYMBOL = 415;
473 const PRECISION_SYMBOL = 416;
474 const PREPARE_SYMBOL = 417;
475 const PRESERVE_SYMBOL = 418;
476 const PREV_SYMBOL = 419;
477 const PRIMARY_SYMBOL = 420;
478 const PRIVILEGES_SYMBOL = 421;
479 const PROCEDURE_SYMBOL = 422;
480 const PROCESS_SYMBOL = 423;
481 const PROCESSLIST_SYMBOL = 424;
482 const PROFILE_SYMBOL = 425;
483 const PROFILES_SYMBOL = 426;
484 const PROXY_SYMBOL = 427;
485 const PURGE_SYMBOL = 428;
486 const QUARTER_SYMBOL = 429;
487 const QUERY_SYMBOL = 430;
488 const QUICK_SYMBOL = 431;
489 const RANGE_SYMBOL = 432;
490 const READS_SYMBOL = 433;
491 const READ_ONLY_SYMBOL = 434;
492 const READ_SYMBOL = 435;
493 const READ_WRITE_SYMBOL = 436;
494 const REAL_SYMBOL = 437;
495 const REBUILD_SYMBOL = 438;
496 const RECOVER_SYMBOL = 439;
497 const REDOFILE_SYMBOL = 440;
498 const REDO_BUFFER_SIZE_SYMBOL = 441;
499 const REDUNDANT_SYMBOL = 442;
500 const REFERENCES_SYMBOL = 443;
501 const REGEXP_SYMBOL = 444;
502 const RELAY_SYMBOL = 445;
503 const RELAYLOG_SYMBOL = 446;
504 const RELAY_LOG_FILE_SYMBOL = 447;
505 const RELAY_LOG_POS_SYMBOL = 448;
506 const RELAY_THREAD_SYMBOL = 449;
507 const RELEASE_SYMBOL = 450;
508 const RELOAD_SYMBOL = 451;
509 const REMOVE_SYMBOL = 452;
510 const RENAME_SYMBOL = 453;
511 const REORGANIZE_SYMBOL = 454;
512 const REPAIR_SYMBOL = 455;
513 const REPEATABLE_SYMBOL = 456;
514 const REPEAT_SYMBOL = 457;
515 const REPLACE_SYMBOL = 458;
516 const REPLICATION_SYMBOL = 459;
517 const REPLICATE_DO_DB_SYMBOL = 460;
518 const REPLICATE_IGNORE_DB_SYMBOL = 461;
519 const REPLICATE_DO_TABLE_SYMBOL = 462;
520 const REPLICATE_IGNORE_TABLE_SYMBOL = 463;
521 const REPLICATE_WILD_DO_TABLE_SYMBOL = 464;
522 const REPLICATE_WILD_IGNORE_TABLE_SYMBOL = 465;
523 const REPLICATE_REWRITE_DB_SYMBOL = 466;
524 const REQUIRE_SYMBOL = 467;
525 const RESET_SYMBOL = 468;
526 const RESIGNAL_SYMBOL = 469;
527 const RESTORE_SYMBOL = 470;
528 const RESTRICT_SYMBOL = 471;
529 const RESUME_SYMBOL = 472;
530 const RETURNED_SQLSTATE_SYMBOL = 473;
531 const RETURNS_SYMBOL = 474;
532 const RETURN_SYMBOL = 475;
533 const REVERSE_SYMBOL = 476;
534 const REVOKE_SYMBOL = 477;
535 const RIGHT_SYMBOL = 478;
536 const RLIKE_SYMBOL = 479;
537 const ROLLBACK_SYMBOL = 480;
538 const ROLLUP_SYMBOL = 481;
539 const ROTATE_SYMBOL = 482;
540 const ROUTINE_SYMBOL = 483;
541 const ROWS_SYMBOL = 484;
542 const ROW_COUNT_SYMBOL = 485;
543 const ROW_FORMAT_SYMBOL = 486;
544 const ROW_SYMBOL = 487;
545 const RTREE_SYMBOL = 488;
546 const SAVEPOINT_SYMBOL = 489;
547 const SCHEDULE_SYMBOL = 490;
548 const SCHEMA_SYMBOL = 491;
549 const SCHEMA_NAME_SYMBOL = 492;
550 const SCHEMAS_SYMBOL = 493;
551 const SECOND_MICROSECOND_SYMBOL = 494;
552 const SECOND_SYMBOL = 495;
553 const SECURITY_SYMBOL = 496;
554 const SELECT_SYMBOL = 497;
555 const SENSITIVE_SYMBOL = 498;
556 const SEPARATOR_SYMBOL = 499;
557 const SERIALIZABLE_SYMBOL = 500;
558 const SERIAL_SYMBOL = 501;
559 const SESSION_SYMBOL = 502;
560 const SERVER_SYMBOL = 503;
561 const SERVER_OPTIONS_SYMBOL = 504;
562 const SESSION_USER_SYMBOL = 505;
563 const SET_SYMBOL = 506;
564 const SET_VAR_SYMBOL = 507;
565 const SHARE_SYMBOL = 508;
566 const SHOW_SYMBOL = 509;
567 const SHUTDOWN_SYMBOL = 510;
568 const SIGNAL_SYMBOL = 511;
569 const SIGNED_SYMBOL = 512;
570 const SIMPLE_SYMBOL = 513;
571 const SLAVE_SYMBOL = 514;
572 const SLOW_SYMBOL = 515;
573 const SMALLINT_SYMBOL = 516;
574 const SNAPSHOT_SYMBOL = 517;
575 const SOME_SYMBOL = 518;
576 const SOCKET_SYMBOL = 519;
577 const SONAME_SYMBOL = 520;
578 const SOUNDS_SYMBOL = 521;
579 const SOURCE_SYMBOL = 522;
580 const SPATIAL_SYMBOL = 523;
581 const SPECIFIC_SYMBOL = 524;
582 const SQLEXCEPTION_SYMBOL = 525;
583 const SQLSTATE_SYMBOL = 526;
584 const SQLWARNING_SYMBOL = 527;
585 const SQL_AFTER_GTIDS_SYMBOL = 528;
586 const SQL_AFTER_MTS_GAPS_SYMBOL = 529;
587 const SQL_BEFORE_GTIDS_SYMBOL = 530;
588 const SQL_BIG_RESULT_SYMBOL = 531;
589 const SQL_BUFFER_RESULT_SYMBOL = 532;
590 const SQL_CACHE_SYMBOL = 533;
591 const SQL_CALC_FOUND_ROWS_SYMBOL = 534;
592 const SQL_NO_CACHE_SYMBOL = 535;
593 const SQL_SMALL_RESULT_SYMBOL = 536;
594 const SQL_SYMBOL = 537;
595 const SQL_THREAD_SYMBOL = 538;
596 const SSL_SYMBOL = 539;
597 const STACKED_SYMBOL = 540;
598 const STARTING_SYMBOL = 541;
599 const STARTS_SYMBOL = 542;
600 const START_SYMBOL = 543;
601 const STATS_AUTO_RECALC_SYMBOL = 544;
602 const STATS_PERSISTENT_SYMBOL = 545;
603 const STATS_SAMPLE_PAGES_SYMBOL = 546;
604 const STATUS_SYMBOL = 547;
605 const STDDEV_SAMP_SYMBOL = 548;
606 const STDDEV_SYMBOL = 549;
607 const STDDEV_POP_SYMBOL = 550;
608 const STD_SYMBOL = 551;
609 const STOP_SYMBOL = 552;
610 const STORAGE_SYMBOL = 553;
611 const STORED_SYMBOL = 554;
612 const STRAIGHT_JOIN_SYMBOL = 555;
613 const STRING_SYMBOL = 556;
614 const SUBCLASS_ORIGIN_SYMBOL = 557;
615 const SUBDATE_SYMBOL = 558;
616 const SUBJECT_SYMBOL = 559;
617 const SUBPARTITIONS_SYMBOL = 560;
618 const SUBPARTITION_SYMBOL = 561;
619 const SUBSTR_SYMBOL = 562;
620 const SUBSTRING_SYMBOL = 563;
621 const SUM_SYMBOL = 564;
622 const SUPER_SYMBOL = 565;
623 const SUSPEND_SYMBOL = 566;
624 const SWAPS_SYMBOL = 567;
625 const SWITCHES_SYMBOL = 568;
626 const SYSDATE_SYMBOL = 569;
627 const SYSTEM_USER_SYMBOL = 570;
628 const TABLES_SYMBOL = 571;
629 const TABLESPACE_SYMBOL = 572;
630 const TABLE_REF_PRIORITY_SYMBOL = 573;
631 const TABLE_SYMBOL = 574;
632 const TABLE_CHECKSUM_SYMBOL = 575;
633 const TABLE_NAME_SYMBOL = 576;
634 const TEMPORARY_SYMBOL = 577;
635 const TEMPTABLE_SYMBOL = 578;
636 const TERMINATED_SYMBOL = 579;
637 const TEXT_SYMBOL = 580;
638 const THAN_SYMBOL = 581;
639 const THEN_SYMBOL = 582;
640 const TIMESTAMP_SYMBOL = 583;
641 const TIMESTAMP_ADD_SYMBOL = 584;
642 const TIMESTAMP_DIFF_SYMBOL = 585;
643 const TIME_SYMBOL = 586;
644 const TINYBLOB_SYMBOL = 587;
645 const TINYINT_SYMBOL = 588;
646 const TINYTEXT_SYMBOL = 589;
647 const TO_SYMBOL = 590;
648 const TRAILING_SYMBOL = 591;
649 const TRANSACTION_SYMBOL = 592;
650 const TRIGGERS_SYMBOL = 593;
651 const TRIGGER_SYMBOL = 594;
652 const TRIM_SYMBOL = 595;
653 const TRUE_SYMBOL = 596;
654 const TRUNCATE_SYMBOL = 597;
655 const TYPES_SYMBOL = 598;
656 const TYPE_SYMBOL = 599;
657 const UDF_RETURNS_SYMBOL = 600;
658 const UNCOMMITTED_SYMBOL = 601;
659 const UNDEFINED_SYMBOL = 602;
660 const UNDOFILE_SYMBOL = 603;
661 const UNDO_BUFFER_SIZE_SYMBOL = 604;
662 const UNDO_SYMBOL = 605;
663 const UNICODE_SYMBOL = 606;
664 const UNINSTALL_SYMBOL = 607;
665 const UNION_SYMBOL = 608;
666 const UNIQUE_SYMBOL = 609;
667 const UNKNOWN_SYMBOL = 610;
668 const UNLOCK_SYMBOL = 611;
669 const UNSIGNED_SYMBOL = 612;
670 const UNTIL_SYMBOL = 613;
671 const UPDATE_SYMBOL = 614;
672 const UPGRADE_SYMBOL = 615;
673 const USAGE_SYMBOL = 616;
674 const USER_RESOURCES_SYMBOL = 617;
675 const USER_SYMBOL = 618;
676 const USE_FRM_SYMBOL = 619;
677 const USE_SYMBOL = 620;
678 const USING_SYMBOL = 621;
679 const UTC_DATE_SYMBOL = 622;
680 const UTC_TIMESTAMP_SYMBOL = 623;
681 const UTC_TIME_SYMBOL = 624;
682 const VALIDATION_SYMBOL = 625;
683 const VALUES_SYMBOL = 626;
684 const VALUE_SYMBOL = 627;
685 const VARBINARY_SYMBOL = 628;
686 const VARCHAR_SYMBOL = 629;
687 const VARCHARACTER_SYMBOL = 630;
688 const VARIABLES_SYMBOL = 631;
689 const VARIANCE_SYMBOL = 632;
690 const VARYING_SYMBOL = 633;
691 const VAR_POP_SYMBOL = 634;
692 const VAR_SAMP_SYMBOL = 635;
693 const VIEW_SYMBOL = 636;
694 const VIRTUAL_SYMBOL = 637;
695 const WAIT_SYMBOL = 638;
696 const WARNINGS_SYMBOL = 639;
697 const WEEK_SYMBOL = 640;
698 const WEIGHT_STRING_SYMBOL = 641;
699 const WHEN_SYMBOL = 642;
700 const WHERE_SYMBOL = 643;
701 const WHILE_SYMBOL = 644;
702 const WITH_SYMBOL = 645;
703 const WITHOUT_SYMBOL = 646;
704 const WORK_SYMBOL = 647;
705 const WRAPPER_SYMBOL = 648;
706 const WRITE_SYMBOL = 649;
707 const X509_SYMBOL = 650;
708 const XA_SYMBOL = 651;
709 const XID_SYMBOL = 652;
710 const XML_SYMBOL = 653;
711 const XOR_SYMBOL = 654;
712 const YEAR_MONTH_SYMBOL = 655;
713 const YEAR_SYMBOL = 656;
714 const ZEROFILL_SYMBOL = 657;
715 const PERSIST_SYMBOL = 658;
716 const ROLE_SYMBOL = 659;
717 const ADMIN_SYMBOL = 660;
718 const INVISIBLE_SYMBOL = 661;
719 const VISIBLE_SYMBOL = 662;
720 const EXCEPT_SYMBOL = 663;
721 const COMPONENT_SYMBOL = 664;
722 const RECURSIVE_SYMBOL = 665;
723 const JSON_OBJECTAGG_SYMBOL = 666;
724 const JSON_ARRAYAGG_SYMBOL = 667;
725 const OF_SYMBOL = 668;
726 const SKIP_SYMBOL = 669;
727 const LOCKED_SYMBOL = 670;
728 const NOWAIT_SYMBOL = 671;
729 const GROUPING_SYMBOL = 672;
730 const PERSIST_ONLY_SYMBOL = 673;
731 const HISTOGRAM_SYMBOL = 674;
732 const BUCKETS_SYMBOL = 675;
733 const REMOTE_SYMBOL = 676;
734 const CLONE_SYMBOL = 677;
735 const CUME_DIST_SYMBOL = 678;
736 const DENSE_RANK_SYMBOL = 679;
737 const EXCLUDE_SYMBOL = 680;
738 const FIRST_VALUE_SYMBOL = 681;
739 const FOLLOWING_SYMBOL = 682;
740 const GROUPS_SYMBOL = 683;
741 const LAG_SYMBOL = 684;
742 const LAST_VALUE_SYMBOL = 685;
743 const LEAD_SYMBOL = 686;
744 const NTH_VALUE_SYMBOL = 687;
745 const NTILE_SYMBOL = 688;
746 const NULLS_SYMBOL = 689;
747 const OTHERS_SYMBOL = 690;
748 const OVER_SYMBOL = 691;
749 const PERCENT_RANK_SYMBOL = 692;
750 const PRECEDING_SYMBOL = 693;
751 const RANK_SYMBOL = 694;
752 const RESPECT_SYMBOL = 695;
753 const ROW_NUMBER_SYMBOL = 696;
754 const TIES_SYMBOL = 697;
755 const UNBOUNDED_SYMBOL = 698;
756 const WINDOW_SYMBOL = 699;
757 const EMPTY_SYMBOL = 700;
758 const JSON_TABLE_SYMBOL = 701;
759 const NESTED_SYMBOL = 702;
760 const ORDINALITY_SYMBOL = 703;
761 const PATH_SYMBOL = 704;
762 const HISTORY_SYMBOL = 705;
763 const REUSE_SYMBOL = 706;
764 const SRID_SYMBOL = 707;
765 const THREAD_PRIORITY_SYMBOL = 708;
766 const RESOURCE_SYMBOL = 709;
767 const SYSTEM_SYMBOL = 710;
768 const VCPU_SYMBOL = 711;
769 const MASTER_PUBLIC_KEY_PATH_SYMBOL = 712;
770 const GET_MASTER_PUBLIC_KEY_SYMBOL = 713;
771 const RESTART_SYMBOL = 714;
772 const DEFINITION_SYMBOL = 715;
773 const DESCRIPTION_SYMBOL = 716;
774 const ORGANIZATION_SYMBOL = 717;
775 const REFERENCE_SYMBOL = 718;
776 const OPTIONAL_SYMBOL = 719;
777 const SECONDARY_SYMBOL = 720;
778 const SECONDARY_ENGINE_SYMBOL = 721;
779 const SECONDARY_LOAD_SYMBOL = 722;
780 const SECONDARY_UNLOAD_SYMBOL = 723;
781 const ACTIVE_SYMBOL = 724;
782 const INACTIVE_SYMBOL = 725;
783 const LATERAL_SYMBOL = 726;
784 const RETAIN_SYMBOL = 727;
785 const OLD_SYMBOL = 728;
786 const NETWORK_NAMESPACE_SYMBOL = 729;
787 const ENFORCED_SYMBOL = 730;
788 const ARRAY_SYMBOL = 731;
789 const OJ_SYMBOL = 732;
790 const MEMBER_SYMBOL = 733;
791 const RANDOM_SYMBOL = 734;
792 const MASTER_COMPRESSION_ALGORITHM_SYMBOL = 735;
793 const MASTER_ZSTD_COMPRESSION_LEVEL_SYMBOL = 736;
794 const PRIVILEGE_CHECKS_USER_SYMBOL = 737;
795 const MASTER_TLS_CIPHERSUITES_SYMBOL = 738;
796 const REQUIRE_ROW_FORMAT_SYMBOL = 739;
797 const PASSWORD_LOCK_TIME_SYMBOL = 740;
798 const FAILED_LOGIN_ATTEMPTS_SYMBOL = 741;
799 const REQUIRE_TABLE_PRIMARY_KEY_CHECK_SYMBOL = 742;
800 const STREAM_SYMBOL = 743;
801 const OFF_SYMBOL = 744;
802
803 /**
804 * Additional tokens, mostly mirroring the MySQL Workbench lexer grammar.
805 *
806 * These tokens are defined in the MySQL Workbench "MySQLLexer.g4" grammar.
807 *
808 * See:
809 * https://github.com/mysql/mysql-workbench/blob/8.0.38/library/parsers/grammars/MySQLLexer.g4
810 */
811
812 // Punctuators
813 const AT_AT_SIGN_SYMBOL = 745;
814 const AT_SIGN_SYMBOL = 746;
815 const CLOSE_CURLY_SYMBOL = 747;
816 const CLOSE_PAR_SYMBOL = 748;
817 const COLON_SYMBOL = 749;
818 const COMMA_SYMBOL = 750;
819 const DOT_SYMBOL = 751;
820 const OPEN_CURLY_SYMBOL = 752;
821 const OPEN_PAR_SYMBOL = 753;
822 const PARAM_MARKER = 754;
823 const SEMICOLON_SYMBOL = 755;
824
825 // Operators
826 const ASSIGN_OPERATOR = 756;
827 const BITWISE_AND_OPERATOR = 757;
828 const BITWISE_NOT_OPERATOR = 758;
829 const BITWISE_OR_OPERATOR = 759;
830 const BITWISE_XOR_OPERATOR = 760;
831 const CONCAT_PIPES_SYMBOL = 761;
832 const DIV_OPERATOR = 762;
833 const EQUAL_OPERATOR = 763;
834 const GREATER_OR_EQUAL_OPERATOR = 764;
835 const GREATER_THAN_OPERATOR = 765;
836 const JSON_SEPARATOR_SYMBOL = 766;
837 const JSON_UNQUOTED_SEPARATOR_SYMBOL = 767;
838 const LESS_OR_EQUAL_OPERATOR = 768;
839 const LESS_THAN_OPERATOR = 769;
840 const LOGICAL_AND_OPERATOR = 770;
841 const LOGICAL_NOT_OPERATOR = 771;
842 const LOGICAL_OR_OPERATOR = 772;
843 const MINUS_OPERATOR = 773;
844 const MOD_OPERATOR = 774;
845 const MULT_OPERATOR = 775;
846 const NOT_EQUAL_OPERATOR = 776;
847 const NULL_SAFE_EQUAL_OPERATOR = 777;
848 const PLUS_OPERATOR = 778;
849 const SHIFT_LEFT_OPERATOR = 779;
850 const SHIFT_RIGHT_OPERATOR = 780;
851
852 // Literals
853 const BACK_TICK_QUOTED_ID = 781;
854 const BIN_NUMBER = 782;
855 const DECIMAL_NUMBER = 783;
856 const DOUBLE_QUOTED_TEXT = 784;
857 const FLOAT_NUMBER = 785;
858 const HEX_NUMBER = 786;
859 const INT_NUMBER = 787;
860 const LONG_NUMBER = 788;
861 const NCHAR_TEXT = 789;
862 const SINGLE_QUOTED_TEXT = 790;
863 const ULONGLONG_NUMBER = 791;
864
865 // Identifier-like tokens
866 const AT_TEXT_SUFFIX = 792;
867 const IDENTIFIER = 793;
868 const UNDERSCORE_CHARSET = 794;
869
870 // Other tokens
871 const INT1_SYMBOL = 795;
872 const INT2_SYMBOL = 796;
873 const INT3_SYMBOL = 797;
874 const INT4_SYMBOL = 798;
875 const INT8_SYMBOL = 799;
876 const NOT2_SYMBOL = 800;
877 const NULL2_SYMBOL = 801;
878 const SQL_TSI_DAY_SYMBOL = 802;
879 const SQL_TSI_HOUR_SYMBOL = 803;
880 const SQL_TSI_MICROSECOND_SYMBOL = 804;
881 const SQL_TSI_MINUTE_SYMBOL = 805;
882 const SQL_TSI_MONTH_SYMBOL = 806;
883 const SQL_TSI_QUARTER_SYMBOL = 807;
884 const SQL_TSI_SECOND_SYMBOL = 808;
885 const SQL_TSI_WEEK_SYMBOL = 809;
886 const SQL_TSI_YEAR_SYMBOL = 810;
887
888 /**
889 * Other tokens, missing in the MySQL Workbench "MySQLLexer.g4" grammar.
890 *
891 * These tokens are missing in the "MySQLLexer.g4" grammar, because the MySQL
892 * Workbench lexer and parser don't cover 100% of the MySQL syntax.
893 */
894 const INTERSECT_SYMBOL = 811;
895 const ATTRIBUTE_SYMBOL = 812;
896 const SOURCE_AUTO_POSITION_SYMBOL = 813;
897 const SOURCE_BIND_SYMBOL = 814;
898 const SOURCE_COMPRESSION_ALGORITHM_SYMBOL = 815;
899 const SOURCE_CONNECT_RETRY_SYMBOL = 816;
900 const SOURCE_CONNECTION_AUTO_FAILOVER_SYMBOL = 817;
901 const SOURCE_DELAY_SYMBOL = 818;
902 const SOURCE_HEARTBEAT_PERIOD_SYMBOL = 819;
903 const SOURCE_HOST_SYMBOL = 820;
904 const SOURCE_LOG_FILE_SYMBOL = 821;
905 const SOURCE_LOG_POS_SYMBOL = 822;
906 const SOURCE_PASSWORD_SYMBOL = 823;
907 const SOURCE_PORT_SYMBOL = 824;
908 const SOURCE_PUBLIC_KEY_PATH_SYMBOL = 825;
909 const SOURCE_RETRY_COUNT_SYMBOL = 826;
910 const SOURCE_SSL_SYMBOL = 827;
911 const SOURCE_SSL_CA_SYMBOL = 828;
912 const SOURCE_SSL_CAPATH_SYMBOL = 829;
913 const SOURCE_SSL_CERT_SYMBOL = 830;
914 const SOURCE_SSL_CIPHER_SYMBOL = 831;
915 const SOURCE_SSL_CRL_SYMBOL = 832;
916 const SOURCE_SSL_CRLPATH_SYMBOL = 833;
917 const SOURCE_SSL_KEY_SYMBOL = 834;
918 const SOURCE_SSL_VERIFY_SERVER_CERT_SYMBOL = 835;
919 const SOURCE_TLS_CIPHERSUITES_SYMBOL = 836;
920 const SOURCE_TLS_VERSION_SYMBOL = 837;
921 const SOURCE_USER_SYMBOL = 838;
922 const SOURCE_ZSTD_COMPRESSION_LEVEL_SYMBOL = 839;
923 const GET_SOURCE_PUBLIC_KEY_SYMBOL = 840;
924 const GTID_ONLY_SYMBOL = 841;
925 const ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS_SYMBOL = 842;
926 const ZONE_SYMBOL = 843;
927 const INNODB_SYMBOL = 844; // From 5.7.11 defined as is_identifier(..., "INNODB") in "sql_yacc.yy".
928 const TLS_SYMBOL = 845; // Added in 8.0.21. From 8.0.16 defined as is_identifier(..., "TLS") in "sql_yacc.yy".
929 const REDO_LOG_SYMBOL = 846; // From 8.0.21 defined as is_identifier(..., "REDO_LOG") in "sql_yacc.yy".
930 const KEYRING_SYMBOL = 847;
931 const ENGINE_ATTRIBUTE_SYMBOL = 848;
932 const SECONDARY_ENGINE_ATTRIBUTE_SYMBOL = 849;
933 const JSON_VALUE_SYMBOL = 850;
934 const RETURNING_SYMBOL = 851;
935 const GEOMCOLLECTION_SYMBOL = 852;
936
937 // Comments
938 const COMMENT = 900;
939 const MYSQL_COMMENT_START = 901;
940 const MYSQL_COMMENT_END = 902;
941
942 // Special tokens
943 const WHITESPACE = 0;
944 const EOF = -1;
945
946 /**
947 * A map of SQL keyword string values to their corresponding token types.
948 *
949 * This is used for a fast lookup of MySQL keywords during tokenization.
950 */
951 const TOKENS = array(
952 // Tokens from MySQL 5.7:
953 'ACCESSIBLE' => self::ACCESSIBLE_SYMBOL,
954 'ACCOUNT' => self::ACCOUNT_SYMBOL,
955 'ACTION' => self::ACTION_SYMBOL,
956 'ADD' => self::ADD_SYMBOL,
957 'ADDDATE' => self::ADDDATE_SYMBOL,
958 'AFTER' => self::AFTER_SYMBOL,
959 'AGAINST' => self::AGAINST_SYMBOL,
960 'AGGREGATE' => self::AGGREGATE_SYMBOL,
961 'ALGORITHM' => self::ALGORITHM_SYMBOL,
962 'ALL' => self::ALL_SYMBOL,
963 'ALTER' => self::ALTER_SYMBOL,
964 'ALWAYS' => self::ALWAYS_SYMBOL,
965 'ANALYSE' => self::ANALYSE_SYMBOL,
966 'ANALYZE' => self::ANALYZE_SYMBOL,
967 'AND' => self::AND_SYMBOL,
968 'ANY' => self::ANY_SYMBOL,
969 'AS' => self::AS_SYMBOL,
970 'ASC' => self::ASC_SYMBOL,
971 'ASCII' => self::ASCII_SYMBOL,
972 'ASENSITIVE' => self::ASENSITIVE_SYMBOL,
973 'AT' => self::AT_SYMBOL,
974 'ATTRIBUTE' => self::ATTRIBUTE_SYMBOL,
975 'AUTHORS' => self::AUTHORS_SYMBOL,
976 'AUTO_INCREMENT' => self::AUTO_INCREMENT_SYMBOL,
977 'AUTOEXTEND_SIZE' => self::AUTOEXTEND_SIZE_SYMBOL,
978 'AVG' => self::AVG_SYMBOL,
979 'AVG_ROW_LENGTH' => self::AVG_ROW_LENGTH_SYMBOL,
980 'BACKUP' => self::BACKUP_SYMBOL,
981 'BEFORE' => self::BEFORE_SYMBOL,
982 'BEGIN' => self::BEGIN_SYMBOL,
983 'BETWEEN' => self::BETWEEN_SYMBOL,
984 'BIGINT' => self::BIGINT_SYMBOL,
985 'BIN_NUM' => self::BIN_NUM_SYMBOL,
986 'BINARY' => self::BINARY_SYMBOL,
987 'BINLOG' => self::BINLOG_SYMBOL,
988 'BIT' => self::BIT_SYMBOL,
989 'BIT_AND' => self::BIT_AND_SYMBOL,
990 'BIT_OR' => self::BIT_OR_SYMBOL,
991 'BIT_XOR' => self::BIT_XOR_SYMBOL,
992 'BLOB' => self::BLOB_SYMBOL,
993 'BLOCK' => self::BLOCK_SYMBOL,
994 'BOOL' => self::BOOL_SYMBOL,
995 'BOOLEAN' => self::BOOLEAN_SYMBOL,
996 'BOTH' => self::BOTH_SYMBOL,
997 'BTREE' => self::BTREE_SYMBOL,
998 'BY' => self::BY_SYMBOL,
999 'BYTE' => self::BYTE_SYMBOL,
1000 'CACHE' => self::CACHE_SYMBOL,
1001 'CALL' => self::CALL_SYMBOL,
1002 'CASCADE' => self::CASCADE_SYMBOL,
1003 'CASCADED' => self::CASCADED_SYMBOL,
1004 'CASE' => self::CASE_SYMBOL,
1005 'CAST' => self::CAST_SYMBOL,
1006 'CATALOG_NAME' => self::CATALOG_NAME_SYMBOL,
1007 'CHAIN' => self::CHAIN_SYMBOL,
1008 'CHANGE' => self::CHANGE_SYMBOL,
1009 'CHANGED' => self::CHANGED_SYMBOL,
1010 'CHANNEL' => self::CHANNEL_SYMBOL,
1011 'CHAR' => self::CHAR_SYMBOL,
1012 'CHARACTER' => self::CHARACTER_SYMBOL,
1013 'CHARSET' => self::CHARSET_SYMBOL,
1014 'CHECK' => self::CHECK_SYMBOL,
1015 'CHECKSUM' => self::CHECKSUM_SYMBOL,
1016 'CIPHER' => self::CIPHER_SYMBOL,
1017 'CLASS_ORIGIN' => self::CLASS_ORIGIN_SYMBOL,
1018 'CLIENT' => self::CLIENT_SYMBOL,
1019 'CLOSE' => self::CLOSE_SYMBOL,
1020 'COALESCE' => self::COALESCE_SYMBOL,
1021 'CODE' => self::CODE_SYMBOL,
1022 'COLLATE' => self::COLLATE_SYMBOL,
1023 'COLLATION' => self::COLLATION_SYMBOL,
1024 'COLUMN' => self::COLUMN_SYMBOL,
1025 'COLUMN_FORMAT' => self::COLUMN_FORMAT_SYMBOL,
1026 'COLUMN_NAME' => self::COLUMN_NAME_SYMBOL,
1027 'COLUMNS' => self::COLUMNS_SYMBOL,
1028 'COMMENT' => self::COMMENT_SYMBOL,
1029 'COMMIT' => self::COMMIT_SYMBOL,
1030 'COMMITTED' => self::COMMITTED_SYMBOL,
1031 'COMPACT' => self::COMPACT_SYMBOL,
1032 'COMPLETION' => self::COMPLETION_SYMBOL,
1033 'COMPRESSED' => self::COMPRESSED_SYMBOL,
1034 'COMPRESSION' => self::COMPRESSION_SYMBOL,
1035 'CONCURRENT' => self::CONCURRENT_SYMBOL,
1036 'CONDITION' => self::CONDITION_SYMBOL,
1037 'CONNECTION' => self::CONNECTION_SYMBOL,
1038 'CONSISTENT' => self::CONSISTENT_SYMBOL,
1039 'CONSTRAINT' => self::CONSTRAINT_SYMBOL,
1040 'CONSTRAINT_CATALOG' => self::CONSTRAINT_CATALOG_SYMBOL,
1041 'CONSTRAINT_NAME' => self::CONSTRAINT_NAME_SYMBOL,
1042 'CONSTRAINT_SCHEMA' => self::CONSTRAINT_SCHEMA_SYMBOL,
1043 'CONTAINS' => self::CONTAINS_SYMBOL,
1044 'CONTEXT' => self::CONTEXT_SYMBOL,
1045 'CONTINUE' => self::CONTINUE_SYMBOL,
1046 'CONTRIBUTORS' => self::CONTRIBUTORS_SYMBOL,
1047 'CONVERT' => self::CONVERT_SYMBOL,
1048 'COUNT' => self::COUNT_SYMBOL,
1049 'CPU' => self::CPU_SYMBOL,
1050 'CREATE' => self::CREATE_SYMBOL,
1051 'CROSS' => self::CROSS_SYMBOL,
1052 'CUBE' => self::CUBE_SYMBOL,
1053 'CURDATE' => self::CURDATE_SYMBOL,
1054 'CURRENT' => self::CURRENT_SYMBOL,
1055 'CURRENT_DATE' => self::CURRENT_DATE_SYMBOL,
1056 'CURRENT_TIME' => self::CURRENT_TIME_SYMBOL,
1057 'CURRENT_TIMESTAMP' => self::CURRENT_TIMESTAMP_SYMBOL,
1058 'CURRENT_USER' => self::CURRENT_USER_SYMBOL,
1059 'CURSOR' => self::CURSOR_SYMBOL,
1060 'CURSOR_NAME' => self::CURSOR_NAME_SYMBOL,
1061 'CURTIME' => self::CURTIME_SYMBOL,
1062 'DATA' => self::DATA_SYMBOL,
1063 'DATABASE' => self::DATABASE_SYMBOL,
1064 'DATABASES' => self::DATABASES_SYMBOL,
1065 'DATAFILE' => self::DATAFILE_SYMBOL,
1066 'DATE' => self::DATE_SYMBOL,
1067 'DATE_ADD' => self::DATE_ADD_SYMBOL,
1068 'DATE_SUB' => self::DATE_SUB_SYMBOL,
1069 'DATETIME' => self::DATETIME_SYMBOL,
1070 'DAY' => self::DAY_SYMBOL,
1071 'DAY_HOUR' => self::DAY_HOUR_SYMBOL,
1072 'DAY_MICROSECOND' => self::DAY_MICROSECOND_SYMBOL,
1073 'DAY_MINUTE' => self::DAY_MINUTE_SYMBOL,
1074 'DAY_SECOND' => self::DAY_SECOND_SYMBOL,
1075 'DAYOFMONTH' => self::DAYOFMONTH_SYMBOL,
1076 'DEALLOCATE' => self::DEALLOCATE_SYMBOL,
1077 'DEC' => self::DEC_SYMBOL,
1078 'DECIMAL' => self::DECIMAL_SYMBOL,
1079 'DECIMAL_NUM' => self::DECIMAL_NUM_SYMBOL,
1080 'DECLARE' => self::DECLARE_SYMBOL,
1081 'DEFAULT' => self::DEFAULT_SYMBOL,
1082 'DEFAULT_AUTH' => self::DEFAULT_AUTH_SYMBOL,
1083 'DEFINER' => self::DEFINER_SYMBOL,
1084 'DELAY_KEY_WRITE' => self::DELAY_KEY_WRITE_SYMBOL,
1085 'DELAYED' => self::DELAYED_SYMBOL,
1086 'DELETE' => self::DELETE_SYMBOL,
1087 'DES_KEY_FILE' => self::DES_KEY_FILE_SYMBOL,
1088 'DESC' => self::DESC_SYMBOL,
1089 'DESCRIBE' => self::DESCRIBE_SYMBOL,
1090 'DETERMINISTIC' => self::DETERMINISTIC_SYMBOL,
1091 'DIAGNOSTICS' => self::DIAGNOSTICS_SYMBOL,
1092 'DIRECTORY' => self::DIRECTORY_SYMBOL,
1093 'DISABLE' => self::DISABLE_SYMBOL,
1094 'DISCARD' => self::DISCARD_SYMBOL,
1095 'DISK' => self::DISK_SYMBOL,
1096 'DISTINCT' => self::DISTINCT_SYMBOL,
1097 'DISTINCTROW' => self::DISTINCTROW_SYMBOL,
1098 'DIV' => self::DIV_SYMBOL,
1099 'DO' => self::DO_SYMBOL,
1100 'DOUBLE' => self::DOUBLE_SYMBOL,
1101 'DROP' => self::DROP_SYMBOL,
1102 'DUAL' => self::DUAL_SYMBOL,
1103 'DUMPFILE' => self::DUMPFILE_SYMBOL,
1104 'DUPLICATE' => self::DUPLICATE_SYMBOL,
1105 'DYNAMIC' => self::DYNAMIC_SYMBOL,
1106 'EACH' => self::EACH_SYMBOL,
1107 'ELSE' => self::ELSE_SYMBOL,
1108 'ELSEIF' => self::ELSEIF_SYMBOL,
1109 'ENABLE' => self::ENABLE_SYMBOL,
1110 'ENCLOSED' => self::ENCLOSED_SYMBOL,
1111 'ENCRYPTION' => self::ENCRYPTION_SYMBOL,
1112 'END' => self::END_SYMBOL,
1113 'END_OF_INPUT' => self::EOF,
1114 'ENDS' => self::ENDS_SYMBOL,
1115 'ENGINE' => self::ENGINE_SYMBOL,
1116 'ENGINES' => self::ENGINES_SYMBOL,
1117 'ENUM' => self::ENUM_SYMBOL,
1118 'ERROR' => self::ERROR_SYMBOL,
1119 'ERRORS' => self::ERRORS_SYMBOL,
1120 'ESCAPE' => self::ESCAPE_SYMBOL,
1121 'ESCAPED' => self::ESCAPED_SYMBOL,
1122 'EVENT' => self::EVENT_SYMBOL,
1123 'EVENTS' => self::EVENTS_SYMBOL,
1124 'EVERY' => self::EVERY_SYMBOL,
1125 'EXCHANGE' => self::EXCHANGE_SYMBOL,
1126 'EXECUTE' => self::EXECUTE_SYMBOL,
1127 'EXISTS' => self::EXISTS_SYMBOL,
1128 'EXIT' => self::EXIT_SYMBOL,
1129 'EXPANSION' => self::EXPANSION_SYMBOL,
1130 'EXPIRE' => self::EXPIRE_SYMBOL,
1131 'EXPLAIN' => self::EXPLAIN_SYMBOL,
1132 'EXPORT' => self::EXPORT_SYMBOL,
1133 'EXTENDED' => self::EXTENDED_SYMBOL,
1134 'EXTENT_SIZE' => self::EXTENT_SIZE_SYMBOL,
1135 'EXTRACT' => self::EXTRACT_SYMBOL,
1136 'FALSE' => self::FALSE_SYMBOL,
1137 'FAST' => self::FAST_SYMBOL,
1138 'FAULTS' => self::FAULTS_SYMBOL,
1139 'FETCH' => self::FETCH_SYMBOL,
1140 'FIELDS' => self::FIELDS_SYMBOL,
1141 'FILE' => self::FILE_SYMBOL,
1142 'FILE_BLOCK_SIZE' => self::FILE_BLOCK_SIZE_SYMBOL,
1143 'FILTER' => self::FILTER_SYMBOL,
1144 'FIRST' => self::FIRST_SYMBOL,
1145 'FIXED' => self::FIXED_SYMBOL,
1146 'FLOAT' => self::FLOAT_SYMBOL,
1147 'FLOAT4' => self::FLOAT4_SYMBOL,
1148 'FLOAT8' => self::FLOAT8_SYMBOL,
1149 'FLUSH' => self::FLUSH_SYMBOL,
1150 'FOLLOWS' => self::FOLLOWS_SYMBOL,
1151 'FOR' => self::FOR_SYMBOL,
1152 'FORCE' => self::FORCE_SYMBOL,
1153 'FOREIGN' => self::FOREIGN_SYMBOL,
1154 'FORMAT' => self::FORMAT_SYMBOL,
1155 'FOUND' => self::FOUND_SYMBOL,
1156 'FROM' => self::FROM_SYMBOL,
1157 'FULL' => self::FULL_SYMBOL,
1158 'FULLTEXT' => self::FULLTEXT_SYMBOL,
1159 'FUNCTION' => self::FUNCTION_SYMBOL,
1160 'GENERAL' => self::GENERAL_SYMBOL,
1161 'GENERATED' => self::GENERATED_SYMBOL,
1162 'GEOMCOLLECTION' => self::GEOMCOLLECTION_SYMBOL,
1163 'GEOMETRY' => self::GEOMETRY_SYMBOL,
1164 'GEOMETRYCOLLECTION' => self::GEOMETRYCOLLECTION_SYMBOL,
1165 'GET' => self::GET_SYMBOL,
1166 'GET_FORMAT' => self::GET_FORMAT_SYMBOL,
1167 'GLOBAL' => self::GLOBAL_SYMBOL,
1168 'GRANT' => self::GRANT_SYMBOL,
1169 'GRANTS' => self::GRANTS_SYMBOL,
1170 'GROUP' => self::GROUP_SYMBOL,
1171 'GROUP_CONCAT' => self::GROUP_CONCAT_SYMBOL,
1172 'GROUP_REPLICATION' => self::GROUP_REPLICATION_SYMBOL,
1173 'HANDLER' => self::HANDLER_SYMBOL,
1174 'HASH' => self::HASH_SYMBOL,
1175 'HAVING' => self::HAVING_SYMBOL,
1176 'HELP' => self::HELP_SYMBOL,
1177 'HIGH_PRIORITY' => self::HIGH_PRIORITY_SYMBOL,
1178 'HOST' => self::HOST_SYMBOL,
1179 'HOSTS' => self::HOSTS_SYMBOL,
1180 'HOUR' => self::HOUR_SYMBOL,
1181 'HOUR_MICROSECOND' => self::HOUR_MICROSECOND_SYMBOL,
1182 'HOUR_MINUTE' => self::HOUR_MINUTE_SYMBOL,
1183 'HOUR_SECOND' => self::HOUR_SECOND_SYMBOL,
1184 'IDENTIFIED' => self::IDENTIFIED_SYMBOL,
1185 'IF' => self::IF_SYMBOL,
1186 'IGNORE' => self::IGNORE_SYMBOL,
1187 'IGNORE_SERVER_IDS' => self::IGNORE_SERVER_IDS_SYMBOL,
1188 'IMPORT' => self::IMPORT_SYMBOL,
1189 'IN' => self::IN_SYMBOL,
1190 'INDEX' => self::INDEX_SYMBOL,
1191 'INDEXES' => self::INDEXES_SYMBOL,
1192 'INFILE' => self::INFILE_SYMBOL,
1193 'INITIAL_SIZE' => self::INITIAL_SIZE_SYMBOL,
1194 'INNER' => self::INNER_SYMBOL,
1195 'INNODB' => self::INNODB_SYMBOL,
1196 'INOUT' => self::INOUT_SYMBOL,
1197 'INSENSITIVE' => self::INSENSITIVE_SYMBOL,
1198 'INSERT' => self::INSERT_SYMBOL,
1199 'INSERT_METHOD' => self::INSERT_METHOD_SYMBOL,
1200 'INSTALL' => self::INSTALL_SYMBOL,
1201 'INSTANCE' => self::INSTANCE_SYMBOL,
1202 'INT' => self::INT_SYMBOL,
1203 'INT1' => self::INT1_SYMBOL,
1204 'INT2' => self::INT2_SYMBOL,
1205 'INT3' => self::INT3_SYMBOL,
1206 'INT4' => self::INT4_SYMBOL,
1207 'INT8' => self::INT8_SYMBOL,
1208 'INTEGER' => self::INTEGER_SYMBOL,
1209 'INTERVAL' => self::INTERVAL_SYMBOL,
1210 'INTO' => self::INTO_SYMBOL,
1211 'INVOKER' => self::INVOKER_SYMBOL,
1212 'IO' => self::IO_SYMBOL,
1213 'IO_AFTER_GTIDS' => self::IO_AFTER_GTIDS_SYMBOL,
1214 'IO_BEFORE_GTIDS' => self::IO_BEFORE_GTIDS_SYMBOL,
1215 'IO_THREAD' => self::IO_THREAD_SYMBOL,
1216 'IPC' => self::IPC_SYMBOL,
1217 'IS' => self::IS_SYMBOL,
1218 'ISOLATION' => self::ISOLATION_SYMBOL,
1219 'ISSUER' => self::ISSUER_SYMBOL,
1220 'ITERATE' => self::ITERATE_SYMBOL,
1221 'JOIN' => self::JOIN_SYMBOL,
1222 'JSON' => self::JSON_SYMBOL,
1223 'KEY' => self::KEY_SYMBOL,
1224 'KEY_BLOCK_SIZE' => self::KEY_BLOCK_SIZE_SYMBOL,
1225 'KEYS' => self::KEYS_SYMBOL,
1226 'KILL' => self::KILL_SYMBOL,
1227 'LANGUAGE' => self::LANGUAGE_SYMBOL,
1228 'LAST' => self::LAST_SYMBOL,
1229 'LEADING' => self::LEADING_SYMBOL,
1230 'LEAVE' => self::LEAVE_SYMBOL,
1231 'LEAVES' => self::LEAVES_SYMBOL,
1232 'LEFT' => self::LEFT_SYMBOL,
1233 'LESS' => self::LESS_SYMBOL,
1234 'LEVEL' => self::LEVEL_SYMBOL,
1235 'LIKE' => self::LIKE_SYMBOL,
1236 'LIMIT' => self::LIMIT_SYMBOL,
1237 'LINEAR' => self::LINEAR_SYMBOL,
1238 'LINES' => self::LINES_SYMBOL,
1239 'LINESTRING' => self::LINESTRING_SYMBOL,
1240 'LIST' => self::LIST_SYMBOL,
1241 'LOAD' => self::LOAD_SYMBOL,
1242 'LOCAL' => self::LOCAL_SYMBOL,
1243 'LOCALTIME' => self::LOCALTIME_SYMBOL,
1244 'LOCALTIMESTAMP' => self::LOCALTIMESTAMP_SYMBOL,
1245 'LOCATOR' => self::LOCATOR_SYMBOL,
1246 'LOCK' => self::LOCK_SYMBOL,
1247 'LOCKS' => self::LOCKS_SYMBOL,
1248 'LOGFILE' => self::LOGFILE_SYMBOL,
1249 'LOGS' => self::LOGS_SYMBOL,
1250 'LONG' => self::LONG_SYMBOL,
1251 'LONG_NUM' => self::LONG_NUM_SYMBOL,
1252 'LONGBLOB' => self::LONGBLOB_SYMBOL,
1253 'LONGTEXT' => self::LONGTEXT_SYMBOL,
1254 'LOOP' => self::LOOP_SYMBOL,
1255 'LOW_PRIORITY' => self::LOW_PRIORITY_SYMBOL,
1256 'MASTER' => self::MASTER_SYMBOL,
1257 'MASTER_AUTO_POSITION' => self::MASTER_AUTO_POSITION_SYMBOL,
1258 'MASTER_BIND' => self::MASTER_BIND_SYMBOL,
1259 'MASTER_CONNECT_RETRY' => self::MASTER_CONNECT_RETRY_SYMBOL,
1260 'MASTER_DELAY' => self::MASTER_DELAY_SYMBOL,
1261 'MASTER_HEARTBEAT_PERIOD' => self::MASTER_HEARTBEAT_PERIOD_SYMBOL,
1262 'MASTER_HOST' => self::MASTER_HOST_SYMBOL,
1263 'MASTER_LOG_FILE' => self::MASTER_LOG_FILE_SYMBOL,
1264 'MASTER_LOG_POS' => self::MASTER_LOG_POS_SYMBOL,
1265 'MASTER_PASSWORD' => self::MASTER_PASSWORD_SYMBOL,
1266 'MASTER_PORT' => self::MASTER_PORT_SYMBOL,
1267 'MASTER_RETRY_COUNT' => self::MASTER_RETRY_COUNT_SYMBOL,
1268 'MASTER_SERVER_ID' => self::MASTER_SERVER_ID_SYMBOL,
1269 'MASTER_SSL' => self::MASTER_SSL_SYMBOL,
1270 'MASTER_SSL_CA' => self::MASTER_SSL_CA_SYMBOL,
1271 'MASTER_SSL_CAPATH' => self::MASTER_SSL_CAPATH_SYMBOL,
1272 'MASTER_SSL_CERT' => self::MASTER_SSL_CERT_SYMBOL,
1273 'MASTER_SSL_CIPHER' => self::MASTER_SSL_CIPHER_SYMBOL,
1274 'MASTER_SSL_CRL' => self::MASTER_SSL_CRL_SYMBOL,
1275 'MASTER_SSL_CRLPATH' => self::MASTER_SSL_CRLPATH_SYMBOL,
1276 'MASTER_SSL_KEY' => self::MASTER_SSL_KEY_SYMBOL,
1277 'MASTER_SSL_VERIFY_SERVER_CERT' => self::MASTER_SSL_VERIFY_SERVER_CERT_SYMBOL,
1278 'MASTER_TLS_VERSION' => self::MASTER_TLS_VERSION_SYMBOL,
1279 'MASTER_USER' => self::MASTER_USER_SYMBOL,
1280 'MATCH' => self::MATCH_SYMBOL,
1281 'MAX' => self::MAX_SYMBOL,
1282 'MAX_CONNECTIONS_PER_HOUR' => self::MAX_CONNECTIONS_PER_HOUR_SYMBOL,
1283 'MAX_QUERIES_PER_HOUR' => self::MAX_QUERIES_PER_HOUR_SYMBOL,
1284 'MAX_ROWS' => self::MAX_ROWS_SYMBOL,
1285 'MAX_SIZE' => self::MAX_SIZE_SYMBOL,
1286 'MAX_STATEMENT_TIME' => self::MAX_STATEMENT_TIME_SYMBOL,
1287 'MAX_UPDATES_PER_HOUR' => self::MAX_UPDATES_PER_HOUR_SYMBOL,
1288 'MAX_USER_CONNECTIONS' => self::MAX_USER_CONNECTIONS_SYMBOL,
1289 'MAXVALUE' => self::MAXVALUE_SYMBOL,
1290 'MEDIUM' => self::MEDIUM_SYMBOL,
1291 'MEDIUMBLOB' => self::MEDIUMBLOB_SYMBOL,
1292 'MEDIUMINT' => self::MEDIUMINT_SYMBOL,
1293 'MEDIUMTEXT' => self::MEDIUMTEXT_SYMBOL,
1294 'MEMORY' => self::MEMORY_SYMBOL,
1295 'MERGE' => self::MERGE_SYMBOL,
1296 'MESSAGE_TEXT' => self::MESSAGE_TEXT_SYMBOL,
1297 'MICROSECOND' => self::MICROSECOND_SYMBOL,
1298 'MID' => self::MID_SYMBOL,
1299 'MIDDLEINT' => self::MIDDLEINT_SYMBOL,
1300 'MIGRATE' => self::MIGRATE_SYMBOL,
1301 'MIN' => self::MIN_SYMBOL,
1302 'MIN_ROWS' => self::MIN_ROWS_SYMBOL,
1303 'MINUTE' => self::MINUTE_SYMBOL,
1304 'MINUTE_MICROSECOND' => self::MINUTE_MICROSECOND_SYMBOL,
1305 'MINUTE_SECOND' => self::MINUTE_SECOND_SYMBOL,
1306 'MOD' => self::MOD_SYMBOL,
1307 'MODE' => self::MODE_SYMBOL,
1308 'MODIFIES' => self::MODIFIES_SYMBOL,
1309 'MODIFY' => self::MODIFY_SYMBOL,
1310 'MONTH' => self::MONTH_SYMBOL,
1311 'MULTILINESTRING' => self::MULTILINESTRING_SYMBOL,
1312 'MULTIPOINT' => self::MULTIPOINT_SYMBOL,
1313 'MULTIPOLYGON' => self::MULTIPOLYGON_SYMBOL,
1314 'MUTEX' => self::MUTEX_SYMBOL,
1315 'MYSQL_ERRNO' => self::MYSQL_ERRNO_SYMBOL,
1316 'NAME' => self::NAME_SYMBOL,
1317 'NAMES' => self::NAMES_SYMBOL,
1318 'NATIONAL' => self::NATIONAL_SYMBOL,
1319 'NATURAL' => self::NATURAL_SYMBOL,
1320 'NCHAR' => self::NCHAR_SYMBOL,
1321 'NCHAR_STRING' => self::NCHAR_STRING_SYMBOL,
1322 'NDB' => self::NDB_SYMBOL,
1323 'NDBCLUSTER' => self::NDBCLUSTER_SYMBOL,
1324 'NEG' => self::NEG_SYMBOL,
1325 'NEVER' => self::NEVER_SYMBOL,
1326 'NEW' => self::NEW_SYMBOL,
1327 'NEXT' => self::NEXT_SYMBOL,
1328 'NO' => self::NO_SYMBOL,
1329 'NO_WAIT' => self::NO_WAIT_SYMBOL,
1330 'NO_WRITE_TO_BINLOG' => self::NO_WRITE_TO_BINLOG_SYMBOL,
1331 'NODEGROUP' => self::NODEGROUP_SYMBOL,
1332 'NONBLOCKING' => self::NONBLOCKING_SYMBOL,
1333 'NONE' => self::NONE_SYMBOL,
1334 'NOT' => self::NOT_SYMBOL,
1335 'NOW' => self::NOW_SYMBOL,
1336 'NULL' => self::NULL_SYMBOL,
1337 'NUMBER' => self::NUMBER_SYMBOL,
1338 'NUMERIC' => self::NUMERIC_SYMBOL,
1339 'NVARCHAR' => self::NVARCHAR_SYMBOL,
1340 'OFFLINE' => self::OFFLINE_SYMBOL,
1341 'OFFSET' => self::OFFSET_SYMBOL,
1342 'OLD_PASSWORD' => self::OLD_PASSWORD_SYMBOL,
1343 'ON' => self::ON_SYMBOL,
1344 'ONE' => self::ONE_SYMBOL,
1345 'ONLINE' => self::ONLINE_SYMBOL,
1346 'ONLY' => self::ONLY_SYMBOL,
1347 'OPEN' => self::OPEN_SYMBOL,
1348 'OPTIMIZE' => self::OPTIMIZE_SYMBOL,
1349 'OPTIMIZER_COSTS' => self::OPTIMIZER_COSTS_SYMBOL,
1350 'OPTION' => self::OPTION_SYMBOL,
1351 'OPTIONALLY' => self::OPTIONALLY_SYMBOL,
1352 'OPTIONS' => self::OPTIONS_SYMBOL,
1353 'OR' => self::OR_SYMBOL,
1354 'ORDER' => self::ORDER_SYMBOL,
1355 'OUT' => self::OUT_SYMBOL,
1356 'OUTER' => self::OUTER_SYMBOL,
1357 'OUTFILE' => self::OUTFILE_SYMBOL,
1358 'OWNER' => self::OWNER_SYMBOL,
1359 'PACK_KEYS' => self::PACK_KEYS_SYMBOL,
1360 'PAGE' => self::PAGE_SYMBOL,
1361 'PARSER' => self::PARSER_SYMBOL,
1362 'PARTIAL' => self::PARTIAL_SYMBOL,
1363 'PARTITION' => self::PARTITION_SYMBOL,
1364 'PARTITIONING' => self::PARTITIONING_SYMBOL,
1365 'PARTITIONS' => self::PARTITIONS_SYMBOL,
1366 'PASSWORD' => self::PASSWORD_SYMBOL,
1367 'PHASE' => self::PHASE_SYMBOL,
1368 'PLUGIN' => self::PLUGIN_SYMBOL,
1369 'PLUGIN_DIR' => self::PLUGIN_DIR_SYMBOL,
1370 'PLUGINS' => self::PLUGINS_SYMBOL,
1371 'POINT' => self::POINT_SYMBOL,
1372 'POLYGON' => self::POLYGON_SYMBOL,
1373 'PORT' => self::PORT_SYMBOL,
1374 'POSITION' => self::POSITION_SYMBOL,
1375 'PRECEDES' => self::PRECEDES_SYMBOL,
1376 'PRECISION' => self::PRECISION_SYMBOL,
1377 'PREPARE' => self::PREPARE_SYMBOL,
1378 'PRESERVE' => self::PRESERVE_SYMBOL,
1379 'PREV' => self::PREV_SYMBOL,
1380 'PRIMARY' => self::PRIMARY_SYMBOL,
1381 'PRIVILEGES' => self::PRIVILEGES_SYMBOL,
1382 'PROCEDURE' => self::PROCEDURE_SYMBOL,
1383 'PROCESS' => self::PROCESS_SYMBOL,
1384 'PROCESSLIST' => self::PROCESSLIST_SYMBOL,
1385 'PROFILE' => self::PROFILE_SYMBOL,
1386 'PROFILES' => self::PROFILES_SYMBOL,
1387 'PROXY' => self::PROXY_SYMBOL,
1388 'PURGE' => self::PURGE_SYMBOL,
1389 'QUARTER' => self::QUARTER_SYMBOL,
1390 'QUERY' => self::QUERY_SYMBOL,
1391 'QUICK' => self::QUICK_SYMBOL,
1392 'RANGE' => self::RANGE_SYMBOL,
1393 'READ' => self::READ_SYMBOL,
1394 'READ_ONLY' => self::READ_ONLY_SYMBOL,
1395 'READ_WRITE' => self::READ_WRITE_SYMBOL,
1396 'READS' => self::READS_SYMBOL,
1397 'REAL' => self::REAL_SYMBOL,
1398 'REBUILD' => self::REBUILD_SYMBOL,
1399 'RECOVER' => self::RECOVER_SYMBOL,
1400 'REDO_BUFFER_SIZE' => self::REDO_BUFFER_SIZE_SYMBOL,
1401 'REDOFILE' => self::REDOFILE_SYMBOL,
1402 'REDUNDANT' => self::REDUNDANT_SYMBOL,
1403 'REFERENCES' => self::REFERENCES_SYMBOL,
1404 'REGEXP' => self::REGEXP_SYMBOL,
1405 'RELAY' => self::RELAY_SYMBOL,
1406 'RELAY_LOG_FILE' => self::RELAY_LOG_FILE_SYMBOL,
1407 'RELAY_LOG_POS' => self::RELAY_LOG_POS_SYMBOL,
1408 'RELAY_THREAD' => self::RELAY_THREAD_SYMBOL,
1409 'RELAYLOG' => self::RELAYLOG_SYMBOL,
1410 'RELEASE' => self::RELEASE_SYMBOL,
1411 'RELOAD' => self::RELOAD_SYMBOL,
1412 'REMOVE' => self::REMOVE_SYMBOL,
1413 'RENAME' => self::RENAME_SYMBOL,
1414 'REORGANIZE' => self::REORGANIZE_SYMBOL,
1415 'REPAIR' => self::REPAIR_SYMBOL,
1416 'REPEAT' => self::REPEAT_SYMBOL,
1417 'REPEATABLE' => self::REPEATABLE_SYMBOL,
1418 'REPLACE' => self::REPLACE_SYMBOL,
1419 'REPLICATE_DO_DB' => self::REPLICATE_DO_DB_SYMBOL,
1420 'REPLICATE_DO_TABLE' => self::REPLICATE_DO_TABLE_SYMBOL,
1421 'REPLICATE_IGNORE_DB' => self::REPLICATE_IGNORE_DB_SYMBOL,
1422 'REPLICATE_IGNORE_TABLE' => self::REPLICATE_IGNORE_TABLE_SYMBOL,
1423 'REPLICATE_REWRITE_DB' => self::REPLICATE_REWRITE_DB_SYMBOL,
1424 'REPLICATE_WILD_DO_TABLE' => self::REPLICATE_WILD_DO_TABLE_SYMBOL,
1425 'REPLICATE_WILD_IGNORE_TABLE' => self::REPLICATE_WILD_IGNORE_TABLE_SYMBOL,
1426 'REPLICATION' => self::REPLICATION_SYMBOL,
1427 'REQUIRE' => self::REQUIRE_SYMBOL,
1428 'RESET' => self::RESET_SYMBOL,
1429 'RESIGNAL' => self::RESIGNAL_SYMBOL,
1430 'RESTORE' => self::RESTORE_SYMBOL,
1431 'RESTRICT' => self::RESTRICT_SYMBOL,
1432 'RESUME' => self::RESUME_SYMBOL,
1433 'RETURN' => self::RETURN_SYMBOL,
1434 'RETURNED_SQLSTATE' => self::RETURNED_SQLSTATE_SYMBOL,
1435 'RETURNS' => self::RETURNS_SYMBOL,
1436 'REVERSE' => self::REVERSE_SYMBOL,
1437 'REVOKE' => self::REVOKE_SYMBOL,
1438 'RIGHT' => self::RIGHT_SYMBOL,
1439 'RLIKE' => self::RLIKE_SYMBOL,
1440 'ROLLBACK' => self::ROLLBACK_SYMBOL,
1441 'ROLLUP' => self::ROLLUP_SYMBOL,
1442 'ROTATE' => self::ROTATE_SYMBOL,
1443 'ROUTINE' => self::ROUTINE_SYMBOL,
1444 'ROW' => self::ROW_SYMBOL,
1445 'ROW_COUNT' => self::ROW_COUNT_SYMBOL,
1446 'ROW_FORMAT' => self::ROW_FORMAT_SYMBOL,
1447 'ROWS' => self::ROWS_SYMBOL,
1448 'RTREE' => self::RTREE_SYMBOL,
1449 'SAVEPOINT' => self::SAVEPOINT_SYMBOL,
1450 'SCHEDULE' => self::SCHEDULE_SYMBOL,
1451 'SCHEMA' => self::SCHEMA_SYMBOL,
1452 'SCHEMA_NAME' => self::SCHEMA_NAME_SYMBOL,
1453 'SCHEMAS' => self::SCHEMAS_SYMBOL,
1454 'SECOND' => self::SECOND_SYMBOL,
1455 'SECOND_MICROSECOND' => self::SECOND_MICROSECOND_SYMBOL,
1456 'SECURITY' => self::SECURITY_SYMBOL,
1457 'SELECT' => self::SELECT_SYMBOL,
1458 'SENSITIVE' => self::SENSITIVE_SYMBOL,
1459 'SEPARATOR' => self::SEPARATOR_SYMBOL,
1460 'SERIAL' => self::SERIAL_SYMBOL,
1461 'SERIALIZABLE' => self::SERIALIZABLE_SYMBOL,
1462 'SERVER' => self::SERVER_SYMBOL,
1463 'SERVER_OPTIONS' => self::SERVER_OPTIONS_SYMBOL,
1464 'SESSION' => self::SESSION_SYMBOL,
1465 'SESSION_USER' => self::SESSION_USER_SYMBOL,
1466 'SET' => self::SET_SYMBOL,
1467 'SET_VAR' => self::SET_VAR_SYMBOL,
1468 'SHARE' => self::SHARE_SYMBOL,
1469 'SHOW' => self::SHOW_SYMBOL,
1470 'SHUTDOWN' => self::SHUTDOWN_SYMBOL,
1471 'SIGNAL' => self::SIGNAL_SYMBOL,
1472 'SIGNED' => self::SIGNED_SYMBOL,
1473 'SIMPLE' => self::SIMPLE_SYMBOL,
1474 'SLAVE' => self::SLAVE_SYMBOL,
1475 'SLOW' => self::SLOW_SYMBOL,
1476 'SMALLINT' => self::SMALLINT_SYMBOL,
1477 'SNAPSHOT' => self::SNAPSHOT_SYMBOL,
1478 'SOCKET' => self::SOCKET_SYMBOL,
1479 'SOME' => self::SOME_SYMBOL,
1480 'SONAME' => self::SONAME_SYMBOL,
1481 'SOUNDS' => self::SOUNDS_SYMBOL,
1482 'SOURCE' => self::SOURCE_SYMBOL,
1483 'SPATIAL' => self::SPATIAL_SYMBOL,
1484 'SPECIFIC' => self::SPECIFIC_SYMBOL,
1485 'SQL' => self::SQL_SYMBOL,
1486 'SQL_AFTER_GTIDS' => self::SQL_AFTER_GTIDS_SYMBOL,
1487 'SQL_AFTER_MTS_GAPS' => self::SQL_AFTER_MTS_GAPS_SYMBOL,
1488 'SQL_BEFORE_GTIDS' => self::SQL_BEFORE_GTIDS_SYMBOL,
1489 'SQL_BIG_RESULT' => self::SQL_BIG_RESULT_SYMBOL,
1490 'SQL_BUFFER_RESULT' => self::SQL_BUFFER_RESULT_SYMBOL,
1491 'SQL_CACHE' => self::SQL_CACHE_SYMBOL,
1492 'SQL_CALC_FOUND_ROWS' => self::SQL_CALC_FOUND_ROWS_SYMBOL,
1493 'SQL_NO_CACHE' => self::SQL_NO_CACHE_SYMBOL,
1494 'SQL_SMALL_RESULT' => self::SQL_SMALL_RESULT_SYMBOL,
1495 'SQL_THREAD' => self::SQL_THREAD_SYMBOL,
1496 'SQL_TSI_DAY' => self::SQL_TSI_DAY_SYMBOL,
1497 'SQL_TSI_HOUR' => self::SQL_TSI_HOUR_SYMBOL,
1498 'SQL_TSI_MICROSECOND' => self::SQL_TSI_MICROSECOND_SYMBOL,
1499 'SQL_TSI_MINUTE' => self::SQL_TSI_MINUTE_SYMBOL,
1500 'SQL_TSI_MONTH' => self::SQL_TSI_MONTH_SYMBOL,
1501 'SQL_TSI_QUARTER' => self::SQL_TSI_QUARTER_SYMBOL,
1502 'SQL_TSI_SECOND' => self::SQL_TSI_SECOND_SYMBOL,
1503 'SQL_TSI_WEEK' => self::SQL_TSI_WEEK_SYMBOL,
1504 'SQL_TSI_YEAR' => self::SQL_TSI_YEAR_SYMBOL,
1505 'SQLEXCEPTION' => self::SQLEXCEPTION_SYMBOL,
1506 'SQLSTATE' => self::SQLSTATE_SYMBOL,
1507 'SQLWARNING' => self::SQLWARNING_SYMBOL,
1508 'SSL' => self::SSL_SYMBOL,
1509 'STACKED' => self::STACKED_SYMBOL,
1510 'START' => self::START_SYMBOL,
1511 'STARTING' => self::STARTING_SYMBOL,
1512 'STARTS' => self::STARTS_SYMBOL,
1513 'STATS_AUTO_RECALC' => self::STATS_AUTO_RECALC_SYMBOL,
1514 'STATS_PERSISTENT' => self::STATS_PERSISTENT_SYMBOL,
1515 'STATS_SAMPLE_PAGES' => self::STATS_SAMPLE_PAGES_SYMBOL,
1516 'STATUS' => self::STATUS_SYMBOL,
1517 'STD' => self::STD_SYMBOL,
1518 'STDDEV' => self::STDDEV_SYMBOL,
1519 'STDDEV_POP' => self::STDDEV_POP_SYMBOL,
1520 'STDDEV_SAMP' => self::STDDEV_SAMP_SYMBOL,
1521 'STOP' => self::STOP_SYMBOL,
1522 'STORAGE' => self::STORAGE_SYMBOL,
1523 'STORED' => self::STORED_SYMBOL,
1524 'STRAIGHT_JOIN' => self::STRAIGHT_JOIN_SYMBOL,
1525 'STRING' => self::STRING_SYMBOL,
1526 'SUBCLASS_ORIGIN' => self::SUBCLASS_ORIGIN_SYMBOL,
1527 'SUBDATE' => self::SUBDATE_SYMBOL,
1528 'SUBJECT' => self::SUBJECT_SYMBOL,
1529 'SUBPARTITION' => self::SUBPARTITION_SYMBOL,
1530 'SUBPARTITIONS' => self::SUBPARTITIONS_SYMBOL,
1531 'SUBSTR' => self::SUBSTR_SYMBOL,
1532 'SUBSTRING' => self::SUBSTRING_SYMBOL,
1533 'SUM' => self::SUM_SYMBOL,
1534 'SUPER' => self::SUPER_SYMBOL,
1535 'SUSPEND' => self::SUSPEND_SYMBOL,
1536 'SWAPS' => self::SWAPS_SYMBOL,
1537 'SWITCHES' => self::SWITCHES_SYMBOL,
1538 'SYSDATE' => self::SYSDATE_SYMBOL,
1539 'SYSTEM_USER' => self::SYSTEM_USER_SYMBOL,
1540 'TABLE' => self::TABLE_SYMBOL,
1541 'TABLE_CHECKSUM' => self::TABLE_CHECKSUM_SYMBOL,
1542 'TABLE_NAME' => self::TABLE_NAME_SYMBOL,
1543 'TABLE_REF_PRIORITY' => self::TABLE_REF_PRIORITY_SYMBOL,
1544 'TABLES' => self::TABLES_SYMBOL,
1545 'TABLESPACE' => self::TABLESPACE_SYMBOL,
1546 'TEMPORARY' => self::TEMPORARY_SYMBOL,
1547 'TEMPTABLE' => self::TEMPTABLE_SYMBOL,
1548 'TERMINATED' => self::TERMINATED_SYMBOL,
1549 'TEXT' => self::TEXT_SYMBOL,
1550 'THAN' => self::THAN_SYMBOL,
1551 'THEN' => self::THEN_SYMBOL,
1552 'TIME' => self::TIME_SYMBOL,
1553 'TIMESTAMP' => self::TIMESTAMP_SYMBOL,
1554 'TIMESTAMP_ADD' => self::TIMESTAMP_ADD_SYMBOL,
1555 'TIMESTAMP_DIFF' => self::TIMESTAMP_DIFF_SYMBOL,
1556 'TINYBLOB' => self::TINYBLOB_SYMBOL,
1557 'TINYINT' => self::TINYINT_SYMBOL,
1558 'TINYTEXT' => self::TINYTEXT_SYMBOL,
1559 'TO' => self::TO_SYMBOL,
1560 'TRAILING' => self::TRAILING_SYMBOL,
1561 'TRANSACTION' => self::TRANSACTION_SYMBOL,
1562 'TRIGGER' => self::TRIGGER_SYMBOL,
1563 'TRIGGERS' => self::TRIGGERS_SYMBOL,
1564 'TRIM' => self::TRIM_SYMBOL,
1565 'TRUE' => self::TRUE_SYMBOL,
1566 'TRUNCATE' => self::TRUNCATE_SYMBOL,
1567 'TYPE' => self::TYPE_SYMBOL,
1568 'TYPES' => self::TYPES_SYMBOL,
1569 'UDF_RETURNS' => self::UDF_RETURNS_SYMBOL,
1570 'UNCOMMITTED' => self::UNCOMMITTED_SYMBOL,
1571 'UNDEFINED' => self::UNDEFINED_SYMBOL,
1572 'UNDO' => self::UNDO_SYMBOL,
1573 'UNDO_BUFFER_SIZE' => self::UNDO_BUFFER_SIZE_SYMBOL,
1574 'UNDOFILE' => self::UNDOFILE_SYMBOL,
1575 'UNICODE' => self::UNICODE_SYMBOL,
1576 'UNINSTALL' => self::UNINSTALL_SYMBOL,
1577 'UNION' => self::UNION_SYMBOL,
1578 'UNIQUE' => self::UNIQUE_SYMBOL,
1579 'UNKNOWN' => self::UNKNOWN_SYMBOL,
1580 'UNLOCK' => self::UNLOCK_SYMBOL,
1581 'UNSIGNED' => self::UNSIGNED_SYMBOL,
1582 'UNTIL' => self::UNTIL_SYMBOL,
1583 'UPDATE' => self::UPDATE_SYMBOL,
1584 'UPGRADE' => self::UPGRADE_SYMBOL,
1585 'USAGE' => self::USAGE_SYMBOL,
1586 'USE' => self::USE_SYMBOL,
1587 'USE_FRM' => self::USE_FRM_SYMBOL,
1588 'USER' => self::USER_SYMBOL,
1589 'USER_RESOURCES' => self::USER_RESOURCES_SYMBOL,
1590 'USING' => self::USING_SYMBOL,
1591 'UTC_DATE' => self::UTC_DATE_SYMBOL,
1592 'UTC_TIME' => self::UTC_TIME_SYMBOL,
1593 'UTC_TIMESTAMP' => self::UTC_TIMESTAMP_SYMBOL,
1594 'VALIDATION' => self::VALIDATION_SYMBOL,
1595 'VALUE' => self::VALUE_SYMBOL,
1596 'VALUES' => self::VALUES_SYMBOL,
1597 'VAR_POP' => self::VAR_POP_SYMBOL,
1598 'VAR_SAMP' => self::VAR_SAMP_SYMBOL,
1599 'VARBINARY' => self::VARBINARY_SYMBOL,
1600 'VARCHAR' => self::VARCHAR_SYMBOL,
1601 'VARCHARACTER' => self::VARCHARACTER_SYMBOL,
1602 'VARIABLES' => self::VARIABLES_SYMBOL,
1603 'VARIANCE' => self::VARIANCE_SYMBOL,
1604 'VARYING' => self::VARYING_SYMBOL,
1605 'VIEW' => self::VIEW_SYMBOL,
1606 'VIRTUAL' => self::VIRTUAL_SYMBOL,
1607 'WAIT' => self::WAIT_SYMBOL,
1608 'WARNINGS' => self::WARNINGS_SYMBOL,
1609 'WEEK' => self::WEEK_SYMBOL,
1610 'WEIGHT_STRING' => self::WEIGHT_STRING_SYMBOL,
1611 'WHEN' => self::WHEN_SYMBOL,
1612 'WHERE' => self::WHERE_SYMBOL,
1613 'WHILE' => self::WHILE_SYMBOL,
1614 'WITH' => self::WITH_SYMBOL,
1615 'WITHOUT' => self::WITHOUT_SYMBOL,
1616 'WORK' => self::WORK_SYMBOL,
1617 'WRAPPER' => self::WRAPPER_SYMBOL,
1618 'WRITE' => self::WRITE_SYMBOL,
1619 'X509' => self::X509_SYMBOL,
1620 'XA' => self::XA_SYMBOL,
1621 'XID' => self::XID_SYMBOL,
1622 'XML' => self::XML_SYMBOL,
1623 'XOR' => self::XOR_SYMBOL,
1624 'YEAR' => self::YEAR_SYMBOL,
1625 'YEAR_MONTH' => self::YEAR_MONTH_SYMBOL,
1626 'ZEROFILL' => self::ZEROFILL_SYMBOL,
1627
1628 // Tokens from MySQL 8.0:
1629 'ACTIVE' => self::ACTIVE_SYMBOL,
1630 'ADMIN' => self::ADMIN_SYMBOL,
1631 'ARRAY' => self::ARRAY_SYMBOL,
1632 'ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS' => self::ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS_SYMBOL,
1633 'BUCKETS' => self::BUCKETS_SYMBOL,
1634 'CLONE' => self::CLONE_SYMBOL,
1635 'COMPONENT' => self::COMPONENT_SYMBOL,
1636 'CUME_DIST' => self::CUME_DIST_SYMBOL,
1637 'DEFINITION' => self::DEFINITION_SYMBOL,
1638 'DENSE_RANK' => self::DENSE_RANK_SYMBOL,
1639 'DESCRIPTION' => self::DESCRIPTION_SYMBOL,
1640 'EMPTY' => self::EMPTY_SYMBOL,
1641 'ENFORCED' => self::ENFORCED_SYMBOL,
1642 'ENGINE_ATTRIBUTE' => self::ENGINE_ATTRIBUTE_SYMBOL,
1643 'EXCEPT' => self::EXCEPT_SYMBOL,
1644 'EXCLUDE' => self::EXCLUDE_SYMBOL,
1645 'FAILED_LOGIN_ATTEMPTS' => self::FAILED_LOGIN_ATTEMPTS_SYMBOL,
1646 'FIRST_VALUE' => self::FIRST_VALUE_SYMBOL,
1647 'FOLLOWING' => self::FOLLOWING_SYMBOL,
1648 'GET_MASTER_PUBLIC_KEY_SYM' => self::GET_MASTER_PUBLIC_KEY_SYMBOL,
1649 'GET_SOURCE_PUBLIC_KEY' => self::GET_SOURCE_PUBLIC_KEY_SYMBOL,
1650 'GROUPING' => self::GROUPING_SYMBOL,
1651 'GROUPS' => self::GROUPS_SYMBOL,
1652 'GTID_ONLY' => self::GTID_ONLY_SYMBOL,
1653 'HISTOGRAM' => self::HISTOGRAM_SYMBOL,
1654 'HISTORY' => self::HISTORY_SYMBOL,
1655 'INACTIVE' => self::INACTIVE_SYMBOL,
1656 'INTERSECT' => self::INTERSECT_SYMBOL,
1657 'INVISIBLE' => self::INVISIBLE_SYMBOL,
1658 'JSON_ARRAYAGG' => self::JSON_ARRAYAGG_SYMBOL,
1659 'JSON_OBJECTAGG' => self::JSON_OBJECTAGG_SYMBOL,
1660 'JSON_TABLE' => self::JSON_TABLE_SYMBOL,
1661 'JSON_VALUE' => self::JSON_VALUE_SYMBOL,
1662 'KEYRING' => self::KEYRING_SYMBOL,
1663 'LAG' => self::LAG_SYMBOL,
1664 'LAST_VALUE' => self::LAST_VALUE_SYMBOL,
1665 'LATERAL' => self::LATERAL_SYMBOL,
1666 'LEAD' => self::LEAD_SYMBOL,
1667 'LOCKED' => self::LOCKED_SYMBOL,
1668 'MASTER_COMPRESSION_ALGORITHM' => self::MASTER_COMPRESSION_ALGORITHM_SYMBOL,
1669 'MASTER_PUBLIC_KEY_PATH' => self::MASTER_PUBLIC_KEY_PATH_SYMBOL,
1670 'MASTER_TLS_CIPHERSUITES' => self::MASTER_TLS_CIPHERSUITES_SYMBOL,
1671 'MASTER_ZSTD_COMPRESSION_LEVEL' => self::MASTER_ZSTD_COMPRESSION_LEVEL_SYMBOL,
1672 'MEMBER' => self::MEMBER_SYMBOL,
1673 'NESTED' => self::NESTED_SYMBOL,
1674 'NETWORK_NAMESPACE' => self::NETWORK_NAMESPACE_SYMBOL,
1675 'NOWAIT' => self::NOWAIT_SYMBOL,
1676 'NTH_VALUE' => self::NTH_VALUE_SYMBOL,
1677 'NTILE' => self::NTILE_SYMBOL,
1678 'NULLS' => self::NULLS_SYMBOL,
1679 'OF' => self::OF_SYMBOL,
1680 'OFF' => self::OFF_SYMBOL,
1681 'OJ' => self::OJ_SYMBOL,
1682 'OLD' => self::OLD_SYMBOL,
1683 'OPTIONAL' => self::OPTIONAL_SYMBOL,
1684 'ORDINALITY' => self::ORDINALITY_SYMBOL,
1685 'ORGANIZATION' => self::ORGANIZATION_SYMBOL,
1686 'OTHERS' => self::OTHERS_SYMBOL,
1687 'OVER' => self::OVER_SYMBOL,
1688 'PASSWORD_LOCK_TIME' => self::PASSWORD_LOCK_TIME_SYMBOL,
1689 'PATH' => self::PATH_SYMBOL,
1690 'PERCENT_RANK' => self::PERCENT_RANK_SYMBOL,
1691 'PERSIST' => self::PERSIST_SYMBOL,
1692 'PERSIST_ONLY' => self::PERSIST_ONLY_SYMBOL,
1693 'PRECEDING' => self::PRECEDING_SYMBOL,
1694 'PRIVILEGE_CHECKS_USER' => self::PRIVILEGE_CHECKS_USER_SYMBOL,
1695 'RANDOM' => self::RANDOM_SYMBOL,
1696 'RANK' => self::RANK_SYMBOL,
1697 'RECURSIVE' => self::RECURSIVE_SYMBOL,
1698 'REDO_LOG' => self::REDO_LOG_SYMBOL,
1699 'REFERENCE' => self::REFERENCE_SYMBOL,
1700 'REMOTE' => self::REMOTE_SYMBOL,
1701 'REQUIRE_ROW_FORMAT' => self::REQUIRE_ROW_FORMAT_SYMBOL,
1702 'REQUIRE_TABLE_PRIMARY_KEY_CHECK' => self::REQUIRE_TABLE_PRIMARY_KEY_CHECK_SYMBOL,
1703 'RESOURCE' => self::RESOURCE_SYMBOL,
1704 'RESPECT' => self::RESPECT_SYMBOL,
1705 'RESTART' => self::RESTART_SYMBOL,
1706 'RETAIN' => self::RETAIN_SYMBOL,
1707 'RETURNING' => self::RETURNING_SYMBOL,
1708 'REUSE' => self::REUSE_SYMBOL,
1709 'ROLE' => self::ROLE_SYMBOL,
1710 'ROW_NUMBER' => self::ROW_NUMBER_SYMBOL,
1711 'SECONDARY' => self::SECONDARY_SYMBOL,
1712 'SECONDARY_ENGINE' => self::SECONDARY_ENGINE_SYMBOL,
1713 'SECONDARY_ENGINE_ATTRIBUTE' => self::SECONDARY_ENGINE_ATTRIBUTE_SYMBOL,
1714 'SECONDARY_LOAD' => self::SECONDARY_LOAD_SYMBOL,
1715 'SECONDARY_UNLOAD' => self::SECONDARY_UNLOAD_SYMBOL,
1716 'SKIP' => self::SKIP_SYMBOL,
1717 'SOURCE_AUTO_POSITION' => self::SOURCE_AUTO_POSITION_SYMBOL,
1718 'SOURCE_BIND' => self::SOURCE_BIND_SYMBOL,
1719 'SOURCE_COMPRESSION_ALGORITHM' => self::SOURCE_COMPRESSION_ALGORITHM_SYMBOL,
1720 'SOURCE_CONNECT_RETRY' => self::SOURCE_CONNECT_RETRY_SYMBOL,
1721 'SOURCE_CONNECTION_AUTO_FAILOVER' => self::SOURCE_CONNECTION_AUTO_FAILOVER_SYMBOL,
1722 'SOURCE_DELAY' => self::SOURCE_DELAY_SYMBOL,
1723 'SOURCE_HEARTBEAT_PERIOD' => self::SOURCE_HEARTBEAT_PERIOD_SYMBOL,
1724 'SOURCE_HOST' => self::SOURCE_HOST_SYMBOL,
1725 'SOURCE_LOG_FILE' => self::SOURCE_LOG_FILE_SYMBOL,
1726 'SOURCE_LOG_POS' => self::SOURCE_LOG_POS_SYMBOL,
1727 'SOURCE_PASSWORD' => self::SOURCE_PASSWORD_SYMBOL,
1728 'SOURCE_PORT' => self::SOURCE_PORT_SYMBOL,
1729 'SOURCE_PUBLIC_KEY_PATH' => self::SOURCE_PUBLIC_KEY_PATH_SYMBOL,
1730 'SOURCE_RETRY_COUNT' => self::SOURCE_RETRY_COUNT_SYMBOL,
1731 'SOURCE_SSL' => self::SOURCE_SSL_SYMBOL,
1732 'SOURCE_SSL_CA' => self::SOURCE_SSL_CA_SYMBOL,
1733 'SOURCE_SSL_CAPATH' => self::SOURCE_SSL_CAPATH_SYMBOL,
1734 'SOURCE_SSL_CERT' => self::SOURCE_SSL_CERT_SYMBOL,
1735 'SOURCE_SSL_CIPHER' => self::SOURCE_SSL_CIPHER_SYMBOL,
1736 'SOURCE_SSL_CRL' => self::SOURCE_SSL_CRL_SYMBOL,
1737 'SOURCE_SSL_CRLPATH' => self::SOURCE_SSL_CRLPATH_SYMBOL,
1738 'SOURCE_SSL_KEY' => self::SOURCE_SSL_KEY_SYMBOL,
1739 'SOURCE_SSL_VERIFY_SERVER_CERT' => self::SOURCE_SSL_VERIFY_SERVER_CERT_SYMBOL,
1740 'SOURCE_TLS_CIPHERSUITES' => self::SOURCE_TLS_CIPHERSUITES_SYMBOL,
1741 'SOURCE_TLS_VERSION' => self::SOURCE_TLS_VERSION_SYMBOL,
1742 'SOURCE_USER' => self::SOURCE_USER_SYMBOL,
1743 'SOURCE_ZSTD_COMPRESSION_LEVEL' => self::SOURCE_ZSTD_COMPRESSION_LEVEL_SYMBOL,
1744 'SRID' => self::SRID_SYMBOL,
1745 'STREAM' => self::STREAM_SYMBOL,
1746 'SYSTEM' => self::SYSTEM_SYMBOL,
1747 'THREAD_PRIORITY' => self::THREAD_PRIORITY_SYMBOL,
1748 'TIES' => self::TIES_SYMBOL,
1749 'TLS' => self::TLS_SYMBOL,
1750 'UNBOUNDED' => self::UNBOUNDED_SYMBOL,
1751 'VCPU' => self::VCPU_SYMBOL,
1752 'VISIBLE' => self::VISIBLE_SYMBOL,
1753 'WINDOW' => self::WINDOW_SYMBOL,
1754 'ZONE' => self::ZONE_SYMBOL,
1755 );
1756
1757 /**
1758 * Tokens that represent function calls when followed by a parenthesis.
1759 */
1760 const FUNCTIONS = array(
1761 self::ADDDATE_SYMBOL => true,
1762 self::BIT_AND_SYMBOL => true,
1763 self::BIT_OR_SYMBOL => true,
1764 self::BIT_XOR_SYMBOL => true,
1765 self::CAST_SYMBOL => true,
1766 self::COUNT_SYMBOL => true,
1767 self::CURDATE_SYMBOL => true,
1768 self::CURRENT_DATE_SYMBOL => true,
1769 self::CURRENT_TIME_SYMBOL => true,
1770 self::CURTIME_SYMBOL => true,
1771 self::DATE_ADD_SYMBOL => true,
1772 self::DATE_SUB_SYMBOL => true,
1773 self::EXTRACT_SYMBOL => true,
1774 self::GROUP_CONCAT_SYMBOL => true,
1775 self::MAX_SYMBOL => true,
1776 self::MID_SYMBOL => true,
1777 self::MIN_SYMBOL => true,
1778 self::NOW_SYMBOL => true,
1779 self::POSITION_SYMBOL => true,
1780 self::SESSION_USER_SYMBOL => true,
1781 self::STD_SYMBOL => true,
1782 self::STDDEV_POP_SYMBOL => true,
1783 self::STDDEV_SAMP_SYMBOL => true,
1784 self::STDDEV_SYMBOL => true,
1785 self::SUBDATE_SYMBOL => true,
1786 self::SUBSTR_SYMBOL => true,
1787 self::SUBSTRING_SYMBOL => true,
1788 self::SUM_SYMBOL => true,
1789 self::SYSDATE_SYMBOL => true,
1790 self::SYSTEM_USER_SYMBOL => true,
1791 self::TRIM_SYMBOL => true,
1792 self::VAR_POP_SYMBOL => true,
1793 self::VAR_SAMP_SYMBOL => true,
1794 self::VARIANCE_SYMBOL => true,
1795 );
1796
1797 /**
1798 * Tokens that are functionally equivalent and can be used interchangeably.
1799 *
1800 * Some of the synonyms may have a different keyword or function status and
1801 * version constraints, hence the synonym conversion needs to be applied
1802 * at the end of the tokenization process, after all other transformations.
1803 *
1804 * E.g.: NOW is a non-reserved keyword that needs to be used with "()" while
1805 * CURRENT_TIMESTAMP is a reserved keyword that can be used without "()".
1806 */
1807 const SYNONYMS = array(
1808 self::CHARACTER_SYMBOL => self::CHAR_SYMBOL,
1809 self::CURRENT_DATE_SYMBOL => self::CURDATE_SYMBOL,
1810 self::CURRENT_TIME_SYMBOL => self::CURTIME_SYMBOL,
1811 self::CURRENT_TIMESTAMP_SYMBOL => self::NOW_SYMBOL,
1812 self::DAYOFMONTH_SYMBOL => self::DAY_SYMBOL,
1813 self::DEC_SYMBOL => self::DECIMAL_SYMBOL,
1814 self::DISTINCTROW_SYMBOL => self::DISTINCT_SYMBOL,
1815 self::FIELDS_SYMBOL => self::COLUMNS_SYMBOL,
1816 self::FLOAT4_SYMBOL => self::FLOAT_SYMBOL,
1817 self::FLOAT8_SYMBOL => self::DOUBLE_SYMBOL,
1818 self::GEOMCOLLECTION_SYMBOL => self::GEOMETRYCOLLECTION_SYMBOL,
1819 self::INT1_SYMBOL => self::TINYINT_SYMBOL,
1820 self::INT2_SYMBOL => self::SMALLINT_SYMBOL,
1821 self::INT3_SYMBOL => self::MEDIUMINT_SYMBOL,
1822 self::INT4_SYMBOL => self::INT_SYMBOL,
1823 self::INT8_SYMBOL => self::BIGINT_SYMBOL,
1824 self::INTEGER_SYMBOL => self::INT_SYMBOL,
1825 self::IO_THREAD_SYMBOL => self::RELAY_THREAD_SYMBOL,
1826 self::LOCALTIME_SYMBOL => self::NOW_SYMBOL,
1827 self::LOCALTIMESTAMP_SYMBOL => self::NOW_SYMBOL,
1828 self::MID_SYMBOL => self::SUBSTRING_SYMBOL,
1829 self::MIDDLEINT_SYMBOL => self::MEDIUMINT_SYMBOL,
1830 self::NDB_SYMBOL => self::NDBCLUSTER_SYMBOL,
1831 self::RLIKE_SYMBOL => self::REGEXP_SYMBOL,
1832 self::SCHEMA_SYMBOL => self::DATABASE_SYMBOL,
1833 self::SCHEMAS_SYMBOL => self::DATABASES_SYMBOL,
1834 self::SESSION_USER_SYMBOL => self::USER_SYMBOL,
1835 self::SOME_SYMBOL => self::ANY_SYMBOL,
1836 self::SQL_TSI_DAY_SYMBOL => self::DAY_SYMBOL,
1837 self::SQL_TSI_HOUR_SYMBOL => self::HOUR_SYMBOL,
1838 self::SQL_TSI_MICROSECOND_SYMBOL => self::MICROSECOND_SYMBOL,
1839 self::SQL_TSI_MINUTE_SYMBOL => self::MINUTE_SYMBOL,
1840 self::SQL_TSI_MONTH_SYMBOL => self::MONTH_SYMBOL,
1841 self::SQL_TSI_QUARTER_SYMBOL => self::QUARTER_SYMBOL,
1842 self::SQL_TSI_SECOND_SYMBOL => self::SECOND_SYMBOL,
1843 self::SQL_TSI_WEEK_SYMBOL => self::WEEK_SYMBOL,
1844 self::SQL_TSI_YEAR_SYMBOL => self::YEAR_SYMBOL,
1845 self::STDDEV_POP_SYMBOL => self::STD_SYMBOL,
1846 self::STDDEV_SYMBOL => self::STD_SYMBOL,
1847 self::SUBSTR_SYMBOL => self::SUBSTRING_SYMBOL,
1848 self::SYSTEM_USER_SYMBOL => self::USER_SYMBOL,
1849 self::VAR_POP_SYMBOL => self::VARIANCE_SYMBOL,
1850 self::VARCHARACTER_SYMBOL => self::VARCHAR_SYMBOL,
1851 );
1852
1853 /**
1854 * Version constraints for version-specific tokens.
1855 *
1856 * This is a map of tokens to the MySQL server versions in which they were
1857 * introduced (positive number) or removed (negative number). Tokens that
1858 * were both introduced and later removed are not included in this list
1859 * and are handled by manual version checks in the tokenization process.
1860 *
1861 * See:
1862 * https://dev.mysql.com/doc/mysqld-version-reference/en/keywords.html
1863 *
1864 * @TODO Verify the version specifiers and ranges against the list above.
1865 *
1866 * Positive number: >= <version> (introduced in <version>)
1867 * Negative number: < <version> (removed in <version>)
1868 */
1869 const VERSIONS = array(
1870 // MySQL 5
1871 self::ACCOUNT_SYMBOL => 50707,
1872 self::ALWAYS_SYMBOL => 50707,
1873 self::ANALYSE_SYMBOL => -80000,
1874 self::AUTHORS_SYMBOL => -50700,
1875 self::CHANNEL_SYMBOL => 50706,
1876 self::COMPRESSION_SYMBOL => 50707,
1877 self::CONTRIBUTORS_SYMBOL => -50700,
1878 self::CURRENT_SYMBOL => 50604,
1879 self::DEFAULT_AUTH_SYMBOL => 50604,
1880 self::DES_KEY_FILE_SYMBOL => -80003,
1881 self::ENCRYPTION_SYMBOL => 50711,
1882 self::EXPIRE_SYMBOL => 50606,
1883 self::EXPORT_SYMBOL => 50606,
1884 self::FILE_BLOCK_SIZE_SYMBOL => 50707,
1885 self::FILTER_SYMBOL => 50700,
1886 self::FOLLOWS_SYMBOL => 50700,
1887 self::GENERATED_SYMBOL => 50707,
1888 self::GET_SYMBOL => 50604,
1889 self::GROUP_REPLICATION_SYMBOL => 50707,
1890 self::INNODB_SYMBOL => 50711,
1891 self::INSTANCE_SYMBOL => 50713,
1892 self::JSON_SYMBOL => 50708,
1893 self::MASTER_AUTO_POSITION_SYMBOL => 50605,
1894 self::MASTER_BIND_SYMBOL => 50602,
1895 self::MASTER_RETRY_COUNT_SYMBOL => 50601,
1896 self::MASTER_SSL_CRL_SYMBOL => 50603,
1897 self::MASTER_SSL_CRLPATH_SYMBOL => 50603,
1898 self::MASTER_TLS_VERSION_SYMBOL => 50713,
1899 self::NEVER_SYMBOL => 50704,
1900 self::NUMBER_SYMBOL => 50606,
1901 self::OLD_PASSWORD_SYMBOL => -50706,
1902 self::ONLY_SYMBOL => 50605,
1903 self::OPTIMIZER_COSTS_SYMBOL => 50706,
1904 self::PLUGIN_DIR_SYMBOL => 50604,
1905 self::PRECEDES_SYMBOL => 50700,
1906 self::REDOFILE_SYMBOL => -80000,
1907 self::REPLICATE_DO_DB_SYMBOL => 50700,
1908 self::REPLICATE_DO_TABLE_SYMBOL => 50700,
1909 self::REPLICATE_IGNORE_DB_SYMBOL => 50700,
1910 self::REPLICATE_IGNORE_TABLE_SYMBOL => 50700,
1911 self::REPLICATE_REWRITE_DB_SYMBOL => 50700,
1912 self::REPLICATE_WILD_DO_TABLE_SYMBOL => 50700,
1913 self::REPLICATE_WILD_IGNORE_TABLE_SYMBOL => 50700,
1914 self::ROTATE_SYMBOL => 50713,
1915 self::SQL_AFTER_MTS_GAPS_SYMBOL => 50606,
1916 self::SQL_CACHE_SYMBOL => -80000,
1917 self::STACKED_SYMBOL => 50700,
1918 self::STORED_SYMBOL => 50707,
1919 self::TABLE_REF_PRIORITY_SYMBOL => -80000,
1920 self::VALIDATION_SYMBOL => 50706,
1921 self::VIRTUAL_SYMBOL => 50707,
1922 self::XID_SYMBOL => 50704,
1923
1924 // MySQL 8
1925 self::ACTIVE_SYMBOL => 80014,
1926 self::ADMIN_SYMBOL => 80000,
1927 self::ARRAY_SYMBOL => 80017,
1928 self::ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS_SYMBOL => 80000,
1929 self::ATTRIBUTE_SYMBOL => 80021,
1930 self::BUCKETS_SYMBOL => 80000,
1931 self::CLONE_SYMBOL => 80000,
1932 self::COMPONENT_SYMBOL => 80000,
1933 self::CUME_DIST_SYMBOL => 80000,
1934 self::DEFINITION_SYMBOL => 80011,
1935 self::DENSE_RANK_SYMBOL => 80000,
1936 self::DESCRIPTION_SYMBOL => 80011,
1937 self::EMPTY_SYMBOL => 80000,
1938 self::ENFORCED_SYMBOL => 80017,
1939 self::ENGINE_ATTRIBUTE_SYMBOL => 80021,
1940 self::EXCEPT_SYMBOL => 80000,
1941 self::EXCLUDE_SYMBOL => 80000,
1942 self::FAILED_LOGIN_ATTEMPTS_SYMBOL => 80019,
1943 self::FIRST_VALUE_SYMBOL => 80000,
1944 self::FOLLOWING_SYMBOL => 80000,
1945 self::GEOMCOLLECTION_SYMBOL => 80000,
1946 self::GET_MASTER_PUBLIC_KEY_SYMBOL => 80000,
1947 self::GET_SOURCE_PUBLIC_KEY_SYMBOL => 80000,
1948 self::GROUPING_SYMBOL => 80000,
1949 self::GROUPS_SYMBOL => 80000,
1950 self::GTID_ONLY_SYMBOL => 80000,
1951 self::HISTOGRAM_SYMBOL => 80000,
1952 self::HISTORY_SYMBOL => 80000,
1953 self::INACTIVE_SYMBOL => 80014,
1954 self::INTERSECT_SYMBOL => 80031,
1955 self::INVISIBLE_SYMBOL => 80000,
1956 self::JSON_ARRAYAGG_SYMBOL => 80000,
1957 self::JSON_OBJECTAGG_SYMBOL => 80000,
1958 self::JSON_TABLE_SYMBOL => 80000,
1959 self::JSON_VALUE_SYMBOL => 80021,
1960 self::KEYRING_SYMBOL => 80024,
1961 self::LAG_SYMBOL => 80000,
1962 self::LAST_VALUE_SYMBOL => 80000,
1963 self::LATERAL_SYMBOL => 80014,
1964 self::LEAD_SYMBOL => 80000,
1965 self::LOCKED_SYMBOL => 80000,
1966 self::MASTER_COMPRESSION_ALGORITHM_SYMBOL => 80018,
1967 self::MASTER_PUBLIC_KEY_PATH_SYMBOL => 80000,
1968 self::MASTER_TLS_CIPHERSUITES_SYMBOL => 80018,
1969 self::MASTER_ZSTD_COMPRESSION_LEVEL_SYMBOL => 80018,
1970 self::MEMBER_SYMBOL => 80017,
1971 self::NESTED_SYMBOL => 80000,
1972 self::NETWORK_NAMESPACE_SYMBOL => 80017,
1973 self::NOWAIT_SYMBOL => 80000,
1974 self::NTH_VALUE_SYMBOL => 80000,
1975 self::NTILE_SYMBOL => 80000,
1976 self::NULLS_SYMBOL => 80000,
1977 self::OF_SYMBOL => 80000,
1978 self::OFF_SYMBOL => 80019,
1979 self::OJ_SYMBOL => 80017,
1980 self::OLD_SYMBOL => 80014,
1981 self::OPTIONAL_SYMBOL => 80013,
1982 self::ORDINALITY_SYMBOL => 80000,
1983 self::ORGANIZATION_SYMBOL => 80011,
1984 self::OTHERS_SYMBOL => 80000,
1985 self::OVER_SYMBOL => 80000,
1986 self::PASSWORD_LOCK_TIME_SYMBOL => 80019,
1987 self::PATH_SYMBOL => 80000,
1988 self::PERCENT_RANK_SYMBOL => 80000,
1989 self::PERSIST_ONLY_SYMBOL => 80000,
1990 self::PERSIST_SYMBOL => 80000,
1991 self::PRECEDING_SYMBOL => 80000,
1992 self::PRIVILEGE_CHECKS_USER_SYMBOL => 80018,
1993 self::RANDOM_SYMBOL => 80018,
1994 self::RANK_SYMBOL => 80000,
1995 self::RECURSIVE_SYMBOL => 80000,
1996 self::REDO_LOG_SYMBOL => 80021,
1997 self::REFERENCE_SYMBOL => 80011,
1998 self::REQUIRE_ROW_FORMAT_SYMBOL => 80019,
1999 self::REQUIRE_TABLE_PRIMARY_KEY_CHECK_SYMBOL => 80019,
2000 self::RESOURCE_SYMBOL => 80000,
2001 self::RESPECT_SYMBOL => 80000,
2002 self::RESTART_SYMBOL => 80011,
2003 self::RETAIN_SYMBOL => 80014,
2004 self::REUSE_SYMBOL => 80000,
2005 self::RETURNING_SYMBOL => 80021,
2006 self::ROLE_SYMBOL => 80000,
2007 self::ROW_NUMBER_SYMBOL => 80000,
2008 self::SECONDARY_ENGINE_ATTRIBUTE_SYMBOL => 80021,
2009 self::SECONDARY_ENGINE_SYMBOL => 80013,
2010 self::SECONDARY_LOAD_SYMBOL => 80013,
2011 self::SECONDARY_SYMBOL => 80013,
2012 self::SECONDARY_UNLOAD_SYMBOL => 80013,
2013 self::SKIP_SYMBOL => 80000,
2014 self::SOURCE_AUTO_POSITION_SYMBOL => 80000,
2015 self::SOURCE_BIND_SYMBOL => 80000,
2016 self::SOURCE_COMPRESSION_ALGORITHM_SYMBOL => 80000,
2017 self::SOURCE_CONNECT_RETRY_SYMBOL => 80000,
2018 self::SOURCE_CONNECTION_AUTO_FAILOVER_SYMBOL => 80000,
2019 self::SOURCE_DELAY_SYMBOL => 80000,
2020 self::SOURCE_HEARTBEAT_PERIOD_SYMBOL => 80000,
2021 self::SOURCE_HOST_SYMBOL => 80000,
2022 self::SOURCE_LOG_FILE_SYMBOL => 80000,
2023 self::SOURCE_LOG_POS_SYMBOL => 80000,
2024 self::SOURCE_PASSWORD_SYMBOL => 80000,
2025 self::SOURCE_PORT_SYMBOL => 80000,
2026 self::SOURCE_PUBLIC_KEY_PATH_SYMBOL => 80000,
2027 self::SOURCE_RETRY_COUNT_SYMBOL => 80000,
2028 self::SOURCE_SSL_CA_SYMBOL => 80000,
2029 self::SOURCE_SSL_CAPATH_SYMBOL => 80000,
2030 self::SOURCE_SSL_CERT_SYMBOL => 80000,
2031 self::SOURCE_SSL_CIPHER_SYMBOL => 80000,
2032 self::SOURCE_SSL_CRL_SYMBOL => 80000,
2033 self::SOURCE_SSL_CRLPATH_SYMBOL => 80000,
2034 self::SOURCE_SSL_KEY_SYMBOL => 80000,
2035 self::SOURCE_SSL_SYMBOL => 80000,
2036 self::SOURCE_SSL_VERIFY_SERVER_CERT_SYMBOL => 80000,
2037 self::SOURCE_TLS_CIPHERSUITES_SYMBOL => 80000,
2038 self::SOURCE_TLS_VERSION_SYMBOL => 80000,
2039 self::SOURCE_USER_SYMBOL => 80000,
2040 self::SOURCE_ZSTD_COMPRESSION_LEVEL_SYMBOL => 80000,
2041 self::SRID_SYMBOL => 80000,
2042 self::STREAM_SYMBOL => 80019,
2043 self::SYSTEM_SYMBOL => 80000,
2044 self::THREAD_PRIORITY_SYMBOL => 80000,
2045 self::TIES_SYMBOL => 80000,
2046 self::TLS_SYMBOL => 80016,
2047 self::UNBOUNDED_SYMBOL => 80000,
2048 self::VCPU_SYMBOL => 80000,
2049 self::VISIBLE_SYMBOL => 80000,
2050 self::WINDOW_SYMBOL => 80000,
2051 self::ZONE_SYMBOL => 80022,
2052 );
2053
2054 /**
2055 * Identifier-like strings that may represent underscore-prefixed charset names.
2056 *
2057 * Includes charsets from both MySQL 5 and 8; via "SHOW CHARACTER SET"/docs:
2058 * https://dev.mysql.com/doc/refman/5.7/en/charset-charsets.html
2059 * https://dev.mysql.com/doc/refman/8.4/en/charset-charsets.html
2060 *
2061 * @TODO: Make the list respect the MySQL version. The _utf8 underscore charset
2062 * exists only on MySQL 5, and maybe some others are version-dependant too.
2063 * We can check this using SHOW CHARACTER SET on different MySQL versions.
2064 */
2065 const UNDERSCORE_CHARSETS = array(
2066 '_armscii8' => true,
2067 '_ascii' => true,
2068 '_big5' => true,
2069 '_binary' => true,
2070 '_cp1250' => true,
2071 '_cp1251' => true,
2072 '_cp1256' => true,
2073 '_cp1257' => true,
2074 '_cp850' => true,
2075 '_cp852' => true,
2076 '_cp866' => true,
2077 '_cp932' => true,
2078 '_dec8' => true,
2079 '_eucjpms' => true,
2080 '_euckr' => true,
2081 '_gb18030' => true,
2082 '_gb2312' => true,
2083 '_gbk' => true,
2084 '_geostd8' => true,
2085 '_greek' => true,
2086 '_hebrew' => true,
2087 '_hp8' => true,
2088 '_keybcs2' => true,
2089 '_koi8r' => true,
2090 '_koi8u' => true,
2091 '_latin1' => true,
2092 '_latin2' => true,
2093 '_latin5' => true,
2094 '_latin7' => true,
2095 '_macce' => true,
2096 '_macroman' => true,
2097 '_sjis' => true,
2098 '_swe7' => true,
2099 '_tis620' => true,
2100 '_ucs2' => true,
2101 '_ujis' => true,
2102 '_utf16' => true,
2103 '_utf16le' => true,
2104 '_utf32' => true,
2105 '_utf8' => true,
2106 '_utf8mb3' => true,
2107 '_utf8mb4' => true,
2108 );
2109
2110 /**
2111 * The SQL payload to tokenize.
2112 *
2113 * @var string
2114 */
2115 private $sql;
2116
2117 /**
2118 * Byte length of the SQL payload.
2119 *
2120 * @var int
2121 */
2122 private $sql_length;
2123
2124 /**
2125 * The version of the MySQL server that the SQL payload is intended for.
2126 *
2127 * This is used to determine which tokens are valid for the given MySQL
2128 * version, and how some tokens should be interpreted.
2129 *
2130 * @var int
2131 */
2132 private $mysql_version;
2133
2134 /**
2135 * The SQL modes that should be considered active during tokenization.
2136 *
2137 * This is an integer that represents currently active SQL modes as a bitmask.
2138 * The SQL modes are defined as "SQL_MODE_"-prefixed constants in this class.
2139 * The list of the SQL modes isn't exhaustive, as only some affect tokenization.
2140 *
2141 * @var int
2142 */
2143 private $sql_modes = 0;
2144
2145 /**
2146 * How many bytes from the original SQL payload have been read and tokenized.
2147 *
2148 * This is an internal cursor that is used to track the current position in
2149 * the SQL payload during tokenization. When used as an index in the SQL
2150 * payload, it points to the next byte to read.
2151 *
2152 * @var int
2153 */
2154 private $bytes_already_read = 0;
2155
2156 /**
2157 * Byte offset in the SQL payload where current token starts.
2158 *
2159 * This is used to extract the token bytes after the token is processed.
2160 * The bytes of the current token are represented by "$this->sql" in range
2161 * from "$this->token_starts_at" to "$this->bytes_already_read - 1".
2162 *
2163 * @var int
2164 */
2165 private $token_starts_at = 0;
2166
2167 /**
2168 * The type of the current token.
2169 *
2170 * When a token is successfully recognized and read, this value is set to the
2171 * constant representing the token type. When no token was read yet, or the
2172 * end of the SQL payload or an invalid token is reached, this value is null.
2173 *
2174 * @var int|null
2175 */
2176 private $token_type;
2177
2178 /**
2179 * Whether the tokenizer is inside an active MySQL-specific comment.
2180 *
2181 * MySQL supports a special comment syntax whose content is recognized as
2182 * a comment by most database engines, but can be treated as SQL by MySQL:
2183 *
2184 * 1. /*! ... - The content is treated as SQL.
2185 * 2. /*!12345 - The content is treated as SQL when "MySQL version >= 12345".
2186 *
2187 * @var bool
2188 */
2189 private $in_mysql_comment = false;
2190
2191 /**
2192 * @param string $sql The SQL payload to tokenize.
2193 * @param int $mysql_version The version of the MySQL server that the SQL payload is intended for.
2194 * @param string[] $sql_modes The SQL modes that should be considered active during tokenization.
2195 */
2196 public function __construct(
2197 string $sql,
2198 int $mysql_version = 80038,
2199 array $sql_modes = array()
2200 ) {
2201 $this->sql = $sql;
2202 $this->sql_length = strlen( $sql );
2203 $this->mysql_version = $mysql_version;
2204
2205 foreach ( $sql_modes as $sql_mode ) {
2206 $sql_mode = strtoupper( $sql_mode );
2207 if ( 'HIGH_NOT_PRECEDENCE' === $sql_mode ) {
2208 $this->sql_modes |= self::SQL_MODE_HIGH_NOT_PRECEDENCE;
2209 } elseif ( 'PIPES_AS_CONCAT' === $sql_mode ) {
2210 $this->sql_modes |= self::SQL_MODE_PIPES_AS_CONCAT;
2211 } elseif ( 'IGNORE_SPACE' === $sql_mode ) {
2212 $this->sql_modes |= self::SQL_MODE_IGNORE_SPACE;
2213 } elseif ( 'NO_BACKSLASH_ESCAPES' === $sql_mode ) {
2214 $this->sql_modes |= self::SQL_MODE_NO_BACKSLASH_ESCAPES;
2215 } elseif ( 'ANSI_QUOTES' === $sql_mode ) {
2216 $this->sql_modes |= self::SQL_MODE_ANSI_QUOTES;
2217 } elseif ( 'ANSI' === $sql_mode ) {
2218 /*
2219 * Expand the composite ANSI mode into its lexer-relevant components.
2220 * The ANSI mode also implies REAL_AS_FLOAT and ONLY_FULL_GROUP_BY,
2221 * which do not affect the lexer.
2222 *
2223 * See: https://dev.mysql.com/doc/refman/8.4/en/sql-mode.html#sqlmode_ansi
2224 */
2225 $this->sql_modes |= self::SQL_MODE_PIPES_AS_CONCAT
2226 | self::SQL_MODE_IGNORE_SPACE
2227 | self::SQL_MODE_ANSI_QUOTES;
2228 }
2229 }
2230 }
2231
2232 /**
2233 * Read the next token from the SQL payload and return it as a token object.
2234 *
2235 * This method reads bytes from the SQL payload until a token is recognized.
2236 * It starts from "$this->sql[ $this->bytes_already_read ]", advances the
2237 * number of bytes read, and returns a boolean indicating whether a token
2238 * was successfully recognized and read. When the end of the SQL payload
2239 * or an invalid token is reached, the method returns false.
2240 *
2241 * @return bool Whether a token was successfully recognized and read.
2242 */
2243 public function next_token(): bool {
2244 // We already reached the end of the SQL payload or an invalid token.
2245 // Don't attempt to read any more bytes, and bail out immediately.
2246 if (
2247 self::EOF === $this->token_type
2248 || ( null === $this->token_type && $this->bytes_already_read > 0 )
2249 ) {
2250 $this->token_type = null;
2251 return false;
2252 }
2253
2254 // Skip leading whitespace inline for optimal performance.
2255 $this->bytes_already_read += strspn( $this->sql, self::WHITESPACE_MASK, $this->bytes_already_read );
2256
2257 do {
2258 $this->token_starts_at = $this->bytes_already_read;
2259 $this->token_type = $this->read_next_token();
2260 } while (
2261 self::WHITESPACE === $this->token_type
2262 || self::COMMENT === $this->token_type
2263 || self::MYSQL_COMMENT_START === $this->token_type
2264 || self::MYSQL_COMMENT_END === $this->token_type
2265 );
2266
2267 // Invalid input.
2268 if ( null === $this->token_type ) {
2269 return false;
2270 }
2271 return true;
2272 }
2273
2274 /**
2275 * Return the current token represented as a WP_MySQL_Token object.
2276 *
2277 * When no token was read yet, or the end of the SQL payload or an invalid
2278 * token is reached, the method returns null.
2279 *
2280 * @TODO: Consider referential stability ($lexer->get_token() === $lexer->get_token()),
2281 * or separate getters for the token type and token bytes (no token objects).
2282 *
2283 * @return WP_MySQL_Token|null An object representing the next recognized token or null.
2284 */
2285 public function get_token(): ?WP_MySQL_Token {
2286 if ( null === $this->token_type ) {
2287 return null;
2288 }
2289 return new WP_MySQL_Token(
2290 $this->token_type,
2291 $this->token_starts_at,
2292 $this->bytes_already_read - $this->token_starts_at,
2293 $this->sql,
2294 $this->is_sql_mode_active( self::SQL_MODE_NO_BACKSLASH_ESCAPES )
2295 );
2296 }
2297
2298 /**
2299 * Read all remaining tokens from the SQL payload and return them as an array.
2300 *
2301 * This method starts from the current position in the SQL payload, as marked
2302 * by "$this->sql[ $this->bytes_already_read ]", and reads all tokens until
2303 * the end of the SQL payload is reached, returning an array of token objects.
2304 *
2305 * When an invalid token is reached, the method stops and returns the partial
2306 * sequence of valid tokens. In this case, the EOF token will not be included.
2307 *
2308 * This method can be used to tokenize the whole SQL payload at once, at the
2309 * expense of storing all token objects in memory at the same time.
2310 *
2311 * @return WP_MySQL_Token[] An array of token objects representing the remaining tokens.
2312 */
2313 public function remaining_tokens(): array {
2314 $tokens = array();
2315 $no_backslash_escapes_sql_mode_set = $this->is_sql_mode_active(
2316 self::SQL_MODE_NO_BACKSLASH_ESCAPES
2317 );
2318
2319 while ( true ) {
2320 // Bail on EOF, or on a null token type once at least one byte has
2321 // been consumed (read_next_token() hit invalid input mid-stream).
2322 if (
2323 self::EOF === $this->token_type
2324 || ( null === $this->token_type && $this->bytes_already_read > 0 )
2325 ) {
2326 $this->token_type = null;
2327 break;
2328 }
2329
2330 // Skip leading whitespace inline for optimal performance.
2331 $this->bytes_already_read += strspn( $this->sql, self::WHITESPACE_MASK, $this->bytes_already_read );
2332
2333 do {
2334 $this->token_starts_at = $this->bytes_already_read;
2335 $this->token_type = $this->read_next_token();
2336 } while (
2337 self::WHITESPACE === $this->token_type
2338 || self::COMMENT === $this->token_type
2339 || self::MYSQL_COMMENT_START === $this->token_type
2340 || self::MYSQL_COMMENT_END === $this->token_type
2341 );
2342
2343 if ( null === $this->token_type ) {
2344 break;
2345 }
2346
2347 $tokens[] = new WP_MySQL_Token(
2348 $this->token_type,
2349 $this->token_starts_at,
2350 $this->bytes_already_read - $this->token_starts_at,
2351 $this->sql,
2352 $no_backslash_escapes_sql_mode_set
2353 );
2354
2355 if ( self::EOF === $this->token_type ) {
2356 $this->token_type = null;
2357 break;
2358 }
2359 }
2360 return $tokens;
2361 }
2362
2363 /**
2364 * The version of the MySQL server that the SQL payload is intended for.
2365 *
2366 * This represents the MySQL server version that the lexer is set up to
2367 * consider when tokenizing the SQL payload.
2368 *
2369 * @return int The MySQL server version that the lexer is set up to consider.
2370 */
2371 public function get_mysql_version(): int {
2372 return $this->mysql_version;
2373 }
2374
2375 /**
2376 * Whether an SQL mode is set to be considered as active during tokenization.
2377 * The SQL modes are defined as "SQL_MODE_"-prefixed constants in this class.
2378 *
2379 * @param int $mode The SQL mode to check, an "SQL_MODE_"-prefixed constant.
2380 * @return bool Whether the given SQL mode is active.
2381 */
2382 public function is_sql_mode_active( int $mode ): bool {
2383 return ( $this->sql_modes & $mode ) !== 0;
2384 }
2385
2386 /**
2387 * Get the numeric token ID for a given token name.
2388 *
2389 * @param string $token_name The name of the token.
2390 * @return int|null The token ID for the given token name; null when not found.
2391 */
2392 public static function get_token_id( string $token_name ): ?int {
2393 $constant_name = self::class . '::' . $token_name;
2394 if ( ! defined( $constant_name ) ) {
2395 return null;
2396 }
2397 return constant( $constant_name );
2398 }
2399
2400 /**
2401 * Get the name of a token for a given token ID.
2402 *
2403 * This method is intended to be used only for testing and debugging purposes,
2404 * when tokens need to be presented by their names in a human-readable form.
2405 * It should not be used in production code, as it's not performance-optimized.
2406 *
2407 * @param int $token_id The numeric token ID.
2408 * @return string The token name for the given token ID; null when not found.
2409 */
2410 public static function get_token_name( int $token_id ): ?string {
2411 $reflection = new ReflectionClass( self::class );
2412 // Reverse the array, as some constant values in the class can conflict,
2413 // and tokens are defined at the end of the class constant definitions.
2414 // @TODO: Consider are more robust way to determine the token name.
2415 // E.g., prefix all token constant names with a common prefix.
2416 $constants = array_reverse( $reflection->getConstants() );
2417 $token_name = array_search( $token_id, $constants, true );
2418 return $token_name ? $token_name : null;
2419 }
2420
2421 private function read_next_token(): ?int {
2422 $byte = $this->sql[ $this->bytes_already_read ] ?? null;
2423 $next_byte = $this->sql[ $this->bytes_already_read + 1 ] ?? null;
2424
2425 // A map for a single-byte symbol fast path.
2426 static $single_byte_ops = array(
2427 '(' => self::OPEN_PAR_SYMBOL,
2428 ')' => self::CLOSE_PAR_SYMBOL,
2429 ',' => self::COMMA_SYMBOL,
2430 ';' => self::SEMICOLON_SYMBOL,
2431 '+' => self::PLUS_OPERATOR,
2432 '~' => self::BITWISE_NOT_OPERATOR,
2433 '%' => self::MOD_OPERATOR,
2434 '^' => self::BITWISE_XOR_OPERATOR,
2435 '?' => self::PARAM_MARKER,
2436 '{' => self::OPEN_CURLY_SYMBOL,
2437 '}' => self::CLOSE_CURLY_SYMBOL,
2438 '=' => self::EQUAL_OPERATOR,
2439 );
2440
2441 // Fast path for keywords and identifiers.
2442 // `$byte > "\x7F"` catches any non-ASCII byte (0x80-0xFF); read_identifier()
2443 // restricts the accepted identifier codepoints to U+0080-U+FFFF.
2444 // `"'" !== $next_byte` defers x'..', n'..' and similar special
2445 // literals to their dedicated branches below; only single quotes
2446 // form those, regardless of SQL mode.
2447 if (
2448 (
2449 ( $byte >= 'a' && $byte <= 'z' )
2450 || ( $byte >= 'A' && $byte <= 'Z' )
2451 || $byte > "\x7F"
2452 )
2453 && "'" !== $next_byte
2454 ) {
2455 $started_at = $this->bytes_already_read;
2456 $type = $this->read_identifier();
2457 if (
2458 self::IDENTIFIER === $type
2459 // When preceded by a dot, it is always an identifier.
2460 && ! ( $started_at > 0 && '.' === $this->sql[ $started_at - 1 ] )
2461 ) {
2462 // Inline the keyword lookup on the hot identifier path: most
2463 // identifiers are not keywords, so this avoids two method calls
2464 // (token-bytes extraction + keyword determination) per token.
2465 $keyword = self::TOKENS[ strtoupper(
2466 substr( $this->sql, $started_at, $this->bytes_already_read - $started_at )
2467 ) ] ?? self::IDENTIFIER;
2468 if ( self::IDENTIFIER !== $keyword ) {
2469 $type = $this->resolve_keyword_type( $keyword );
2470 }
2471 }
2472 } elseif ( null !== $byte && isset( $single_byte_ops[ $byte ] ) ) {
2473 // Fast path for single-byte symbols.
2474 $this->bytes_already_read += 1;
2475 $type = $single_byte_ops[ $byte ];
2476 } elseif ( "'" === $byte || '"' === $byte || '`' === $byte ) {
2477 $type = $this->read_quoted_text();
2478 } elseif ( null !== $byte && strspn( $byte, self::DIGIT_MASK ) > 0 ) {
2479 $type = $this->read_number();
2480 } elseif ( '.' === $byte ) {
2481 if ( null !== $next_byte && strspn( $next_byte, self::DIGIT_MASK ) > 0 ) {
2482 $type = $this->read_number();
2483 } else {
2484 $this->bytes_already_read += 1;
2485 $type = self::DOT_SYMBOL;
2486 }
2487 } elseif ( ':' === $byte ) {
2488 $this->bytes_already_read += 1; // Consume the ':'.
2489 if ( '=' === $next_byte ) {
2490 $this->bytes_already_read += 1; // Consume the '='.
2491 $type = self::ASSIGN_OPERATOR;
2492 } else {
2493 $type = self::COLON_SYMBOL;
2494 }
2495 } elseif ( '<' === $byte ) {
2496 $this->bytes_already_read += 1; // Consume the '<'.
2497 if ( '=' === $next_byte ) {
2498 $this->bytes_already_read += 1; // Consume the '='.
2499 if ( '>' === ( $this->sql[ $this->bytes_already_read ] ?? null ) ) {
2500 $this->bytes_already_read += 1; // Consume the '>'.
2501 $type = self::NULL_SAFE_EQUAL_OPERATOR;
2502 } else {
2503 $type = self::LESS_OR_EQUAL_OPERATOR;
2504 }
2505 } elseif ( '>' === $next_byte ) {
2506 $this->bytes_already_read += 1; // Consume the '>'.
2507 $type = self::NOT_EQUAL_OPERATOR;
2508 } elseif ( '<' === $next_byte ) {
2509 $this->bytes_already_read += 1; // Consume the '<'.
2510 $type = self::SHIFT_LEFT_OPERATOR;
2511 } else {
2512 $type = self::LESS_THAN_OPERATOR;
2513 }
2514 } elseif ( '>' === $byte ) {
2515 $this->bytes_already_read += 1; // Consume the '>'.
2516 if ( '=' === $next_byte ) {
2517 $this->bytes_already_read += 1; // Consume the '='.
2518 $type = self::GREATER_OR_EQUAL_OPERATOR;
2519 } elseif ( '>' === $next_byte ) {
2520 $this->bytes_already_read += 1; // Consume the '>'.
2521 $type = self::SHIFT_RIGHT_OPERATOR;
2522 } else {
2523 $type = self::GREATER_THAN_OPERATOR;
2524 }
2525 } elseif ( '!' === $byte ) {
2526 $this->bytes_already_read += 1; // Consume the '!'.
2527 if ( '=' === $next_byte ) {
2528 $this->bytes_already_read += 1; // Consume the '='.
2529 $type = self::NOT_EQUAL_OPERATOR;
2530 } else {
2531 $type = self::LOGICAL_NOT_OPERATOR;
2532 }
2533 } elseif ( '-' === $byte ) {
2534 if (
2535 '-' === $next_byte
2536 && $this->bytes_already_read + 2 < $this->sql_length
2537 && strspn( $this->sql[ $this->bytes_already_read + 2 ], self::WHITESPACE_MASK ) > 0
2538 ) {
2539 $type = $this->read_line_comment();
2540 } elseif ( '>' === $next_byte ) {
2541 $this->bytes_already_read += 2; // Consume the '->'.
2542 if ( '>' === ( $this->sql[ $this->bytes_already_read ] ?? null ) ) {
2543 $this->bytes_already_read += 1; // Consume the '>'.
2544 if ( $this->mysql_version >= 50713 ) {
2545 $type = self::JSON_UNQUOTED_SEPARATOR_SYMBOL;
2546 } else {
2547 return null; // Invalid input.
2548 }
2549 } else {
2550 if ( $this->mysql_version >= 50708 ) {
2551 $type = self::JSON_SEPARATOR_SYMBOL;
2552 } else {
2553 return null; // Invalid input.
2554 }
2555 }
2556 } else {
2557 $this->bytes_already_read += 1; // Consume the '-'.
2558 $type = self::MINUS_OPERATOR;
2559 }
2560 } elseif ( '*' === $byte ) {
2561 $this->bytes_already_read += 1;
2562 if ( '/' === $next_byte && $this->in_mysql_comment ) {
2563 $this->bytes_already_read += 1; // Consume the '/'.
2564 $type = self::MYSQL_COMMENT_END;
2565 $this->in_mysql_comment = false;
2566 } else {
2567 $type = self::MULT_OPERATOR;
2568 }
2569 } elseif ( '/' === $byte ) {
2570 if ( '*' === $next_byte ) {
2571 if ( '!' === ( $this->sql[ $this->bytes_already_read + 2 ] ?? null ) ) {
2572 $type = $this->read_mysql_comment();
2573 } else {
2574 $this->bytes_already_read += 2; // Consume the '/*'.
2575 $this->read_comment_content();
2576 $type = self::COMMENT;
2577 }
2578 } else {
2579 $this->bytes_already_read += 1;
2580 $type = self::DIV_OPERATOR;
2581 }
2582 } elseif ( '&' === $byte ) {
2583 $this->bytes_already_read += 1; // Consume the '&'.
2584 if ( '&' === $next_byte ) {
2585 $this->bytes_already_read += 1; // Consume the '&'.
2586 $type = self::LOGICAL_AND_OPERATOR;
2587 } else {
2588 $type = self::BITWISE_AND_OPERATOR;
2589 }
2590 } elseif ( '|' === $byte ) {
2591 $this->bytes_already_read += 1; // Consume the '|'.
2592 if ( '|' === $next_byte ) {
2593 $this->bytes_already_read += 1; // Consume the '|'.
2594 $type = $this->is_sql_mode_active( self::SQL_MODE_PIPES_AS_CONCAT )
2595 ? self::CONCAT_PIPES_SYMBOL
2596 : self::LOGICAL_OR_OPERATOR;
2597 } else {
2598 $type = self::BITWISE_OR_OPERATOR;
2599 }
2600 } elseif ( '@' === $byte ) {
2601 $this->bytes_already_read += 1; // Consume the '@'.
2602
2603 if ( '@' === $next_byte ) {
2604 $this->bytes_already_read += 1; // Consume the second '@'.
2605 $type = self::AT_AT_SIGN_SYMBOL;
2606 } else {
2607 /**
2608 * Check whether the '@' marks an unquoted user-defined variable:
2609 * https://dev.mysql.com/doc/refman/8.4/en/user-variables.html
2610 *
2611 * Rules:
2612 * 1. Starts with a '@'.
2613 * 2. Allowed following characters are ASCII a-z, A-Z, 0-9, _, ., $.
2614 */
2615 $length = strspn( $this->sql, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.$', $this->bytes_already_read );
2616 if ( $length > 0 ) {
2617 $this->bytes_already_read += $length;
2618 $type = self::AT_TEXT_SUFFIX;
2619 } else {
2620 $type = self::AT_SIGN_SYMBOL;
2621 }
2622 }
2623 } elseif ( '\\' === $byte ) {
2624 $this->bytes_already_read += 1; // Consume the '\'.
2625 if ( 'N' === $next_byte ) {
2626 $this->bytes_already_read += 1; // Consume the 'N'.
2627 $type = self::NULL2_SYMBOL;
2628 } else {
2629 return null; // Invalid input.
2630 }
2631 } elseif ( '#' === $byte ) {
2632 $type = $this->read_line_comment();
2633 } elseif ( null !== $byte && strspn( $byte, self::WHITESPACE_MASK ) > 0 ) {
2634 $this->bytes_already_read += strspn( $this->sql, self::WHITESPACE_MASK, $this->bytes_already_read );
2635 $type = self::WHITESPACE;
2636 } elseif ( ( 'x' === $byte || 'X' === $byte || 'b' === $byte || 'B' === $byte ) && "'" === $next_byte ) {
2637 $type = $this->read_number();
2638 } elseif ( ( 'n' === $byte || 'N' === $byte ) && "'" === $next_byte ) {
2639 $this->bytes_already_read += 1; // n/N
2640 $type = $this->read_quoted_text( "'" );
2641 if ( self::SINGLE_QUOTED_TEXT === $type ) {
2642 $type = self::NCHAR_TEXT;
2643 }
2644 } elseif ( null === $byte ) {
2645 $type = self::EOF;
2646 } else {
2647 $started_at = $this->bytes_already_read;
2648 $type = $this->read_identifier();
2649 if ( self::IDENTIFIER === $type ) {
2650 // When preceded by a dot, it is always an identifier.
2651 if ( $started_at > 0 && '.' === $this->sql[ $started_at - 1 ] ) {
2652 $type = self::IDENTIFIER;
2653 } elseif ( '_' === $byte && isset( self::UNDERSCORE_CHARSETS[ strtolower( $this->get_current_token_bytes() ) ] ) ) {
2654 $type = self::UNDERSCORE_CHARSET;
2655 } else {
2656 $type = $this->determine_identifier_or_keyword_type( $this->get_current_token_bytes() );
2657 }
2658 }
2659 }
2660 return $type;
2661 }
2662
2663 private function get_current_token_bytes(): string {
2664 return substr(
2665 $this->sql,
2666 $this->token_starts_at,
2667 $this->bytes_already_read - $this->token_starts_at
2668 );
2669 }
2670
2671 /**
2672 * Read an unquoted identifier.
2673 *
2674 * This function reads characters that are allowed in an unquoted identifier.
2675 * An identifier cannot consist solely of digits, but this function doesn't
2676 * ensure that explicitly, as numbers are processed before identifiers in
2677 * the tokenization process, recognizing all digit-only sequences as numbers.
2678 *
2679 * Rules:
2680 * 1. Allowed characters are ASCII a-z, A-Z, 0-9, _, $, and Unicode U+0080-U+FFFF.
2681 * 2. Unquoted identifiers may begin with a digit but may not consist solely of digits.
2682 *
2683 * See:
2684 * https://dev.mysql.com/doc/refman/8.4/en/identifiers.html
2685 */
2686 private function read_identifier(): ?int {
2687 $started_at = $this->bytes_already_read;
2688 while ( true ) {
2689 // First, let's try to parse an ASCII sequence.
2690 $this->bytes_already_read += strspn(
2691 $this->sql,
2692 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$',
2693 $this->bytes_already_read
2694 );
2695
2696 // Check if the following byte can be part of a multibyte character
2697 // in the range of U+0080 to U+FFFF before looking at further bytes.
2698 // If it can't, bail out early to avoid unnecessary UTF-8 decoding.
2699 // Identifiers are usually ASCII-only, so we can optimize for that.
2700 $byte_1 = ord(
2701 $this->sql[ $this->bytes_already_read ] ?? "\0"
2702 );
2703 if ( $byte_1 < 0xC2 || $byte_1 > 0xEF ) {
2704 break;
2705 }
2706
2707 // Look for a valid 2-byte UTF-8 symbol. Covers range U+0080 - U+07FF.
2708 $byte_2 = ord(
2709 $this->sql[ $this->bytes_already_read + 1 ] ?? "\0"
2710 );
2711 if (
2712 $byte_1 <= 0xDF
2713 && $byte_2 >= 0x80 && $byte_2 <= 0xBF
2714 ) {
2715 $this->bytes_already_read += 2;
2716 continue;
2717 }
2718
2719 // Look for a valid 3-byte UTF-8 symbol in range U+0800 - U+FFFF.
2720 $byte_3 = ord(
2721 $this->sql[ $this->bytes_already_read + 2 ] ?? "\0"
2722 );
2723 if (
2724 $byte_1 <= 0xEF
2725 && $byte_2 >= 0x80 && $byte_2 <= 0xBF
2726 && $byte_3 >= 0x80 && $byte_3 <= 0xBF
2727 // Exclude surrogate range U+D800 to U+DFFF:
2728 && ! ( 0xED === $byte_1 && $byte_2 >= 0xA0 )
2729 // Exclude overlong encodings:
2730 && ! ( 0xE0 === $byte_1 && $byte_2 < 0xA0 )
2731 ) {
2732 $this->bytes_already_read += 3;
2733 continue;
2734 }
2735
2736 // Not a valid identifier character.
2737 break;
2738 }
2739
2740 // An identifier cannot consist solely of digits, but we don't need to
2741 // ensure that explicitly, as numbers are processed before identifiers.
2742
2743 return $this->bytes_already_read - $started_at > 0
2744 ? self::IDENTIFIER
2745 : null; // Invalid input.
2746 }
2747
2748 private function read_number(): ?int {
2749 // @TODO: Support numeric-only identifier parts after "." (e.g., 1ea10.1).
2750
2751 $byte = $this->sql[ $this->bytes_already_read ] ?? null;
2752 $next_byte = $this->sql[ $this->bytes_already_read + 1 ] ?? null;
2753 $third_byte = $this->sql[ $this->bytes_already_read + 2 ] ?? null;
2754
2755 if (
2756 // HEX number in the form of 0xN.
2757 (
2758 '0' === $byte
2759 && 'x' === $next_byte
2760 && null !== $third_byte
2761 && strspn( $third_byte, self::HEX_DIGIT_MASK ) > 0
2762 )
2763 // HEX number in the form of x'N' or X'N'.
2764 || ( ( 'x' === $byte || 'X' === $byte ) && "'" === $next_byte )
2765 ) {
2766 $is_quoted = "'" === $next_byte;
2767 $this->bytes_already_read += 2; // Consume "0x" or "x'".
2768 $this->bytes_already_read += strspn( $this->sql, self::HEX_DIGIT_MASK, $this->bytes_already_read );
2769 if ( $is_quoted ) {
2770 if (
2771 $this->bytes_already_read >= $this->sql_length
2772 || "'" !== $this->sql[ $this->bytes_already_read ]
2773 ) {
2774 return null; // Invalid input.
2775 }
2776 $this->bytes_already_read += 1; // Consume the "'".
2777 }
2778 $type = self::HEX_NUMBER;
2779 } elseif (
2780 // BIN number in the form of 0bN.
2781 (
2782 '0' === $byte
2783 && 'b' === $next_byte
2784 && ( '0' === $third_byte || '1' === $third_byte )
2785 )
2786 // BIN number in the form of b'N' or B'N'.
2787 || ( ( 'b' === $byte || 'B' === $byte ) && "'" === $next_byte )
2788 ) {
2789 $is_quoted = "'" === $next_byte;
2790 $this->bytes_already_read += 2; // Consume "0b" or "b'".
2791 $this->bytes_already_read += strspn( $this->sql, '01', $this->bytes_already_read );
2792 if ( $is_quoted ) {
2793 if (
2794 $this->bytes_already_read >= $this->sql_length
2795 || "'" !== $this->sql[ $this->bytes_already_read ]
2796 ) {
2797 return null; // Invalid input.
2798 }
2799 $this->bytes_already_read += 1; // Consume the "'".
2800 }
2801 $type = self::BIN_NUMBER;
2802 } else {
2803 // Here, we have a sequence starting with N or .N, where N is a digit.
2804
2805 // 1. Try integer first.
2806 $this->bytes_already_read += strspn( $this->sql, self::DIGIT_MASK, $this->bytes_already_read );
2807 $type = self::INT_NUMBER;
2808
2809 // 2. In case of N. or .N, it's a decimal or float number.
2810 if ( '.' === ( $this->sql[ $this->bytes_already_read ] ?? null ) ) {
2811 $this->bytes_already_read += 1;
2812 $type = self::DECIMAL_NUMBER;
2813 $this->bytes_already_read += strspn( $this->sql, self::DIGIT_MASK, $this->bytes_already_read );
2814 }
2815
2816 // 3. When exponent is present, it's a float number.
2817 $byte = $this->sql[ $this->bytes_already_read ] ?? null;
2818 $next_byte = $this->sql[ $this->bytes_already_read + 1 ] ?? null;
2819 $has_exponent =
2820 ( 'e' === $byte || 'E' === $byte )
2821 && null !== $next_byte
2822 && (
2823 strspn( $next_byte, self::DIGIT_MASK ) > 0
2824 || (
2825 ( '+' === $next_byte || '-' === $next_byte )
2826 && $this->bytes_already_read + 2 < $this->sql_length
2827 && strspn( $this->sql[ $this->bytes_already_read + 2 ], self::DIGIT_MASK ) > 0
2828 )
2829 );
2830 if ( $has_exponent ) {
2831 $this->bytes_already_read += 1; // Consume the 'e' or 'E'.
2832 $this->bytes_already_read += 1; // Consume the '+', '-', or digit.
2833 $this->bytes_already_read += strspn( $this->sql, self::DIGIT_MASK, $this->bytes_already_read );
2834 $type = self::FLOAT_NUMBER;
2835 }
2836 }
2837
2838 /*
2839 * In MySQL, when an input matches both a number and an identifier, the
2840 * number always wins. However, if the number is followed by a non-numeric
2841 * identifier-like character, then it is recognized as an identifier...
2842 * Unless it's a float number, which ignores any subsequent input.
2843 *
2844 * Examples:
2845 * - "1234" (integer) vs. "1234a" (identifier)
2846 * - "0b01" (bin) vs. "0b012" (identifier)
2847 * - "0xa1" (hex) vs. "0xa1x" (identifier)
2848 * - "12.3" (decimal) vs. "12.3a" (identifier)
2849 * - "1e10" (float) vs. "1e10a" (float, followed by identifier)
2850 */
2851 $text = $this->get_current_token_bytes();
2852 $possible_identifier_prefix =
2853 self::INT_NUMBER === $type
2854 || ( '0' === $text[0] && ( 'b' === $text[1] || 'x' === $text[1] ) );
2855
2856 /*
2857 * When we match some subsequent identifier bytes, it's an identifier.
2858 * Note that the "$this->read_identifier()" method doesn't check that
2859 * the identifier doesn't consist solely of digits. This is an advantage
2860 * here, as we can look only at subsequent bytes instead of backtracking
2861 * to the beginning of the number (for valid identifiers like 0b019).
2862 */
2863 if ( $possible_identifier_prefix && self::IDENTIFIER === $this->read_identifier() ) {
2864 $type = self::IDENTIFIER;
2865 }
2866
2867 // Determine integer type.
2868 if ( self::INT_NUMBER === $type ) {
2869 // Fast path for most integers.
2870 $bytes = $this->get_current_token_bytes();
2871 if ( strlen( $bytes ) < 10 ) {
2872 return self::INT_NUMBER;
2873 }
2874
2875 // Remove leading zeros.
2876 $bytes = substr( $bytes, strspn( $bytes, '0' ) );
2877 $length = strlen( $bytes );
2878
2879 // Determine integer type based on its length and value.
2880 if ( $length < 10 ) {
2881 return self::INT_NUMBER;
2882 } elseif ( 10 === $length ) {
2883 return strcmp( $bytes, '2147483647' ) > 0
2884 ? self::LONG_NUMBER
2885 : self::INT_NUMBER;
2886 } elseif ( $length < 19 ) {
2887 return self::LONG_NUMBER;
2888 } elseif ( 19 === $length ) {
2889 return strcmp( $bytes, '9223372036854775807' ) > 0
2890 ? self::ULONGLONG_NUMBER
2891 : self::LONG_NUMBER;
2892 } elseif ( 20 === $length ) {
2893 return strcmp( $bytes, '18446744073709551615' ) > 0
2894 ? self::DECIMAL_NUMBER
2895 : self::ULONGLONG_NUMBER;
2896 } else {
2897 return self::DECIMAL_NUMBER;
2898 }
2899 }
2900 return $type;
2901 }
2902
2903 /**
2904 * Quoted literals and identifiers:
2905 * https://dev.mysql.com/doc/refman/8.4/en/string-literals.html
2906 * https://dev.mysql.com/doc/refman/8.4/en/identifiers.html
2907 *
2908 * Rules:
2909 * 1. Quotes can be escaped by doubling them ('', "", ``).
2910 * 2. In string literals, backslashes escape the next character,
2911 * unless the NO_BACKSLASH_ESCAPES SQL mode is set.
2912 * 3. In identifiers, backslashes are always literal and never escape.
2913 */
2914 private function read_quoted_text(): ?int {
2915 $quote = $this->sql[ $this->bytes_already_read ];
2916 $this->bytes_already_read += 1; // Consume the quote.
2917
2918 /*
2919 * Determine whether the quote opens an identifier or a string literal.
2920 * An identifier is quoted with a backtick or a double quote when the
2921 * ANSI_QUOTES SQL mode is active. Otherwise, it is a string literal.
2922 *
2923 * See: https://dev.mysql.com/doc/refman/8.4/en/sql-mode.html#sqlmode_ansi_quotes
2924 */
2925 $is_identifier_quote = '`' === $quote
2926 || ( '"' === $quote && $this->is_sql_mode_active( self::SQL_MODE_ANSI_QUOTES ) );
2927
2928 /*
2929 * Backslash escapes apply only to string literals, and only when the
2930 * NO_BACKSLASH_ESCAPES SQL mode is not set.
2931 */
2932 $backslash_is_escape = ! $is_identifier_quote
2933 && ! $this->is_sql_mode_active( self::SQL_MODE_NO_BACKSLASH_ESCAPES );
2934
2935 // We need to look for the closing quote in a loop, as it can be escaped,
2936 // in which case the escape sequence is consumed and the loop continues.
2937 $at = $this->bytes_already_read;
2938 while ( true ) {
2939 $quote_at = strpos( $this->sql, $quote, $at );
2940 if ( false === $quote_at ) {
2941 return null; // Invalid input.
2942 }
2943 $at = $quote_at;
2944
2945 /*
2946 * In string literals, quotes can be escaped with a backslash. When
2947 * NO_BACKSLASH_ESCAPES SQL mode is active, the backslash is treated
2948 * as a regular character. Identifiers never use backslash escaping.
2949 *
2950 * The quote is escaped only when the number of preceding backslashes
2951 * is odd - "\" is an escape sequence, "\\" is an escaped backslash,
2952 * "\\\" is an escaped backslash and an escape sequence, and so on.
2953 *
2954 * The `($at - $i - 1) >= 0` guard prevents PHP's negative-string-
2955 * offset wraparound (PHP 7.1+) when the closing-quote candidate
2956 * sits at the very start of the input. The `?? null` covers
2957 * positive out-of-range indexes belt-and-suspenders.
2958 */
2959 if ( $backslash_is_escape ) {
2960 $i = 0;
2961 while ( ( $at - $i - 1 ) >= 0 && '\\' === ( $this->sql[ $at - $i - 1 ] ?? null ) ) {
2962 $i += 1;
2963 }
2964 if ( 1 === $i % 2 ) {
2965 $at += 1;
2966 continue;
2967 }
2968 }
2969
2970 // Check if the quote is doubled.
2971 if ( ( $this->sql[ $at + 1 ] ?? null ) === $quote ) {
2972 $at += 2;
2973 continue;
2974 }
2975
2976 break;
2977 }
2978 $at += 1;
2979
2980 $this->bytes_already_read = $at;
2981
2982 if ( $is_identifier_quote ) {
2983 return self::BACK_TICK_QUOTED_ID;
2984 }
2985 return '"' === $quote ? self::DOUBLE_QUOTED_TEXT : self::SINGLE_QUOTED_TEXT;
2986 }
2987
2988 private function read_line_comment(): int {
2989 $this->bytes_already_read += strcspn( $this->sql, "\r\n", $this->bytes_already_read );
2990 return self::COMMENT;
2991 }
2992
2993 private function read_mysql_comment(): int {
2994 // @TODO: Consider supporting optimizer hints (/*+ ... */) or document
2995 // that they are not supported.
2996
2997 // MySQL-specific comments in the following forms:
2998 // 1. /*! ... */ - The content is treated as SQL.
2999 // 2. /*!80400 ... */ - SQL when the server version is at least 8.4.0.
3000 // 3. /*!080400 ... */ - The same version in six-digit form (MySQL 8.1+).
3001 //
3002 // See: https://dev.mysql.com/doc/refman/8.4/en/comments.html
3003 $this->bytes_already_read += 3; // Consume the '/*!'.
3004
3005 // Version has 5 digits (Mmmrr) or 6 digits (MMmmrr + whitespace, MySQL 8.1+).
3006 $digit_count = strspn( $this->sql, self::DIGIT_MASK, $this->bytes_already_read, 6 );
3007 $version_length = $digit_count < 5 ? 0 : 5;
3008 if (
3009 6 === $digit_count
3010 && $this->mysql_version >= 80100
3011 && 1 === strspn( $this->sql, self::WHITESPACE_MASK, $this->bytes_already_read + 6, 1 )
3012 ) {
3013 $version_length = 6;
3014 }
3015 $version = (int) substr( $this->sql, $this->bytes_already_read, $version_length );
3016
3017 if ( $this->mysql_version < $version ) {
3018 // Version not satisfied. Treat the content as a regular comment.
3019 $this->read_comment_content();
3020 return self::COMMENT;
3021 } else {
3022 // Version satisfied or not specified. Treat the content as SQL code.
3023 $this->bytes_already_read += $version_length; // Skip the version number.
3024 $this->in_mysql_comment = true;
3025 return self::MYSQL_COMMENT_START;
3026 }
3027 }
3028
3029 private function read_comment_content(): void {
3030 $comment_end = strpos( $this->sql, '*/', $this->bytes_already_read );
3031 if ( false === $comment_end ) {
3032 $this->bytes_already_read = $this->sql_length;
3033 } else {
3034 $this->bytes_already_read = $comment_end + 2;
3035 }
3036 }
3037
3038 private function determine_identifier_or_keyword_type( string $value ): int {
3039 $type = self::TOKENS[ strtoupper( $value ) ] ?? self::IDENTIFIER;
3040 if ( self::IDENTIFIER === $type ) {
3041 return self::IDENTIFIER;
3042 }
3043 return $this->resolve_keyword_type( $type );
3044 }
3045
3046 /**
3047 * Resolve a keyword token id matched in self::TOKENS, applying version gating,
3048 * function-call lookahead, the SQL_MODE_HIGH_NOT_PRECEDENCE rule, and synonyms.
3049 *
3050 * @param int $type A token id already matched in self::TOKENS (never IDENTIFIER).
3051 */
3052 private function resolve_keyword_type( int $type ): int {
3053
3054 // Apply MySQL version specifics (positive number: >= <version>, negative number: < <version>).
3055 if ( isset( self::VERSIONS[ $type ] ) ) {
3056 $version = self::VERSIONS[ $type ];
3057 if ( $this->mysql_version < $version || -$version >= $this->mysql_version ) {
3058 return self::IDENTIFIER;
3059 }
3060 }
3061
3062 // Apply MySQL version ranges manually.
3063 if (
3064 self::MAX_STATEMENT_TIME_SYMBOL === $type
3065 && ! ( $this->mysql_version >= 50704 && $this->mysql_version < 50708 )
3066 ) {
3067 return self::IDENTIFIER;
3068 }
3069
3070 if (
3071 self::NONBLOCKING_SYMBOL === $type
3072 && ! ( $this->mysql_version >= 50700 && $this->mysql_version < 50706 )
3073 ) {
3074 return self::IDENTIFIER;
3075 }
3076
3077 if (
3078 self::REMOTE_SYMBOL === $type
3079 && ( $this->mysql_version >= 80003 && $this->mysql_version < 80014 )
3080 ) {
3081 return self::IDENTIFIER;
3082 }
3083
3084 // Determine function calls.
3085 if ( isset( self::FUNCTIONS[ $type ] ) ) {
3086 // Keep ignored whitespace outside the current token range.
3087 $peek = $this->bytes_already_read;
3088 if ( $this->is_sql_mode_active( self::SQL_MODE_IGNORE_SPACE ) ) {
3089 $peek += strspn( $this->sql, self::WHITESPACE_MASK, $peek );
3090 }
3091 if ( '(' !== ( $this->sql[ $peek ] ?? null ) ) {
3092 return self::IDENTIFIER;
3093 }
3094 }
3095
3096 // With "SQL_MODE_HIGH_NOT_PRECEDENCE" enabled, "NOT" needs to be emitted as a higher priority NOT2 symbol.
3097 if ( self::NOT_SYMBOL === $type && $this->is_sql_mode_active( self::SQL_MODE_HIGH_NOT_PRECEDENCE ) ) {
3098 $type = self::NOT2_SYMBOL;
3099 }
3100
3101 // Apply synonyms.
3102 return self::SYNONYMS[ $type ] ?? $type;
3103 }
3104 }
3105