sql_modes". * The list of the SQL modes is not exhaustive. Only the ones that influence * the lexer behavior are included in this list. * * See: * https://dev.mysql.com/doc/refman/8.4/en/sql-mode.html */ const SQL_MODE_HIGH_NOT_PRECEDENCE = 1; const SQL_MODE_PIPES_AS_CONCAT = 2; const SQL_MODE_IGNORE_SPACE = 4; const SQL_MODE_NO_BACKSLASH_ESCAPES = 8; /** * Character masks for frequently used character classes. * * These are intended to be used with "strspn()" and "strcspn()" functions * for fast character class matching in the SQL payload. */ const WHITESPACE_MASK = " \t\n\r\f"; const DIGIT_MASK = '0123456789'; const HEX_DIGIT_MASK = '0123456789abcdefABCDEF'; /** * Tokens from the MySQL Workbench "predefined.tokens" list. * * This list preserves the token names and IDs from the MySQL Workbench * "predefined.tokens" list, adding some tokens missing from the list. * * See: * https://github.com/mysql/mysql-workbench/blob/8.0.38/library/parsers/grammars/predefined.tokens */ const ACCESSIBLE_SYMBOL = 1; const ACCOUNT_SYMBOL = 2; const ACTION_SYMBOL = 3; const ADD_SYMBOL = 4; const ADDDATE_SYMBOL = 5; const AFTER_SYMBOL = 6; const AGAINST_SYMBOL = 7; const AGGREGATE_SYMBOL = 8; const ALGORITHM_SYMBOL = 9; const ALL_SYMBOL = 10; const ALTER_SYMBOL = 11; const ALWAYS_SYMBOL = 12; const ANALYSE_SYMBOL = 13; const ANALYZE_SYMBOL = 14; const AND_SYMBOL = 15; const ANY_SYMBOL = 16; const AS_SYMBOL = 17; const ASC_SYMBOL = 18; const ASCII_SYMBOL = 19; const ASENSITIVE_SYMBOL = 20; const AT_SYMBOL = 21; const AUTHORS_SYMBOL = 22; const AUTOEXTEND_SIZE_SYMBOL = 23; const AUTO_INCREMENT_SYMBOL = 24; const AVG_ROW_LENGTH_SYMBOL = 25; const AVG_SYMBOL = 26; const BACKUP_SYMBOL = 27; const BEFORE_SYMBOL = 28; const BEGIN_SYMBOL = 29; const BETWEEN_SYMBOL = 30; const BIGINT_SYMBOL = 31; const BINARY_SYMBOL = 32; const BINLOG_SYMBOL = 33; const BIN_NUM_SYMBOL = 34; const BIT_AND_SYMBOL = 35; const BIT_OR_SYMBOL = 36; const BIT_SYMBOL = 37; const BIT_XOR_SYMBOL = 38; const BLOB_SYMBOL = 39; const BLOCK_SYMBOL = 40; const BOOLEAN_SYMBOL = 41; const BOOL_SYMBOL = 42; const BOTH_SYMBOL = 43; const BTREE_SYMBOL = 44; const BY_SYMBOL = 45; const BYTE_SYMBOL = 46; const CACHE_SYMBOL = 47; const CALL_SYMBOL = 48; const CASCADE_SYMBOL = 49; const CASCADED_SYMBOL = 50; const CASE_SYMBOL = 51; const CAST_SYMBOL = 52; const CATALOG_NAME_SYMBOL = 53; const CHAIN_SYMBOL = 54; const CHANGE_SYMBOL = 55; const CHANGED_SYMBOL = 56; const CHANNEL_SYMBOL = 57; const CHARSET_SYMBOL = 58; const CHARACTER_SYMBOL = 59; const CHAR_SYMBOL = 60; const CHECKSUM_SYMBOL = 61; const CHECK_SYMBOL = 62; const CIPHER_SYMBOL = 63; const CLASS_ORIGIN_SYMBOL = 64; const CLIENT_SYMBOL = 65; const CLOSE_SYMBOL = 66; const COALESCE_SYMBOL = 67; const CODE_SYMBOL = 68; const COLLATE_SYMBOL = 69; const COLLATION_SYMBOL = 70; const COLUMNS_SYMBOL = 71; const COLUMN_SYMBOL = 72; const COLUMN_NAME_SYMBOL = 73; const COLUMN_FORMAT_SYMBOL = 74; const COMMENT_SYMBOL = 75; const COMMITTED_SYMBOL = 76; const COMMIT_SYMBOL = 77; const COMPACT_SYMBOL = 78; const COMPLETION_SYMBOL = 79; const COMPRESSED_SYMBOL = 80; const COMPRESSION_SYMBOL = 81; const CONCURRENT_SYMBOL = 82; const CONDITION_SYMBOL = 83; const CONNECTION_SYMBOL = 84; const CONSISTENT_SYMBOL = 85; const CONSTRAINT_SYMBOL = 86; const CONSTRAINT_CATALOG_SYMBOL = 87; const CONSTRAINT_NAME_SYMBOL = 88; const CONSTRAINT_SCHEMA_SYMBOL = 89; const CONTAINS_SYMBOL = 90; const CONTEXT_SYMBOL = 91; const CONTINUE_SYMBOL = 92; const CONTRIBUTORS_SYMBOL = 93; const CONVERT_SYMBOL = 94; const COUNT_SYMBOL = 95; const CPU_SYMBOL = 96; const CREATE_SYMBOL = 97; const CROSS_SYMBOL = 98; const CUBE_SYMBOL = 99; const CURDATE_SYMBOL = 100; const CURRENT_SYMBOL = 101; const CURRENT_DATE_SYMBOL = 102; const CURRENT_TIME_SYMBOL = 103; const CURRENT_TIMESTAMP_SYMBOL = 104; const CURRENT_USER_SYMBOL = 105; const CURSOR_SYMBOL = 106; const CURSOR_NAME_SYMBOL = 107; const CURTIME_SYMBOL = 108; const DATABASE_SYMBOL = 109; const DATABASES_SYMBOL = 110; const DATAFILE_SYMBOL = 111; const DATA_SYMBOL = 112; const DATETIME_SYMBOL = 113; const DATE_ADD_SYMBOL = 114; const DATE_SUB_SYMBOL = 115; const DATE_SYMBOL = 116; const DAYOFMONTH_SYMBOL = 117; const DAY_HOUR_SYMBOL = 118; const DAY_MICROSECOND_SYMBOL = 119; const DAY_MINUTE_SYMBOL = 120; const DAY_SECOND_SYMBOL = 121; const DAY_SYMBOL = 122; const DEALLOCATE_SYMBOL = 123; const DEC_SYMBOL = 124; const DECIMAL_NUM_SYMBOL = 125; const DECIMAL_SYMBOL = 126; const DECLARE_SYMBOL = 127; const DEFAULT_SYMBOL = 128; const DEFAULT_AUTH_SYMBOL = 129; const DEFINER_SYMBOL = 130; const DELAYED_SYMBOL = 131; const DELAY_KEY_WRITE_SYMBOL = 132; const DELETE_SYMBOL = 133; const DESC_SYMBOL = 134; const DESCRIBE_SYMBOL = 135; const DES_KEY_FILE_SYMBOL = 136; const DETERMINISTIC_SYMBOL = 137; const DIAGNOSTICS_SYMBOL = 138; const DIRECTORY_SYMBOL = 139; const DISABLE_SYMBOL = 140; const DISCARD_SYMBOL = 141; const DISK_SYMBOL = 142; const DISTINCT_SYMBOL = 143; const DISTINCTROW_SYMBOL = 144; const DIV_SYMBOL = 145; const DOUBLE_SYMBOL = 146; const DO_SYMBOL = 147; const DROP_SYMBOL = 148; const DUAL_SYMBOL = 149; const DUMPFILE_SYMBOL = 150; const DUPLICATE_SYMBOL = 151; const DYNAMIC_SYMBOL = 152; const EACH_SYMBOL = 153; const ELSE_SYMBOL = 154; const ELSEIF_SYMBOL = 155; const ENABLE_SYMBOL = 156; const ENCLOSED_SYMBOL = 157; const ENCRYPTION_SYMBOL = 158; const END_SYMBOL = 159; const ENDS_SYMBOL = 160; const END_OF_INPUT_SYMBOL = 161; // defined in "predefined.tokens", but not used const ENGINES_SYMBOL = 162; const ENGINE_SYMBOL = 163; const ENUM_SYMBOL = 164; const ERROR_SYMBOL = 165; const ERRORS_SYMBOL = 166; const ESCAPED_SYMBOL = 167; const ESCAPE_SYMBOL = 168; const EVENTS_SYMBOL = 169; const EVENT_SYMBOL = 170; const EVERY_SYMBOL = 171; const EXCHANGE_SYMBOL = 172; const EXECUTE_SYMBOL = 173; const EXISTS_SYMBOL = 174; const EXIT_SYMBOL = 175; const EXPANSION_SYMBOL = 176; const EXPIRE_SYMBOL = 177; const EXPLAIN_SYMBOL = 178; const EXPORT_SYMBOL = 179; const EXTENDED_SYMBOL = 180; const EXTENT_SIZE_SYMBOL = 181; const EXTRACT_SYMBOL = 182; const FALSE_SYMBOL = 183; const FAST_SYMBOL = 184; const FAULTS_SYMBOL = 185; const FETCH_SYMBOL = 186; const FIELDS_SYMBOL = 187; const FILE_SYMBOL = 188; const FILE_BLOCK_SIZE_SYMBOL = 189; const FILTER_SYMBOL = 190; const FIRST_SYMBOL = 191; const FIXED_SYMBOL = 192; const FLOAT4_SYMBOL = 193; const FLOAT8_SYMBOL = 194; const FLOAT_SYMBOL = 195; const FLUSH_SYMBOL = 196; const FOLLOWS_SYMBOL = 197; const FORCE_SYMBOL = 198; const FOREIGN_SYMBOL = 199; const FOR_SYMBOL = 200; const FORMAT_SYMBOL = 201; const FOUND_SYMBOL = 202; const FROM_SYMBOL = 203; const FULL_SYMBOL = 204; const FULLTEXT_SYMBOL = 205; const FUNCTION_SYMBOL = 206; const GET_SYMBOL = 207; const GENERAL_SYMBOL = 208; const GENERATED_SYMBOL = 209; const GROUP_REPLICATION_SYMBOL = 210; const GEOMETRYCOLLECTION_SYMBOL = 211; const GEOMETRY_SYMBOL = 212; const GET_FORMAT_SYMBOL = 213; const GLOBAL_SYMBOL = 214; const GRANT_SYMBOL = 215; const GRANTS_SYMBOL = 216; const GROUP_SYMBOL = 217; const GROUP_CONCAT_SYMBOL = 218; const HANDLER_SYMBOL = 219; const HASH_SYMBOL = 220; const HAVING_SYMBOL = 221; const HELP_SYMBOL = 222; const HIGH_PRIORITY_SYMBOL = 223; const HOST_SYMBOL = 224; const HOSTS_SYMBOL = 225; const HOUR_MICROSECOND_SYMBOL = 226; const HOUR_MINUTE_SYMBOL = 227; const HOUR_SECOND_SYMBOL = 228; const HOUR_SYMBOL = 229; const IDENTIFIED_SYMBOL = 230; const IF_SYMBOL = 231; const IGNORE_SYMBOL = 232; const IGNORE_SERVER_IDS_SYMBOL = 233; const IMPORT_SYMBOL = 234; const INDEXES_SYMBOL = 235; const INDEX_SYMBOL = 236; const INFILE_SYMBOL = 237; const INITIAL_SIZE_SYMBOL = 238; const INNER_SYMBOL = 239; const INOUT_SYMBOL = 240; const INSENSITIVE_SYMBOL = 241; const INSERT_SYMBOL = 242; const INSERT_METHOD_SYMBOL = 243; const INSTANCE_SYMBOL = 244; const INSTALL_SYMBOL = 245; const INTEGER_SYMBOL = 246; const INTERVAL_SYMBOL = 247; const INTO_SYMBOL = 248; const INT_SYMBOL = 249; const INVOKER_SYMBOL = 250; const IN_SYMBOL = 251; const IO_AFTER_GTIDS_SYMBOL = 252; const IO_BEFORE_GTIDS_SYMBOL = 253; const IO_THREAD_SYMBOL = 254; const IO_SYMBOL = 255; const IPC_SYMBOL = 256; const IS_SYMBOL = 257; const ISOLATION_SYMBOL = 258; const ISSUER_SYMBOL = 259; const ITERATE_SYMBOL = 260; const JOIN_SYMBOL = 261; const JSON_SYMBOL = 262; const KEYS_SYMBOL = 263; const KEY_BLOCK_SIZE_SYMBOL = 264; const KEY_SYMBOL = 265; const KILL_SYMBOL = 266; const LANGUAGE_SYMBOL = 267; const LAST_SYMBOL = 268; const LEADING_SYMBOL = 269; const LEAVES_SYMBOL = 270; const LEAVE_SYMBOL = 271; const LEFT_SYMBOL = 272; const LESS_SYMBOL = 273; const LEVEL_SYMBOL = 274; const LIKE_SYMBOL = 275; const LIMIT_SYMBOL = 276; const LINEAR_SYMBOL = 277; const LINES_SYMBOL = 278; const LINESTRING_SYMBOL = 279; const LIST_SYMBOL = 280; const LOAD_SYMBOL = 281; const LOCALTIME_SYMBOL = 282; const LOCALTIMESTAMP_SYMBOL = 283; const LOCAL_SYMBOL = 284; const LOCATOR_SYMBOL = 285; const LOCKS_SYMBOL = 286; const LOCK_SYMBOL = 287; const LOGFILE_SYMBOL = 288; const LOGS_SYMBOL = 289; const LONGBLOB_SYMBOL = 290; const LONGTEXT_SYMBOL = 291; const LONG_NUM_SYMBOL = 292; const LONG_SYMBOL = 293; const LOOP_SYMBOL = 294; const LOW_PRIORITY_SYMBOL = 295; const MASTER_AUTO_POSITION_SYMBOL = 296; const MASTER_BIND_SYMBOL = 297; const MASTER_CONNECT_RETRY_SYMBOL = 298; const MASTER_DELAY_SYMBOL = 299; const MASTER_HOST_SYMBOL = 300; const MASTER_LOG_FILE_SYMBOL = 301; const MASTER_LOG_POS_SYMBOL = 302; const MASTER_PASSWORD_SYMBOL = 303; const MASTER_PORT_SYMBOL = 304; const MASTER_RETRY_COUNT_SYMBOL = 305; const MASTER_SERVER_ID_SYMBOL = 306; const MASTER_SSL_CAPATH_SYMBOL = 307; const MASTER_SSL_CA_SYMBOL = 308; const MASTER_SSL_CERT_SYMBOL = 309; const MASTER_SSL_CIPHER_SYMBOL = 310; const MASTER_SSL_CRL_SYMBOL = 311; const MASTER_SSL_CRLPATH_SYMBOL = 312; const MASTER_SSL_KEY_SYMBOL = 313; const MASTER_SSL_SYMBOL = 314; const MASTER_SSL_VERIFY_SERVER_CERT_SYMBOL = 315; const MASTER_SYMBOL = 316; const MASTER_TLS_VERSION_SYMBOL = 317; const MASTER_USER_SYMBOL = 318; const MASTER_HEARTBEAT_PERIOD_SYMBOL = 319; const MATCH_SYMBOL = 320; const MAX_CONNECTIONS_PER_HOUR_SYMBOL = 321; const MAX_QUERIES_PER_HOUR_SYMBOL = 322; const MAX_ROWS_SYMBOL = 323; const MAX_SIZE_SYMBOL = 324; const MAX_STATEMENT_TIME_SYMBOL = 325; const MAX_SYMBOL = 326; const MAX_UPDATES_PER_HOUR_SYMBOL = 327; const MAX_USER_CONNECTIONS_SYMBOL = 328; const MAXVALUE_SYMBOL = 329; const MEDIUMBLOB_SYMBOL = 330; const MEDIUMINT_SYMBOL = 331; const MEDIUMTEXT_SYMBOL = 332; const MEDIUM_SYMBOL = 333; const MEMORY_SYMBOL = 334; const MERGE_SYMBOL = 335; const MESSAGE_TEXT_SYMBOL = 336; const MICROSECOND_SYMBOL = 337; const MID_SYMBOL = 338; const MIDDLEINT_SYMBOL = 339; const MIGRATE_SYMBOL = 340; const MINUTE_MICROSECOND_SYMBOL = 341; const MINUTE_SECOND_SYMBOL = 342; const MINUTE_SYMBOL = 343; const MIN_ROWS_SYMBOL = 344; const MIN_SYMBOL = 345; const MODE_SYMBOL = 346; const MODIFIES_SYMBOL = 347; const MODIFY_SYMBOL = 348; const MOD_SYMBOL = 349; const MONTH_SYMBOL = 350; const MULTILINESTRING_SYMBOL = 351; const MULTIPOINT_SYMBOL = 352; const MULTIPOLYGON_SYMBOL = 353; const MUTEX_SYMBOL = 354; const MYSQL_ERRNO_SYMBOL = 355; const NAMES_SYMBOL = 356; const NAME_SYMBOL = 357; const NATIONAL_SYMBOL = 358; const NATURAL_SYMBOL = 359; const NCHAR_STRING_SYMBOL = 360; const NCHAR_SYMBOL = 361; const NDB_SYMBOL = 362; const NDBCLUSTER_SYMBOL = 363; const NEG_SYMBOL = 364; const NEVER_SYMBOL = 365; const NEW_SYMBOL = 366; const NEXT_SYMBOL = 367; const NODEGROUP_SYMBOL = 368; const NONE_SYMBOL = 369; const NONBLOCKING_SYMBOL = 370; const NOT_SYMBOL = 371; const NOW_SYMBOL = 372; const NO_SYMBOL = 373; const NO_WAIT_SYMBOL = 374; const NO_WRITE_TO_BINLOG_SYMBOL = 375; const NULL_SYMBOL = 376; const NUMBER_SYMBOL = 377; const NUMERIC_SYMBOL = 378; const NVARCHAR_SYMBOL = 379; const OFFLINE_SYMBOL = 380; const OFFSET_SYMBOL = 381; const OLD_PASSWORD_SYMBOL = 382; const ON_SYMBOL = 383; const ONE_SYMBOL = 384; const ONLINE_SYMBOL = 385; const ONLY_SYMBOL = 386; const OPEN_SYMBOL = 387; const OPTIMIZE_SYMBOL = 388; const OPTIMIZER_COSTS_SYMBOL = 389; const OPTIONS_SYMBOL = 390; const OPTION_SYMBOL = 391; const OPTIONALLY_SYMBOL = 392; const ORDER_SYMBOL = 393; const OR_SYMBOL = 394; const OUTER_SYMBOL = 395; const OUTFILE_SYMBOL = 396; const OUT_SYMBOL = 397; const OWNER_SYMBOL = 398; const PACK_KEYS_SYMBOL = 399; const PAGE_SYMBOL = 400; const PARSER_SYMBOL = 401; const PARTIAL_SYMBOL = 402; const PARTITIONING_SYMBOL = 403; const PARTITIONS_SYMBOL = 404; const PARTITION_SYMBOL = 405; const PASSWORD_SYMBOL = 406; const PHASE_SYMBOL = 407; const PLUGINS_SYMBOL = 408; const PLUGIN_DIR_SYMBOL = 409; const PLUGIN_SYMBOL = 410; const POINT_SYMBOL = 411; const POLYGON_SYMBOL = 412; const PORT_SYMBOL = 413; const POSITION_SYMBOL = 414; const PRECEDES_SYMBOL = 415; const PRECISION_SYMBOL = 416; const PREPARE_SYMBOL = 417; const PRESERVE_SYMBOL = 418; const PREV_SYMBOL = 419; const PRIMARY_SYMBOL = 420; const PRIVILEGES_SYMBOL = 421; const PROCEDURE_SYMBOL = 422; const PROCESS_SYMBOL = 423; const PROCESSLIST_SYMBOL = 424; const PROFILE_SYMBOL = 425; const PROFILES_SYMBOL = 426; const PROXY_SYMBOL = 427; const PURGE_SYMBOL = 428; const QUARTER_SYMBOL = 429; const QUERY_SYMBOL = 430; const QUICK_SYMBOL = 431; const RANGE_SYMBOL = 432; const READS_SYMBOL = 433; const READ_ONLY_SYMBOL = 434; const READ_SYMBOL = 435; const READ_WRITE_SYMBOL = 436; const REAL_SYMBOL = 437; const REBUILD_SYMBOL = 438; const RECOVER_SYMBOL = 439; const REDOFILE_SYMBOL = 440; const REDO_BUFFER_SIZE_SYMBOL = 441; const REDUNDANT_SYMBOL = 442; const REFERENCES_SYMBOL = 443; const REGEXP_SYMBOL = 444; const RELAY_SYMBOL = 445; const RELAYLOG_SYMBOL = 446; const RELAY_LOG_FILE_SYMBOL = 447; const RELAY_LOG_POS_SYMBOL = 448; const RELAY_THREAD_SYMBOL = 449; const RELEASE_SYMBOL = 450; const RELOAD_SYMBOL = 451; const REMOVE_SYMBOL = 452; const RENAME_SYMBOL = 453; const REORGANIZE_SYMBOL = 454; const REPAIR_SYMBOL = 455; const REPEATABLE_SYMBOL = 456; const REPEAT_SYMBOL = 457; const REPLACE_SYMBOL = 458; const REPLICATION_SYMBOL = 459; const REPLICATE_DO_DB_SYMBOL = 460; const REPLICATE_IGNORE_DB_SYMBOL = 461; const REPLICATE_DO_TABLE_SYMBOL = 462; const REPLICATE_IGNORE_TABLE_SYMBOL = 463; const REPLICATE_WILD_DO_TABLE_SYMBOL = 464; const REPLICATE_WILD_IGNORE_TABLE_SYMBOL = 465; const REPLICATE_REWRITE_DB_SYMBOL = 466; const REQUIRE_SYMBOL = 467; const RESET_SYMBOL = 468; const RESIGNAL_SYMBOL = 469; const RESTORE_SYMBOL = 470; const RESTRICT_SYMBOL = 471; const RESUME_SYMBOL = 472; const RETURNED_SQLSTATE_SYMBOL = 473; const RETURNS_SYMBOL = 474; const RETURN_SYMBOL = 475; const REVERSE_SYMBOL = 476; const REVOKE_SYMBOL = 477; const RIGHT_SYMBOL = 478; const RLIKE_SYMBOL = 479; const ROLLBACK_SYMBOL = 480; const ROLLUP_SYMBOL = 481; const ROTATE_SYMBOL = 482; const ROUTINE_SYMBOL = 483; const ROWS_SYMBOL = 484; const ROW_COUNT_SYMBOL = 485; const ROW_FORMAT_SYMBOL = 486; const ROW_SYMBOL = 487; const RTREE_SYMBOL = 488; const SAVEPOINT_SYMBOL = 489; const SCHEDULE_SYMBOL = 490; const SCHEMA_SYMBOL = 491; const SCHEMA_NAME_SYMBOL = 492; const SCHEMAS_SYMBOL = 493; const SECOND_MICROSECOND_SYMBOL = 494; const SECOND_SYMBOL = 495; const SECURITY_SYMBOL = 496; const SELECT_SYMBOL = 497; const SENSITIVE_SYMBOL = 498; const SEPARATOR_SYMBOL = 499; const SERIALIZABLE_SYMBOL = 500; const SERIAL_SYMBOL = 501; const SESSION_SYMBOL = 502; const SERVER_SYMBOL = 503; const SERVER_OPTIONS_SYMBOL = 504; const SESSION_USER_SYMBOL = 505; const SET_SYMBOL = 506; const SET_VAR_SYMBOL = 507; const SHARE_SYMBOL = 508; const SHOW_SYMBOL = 509; const SHUTDOWN_SYMBOL = 510; const SIGNAL_SYMBOL = 511; const SIGNED_SYMBOL = 512; const SIMPLE_SYMBOL = 513; const SLAVE_SYMBOL = 514; const SLOW_SYMBOL = 515; const SMALLINT_SYMBOL = 516; const SNAPSHOT_SYMBOL = 517; const SOME_SYMBOL = 518; const SOCKET_SYMBOL = 519; const SONAME_SYMBOL = 520; const SOUNDS_SYMBOL = 521; const SOURCE_SYMBOL = 522; const SPATIAL_SYMBOL = 523; const SPECIFIC_SYMBOL = 524; const SQLEXCEPTION_SYMBOL = 525; const SQLSTATE_SYMBOL = 526; const SQLWARNING_SYMBOL = 527; const SQL_AFTER_GTIDS_SYMBOL = 528; const SQL_AFTER_MTS_GAPS_SYMBOL = 529; const SQL_BEFORE_GTIDS_SYMBOL = 530; const SQL_BIG_RESULT_SYMBOL = 531; const SQL_BUFFER_RESULT_SYMBOL = 532; const SQL_CACHE_SYMBOL = 533; const SQL_CALC_FOUND_ROWS_SYMBOL = 534; const SQL_NO_CACHE_SYMBOL = 535; const SQL_SMALL_RESULT_SYMBOL = 536; const SQL_SYMBOL = 537; const SQL_THREAD_SYMBOL = 538; const SSL_SYMBOL = 539; const STACKED_SYMBOL = 540; const STARTING_SYMBOL = 541; const STARTS_SYMBOL = 542; const START_SYMBOL = 543; const STATS_AUTO_RECALC_SYMBOL = 544; const STATS_PERSISTENT_SYMBOL = 545; const STATS_SAMPLE_PAGES_SYMBOL = 546; const STATUS_SYMBOL = 547; const STDDEV_SAMP_SYMBOL = 548; const STDDEV_SYMBOL = 549; const STDDEV_POP_SYMBOL = 550; const STD_SYMBOL = 551; const STOP_SYMBOL = 552; const STORAGE_SYMBOL = 553; const STORED_SYMBOL = 554; const STRAIGHT_JOIN_SYMBOL = 555; const STRING_SYMBOL = 556; const SUBCLASS_ORIGIN_SYMBOL = 557; const SUBDATE_SYMBOL = 558; const SUBJECT_SYMBOL = 559; const SUBPARTITIONS_SYMBOL = 560; const SUBPARTITION_SYMBOL = 561; const SUBSTR_SYMBOL = 562; const SUBSTRING_SYMBOL = 563; const SUM_SYMBOL = 564; const SUPER_SYMBOL = 565; const SUSPEND_SYMBOL = 566; const SWAPS_SYMBOL = 567; const SWITCHES_SYMBOL = 568; const SYSDATE_SYMBOL = 569; const SYSTEM_USER_SYMBOL = 570; const TABLES_SYMBOL = 571; const TABLESPACE_SYMBOL = 572; const TABLE_REF_PRIORITY_SYMBOL = 573; const TABLE_SYMBOL = 574; const TABLE_CHECKSUM_SYMBOL = 575; const TABLE_NAME_SYMBOL = 576; const TEMPORARY_SYMBOL = 577; const TEMPTABLE_SYMBOL = 578; const TERMINATED_SYMBOL = 579; const TEXT_SYMBOL = 580; const THAN_SYMBOL = 581; const THEN_SYMBOL = 582; const TIMESTAMP_SYMBOL = 583; const TIMESTAMP_ADD_SYMBOL = 584; const TIMESTAMP_DIFF_SYMBOL = 585; const TIME_SYMBOL = 586; const TINYBLOB_SYMBOL = 587; const TINYINT_SYMBOL = 588; const TINYTEXT_SYMBOL = 589; const TO_SYMBOL = 590; const TRAILING_SYMBOL = 591; const TRANSACTION_SYMBOL = 592; const TRIGGERS_SYMBOL = 593; const TRIGGER_SYMBOL = 594; const TRIM_SYMBOL = 595; const TRUE_SYMBOL = 596; const TRUNCATE_SYMBOL = 597; const TYPES_SYMBOL = 598; const TYPE_SYMBOL = 599; const UDF_RETURNS_SYMBOL = 600; const UNCOMMITTED_SYMBOL = 601; const UNDEFINED_SYMBOL = 602; const UNDOFILE_SYMBOL = 603; const UNDO_BUFFER_SIZE_SYMBOL = 604; const UNDO_SYMBOL = 605; const UNICODE_SYMBOL = 606; const UNINSTALL_SYMBOL = 607; const UNION_SYMBOL = 608; const UNIQUE_SYMBOL = 609; const UNKNOWN_SYMBOL = 610; const UNLOCK_SYMBOL = 611; const UNSIGNED_SYMBOL = 612; const UNTIL_SYMBOL = 613; const UPDATE_SYMBOL = 614; const UPGRADE_SYMBOL = 615; const USAGE_SYMBOL = 616; const USER_RESOURCES_SYMBOL = 617; const USER_SYMBOL = 618; const USE_FRM_SYMBOL = 619; const USE_SYMBOL = 620; const USING_SYMBOL = 621; const UTC_DATE_SYMBOL = 622; const UTC_TIMESTAMP_SYMBOL = 623; const UTC_TIME_SYMBOL = 624; const VALIDATION_SYMBOL = 625; const VALUES_SYMBOL = 626; const VALUE_SYMBOL = 627; const VARBINARY_SYMBOL = 628; const VARCHAR_SYMBOL = 629; const VARCHARACTER_SYMBOL = 630; const VARIABLES_SYMBOL = 631; const VARIANCE_SYMBOL = 632; const VARYING_SYMBOL = 633; const VAR_POP_SYMBOL = 634; const VAR_SAMP_SYMBOL = 635; const VIEW_SYMBOL = 636; const VIRTUAL_SYMBOL = 637; const WAIT_SYMBOL = 638; const WARNINGS_SYMBOL = 639; const WEEK_SYMBOL = 640; const WEIGHT_STRING_SYMBOL = 641; const WHEN_SYMBOL = 642; const WHERE_SYMBOL = 643; const WHILE_SYMBOL = 644; const WITH_SYMBOL = 645; const WITHOUT_SYMBOL = 646; const WORK_SYMBOL = 647; const WRAPPER_SYMBOL = 648; const WRITE_SYMBOL = 649; const X509_SYMBOL = 650; const XA_SYMBOL = 651; const XID_SYMBOL = 652; const XML_SYMBOL = 653; const XOR_SYMBOL = 654; const YEAR_MONTH_SYMBOL = 655; const YEAR_SYMBOL = 656; const ZEROFILL_SYMBOL = 657; const PERSIST_SYMBOL = 658; const ROLE_SYMBOL = 659; const ADMIN_SYMBOL = 660; const INVISIBLE_SYMBOL = 661; const VISIBLE_SYMBOL = 662; const EXCEPT_SYMBOL = 663; const COMPONENT_SYMBOL = 664; const RECURSIVE_SYMBOL = 665; const JSON_OBJECTAGG_SYMBOL = 666; const JSON_ARRAYAGG_SYMBOL = 667; const OF_SYMBOL = 668; const SKIP_SYMBOL = 669; const LOCKED_SYMBOL = 670; const NOWAIT_SYMBOL = 671; const GROUPING_SYMBOL = 672; const PERSIST_ONLY_SYMBOL = 673; const HISTOGRAM_SYMBOL = 674; const BUCKETS_SYMBOL = 675; const REMOTE_SYMBOL = 676; const CLONE_SYMBOL = 677; const CUME_DIST_SYMBOL = 678; const DENSE_RANK_SYMBOL = 679; const EXCLUDE_SYMBOL = 680; const FIRST_VALUE_SYMBOL = 681; const FOLLOWING_SYMBOL = 682; const GROUPS_SYMBOL = 683; const LAG_SYMBOL = 684; const LAST_VALUE_SYMBOL = 685; const LEAD_SYMBOL = 686; const NTH_VALUE_SYMBOL = 687; const NTILE_SYMBOL = 688; const NULLS_SYMBOL = 689; const OTHERS_SYMBOL = 690; const OVER_SYMBOL = 691; const PERCENT_RANK_SYMBOL = 692; const PRECEDING_SYMBOL = 693; const RANK_SYMBOL = 694; const RESPECT_SYMBOL = 695; const ROW_NUMBER_SYMBOL = 696; const TIES_SYMBOL = 697; const UNBOUNDED_SYMBOL = 698; const WINDOW_SYMBOL = 699; const EMPTY_SYMBOL = 700; const JSON_TABLE_SYMBOL = 701; const NESTED_SYMBOL = 702; const ORDINALITY_SYMBOL = 703; const PATH_SYMBOL = 704; const HISTORY_SYMBOL = 705; const REUSE_SYMBOL = 706; const SRID_SYMBOL = 707; const THREAD_PRIORITY_SYMBOL = 708; const RESOURCE_SYMBOL = 709; const SYSTEM_SYMBOL = 710; const VCPU_SYMBOL = 711; const MASTER_PUBLIC_KEY_PATH_SYMBOL = 712; const GET_MASTER_PUBLIC_KEY_SYMBOL = 713; const RESTART_SYMBOL = 714; const DEFINITION_SYMBOL = 715; const DESCRIPTION_SYMBOL = 716; const ORGANIZATION_SYMBOL = 717; const REFERENCE_SYMBOL = 718; const OPTIONAL_SYMBOL = 719; const SECONDARY_SYMBOL = 720; const SECONDARY_ENGINE_SYMBOL = 721; const SECONDARY_LOAD_SYMBOL = 722; const SECONDARY_UNLOAD_SYMBOL = 723; const ACTIVE_SYMBOL = 724; const INACTIVE_SYMBOL = 725; const LATERAL_SYMBOL = 726; const RETAIN_SYMBOL = 727; const OLD_SYMBOL = 728; const NETWORK_NAMESPACE_SYMBOL = 729; const ENFORCED_SYMBOL = 730; const ARRAY_SYMBOL = 731; const OJ_SYMBOL = 732; const MEMBER_SYMBOL = 733; const RANDOM_SYMBOL = 734; const MASTER_COMPRESSION_ALGORITHM_SYMBOL = 735; const MASTER_ZSTD_COMPRESSION_LEVEL_SYMBOL = 736; const PRIVILEGE_CHECKS_USER_SYMBOL = 737; const MASTER_TLS_CIPHERSUITES_SYMBOL = 738; const REQUIRE_ROW_FORMAT_SYMBOL = 739; const PASSWORD_LOCK_TIME_SYMBOL = 740; const FAILED_LOGIN_ATTEMPTS_SYMBOL = 741; const REQUIRE_TABLE_PRIMARY_KEY_CHECK_SYMBOL = 742; const STREAM_SYMBOL = 743; const OFF_SYMBOL = 744; /** * Additional tokens, mostly mirroring the MySQL Workbench lexer grammar. * * These tokens are defined in the MySQL Workbench "MySQLLexer.g4" grammar. * * See: * https://github.com/mysql/mysql-workbench/blob/8.0.38/library/parsers/grammars/MySQLLexer.g4 */ // Punctuators const AT_AT_SIGN_SYMBOL = 745; const AT_SIGN_SYMBOL = 746; const CLOSE_CURLY_SYMBOL = 747; const CLOSE_PAR_SYMBOL = 748; const COLON_SYMBOL = 749; const COMMA_SYMBOL = 750; const DOT_SYMBOL = 751; const OPEN_CURLY_SYMBOL = 752; const OPEN_PAR_SYMBOL = 753; const PARAM_MARKER = 754; const SEMICOLON_SYMBOL = 755; // Operators const ASSIGN_OPERATOR = 756; const BITWISE_AND_OPERATOR = 757; const BITWISE_NOT_OPERATOR = 758; const BITWISE_OR_OPERATOR = 759; const BITWISE_XOR_OPERATOR = 760; const CONCAT_PIPES_SYMBOL = 761; const DIV_OPERATOR = 762; const EQUAL_OPERATOR = 763; const GREATER_OR_EQUAL_OPERATOR = 764; const GREATER_THAN_OPERATOR = 765; const JSON_SEPARATOR_SYMBOL = 766; const JSON_UNQUOTED_SEPARATOR_SYMBOL = 767; const LESS_OR_EQUAL_OPERATOR = 768; const LESS_THAN_OPERATOR = 769; const LOGICAL_AND_OPERATOR = 770; const LOGICAL_NOT_OPERATOR = 771; const LOGICAL_OR_OPERATOR = 772; const MINUS_OPERATOR = 773; const MOD_OPERATOR = 774; const MULT_OPERATOR = 775; const NOT_EQUAL_OPERATOR = 776; const NULL_SAFE_EQUAL_OPERATOR = 777; const PLUS_OPERATOR = 778; const SHIFT_LEFT_OPERATOR = 779; const SHIFT_RIGHT_OPERATOR = 780; // Literals const BACK_TICK_QUOTED_ID = 781; const BIN_NUMBER = 782; const DECIMAL_NUMBER = 783; const DOUBLE_QUOTED_TEXT = 784; const FLOAT_NUMBER = 785; const HEX_NUMBER = 786; const INT_NUMBER = 787; const LONG_NUMBER = 788; const NCHAR_TEXT = 789; const SINGLE_QUOTED_TEXT = 790; const ULONGLONG_NUMBER = 791; // Identifier-like tokens const AT_TEXT_SUFFIX = 792; const IDENTIFIER = 793; const UNDERSCORE_CHARSET = 794; // Other tokens const INT1_SYMBOL = 795; const INT2_SYMBOL = 796; const INT3_SYMBOL = 797; const INT4_SYMBOL = 798; const INT8_SYMBOL = 799; const NOT2_SYMBOL = 800; const NULL2_SYMBOL = 801; const SQL_TSI_DAY_SYMBOL = 802; const SQL_TSI_HOUR_SYMBOL = 803; const SQL_TSI_MICROSECOND_SYMBOL = 804; const SQL_TSI_MINUTE_SYMBOL = 805; const SQL_TSI_MONTH_SYMBOL = 806; const SQL_TSI_QUARTER_SYMBOL = 807; const SQL_TSI_SECOND_SYMBOL = 808; const SQL_TSI_WEEK_SYMBOL = 809; const SQL_TSI_YEAR_SYMBOL = 810; /** * Other tokens, missing in the MySQL Workbench "MySQLLexer.g4" grammar. * * These tokens are missing in the "MySQLLexer.g4" grammar, because the MySQL * Workbench lexer and parser don't cover 100% of the MySQL syntax. */ const INTERSECT_SYMBOL = 811; const ATTRIBUTE_SYMBOL = 812; const SOURCE_AUTO_POSITION_SYMBOL = 813; const SOURCE_BIND_SYMBOL = 814; const SOURCE_COMPRESSION_ALGORITHM_SYMBOL = 815; const SOURCE_CONNECT_RETRY_SYMBOL = 816; const SOURCE_CONNECTION_AUTO_FAILOVER_SYMBOL = 817; const SOURCE_DELAY_SYMBOL = 818; const SOURCE_HEARTBEAT_PERIOD_SYMBOL = 819; const SOURCE_HOST_SYMBOL = 820; const SOURCE_LOG_FILE_SYMBOL = 821; const SOURCE_LOG_POS_SYMBOL = 822; const SOURCE_PASSWORD_SYMBOL = 823; const SOURCE_PORT_SYMBOL = 824; const SOURCE_PUBLIC_KEY_PATH_SYMBOL = 825; const SOURCE_RETRY_COUNT_SYMBOL = 826; const SOURCE_SSL_SYMBOL = 827; const SOURCE_SSL_CA_SYMBOL = 828; const SOURCE_SSL_CAPATH_SYMBOL = 829; const SOURCE_SSL_CERT_SYMBOL = 830; const SOURCE_SSL_CIPHER_SYMBOL = 831; const SOURCE_SSL_CRL_SYMBOL = 832; const SOURCE_SSL_CRLPATH_SYMBOL = 833; const SOURCE_SSL_KEY_SYMBOL = 834; const SOURCE_SSL_VERIFY_SERVER_CERT_SYMBOL = 835; const SOURCE_TLS_CIPHERSUITES_SYMBOL = 836; const SOURCE_TLS_VERSION_SYMBOL = 837; const SOURCE_USER_SYMBOL = 838; const SOURCE_ZSTD_COMPRESSION_LEVEL_SYMBOL = 839; const GET_SOURCE_PUBLIC_KEY_SYMBOL = 840; const GTID_ONLY_SYMBOL = 841; const ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS_SYMBOL = 842; const ZONE_SYMBOL = 843; const INNODB_SYMBOL = 844; // From 5.7.11 defined as is_identifier(..., "INNODB") in "sql_yacc.yy". const TLS_SYMBOL = 845; // Added in 8.0.21. From 8.0.16 defined as is_identifier(..., "TLS") in "sql_yacc.yy". const REDO_LOG_SYMBOL = 846; // From 8.0.21 defined as is_identifier(..., "REDO_LOG") in "sql_yacc.yy". const KEYRING_SYMBOL = 847; const ENGINE_ATTRIBUTE_SYMBOL = 848; const SECONDARY_ENGINE_ATTRIBUTE_SYMBOL = 849; const JSON_VALUE_SYMBOL = 850; const RETURNING_SYMBOL = 851; const GEOMCOLLECTION_SYMBOL = 852; // Comments const COMMENT = 900; const MYSQL_COMMENT_START = 901; const MYSQL_COMMENT_END = 902; // Special tokens const WHITESPACE = 0; const EOF = -1; /** * A map of SQL keyword string values to their corresponding token types. * * This is used for a fast lookup of MySQL keywords during tokenization. */ const TOKENS = array( // Tokens from MySQL 5.7: 'ACCESSIBLE' => self::ACCESSIBLE_SYMBOL, 'ACCOUNT' => self::ACCOUNT_SYMBOL, 'ACTION' => self::ACTION_SYMBOL, 'ADD' => self::ADD_SYMBOL, 'ADDDATE' => self::ADDDATE_SYMBOL, 'AFTER' => self::AFTER_SYMBOL, 'AGAINST' => self::AGAINST_SYMBOL, 'AGGREGATE' => self::AGGREGATE_SYMBOL, 'ALGORITHM' => self::ALGORITHM_SYMBOL, 'ALL' => self::ALL_SYMBOL, 'ALTER' => self::ALTER_SYMBOL, 'ALWAYS' => self::ALWAYS_SYMBOL, 'ANALYSE' => self::ANALYSE_SYMBOL, 'ANALYZE' => self::ANALYZE_SYMBOL, 'AND' => self::AND_SYMBOL, 'ANY' => self::ANY_SYMBOL, 'AS' => self::AS_SYMBOL, 'ASC' => self::ASC_SYMBOL, 'ASCII' => self::ASCII_SYMBOL, 'ASENSITIVE' => self::ASENSITIVE_SYMBOL, 'AT' => self::AT_SYMBOL, 'ATTRIBUTE' => self::ATTRIBUTE_SYMBOL, 'AUTHORS' => self::AUTHORS_SYMBOL, 'AUTO_INCREMENT' => self::AUTO_INCREMENT_SYMBOL, 'AUTOEXTEND_SIZE' => self::AUTOEXTEND_SIZE_SYMBOL, 'AVG' => self::AVG_SYMBOL, 'AVG_ROW_LENGTH' => self::AVG_ROW_LENGTH_SYMBOL, 'BACKUP' => self::BACKUP_SYMBOL, 'BEFORE' => self::BEFORE_SYMBOL, 'BEGIN' => self::BEGIN_SYMBOL, 'BETWEEN' => self::BETWEEN_SYMBOL, 'BIGINT' => self::BIGINT_SYMBOL, 'BIN_NUM' => self::BIN_NUM_SYMBOL, 'BINARY' => self::BINARY_SYMBOL, 'BINLOG' => self::BINLOG_SYMBOL, 'BIT' => self::BIT_SYMBOL, 'BIT_AND' => self::BIT_AND_SYMBOL, 'BIT_OR' => self::BIT_OR_SYMBOL, 'BIT_XOR' => self::BIT_XOR_SYMBOL, 'BLOB' => self::BLOB_SYMBOL, 'BLOCK' => self::BLOCK_SYMBOL, 'BOOL' => self::BOOL_SYMBOL, 'BOOLEAN' => self::BOOLEAN_SYMBOL, 'BOTH' => self::BOTH_SYMBOL, 'BTREE' => self::BTREE_SYMBOL, 'BY' => self::BY_SYMBOL, 'BYTE' => self::BYTE_SYMBOL, 'CACHE' => self::CACHE_SYMBOL, 'CALL' => self::CALL_SYMBOL, 'CASCADE' => self::CASCADE_SYMBOL, 'CASCADED' => self::CASCADED_SYMBOL, 'CASE' => self::CASE_SYMBOL, 'CAST' => self::CAST_SYMBOL, 'CATALOG_NAME' => self::CATALOG_NAME_SYMBOL, 'CHAIN' => self::CHAIN_SYMBOL, 'CHANGE' => self::CHANGE_SYMBOL, 'CHANGED' => self::CHANGED_SYMBOL, 'CHANNEL' => self::CHANNEL_SYMBOL, 'CHAR' => self::CHAR_SYMBOL, 'CHARACTER' => self::CHARACTER_SYMBOL, 'CHARSET' => self::CHARSET_SYMBOL, 'CHECK' => self::CHECK_SYMBOL, 'CHECKSUM' => self::CHECKSUM_SYMBOL, 'CIPHER' => self::CIPHER_SYMBOL, 'CLASS_ORIGIN' => self::CLASS_ORIGIN_SYMBOL, 'CLIENT' => self::CLIENT_SYMBOL, 'CLOSE' => self::CLOSE_SYMBOL, 'COALESCE' => self::COALESCE_SYMBOL, 'CODE' => self::CODE_SYMBOL, 'COLLATE' => self::COLLATE_SYMBOL, 'COLLATION' => self::COLLATION_SYMBOL, 'COLUMN' => self::COLUMN_SYMBOL, 'COLUMN_FORMAT' => self::COLUMN_FORMAT_SYMBOL, 'COLUMN_NAME' => self::COLUMN_NAME_SYMBOL, 'COLUMNS' => self::COLUMNS_SYMBOL, 'COMMENT' => self::COMMENT_SYMBOL, 'COMMIT' => self::COMMIT_SYMBOL, 'COMMITTED' => self::COMMITTED_SYMBOL, 'COMPACT' => self::COMPACT_SYMBOL, 'COMPLETION' => self::COMPLETION_SYMBOL, 'COMPRESSED' => self::COMPRESSED_SYMBOL, 'COMPRESSION' => self::COMPRESSION_SYMBOL, 'CONCURRENT' => self::CONCURRENT_SYMBOL, 'CONDITION' => self::CONDITION_SYMBOL, 'CONNECTION' => self::CONNECTION_SYMBOL, 'CONSISTENT' => self::CONSISTENT_SYMBOL, 'CONSTRAINT' => self::CONSTRAINT_SYMBOL, 'CONSTRAINT_CATALOG' => self::CONSTRAINT_CATALOG_SYMBOL, 'CONSTRAINT_NAME' => self::CONSTRAINT_NAME_SYMBOL, 'CONSTRAINT_SCHEMA' => self::CONSTRAINT_SCHEMA_SYMBOL, 'CONTAINS' => self::CONTAINS_SYMBOL, 'CONTEXT' => self::CONTEXT_SYMBOL, 'CONTINUE' => self::CONTINUE_SYMBOL, 'CONTRIBUTORS' => self::CONTRIBUTORS_SYMBOL, 'CONVERT' => self::CONVERT_SYMBOL, 'COUNT' => self::COUNT_SYMBOL, 'CPU' => self::CPU_SYMBOL, 'CREATE' => self::CREATE_SYMBOL, 'CROSS' => self::CROSS_SYMBOL, 'CUBE' => self::CUBE_SYMBOL, 'CURDATE' => self::CURDATE_SYMBOL, 'CURRENT' => self::CURRENT_SYMBOL, 'CURRENT_DATE' => self::CURRENT_DATE_SYMBOL, 'CURRENT_TIME' => self::CURRENT_TIME_SYMBOL, 'CURRENT_TIMESTAMP' => self::CURRENT_TIMESTAMP_SYMBOL, 'CURRENT_USER' => self::CURRENT_USER_SYMBOL, 'CURSOR' => self::CURSOR_SYMBOL, 'CURSOR_NAME' => self::CURSOR_NAME_SYMBOL, 'CURTIME' => self::CURTIME_SYMBOL, 'DATA' => self::DATA_SYMBOL, 'DATABASE' => self::DATABASE_SYMBOL, 'DATABASES' => self::DATABASES_SYMBOL, 'DATAFILE' => self::DATAFILE_SYMBOL, 'DATE' => self::DATE_SYMBOL, 'DATE_ADD' => self::DATE_ADD_SYMBOL, 'DATE_SUB' => self::DATE_SUB_SYMBOL, 'DATETIME' => self::DATETIME_SYMBOL, 'DAY' => self::DAY_SYMBOL, 'DAY_HOUR' => self::DAY_HOUR_SYMBOL, 'DAY_MICROSECOND' => self::DAY_MICROSECOND_SYMBOL, 'DAY_MINUTE' => self::DAY_MINUTE_SYMBOL, 'DAY_SECOND' => self::DAY_SECOND_SYMBOL, 'DAYOFMONTH' => self::DAYOFMONTH_SYMBOL, 'DEALLOCATE' => self::DEALLOCATE_SYMBOL, 'DEC' => self::DEC_SYMBOL, 'DECIMAL' => self::DECIMAL_SYMBOL, 'DECIMAL_NUM' => self::DECIMAL_NUM_SYMBOL, 'DECLARE' => self::DECLARE_SYMBOL, 'DEFAULT' => self::DEFAULT_SYMBOL, 'DEFAULT_AUTH' => self::DEFAULT_AUTH_SYMBOL, 'DEFINER' => self::DEFINER_SYMBOL, 'DELAY_KEY_WRITE' => self::DELAY_KEY_WRITE_SYMBOL, 'DELAYED' => self::DELAYED_SYMBOL, 'DELETE' => self::DELETE_SYMBOL, 'DES_KEY_FILE' => self::DES_KEY_FILE_SYMBOL, 'DESC' => self::DESC_SYMBOL, 'DESCRIBE' => self::DESCRIBE_SYMBOL, 'DETERMINISTIC' => self::DETERMINISTIC_SYMBOL, 'DIAGNOSTICS' => self::DIAGNOSTICS_SYMBOL, 'DIRECTORY' => self::DIRECTORY_SYMBOL, 'DISABLE' => self::DISABLE_SYMBOL, 'DISCARD' => self::DISCARD_SYMBOL, 'DISK' => self::DISK_SYMBOL, 'DISTINCT' => self::DISTINCT_SYMBOL, 'DISTINCTROW' => self::DISTINCTROW_SYMBOL, 'DIV' => self::DIV_SYMBOL, 'DO' => self::DO_SYMBOL, 'DOUBLE' => self::DOUBLE_SYMBOL, 'DROP' => self::DROP_SYMBOL, 'DUAL' => self::DUAL_SYMBOL, 'DUMPFILE' => self::DUMPFILE_SYMBOL, 'DUPLICATE' => self::DUPLICATE_SYMBOL, 'DYNAMIC' => self::DYNAMIC_SYMBOL, 'EACH' => self::EACH_SYMBOL, 'ELSE' => self::ELSE_SYMBOL, 'ELSEIF' => self::ELSEIF_SYMBOL, 'ENABLE' => self::ENABLE_SYMBOL, 'ENCLOSED' => self::ENCLOSED_SYMBOL, 'ENCRYPTION' => self::ENCRYPTION_SYMBOL, 'END' => self::END_SYMBOL, 'END_OF_INPUT' => self::EOF, 'ENDS' => self::ENDS_SYMBOL, 'ENGINE' => self::ENGINE_SYMBOL, 'ENGINES' => self::ENGINES_SYMBOL, 'ENUM' => self::ENUM_SYMBOL, 'ERROR' => self::ERROR_SYMBOL, 'ERRORS' => self::ERRORS_SYMBOL, 'ESCAPE' => self::ESCAPE_SYMBOL, 'ESCAPED' => self::ESCAPED_SYMBOL, 'EVENT' => self::EVENT_SYMBOL, 'EVENTS' => self::EVENTS_SYMBOL, 'EVERY' => self::EVERY_SYMBOL, 'EXCHANGE' => self::EXCHANGE_SYMBOL, 'EXECUTE' => self::EXECUTE_SYMBOL, 'EXISTS' => self::EXISTS_SYMBOL, 'EXIT' => self::EXIT_SYMBOL, 'EXPANSION' => self::EXPANSION_SYMBOL, 'EXPIRE' => self::EXPIRE_SYMBOL, 'EXPLAIN' => self::EXPLAIN_SYMBOL, 'EXPORT' => self::EXPORT_SYMBOL, 'EXTENDED' => self::EXTENDED_SYMBOL, 'EXTENT_SIZE' => self::EXTENT_SIZE_SYMBOL, 'EXTRACT' => self::EXTRACT_SYMBOL, 'FALSE' => self::FALSE_SYMBOL, 'FAST' => self::FAST_SYMBOL, 'FAULTS' => self::FAULTS_SYMBOL, 'FETCH' => self::FETCH_SYMBOL, 'FIELDS' => self::FIELDS_SYMBOL, 'FILE' => self::FILE_SYMBOL, 'FILE_BLOCK_SIZE' => self::FILE_BLOCK_SIZE_SYMBOL, 'FILTER' => self::FILTER_SYMBOL, 'FIRST' => self::FIRST_SYMBOL, 'FIXED' => self::FIXED_SYMBOL, 'FLOAT' => self::FLOAT_SYMBOL, 'FLOAT4' => self::FLOAT4_SYMBOL, 'FLOAT8' => self::FLOAT8_SYMBOL, 'FLUSH' => self::FLUSH_SYMBOL, 'FOLLOWS' => self::FOLLOWS_SYMBOL, 'FOR' => self::FOR_SYMBOL, 'FORCE' => self::FORCE_SYMBOL, 'FOREIGN' => self::FOREIGN_SYMBOL, 'FORMAT' => self::FORMAT_SYMBOL, 'FOUND' => self::FOUND_SYMBOL, 'FROM' => self::FROM_SYMBOL, 'FULL' => self::FULL_SYMBOL, 'FULLTEXT' => self::FULLTEXT_SYMBOL, 'FUNCTION' => self::FUNCTION_SYMBOL, 'GENERAL' => self::GENERAL_SYMBOL, 'GENERATED' => self::GENERATED_SYMBOL, 'GEOMCOLLECTION' => self::GEOMCOLLECTION_SYMBOL, 'GEOMETRY' => self::GEOMETRY_SYMBOL, 'GEOMETRYCOLLECTION' => self::GEOMETRYCOLLECTION_SYMBOL, 'GET' => self::GET_SYMBOL, 'GET_FORMAT' => self::GET_FORMAT_SYMBOL, 'GLOBAL' => self::GLOBAL_SYMBOL, 'GRANT' => self::GRANT_SYMBOL, 'GRANTS' => self::GRANTS_SYMBOL, 'GROUP' => self::GROUP_SYMBOL, 'GROUP_CONCAT' => self::GROUP_CONCAT_SYMBOL, 'GROUP_REPLICATION' => self::GROUP_REPLICATION_SYMBOL, 'HANDLER' => self::HANDLER_SYMBOL, 'HASH' => self::HASH_SYMBOL, 'HAVING' => self::HAVING_SYMBOL, 'HELP' => self::HELP_SYMBOL, 'HIGH_PRIORITY' => self::HIGH_PRIORITY_SYMBOL, 'HOST' => self::HOST_SYMBOL, 'HOSTS' => self::HOSTS_SYMBOL, 'HOUR' => self::HOUR_SYMBOL, 'HOUR_MICROSECOND' => self::HOUR_MICROSECOND_SYMBOL, 'HOUR_MINUTE' => self::HOUR_MINUTE_SYMBOL, 'HOUR_SECOND' => self::HOUR_SECOND_SYMBOL, 'IDENTIFIED' => self::IDENTIFIED_SYMBOL, 'IF' => self::IF_SYMBOL, 'IGNORE' => self::IGNORE_SYMBOL, 'IGNORE_SERVER_IDS' => self::IGNORE_SERVER_IDS_SYMBOL, 'IMPORT' => self::IMPORT_SYMBOL, 'IN' => self::IN_SYMBOL, 'INDEX' => self::INDEX_SYMBOL, 'INDEXES' => self::INDEXES_SYMBOL, 'INFILE' => self::INFILE_SYMBOL, 'INITIAL_SIZE' => self::INITIAL_SIZE_SYMBOL, 'INNER' => self::INNER_SYMBOL, 'INNODB' => self::INNODB_SYMBOL, 'INOUT' => self::INOUT_SYMBOL, 'INSENSITIVE' => self::INSENSITIVE_SYMBOL, 'INSERT' => self::INSERT_SYMBOL, 'INSERT_METHOD' => self::INSERT_METHOD_SYMBOL, 'INSTALL' => self::INSTALL_SYMBOL, 'INSTANCE' => self::INSTANCE_SYMBOL, 'INT' => self::INT_SYMBOL, 'INT1' => self::INT1_SYMBOL, 'INT2' => self::INT2_SYMBOL, 'INT3' => self::INT3_SYMBOL, 'INT4' => self::INT4_SYMBOL, 'INT8' => self::INT8_SYMBOL, 'INTEGER' => self::INTEGER_SYMBOL, 'INTERVAL' => self::INTERVAL_SYMBOL, 'INTO' => self::INTO_SYMBOL, 'INVOKER' => self::INVOKER_SYMBOL, 'IO' => self::IO_SYMBOL, 'IO_AFTER_GTIDS' => self::IO_AFTER_GTIDS_SYMBOL, 'IO_BEFORE_GTIDS' => self::IO_BEFORE_GTIDS_SYMBOL, 'IO_THREAD' => self::IO_THREAD_SYMBOL, 'IPC' => self::IPC_SYMBOL, 'IS' => self::IS_SYMBOL, 'ISOLATION' => self::ISOLATION_SYMBOL, 'ISSUER' => self::ISSUER_SYMBOL, 'ITERATE' => self::ITERATE_SYMBOL, 'JOIN' => self::JOIN_SYMBOL, 'JSON' => self::JSON_SYMBOL, 'KEY' => self::KEY_SYMBOL, 'KEY_BLOCK_SIZE' => self::KEY_BLOCK_SIZE_SYMBOL, 'KEYS' => self::KEYS_SYMBOL, 'KILL' => self::KILL_SYMBOL, 'LANGUAGE' => self::LANGUAGE_SYMBOL, 'LAST' => self::LAST_SYMBOL, 'LEADING' => self::LEADING_SYMBOL, 'LEAVE' => self::LEAVE_SYMBOL, 'LEAVES' => self::LEAVES_SYMBOL, 'LEFT' => self::LEFT_SYMBOL, 'LESS' => self::LESS_SYMBOL, 'LEVEL' => self::LEVEL_SYMBOL, 'LIKE' => self::LIKE_SYMBOL, 'LIMIT' => self::LIMIT_SYMBOL, 'LINEAR' => self::LINEAR_SYMBOL, 'LINES' => self::LINES_SYMBOL, 'LINESTRING' => self::LINESTRING_SYMBOL, 'LIST' => self::LIST_SYMBOL, 'LOAD' => self::LOAD_SYMBOL, 'LOCAL' => self::LOCAL_SYMBOL, 'LOCALTIME' => self::LOCALTIME_SYMBOL, 'LOCALTIMESTAMP' => self::LOCALTIMESTAMP_SYMBOL, 'LOCATOR' => self::LOCATOR_SYMBOL, 'LOCK' => self::LOCK_SYMBOL, 'LOCKS' => self::LOCKS_SYMBOL, 'LOGFILE' => self::LOGFILE_SYMBOL, 'LOGS' => self::LOGS_SYMBOL, 'LONG' => self::LONG_SYMBOL, 'LONG_NUM' => self::LONG_NUM_SYMBOL, 'LONGBLOB' => self::LONGBLOB_SYMBOL, 'LONGTEXT' => self::LONGTEXT_SYMBOL, 'LOOP' => self::LOOP_SYMBOL, 'LOW_PRIORITY' => self::LOW_PRIORITY_SYMBOL, 'MASTER' => self::MASTER_SYMBOL, 'MASTER_AUTO_POSITION' => self::MASTER_AUTO_POSITION_SYMBOL, 'MASTER_BIND' => self::MASTER_BIND_SYMBOL, 'MASTER_CONNECT_RETRY' => self::MASTER_CONNECT_RETRY_SYMBOL, 'MASTER_DELAY' => self::MASTER_DELAY_SYMBOL, 'MASTER_HEARTBEAT_PERIOD' => self::MASTER_HEARTBEAT_PERIOD_SYMBOL, 'MASTER_HOST' => self::MASTER_HOST_SYMBOL, 'MASTER_LOG_FILE' => self::MASTER_LOG_FILE_SYMBOL, 'MASTER_LOG_POS' => self::MASTER_LOG_POS_SYMBOL, 'MASTER_PASSWORD' => self::MASTER_PASSWORD_SYMBOL, 'MASTER_PORT' => self::MASTER_PORT_SYMBOL, 'MASTER_RETRY_COUNT' => self::MASTER_RETRY_COUNT_SYMBOL, 'MASTER_SERVER_ID' => self::MASTER_SERVER_ID_SYMBOL, 'MASTER_SSL' => self::MASTER_SSL_SYMBOL, 'MASTER_SSL_CA' => self::MASTER_SSL_CA_SYMBOL, 'MASTER_SSL_CAPATH' => self::MASTER_SSL_CAPATH_SYMBOL, 'MASTER_SSL_CERT' => self::MASTER_SSL_CERT_SYMBOL, 'MASTER_SSL_CIPHER' => self::MASTER_SSL_CIPHER_SYMBOL, 'MASTER_SSL_CRL' => self::MASTER_SSL_CRL_SYMBOL, 'MASTER_SSL_CRLPATH' => self::MASTER_SSL_CRLPATH_SYMBOL, 'MASTER_SSL_KEY' => self::MASTER_SSL_KEY_SYMBOL, 'MASTER_SSL_VERIFY_SERVER_CERT' => self::MASTER_SSL_VERIFY_SERVER_CERT_SYMBOL, 'MASTER_TLS_VERSION' => self::MASTER_TLS_VERSION_SYMBOL, 'MASTER_USER' => self::MASTER_USER_SYMBOL, 'MATCH' => self::MATCH_SYMBOL, 'MAX' => self::MAX_SYMBOL, 'MAX_CONNECTIONS_PER_HOUR' => self::MAX_CONNECTIONS_PER_HOUR_SYMBOL, 'MAX_QUERIES_PER_HOUR' => self::MAX_QUERIES_PER_HOUR_SYMBOL, 'MAX_ROWS' => self::MAX_ROWS_SYMBOL, 'MAX_SIZE' => self::MAX_SIZE_SYMBOL, 'MAX_STATEMENT_TIME' => self::MAX_STATEMENT_TIME_SYMBOL, 'MAX_UPDATES_PER_HOUR' => self::MAX_UPDATES_PER_HOUR_SYMBOL, 'MAX_USER_CONNECTIONS' => self::MAX_USER_CONNECTIONS_SYMBOL, 'MAXVALUE' => self::MAXVALUE_SYMBOL, 'MEDIUM' => self::MEDIUM_SYMBOL, 'MEDIUMBLOB' => self::MEDIUMBLOB_SYMBOL, 'MEDIUMINT' => self::MEDIUMINT_SYMBOL, 'MEDIUMTEXT' => self::MEDIUMTEXT_SYMBOL, 'MEMORY' => self::MEMORY_SYMBOL, 'MERGE' => self::MERGE_SYMBOL, 'MESSAGE_TEXT' => self::MESSAGE_TEXT_SYMBOL, 'MICROSECOND' => self::MICROSECOND_SYMBOL, 'MID' => self::MID_SYMBOL, 'MIDDLEINT' => self::MIDDLEINT_SYMBOL, 'MIGRATE' => self::MIGRATE_SYMBOL, 'MIN' => self::MIN_SYMBOL, 'MIN_ROWS' => self::MIN_ROWS_SYMBOL, 'MINUTE' => self::MINUTE_SYMBOL, 'MINUTE_MICROSECOND' => self::MINUTE_MICROSECOND_SYMBOL, 'MINUTE_SECOND' => self::MINUTE_SECOND_SYMBOL, 'MOD' => self::MOD_SYMBOL, 'MODE' => self::MODE_SYMBOL, 'MODIFIES' => self::MODIFIES_SYMBOL, 'MODIFY' => self::MODIFY_SYMBOL, 'MONTH' => self::MONTH_SYMBOL, 'MULTILINESTRING' => self::MULTILINESTRING_SYMBOL, 'MULTIPOINT' => self::MULTIPOINT_SYMBOL, 'MULTIPOLYGON' => self::MULTIPOLYGON_SYMBOL, 'MUTEX' => self::MUTEX_SYMBOL, 'MYSQL_ERRNO' => self::MYSQL_ERRNO_SYMBOL, 'NAME' => self::NAME_SYMBOL, 'NAMES' => self::NAMES_SYMBOL, 'NATIONAL' => self::NATIONAL_SYMBOL, 'NATURAL' => self::NATURAL_SYMBOL, 'NCHAR' => self::NCHAR_SYMBOL, 'NCHAR_STRING' => self::NCHAR_STRING_SYMBOL, 'NDB' => self::NDB_SYMBOL, 'NDBCLUSTER' => self::NDBCLUSTER_SYMBOL, 'NEG' => self::NEG_SYMBOL, 'NEVER' => self::NEVER_SYMBOL, 'NEW' => self::NEW_SYMBOL, 'NEXT' => self::NEXT_SYMBOL, 'NO' => self::NO_SYMBOL, 'NO_WAIT' => self::NO_WAIT_SYMBOL, 'NO_WRITE_TO_BINLOG' => self::NO_WRITE_TO_BINLOG_SYMBOL, 'NODEGROUP' => self::NODEGROUP_SYMBOL, 'NONBLOCKING' => self::NONBLOCKING_SYMBOL, 'NONE' => self::NONE_SYMBOL, 'NOT' => self::NOT_SYMBOL, 'NOW' => self::NOW_SYMBOL, 'NULL' => self::NULL_SYMBOL, 'NUMBER' => self::NUMBER_SYMBOL, 'NUMERIC' => self::NUMERIC_SYMBOL, 'NVARCHAR' => self::NVARCHAR_SYMBOL, 'OFFLINE' => self::OFFLINE_SYMBOL, 'OFFSET' => self::OFFSET_SYMBOL, 'OLD_PASSWORD' => self::OLD_PASSWORD_SYMBOL, 'ON' => self::ON_SYMBOL, 'ONE' => self::ONE_SYMBOL, 'ONLINE' => self::ONLINE_SYMBOL, 'ONLY' => self::ONLY_SYMBOL, 'OPEN' => self::OPEN_SYMBOL, 'OPTIMIZE' => self::OPTIMIZE_SYMBOL, 'OPTIMIZER_COSTS' => self::OPTIMIZER_COSTS_SYMBOL, 'OPTION' => self::OPTION_SYMBOL, 'OPTIONALLY' => self::OPTIONALLY_SYMBOL, 'OPTIONS' => self::OPTIONS_SYMBOL, 'OR' => self::OR_SYMBOL, 'ORDER' => self::ORDER_SYMBOL, 'OUT' => self::OUT_SYMBOL, 'OUTER' => self::OUTER_SYMBOL, 'OUTFILE' => self::OUTFILE_SYMBOL, 'OWNER' => self::OWNER_SYMBOL, 'PACK_KEYS' => self::PACK_KEYS_SYMBOL, 'PAGE' => self::PAGE_SYMBOL, 'PARSER' => self::PARSER_SYMBOL, 'PARTIAL' => self::PARTIAL_SYMBOL, 'PARTITION' => self::PARTITION_SYMBOL, 'PARTITIONING' => self::PARTITIONING_SYMBOL, 'PARTITIONS' => self::PARTITIONS_SYMBOL, 'PASSWORD' => self::PASSWORD_SYMBOL, 'PHASE' => self::PHASE_SYMBOL, 'PLUGIN' => self::PLUGIN_SYMBOL, 'PLUGIN_DIR' => self::PLUGIN_DIR_SYMBOL, 'PLUGINS' => self::PLUGINS_SYMBOL, 'POINT' => self::POINT_SYMBOL, 'POLYGON' => self::POLYGON_SYMBOL, 'PORT' => self::PORT_SYMBOL, 'POSITION' => self::POSITION_SYMBOL, 'PRECEDES' => self::PRECEDES_SYMBOL, 'PRECISION' => self::PRECISION_SYMBOL, 'PREPARE' => self::PREPARE_SYMBOL, 'PRESERVE' => self::PRESERVE_SYMBOL, 'PREV' => self::PREV_SYMBOL, 'PRIMARY' => self::PRIMARY_SYMBOL, 'PRIVILEGES' => self::PRIVILEGES_SYMBOL, 'PROCEDURE' => self::PROCEDURE_SYMBOL, 'PROCESS' => self::PROCESS_SYMBOL, 'PROCESSLIST' => self::PROCESSLIST_SYMBOL, 'PROFILE' => self::PROFILE_SYMBOL, 'PROFILES' => self::PROFILES_SYMBOL, 'PROXY' => self::PROXY_SYMBOL, 'PURGE' => self::PURGE_SYMBOL, 'QUARTER' => self::QUARTER_SYMBOL, 'QUERY' => self::QUERY_SYMBOL, 'QUICK' => self::QUICK_SYMBOL, 'RANGE' => self::RANGE_SYMBOL, 'READ' => self::READ_SYMBOL, 'READ_ONLY' => self::READ_ONLY_SYMBOL, 'READ_WRITE' => self::READ_WRITE_SYMBOL, 'READS' => self::READS_SYMBOL, 'REAL' => self::REAL_SYMBOL, 'REBUILD' => self::REBUILD_SYMBOL, 'RECOVER' => self::RECOVER_SYMBOL, 'REDO_BUFFER_SIZE' => self::REDO_BUFFER_SIZE_SYMBOL, 'REDOFILE' => self::REDOFILE_SYMBOL, 'REDUNDANT' => self::REDUNDANT_SYMBOL, 'REFERENCES' => self::REFERENCES_SYMBOL, 'REGEXP' => self::REGEXP_SYMBOL, 'RELAY' => self::RELAY_SYMBOL, 'RELAY_LOG_FILE' => self::RELAY_LOG_FILE_SYMBOL, 'RELAY_LOG_POS' => self::RELAY_LOG_POS_SYMBOL, 'RELAY_THREAD' => self::RELAY_THREAD_SYMBOL, 'RELAYLOG' => self::RELAYLOG_SYMBOL, 'RELEASE' => self::RELEASE_SYMBOL, 'RELOAD' => self::RELOAD_SYMBOL, 'REMOVE' => self::REMOVE_SYMBOL, 'RENAME' => self::RENAME_SYMBOL, 'REORGANIZE' => self::REORGANIZE_SYMBOL, 'REPAIR' => self::REPAIR_SYMBOL, 'REPEAT' => self::REPEAT_SYMBOL, 'REPEATABLE' => self::REPEATABLE_SYMBOL, 'REPLACE' => self::REPLACE_SYMBOL, 'REPLICATE_DO_DB' => self::REPLICATE_DO_DB_SYMBOL, 'REPLICATE_DO_TABLE' => self::REPLICATE_DO_TABLE_SYMBOL, 'REPLICATE_IGNORE_DB' => self::REPLICATE_IGNORE_DB_SYMBOL, 'REPLICATE_IGNORE_TABLE' => self::REPLICATE_IGNORE_TABLE_SYMBOL, 'REPLICATE_REWRITE_DB' => self::REPLICATE_REWRITE_DB_SYMBOL, 'REPLICATE_WILD_DO_TABLE' => self::REPLICATE_WILD_DO_TABLE_SYMBOL, 'REPLICATE_WILD_IGNORE_TABLE' => self::REPLICATE_WILD_IGNORE_TABLE_SYMBOL, 'REPLICATION' => self::REPLICATION_SYMBOL, 'REQUIRE' => self::REQUIRE_SYMBOL, 'RESET' => self::RESET_SYMBOL, 'RESIGNAL' => self::RESIGNAL_SYMBOL, 'RESTORE' => self::RESTORE_SYMBOL, 'RESTRICT' => self::RESTRICT_SYMBOL, 'RESUME' => self::RESUME_SYMBOL, 'RETURN' => self::RETURN_SYMBOL, 'RETURNED_SQLSTATE' => self::RETURNED_SQLSTATE_SYMBOL, 'RETURNS' => self::RETURNS_SYMBOL, 'REVERSE' => self::REVERSE_SYMBOL, 'REVOKE' => self::REVOKE_SYMBOL, 'RIGHT' => self::RIGHT_SYMBOL, 'RLIKE' => self::RLIKE_SYMBOL, 'ROLLBACK' => self::ROLLBACK_SYMBOL, 'ROLLUP' => self::ROLLUP_SYMBOL, 'ROTATE' => self::ROTATE_SYMBOL, 'ROUTINE' => self::ROUTINE_SYMBOL, 'ROW' => self::ROW_SYMBOL, 'ROW_COUNT' => self::ROW_COUNT_SYMBOL, 'ROW_FORMAT' => self::ROW_FORMAT_SYMBOL, 'ROWS' => self::ROWS_SYMBOL, 'RTREE' => self::RTREE_SYMBOL, 'SAVEPOINT' => self::SAVEPOINT_SYMBOL, 'SCHEDULE' => self::SCHEDULE_SYMBOL, 'SCHEMA' => self::SCHEMA_SYMBOL, 'SCHEMA_NAME' => self::SCHEMA_NAME_SYMBOL, 'SCHEMAS' => self::SCHEMAS_SYMBOL, 'SECOND' => self::SECOND_SYMBOL, 'SECOND_MICROSECOND' => self::SECOND_MICROSECOND_SYMBOL, 'SECURITY' => self::SECURITY_SYMBOL, 'SELECT' => self::SELECT_SYMBOL, 'SENSITIVE' => self::SENSITIVE_SYMBOL, 'SEPARATOR' => self::SEPARATOR_SYMBOL, 'SERIAL' => self::SERIAL_SYMBOL, 'SERIALIZABLE' => self::SERIALIZABLE_SYMBOL, 'SERVER' => self::SERVER_SYMBOL, 'SERVER_OPTIONS' => self::SERVER_OPTIONS_SYMBOL, 'SESSION' => self::SESSION_SYMBOL, 'SESSION_USER' => self::SESSION_USER_SYMBOL, 'SET' => self::SET_SYMBOL, 'SET_VAR' => self::SET_VAR_SYMBOL, 'SHARE' => self::SHARE_SYMBOL, 'SHOW' => self::SHOW_SYMBOL, 'SHUTDOWN' => self::SHUTDOWN_SYMBOL, 'SIGNAL' => self::SIGNAL_SYMBOL, 'SIGNED' => self::SIGNED_SYMBOL, 'SIMPLE' => self::SIMPLE_SYMBOL, 'SLAVE' => self::SLAVE_SYMBOL, 'SLOW' => self::SLOW_SYMBOL, 'SMALLINT' => self::SMALLINT_SYMBOL, 'SNAPSHOT' => self::SNAPSHOT_SYMBOL, 'SOCKET' => self::SOCKET_SYMBOL, 'SOME' => self::SOME_SYMBOL, 'SONAME' => self::SONAME_SYMBOL, 'SOUNDS' => self::SOUNDS_SYMBOL, 'SOURCE' => self::SOURCE_SYMBOL, 'SPATIAL' => self::SPATIAL_SYMBOL, 'SPECIFIC' => self::SPECIFIC_SYMBOL, 'SQL' => self::SQL_SYMBOL, 'SQL_AFTER_GTIDS' => self::SQL_AFTER_GTIDS_SYMBOL, 'SQL_AFTER_MTS_GAPS' => self::SQL_AFTER_MTS_GAPS_SYMBOL, 'SQL_BEFORE_GTIDS' => self::SQL_BEFORE_GTIDS_SYMBOL, 'SQL_BIG_RESULT' => self::SQL_BIG_RESULT_SYMBOL, 'SQL_BUFFER_RESULT' => self::SQL_BUFFER_RESULT_SYMBOL, 'SQL_CACHE' => self::SQL_CACHE_SYMBOL, 'SQL_CALC_FOUND_ROWS' => self::SQL_CALC_FOUND_ROWS_SYMBOL, 'SQL_NO_CACHE' => self::SQL_NO_CACHE_SYMBOL, 'SQL_SMALL_RESULT' => self::SQL_SMALL_RESULT_SYMBOL, 'SQL_THREAD' => self::SQL_THREAD_SYMBOL, 'SQL_TSI_DAY' => self::SQL_TSI_DAY_SYMBOL, 'SQL_TSI_HOUR' => self::SQL_TSI_HOUR_SYMBOL, 'SQL_TSI_MICROSECOND' => self::SQL_TSI_MICROSECOND_SYMBOL, 'SQL_TSI_MINUTE' => self::SQL_TSI_MINUTE_SYMBOL, 'SQL_TSI_MONTH' => self::SQL_TSI_MONTH_SYMBOL, 'SQL_TSI_QUARTER' => self::SQL_TSI_QUARTER_SYMBOL, 'SQL_TSI_SECOND' => self::SQL_TSI_SECOND_SYMBOL, 'SQL_TSI_WEEK' => self::SQL_TSI_WEEK_SYMBOL, 'SQL_TSI_YEAR' => self::SQL_TSI_YEAR_SYMBOL, 'SQLEXCEPTION' => self::SQLEXCEPTION_SYMBOL, 'SQLSTATE' => self::SQLSTATE_SYMBOL, 'SQLWARNING' => self::SQLWARNING_SYMBOL, 'SSL' => self::SSL_SYMBOL, 'STACKED' => self::STACKED_SYMBOL, 'START' => self::START_SYMBOL, 'STARTING' => self::STARTING_SYMBOL, 'STARTS' => self::STARTS_SYMBOL, 'STATS_AUTO_RECALC' => self::STATS_AUTO_RECALC_SYMBOL, 'STATS_PERSISTENT' => self::STATS_PERSISTENT_SYMBOL, 'STATS_SAMPLE_PAGES' => self::STATS_SAMPLE_PAGES_SYMBOL, 'STATUS' => self::STATUS_SYMBOL, 'STD' => self::STD_SYMBOL, 'STDDEV' => self::STDDEV_SYMBOL, 'STDDEV_POP' => self::STDDEV_POP_SYMBOL, 'STDDEV_SAMP' => self::STDDEV_SAMP_SYMBOL, 'STOP' => self::STOP_SYMBOL, 'STORAGE' => self::STORAGE_SYMBOL, 'STORED' => self::STORED_SYMBOL, 'STRAIGHT_JOIN' => self::STRAIGHT_JOIN_SYMBOL, 'STRING' => self::STRING_SYMBOL, 'SUBCLASS_ORIGIN' => self::SUBCLASS_ORIGIN_SYMBOL, 'SUBDATE' => self::SUBDATE_SYMBOL, 'SUBJECT' => self::SUBJECT_SYMBOL, 'SUBPARTITION' => self::SUBPARTITION_SYMBOL, 'SUBPARTITIONS' => self::SUBPARTITIONS_SYMBOL, 'SUBSTR' => self::SUBSTR_SYMBOL, 'SUBSTRING' => self::SUBSTRING_SYMBOL, 'SUM' => self::SUM_SYMBOL, 'SUPER' => self::SUPER_SYMBOL, 'SUSPEND' => self::SUSPEND_SYMBOL, 'SWAPS' => self::SWAPS_SYMBOL, 'SWITCHES' => self::SWITCHES_SYMBOL, 'SYSDATE' => self::SYSDATE_SYMBOL, 'SYSTEM_USER' => self::SYSTEM_USER_SYMBOL, 'TABLE' => self::TABLE_SYMBOL, 'TABLE_CHECKSUM' => self::TABLE_CHECKSUM_SYMBOL, 'TABLE_NAME' => self::TABLE_NAME_SYMBOL, 'TABLE_REF_PRIORITY' => self::TABLE_REF_PRIORITY_SYMBOL, 'TABLES' => self::TABLES_SYMBOL, 'TABLESPACE' => self::TABLESPACE_SYMBOL, 'TEMPORARY' => self::TEMPORARY_SYMBOL, 'TEMPTABLE' => self::TEMPTABLE_SYMBOL, 'TERMINATED' => self::TERMINATED_SYMBOL, 'TEXT' => self::TEXT_SYMBOL, 'THAN' => self::THAN_SYMBOL, 'THEN' => self::THEN_SYMBOL, 'TIME' => self::TIME_SYMBOL, 'TIMESTAMP' => self::TIMESTAMP_SYMBOL, 'TIMESTAMP_ADD' => self::TIMESTAMP_ADD_SYMBOL, 'TIMESTAMP_DIFF' => self::TIMESTAMP_DIFF_SYMBOL, 'TINYBLOB' => self::TINYBLOB_SYMBOL, 'TINYINT' => self::TINYINT_SYMBOL, 'TINYTEXT' => self::TINYTEXT_SYMBOL, 'TO' => self::TO_SYMBOL, 'TRAILING' => self::TRAILING_SYMBOL, 'TRANSACTION' => self::TRANSACTION_SYMBOL, 'TRIGGER' => self::TRIGGER_SYMBOL, 'TRIGGERS' => self::TRIGGERS_SYMBOL, 'TRIM' => self::TRIM_SYMBOL, 'TRUE' => self::TRUE_SYMBOL, 'TRUNCATE' => self::TRUNCATE_SYMBOL, 'TYPE' => self::TYPE_SYMBOL, 'TYPES' => self::TYPES_SYMBOL, 'UDF_RETURNS' => self::UDF_RETURNS_SYMBOL, 'UNCOMMITTED' => self::UNCOMMITTED_SYMBOL, 'UNDEFINED' => self::UNDEFINED_SYMBOL, 'UNDO' => self::UNDO_SYMBOL, 'UNDO_BUFFER_SIZE' => self::UNDO_BUFFER_SIZE_SYMBOL, 'UNDOFILE' => self::UNDOFILE_SYMBOL, 'UNICODE' => self::UNICODE_SYMBOL, 'UNINSTALL' => self::UNINSTALL_SYMBOL, 'UNION' => self::UNION_SYMBOL, 'UNIQUE' => self::UNIQUE_SYMBOL, 'UNKNOWN' => self::UNKNOWN_SYMBOL, 'UNLOCK' => self::UNLOCK_SYMBOL, 'UNSIGNED' => self::UNSIGNED_SYMBOL, 'UNTIL' => self::UNTIL_SYMBOL, 'UPDATE' => self::UPDATE_SYMBOL, 'UPGRADE' => self::UPGRADE_SYMBOL, 'USAGE' => self::USAGE_SYMBOL, 'USE' => self::USE_SYMBOL, 'USE_FRM' => self::USE_FRM_SYMBOL, 'USER' => self::USER_SYMBOL, 'USER_RESOURCES' => self::USER_RESOURCES_SYMBOL, 'USING' => self::USING_SYMBOL, 'UTC_DATE' => self::UTC_DATE_SYMBOL, 'UTC_TIME' => self::UTC_TIME_SYMBOL, 'UTC_TIMESTAMP' => self::UTC_TIMESTAMP_SYMBOL, 'VALIDATION' => self::VALIDATION_SYMBOL, 'VALUE' => self::VALUE_SYMBOL, 'VALUES' => self::VALUES_SYMBOL, 'VAR_POP' => self::VAR_POP_SYMBOL, 'VAR_SAMP' => self::VAR_SAMP_SYMBOL, 'VARBINARY' => self::VARBINARY_SYMBOL, 'VARCHAR' => self::VARCHAR_SYMBOL, 'VARCHARACTER' => self::VARCHARACTER_SYMBOL, 'VARIABLES' => self::VARIABLES_SYMBOL, 'VARIANCE' => self::VARIANCE_SYMBOL, 'VARYING' => self::VARYING_SYMBOL, 'VIEW' => self::VIEW_SYMBOL, 'VIRTUAL' => self::VIRTUAL_SYMBOL, 'WAIT' => self::WAIT_SYMBOL, 'WARNINGS' => self::WARNINGS_SYMBOL, 'WEEK' => self::WEEK_SYMBOL, 'WEIGHT_STRING' => self::WEIGHT_STRING_SYMBOL, 'WHEN' => self::WHEN_SYMBOL, 'WHERE' => self::WHERE_SYMBOL, 'WHILE' => self::WHILE_SYMBOL, 'WITH' => self::WITH_SYMBOL, 'WITHOUT' => self::WITHOUT_SYMBOL, 'WORK' => self::WORK_SYMBOL, 'WRAPPER' => self::WRAPPER_SYMBOL, 'WRITE' => self::WRITE_SYMBOL, 'X509' => self::X509_SYMBOL, 'XA' => self::XA_SYMBOL, 'XID' => self::XID_SYMBOL, 'XML' => self::XML_SYMBOL, 'XOR' => self::XOR_SYMBOL, 'YEAR' => self::YEAR_SYMBOL, 'YEAR_MONTH' => self::YEAR_MONTH_SYMBOL, 'ZEROFILL' => self::ZEROFILL_SYMBOL, // Tokens from MySQL 8.0: 'ACTIVE' => self::ACTIVE_SYMBOL, 'ADMIN' => self::ADMIN_SYMBOL, 'ARRAY' => self::ARRAY_SYMBOL, 'ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS' => self::ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS_SYMBOL, 'BUCKETS' => self::BUCKETS_SYMBOL, 'CLONE' => self::CLONE_SYMBOL, 'COMPONENT' => self::COMPONENT_SYMBOL, 'CUME_DIST' => self::CUME_DIST_SYMBOL, 'DEFINITION' => self::DEFINITION_SYMBOL, 'DENSE_RANK' => self::DENSE_RANK_SYMBOL, 'DESCRIPTION' => self::DESCRIPTION_SYMBOL, 'EMPTY' => self::EMPTY_SYMBOL, 'ENFORCED' => self::ENFORCED_SYMBOL, 'ENGINE_ATTRIBUTE' => self::ENGINE_ATTRIBUTE_SYMBOL, 'EXCEPT' => self::EXCEPT_SYMBOL, 'EXCLUDE' => self::EXCLUDE_SYMBOL, 'FAILED_LOGIN_ATTEMPTS' => self::FAILED_LOGIN_ATTEMPTS_SYMBOL, 'FIRST_VALUE' => self::FIRST_VALUE_SYMBOL, 'FOLLOWING' => self::FOLLOWING_SYMBOL, 'GET_MASTER_PUBLIC_KEY_SYM' => self::GET_MASTER_PUBLIC_KEY_SYMBOL, 'GET_SOURCE_PUBLIC_KEY' => self::GET_SOURCE_PUBLIC_KEY_SYMBOL, 'GROUPING' => self::GROUPING_SYMBOL, 'GROUPS' => self::GROUPS_SYMBOL, 'GTID_ONLY' => self::GTID_ONLY_SYMBOL, 'HISTOGRAM' => self::HISTOGRAM_SYMBOL, 'HISTORY' => self::HISTORY_SYMBOL, 'INACTIVE' => self::INACTIVE_SYMBOL, 'INTERSECT' => self::INTERSECT_SYMBOL, 'INVISIBLE' => self::INVISIBLE_SYMBOL, 'JSON_ARRAYAGG' => self::JSON_ARRAYAGG_SYMBOL, 'JSON_OBJECTAGG' => self::JSON_OBJECTAGG_SYMBOL, 'JSON_TABLE' => self::JSON_TABLE_SYMBOL, 'JSON_VALUE' => self::JSON_VALUE_SYMBOL, 'KEYRING' => self::KEYRING_SYMBOL, 'LAG' => self::LAG_SYMBOL, 'LAST_VALUE' => self::LAST_VALUE_SYMBOL, 'LATERAL' => self::LATERAL_SYMBOL, 'LEAD' => self::LEAD_SYMBOL, 'LOCKED' => self::LOCKED_SYMBOL, 'MASTER_COMPRESSION_ALGORITHM' => self::MASTER_COMPRESSION_ALGORITHM_SYMBOL, 'MASTER_PUBLIC_KEY_PATH' => self::MASTER_PUBLIC_KEY_PATH_SYMBOL, 'MASTER_TLS_CIPHERSUITES' => self::MASTER_TLS_CIPHERSUITES_SYMBOL, 'MASTER_ZSTD_COMPRESSION_LEVEL' => self::MASTER_ZSTD_COMPRESSION_LEVEL_SYMBOL, 'MEMBER' => self::MEMBER_SYMBOL, 'NESTED' => self::NESTED_SYMBOL, 'NETWORK_NAMESPACE' => self::NETWORK_NAMESPACE_SYMBOL, 'NOWAIT' => self::NOWAIT_SYMBOL, 'NTH_VALUE' => self::NTH_VALUE_SYMBOL, 'NTILE' => self::NTILE_SYMBOL, 'NULLS' => self::NULLS_SYMBOL, 'OF' => self::OF_SYMBOL, 'OFF' => self::OFF_SYMBOL, 'OJ' => self::OJ_SYMBOL, 'OLD' => self::OLD_SYMBOL, 'OPTIONAL' => self::OPTIONAL_SYMBOL, 'ORDINALITY' => self::ORDINALITY_SYMBOL, 'ORGANIZATION' => self::ORGANIZATION_SYMBOL, 'OTHERS' => self::OTHERS_SYMBOL, 'OVER' => self::OVER_SYMBOL, 'PASSWORD_LOCK_TIME' => self::PASSWORD_LOCK_TIME_SYMBOL, 'PATH' => self::PATH_SYMBOL, 'PERCENT_RANK' => self::PERCENT_RANK_SYMBOL, 'PERSIST' => self::PERSIST_SYMBOL, 'PERSIST_ONLY' => self::PERSIST_ONLY_SYMBOL, 'PRECEDING' => self::PRECEDING_SYMBOL, 'PRIVILEGE_CHECKS_USER' => self::PRIVILEGE_CHECKS_USER_SYMBOL, 'RANDOM' => self::RANDOM_SYMBOL, 'RANK' => self::RANK_SYMBOL, 'RECURSIVE' => self::RECURSIVE_SYMBOL, 'REDO_LOG' => self::REDO_LOG_SYMBOL, 'REFERENCE' => self::REFERENCE_SYMBOL, 'REMOTE' => self::REMOTE_SYMBOL, 'REQUIRE_ROW_FORMAT' => self::REQUIRE_ROW_FORMAT_SYMBOL, 'REQUIRE_TABLE_PRIMARY_KEY_CHECK' => self::REQUIRE_TABLE_PRIMARY_KEY_CHECK_SYMBOL, 'RESOURCE' => self::RESOURCE_SYMBOL, 'RESPECT' => self::RESPECT_SYMBOL, 'RESTART' => self::RESTART_SYMBOL, 'RETAIN' => self::RETAIN_SYMBOL, 'RETURNING' => self::RETURNING_SYMBOL, 'REUSE' => self::REUSE_SYMBOL, 'ROLE' => self::ROLE_SYMBOL, 'ROW_NUMBER' => self::ROW_NUMBER_SYMBOL, 'SECONDARY' => self::SECONDARY_SYMBOL, 'SECONDARY_ENGINE' => self::SECONDARY_ENGINE_SYMBOL, 'SECONDARY_ENGINE_ATTRIBUTE' => self::SECONDARY_ENGINE_ATTRIBUTE_SYMBOL, 'SECONDARY_LOAD' => self::SECONDARY_LOAD_SYMBOL, 'SECONDARY_UNLOAD' => self::SECONDARY_UNLOAD_SYMBOL, 'SKIP' => self::SKIP_SYMBOL, 'SOURCE_AUTO_POSITION' => self::SOURCE_AUTO_POSITION_SYMBOL, 'SOURCE_BIND' => self::SOURCE_BIND_SYMBOL, 'SOURCE_COMPRESSION_ALGORITHM' => self::SOURCE_COMPRESSION_ALGORITHM_SYMBOL, 'SOURCE_CONNECT_RETRY' => self::SOURCE_CONNECT_RETRY_SYMBOL, 'SOURCE_CONNECTION_AUTO_FAILOVER' => self::SOURCE_CONNECTION_AUTO_FAILOVER_SYMBOL, 'SOURCE_DELAY' => self::SOURCE_DELAY_SYMBOL, 'SOURCE_HEARTBEAT_PERIOD' => self::SOURCE_HEARTBEAT_PERIOD_SYMBOL, 'SOURCE_HOST' => self::SOURCE_HOST_SYMBOL, 'SOURCE_LOG_FILE' => self::SOURCE_LOG_FILE_SYMBOL, 'SOURCE_LOG_POS' => self::SOURCE_LOG_POS_SYMBOL, 'SOURCE_PASSWORD' => self::SOURCE_PASSWORD_SYMBOL, 'SOURCE_PORT' => self::SOURCE_PORT_SYMBOL, 'SOURCE_PUBLIC_KEY_PATH' => self::SOURCE_PUBLIC_KEY_PATH_SYMBOL, 'SOURCE_RETRY_COUNT' => self::SOURCE_RETRY_COUNT_SYMBOL, 'SOURCE_SSL' => self::SOURCE_SSL_SYMBOL, 'SOURCE_SSL_CA' => self::SOURCE_SSL_CA_SYMBOL, 'SOURCE_SSL_CAPATH' => self::SOURCE_SSL_CAPATH_SYMBOL, 'SOURCE_SSL_CERT' => self::SOURCE_SSL_CERT_SYMBOL, 'SOURCE_SSL_CIPHER' => self::SOURCE_SSL_CIPHER_SYMBOL, 'SOURCE_SSL_CRL' => self::SOURCE_SSL_CRL_SYMBOL, 'SOURCE_SSL_CRLPATH' => self::SOURCE_SSL_CRLPATH_SYMBOL, 'SOURCE_SSL_KEY' => self::SOURCE_SSL_KEY_SYMBOL, 'SOURCE_SSL_VERIFY_SERVER_CERT' => self::SOURCE_SSL_VERIFY_SERVER_CERT_SYMBOL, 'SOURCE_TLS_CIPHERSUITES' => self::SOURCE_TLS_CIPHERSUITES_SYMBOL, 'SOURCE_TLS_VERSION' => self::SOURCE_TLS_VERSION_SYMBOL, 'SOURCE_USER' => self::SOURCE_USER_SYMBOL, 'SOURCE_ZSTD_COMPRESSION_LEVEL' => self::SOURCE_ZSTD_COMPRESSION_LEVEL_SYMBOL, 'SRID' => self::SRID_SYMBOL, 'STREAM' => self::STREAM_SYMBOL, 'SYSTEM' => self::SYSTEM_SYMBOL, 'THREAD_PRIORITY' => self::THREAD_PRIORITY_SYMBOL, 'TIES' => self::TIES_SYMBOL, 'TLS' => self::TLS_SYMBOL, 'UNBOUNDED' => self::UNBOUNDED_SYMBOL, 'VCPU' => self::VCPU_SYMBOL, 'VISIBLE' => self::VISIBLE_SYMBOL, 'WINDOW' => self::WINDOW_SYMBOL, 'ZONE' => self::ZONE_SYMBOL, ); /** * Tokens that represent function calls when followed by a parenthesis. */ const FUNCTIONS = array( self::ADDDATE_SYMBOL => true, self::BIT_AND_SYMBOL => true, self::BIT_OR_SYMBOL => true, self::BIT_XOR_SYMBOL => true, self::CAST_SYMBOL => true, self::COUNT_SYMBOL => true, self::CURDATE_SYMBOL => true, self::CURRENT_DATE_SYMBOL => true, self::CURRENT_TIME_SYMBOL => true, self::CURTIME_SYMBOL => true, self::DATE_ADD_SYMBOL => true, self::DATE_SUB_SYMBOL => true, self::EXTRACT_SYMBOL => true, self::GROUP_CONCAT_SYMBOL => true, self::MAX_SYMBOL => true, self::MID_SYMBOL => true, self::MIN_SYMBOL => true, self::NOW_SYMBOL => true, self::POSITION_SYMBOL => true, self::SESSION_USER_SYMBOL => true, self::STD_SYMBOL => true, self::STDDEV_POP_SYMBOL => true, self::STDDEV_SAMP_SYMBOL => true, self::STDDEV_SYMBOL => true, self::SUBDATE_SYMBOL => true, self::SUBSTR_SYMBOL => true, self::SUBSTRING_SYMBOL => true, self::SUM_SYMBOL => true, self::SYSDATE_SYMBOL => true, self::SYSTEM_USER_SYMBOL => true, self::TRIM_SYMBOL => true, self::VAR_POP_SYMBOL => true, self::VAR_SAMP_SYMBOL => true, self::VARIANCE_SYMBOL => true, ); /** * Tokens that are functionally equivalent and can be used interchangeably. * * Some of the synonyms may have a different keyword or function status and * version constraints, hence the synonym conversion needs to be applied * at the end of the tokenization process, after all other transformations. * * E.g.: NOW is a non-reserved keyword that needs to be used with "()" while * CURRENT_TIMESTAMP is a reserved keyword that can be used without "()". */ const SYNONYMS = array( self::CHARACTER_SYMBOL => self::CHAR_SYMBOL, self::CURRENT_DATE_SYMBOL => self::CURDATE_SYMBOL, self::CURRENT_TIME_SYMBOL => self::CURTIME_SYMBOL, self::CURRENT_TIMESTAMP_SYMBOL => self::NOW_SYMBOL, self::DAYOFMONTH_SYMBOL => self::DAY_SYMBOL, self::DEC_SYMBOL => self::DECIMAL_SYMBOL, self::DISTINCTROW_SYMBOL => self::DISTINCT_SYMBOL, self::FIELDS_SYMBOL => self::COLUMNS_SYMBOL, self::FLOAT4_SYMBOL => self::FLOAT_SYMBOL, self::FLOAT8_SYMBOL => self::DOUBLE_SYMBOL, self::GEOMCOLLECTION_SYMBOL => self::GEOMETRYCOLLECTION_SYMBOL, self::INT1_SYMBOL => self::TINYINT_SYMBOL, self::INT2_SYMBOL => self::SMALLINT_SYMBOL, self::INT3_SYMBOL => self::MEDIUMINT_SYMBOL, self::INT4_SYMBOL => self::INT_SYMBOL, self::INT8_SYMBOL => self::BIGINT_SYMBOL, self::INTEGER_SYMBOL => self::INT_SYMBOL, self::IO_THREAD_SYMBOL => self::RELAY_THREAD_SYMBOL, self::LOCALTIME_SYMBOL => self::NOW_SYMBOL, self::LOCALTIMESTAMP_SYMBOL => self::NOW_SYMBOL, self::MID_SYMBOL => self::SUBSTRING_SYMBOL, self::MIDDLEINT_SYMBOL => self::MEDIUMINT_SYMBOL, self::NDB_SYMBOL => self::NDBCLUSTER_SYMBOL, self::RLIKE_SYMBOL => self::REGEXP_SYMBOL, self::SCHEMA_SYMBOL => self::DATABASE_SYMBOL, self::SCHEMAS_SYMBOL => self::DATABASES_SYMBOL, self::SESSION_USER_SYMBOL => self::USER_SYMBOL, self::SOME_SYMBOL => self::ANY_SYMBOL, self::SQL_TSI_DAY_SYMBOL => self::DAY_SYMBOL, self::SQL_TSI_HOUR_SYMBOL => self::HOUR_SYMBOL, self::SQL_TSI_MICROSECOND_SYMBOL => self::MICROSECOND_SYMBOL, self::SQL_TSI_MINUTE_SYMBOL => self::MINUTE_SYMBOL, self::SQL_TSI_MONTH_SYMBOL => self::MONTH_SYMBOL, self::SQL_TSI_QUARTER_SYMBOL => self::QUARTER_SYMBOL, self::SQL_TSI_SECOND_SYMBOL => self::SECOND_SYMBOL, self::SQL_TSI_WEEK_SYMBOL => self::WEEK_SYMBOL, self::SQL_TSI_YEAR_SYMBOL => self::YEAR_SYMBOL, self::STDDEV_POP_SYMBOL => self::STD_SYMBOL, self::STDDEV_SYMBOL => self::STD_SYMBOL, self::SUBSTR_SYMBOL => self::SUBSTRING_SYMBOL, self::SYSTEM_USER_SYMBOL => self::USER_SYMBOL, self::VAR_POP_SYMBOL => self::VARIANCE_SYMBOL, self::VARCHARACTER_SYMBOL => self::VARCHAR_SYMBOL, ); /** * Version constraints for version-specific tokens. * * This is a map of tokens to the MySQL server versions in which they were * introduced (positive number) or removed (negative number). Tokens that * were both introduced and later removed are not included in this list * and are handled by manual version checks in the tokenization process. * * See: * https://dev.mysql.com/doc/mysqld-version-reference/en/keywords.html * * @TODO Verify the version specifiers and ranges against the list above. * * Positive number: >= (introduced in ) * Negative number: < (removed in ) */ const VERSIONS = array( // MySQL 5 self::ACCOUNT_SYMBOL => 50707, self::ALWAYS_SYMBOL => 50707, self::ANALYSE_SYMBOL => -80000, self::AUTHORS_SYMBOL => -50700, self::CHANNEL_SYMBOL => 50706, self::COMPRESSION_SYMBOL => 50707, self::CONTRIBUTORS_SYMBOL => -50700, self::CURRENT_SYMBOL => 50604, self::DEFAULT_AUTH_SYMBOL => 50604, self::DES_KEY_FILE_SYMBOL => -80003, self::ENCRYPTION_SYMBOL => 50711, self::EXPIRE_SYMBOL => 50606, self::EXPORT_SYMBOL => 50606, self::FILE_BLOCK_SIZE_SYMBOL => 50707, self::FILTER_SYMBOL => 50700, self::FOLLOWS_SYMBOL => 50700, self::GENERATED_SYMBOL => 50707, self::GET_SYMBOL => 50604, self::GROUP_REPLICATION_SYMBOL => 50707, self::INNODB_SYMBOL => 50711, self::INSTANCE_SYMBOL => 50713, self::JSON_SYMBOL => 50708, self::MASTER_AUTO_POSITION_SYMBOL => 50605, self::MASTER_BIND_SYMBOL => 50602, self::MASTER_RETRY_COUNT_SYMBOL => 50601, self::MASTER_SSL_CRL_SYMBOL => 50603, self::MASTER_SSL_CRLPATH_SYMBOL => 50603, self::MASTER_TLS_VERSION_SYMBOL => 50713, self::NEVER_SYMBOL => 50704, self::NUMBER_SYMBOL => 50606, self::OLD_PASSWORD_SYMBOL => -50706, self::ONLY_SYMBOL => 50605, self::OPTIMIZER_COSTS_SYMBOL => 50706, self::PLUGIN_DIR_SYMBOL => 50604, self::PRECEDES_SYMBOL => 50700, self::REDOFILE_SYMBOL => -80000, self::REPLICATE_DO_DB_SYMBOL => 50700, self::REPLICATE_DO_TABLE_SYMBOL => 50700, self::REPLICATE_IGNORE_DB_SYMBOL => 50700, self::REPLICATE_IGNORE_TABLE_SYMBOL => 50700, self::REPLICATE_REWRITE_DB_SYMBOL => 50700, self::REPLICATE_WILD_DO_TABLE_SYMBOL => 50700, self::REPLICATE_WILD_IGNORE_TABLE_SYMBOL => 50700, self::ROTATE_SYMBOL => 50713, self::SQL_AFTER_MTS_GAPS_SYMBOL => 50606, self::SQL_CACHE_SYMBOL => -80000, self::STACKED_SYMBOL => 50700, self::STORED_SYMBOL => 50707, self::TABLE_REF_PRIORITY_SYMBOL => -80000, self::VALIDATION_SYMBOL => 50706, self::VIRTUAL_SYMBOL => 50707, self::XID_SYMBOL => 50704, // MySQL 8 self::ACTIVE_SYMBOL => 80014, self::ADMIN_SYMBOL => 80000, self::ARRAY_SYMBOL => 80017, self::ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS_SYMBOL => 80000, self::ATTRIBUTE_SYMBOL => 80021, self::BUCKETS_SYMBOL => 80000, self::CLONE_SYMBOL => 80000, self::COMPONENT_SYMBOL => 80000, self::CUME_DIST_SYMBOL => 80000, self::DEFINITION_SYMBOL => 80011, self::DENSE_RANK_SYMBOL => 80000, self::DESCRIPTION_SYMBOL => 80011, self::EMPTY_SYMBOL => 80000, self::ENFORCED_SYMBOL => 80017, self::ENGINE_ATTRIBUTE_SYMBOL => 80021, self::EXCEPT_SYMBOL => 80000, self::EXCLUDE_SYMBOL => 80000, self::FAILED_LOGIN_ATTEMPTS_SYMBOL => 80019, self::FIRST_VALUE_SYMBOL => 80000, self::FOLLOWING_SYMBOL => 80000, self::GEOMCOLLECTION_SYMBOL => 80000, self::GET_MASTER_PUBLIC_KEY_SYMBOL => 80000, self::GET_SOURCE_PUBLIC_KEY_SYMBOL => 80000, self::GROUPING_SYMBOL => 80000, self::GROUPS_SYMBOL => 80000, self::GTID_ONLY_SYMBOL => 80000, self::HISTOGRAM_SYMBOL => 80000, self::HISTORY_SYMBOL => 80000, self::INACTIVE_SYMBOL => 80014, self::INTERSECT_SYMBOL => 80031, self::INVISIBLE_SYMBOL => 80000, self::JSON_ARRAYAGG_SYMBOL => 80000, self::JSON_OBJECTAGG_SYMBOL => 80000, self::JSON_TABLE_SYMBOL => 80000, self::JSON_VALUE_SYMBOL => 80021, self::KEYRING_SYMBOL => 80024, self::LAG_SYMBOL => 80000, self::LAST_VALUE_SYMBOL => 80000, self::LATERAL_SYMBOL => 80014, self::LEAD_SYMBOL => 80000, self::LOCKED_SYMBOL => 80000, self::MASTER_COMPRESSION_ALGORITHM_SYMBOL => 80018, self::MASTER_PUBLIC_KEY_PATH_SYMBOL => 80000, self::MASTER_TLS_CIPHERSUITES_SYMBOL => 80018, self::MASTER_ZSTD_COMPRESSION_LEVEL_SYMBOL => 80018, self::MEMBER_SYMBOL => 80017, self::NESTED_SYMBOL => 80000, self::NETWORK_NAMESPACE_SYMBOL => 80017, self::NOWAIT_SYMBOL => 80000, self::NTH_VALUE_SYMBOL => 80000, self::NTILE_SYMBOL => 80000, self::NULLS_SYMBOL => 80000, self::OF_SYMBOL => 80000, self::OFF_SYMBOL => 80019, self::OJ_SYMBOL => 80017, self::OLD_SYMBOL => 80014, self::OPTIONAL_SYMBOL => 80013, self::ORDINALITY_SYMBOL => 80000, self::ORGANIZATION_SYMBOL => 80011, self::OTHERS_SYMBOL => 80000, self::OVER_SYMBOL => 80000, self::PASSWORD_LOCK_TIME_SYMBOL => 80019, self::PATH_SYMBOL => 80000, self::PERCENT_RANK_SYMBOL => 80000, self::PERSIST_ONLY_SYMBOL => 80000, self::PERSIST_SYMBOL => 80000, self::PRECEDING_SYMBOL => 80000, self::PRIVILEGE_CHECKS_USER_SYMBOL => 80018, self::RANDOM_SYMBOL => 80018, self::RANK_SYMBOL => 80000, self::RECURSIVE_SYMBOL => 80000, self::REDO_LOG_SYMBOL => 80021, self::REFERENCE_SYMBOL => 80011, self::REQUIRE_ROW_FORMAT_SYMBOL => 80019, self::REQUIRE_TABLE_PRIMARY_KEY_CHECK_SYMBOL => 80019, self::RESOURCE_SYMBOL => 80000, self::RESPECT_SYMBOL => 80000, self::RESTART_SYMBOL => 80011, self::RETAIN_SYMBOL => 80014, self::REUSE_SYMBOL => 80000, self::RETURNING_SYMBOL => 80021, self::ROLE_SYMBOL => 80000, self::ROW_NUMBER_SYMBOL => 80000, self::SECONDARY_ENGINE_ATTRIBUTE_SYMBOL => 80021, self::SECONDARY_ENGINE_SYMBOL => 80013, self::SECONDARY_LOAD_SYMBOL => 80013, self::SECONDARY_SYMBOL => 80013, self::SECONDARY_UNLOAD_SYMBOL => 80013, self::SKIP_SYMBOL => 80000, self::SOURCE_AUTO_POSITION_SYMBOL => 80000, self::SOURCE_BIND_SYMBOL => 80000, self::SOURCE_COMPRESSION_ALGORITHM_SYMBOL => 80000, self::SOURCE_CONNECT_RETRY_SYMBOL => 80000, self::SOURCE_CONNECTION_AUTO_FAILOVER_SYMBOL => 80000, self::SOURCE_DELAY_SYMBOL => 80000, self::SOURCE_HEARTBEAT_PERIOD_SYMBOL => 80000, self::SOURCE_HOST_SYMBOL => 80000, self::SOURCE_LOG_FILE_SYMBOL => 80000, self::SOURCE_LOG_POS_SYMBOL => 80000, self::SOURCE_PASSWORD_SYMBOL => 80000, self::SOURCE_PORT_SYMBOL => 80000, self::SOURCE_PUBLIC_KEY_PATH_SYMBOL => 80000, self::SOURCE_RETRY_COUNT_SYMBOL => 80000, self::SOURCE_SSL_CA_SYMBOL => 80000, self::SOURCE_SSL_CAPATH_SYMBOL => 80000, self::SOURCE_SSL_CERT_SYMBOL => 80000, self::SOURCE_SSL_CIPHER_SYMBOL => 80000, self::SOURCE_SSL_CRL_SYMBOL => 80000, self::SOURCE_SSL_CRLPATH_SYMBOL => 80000, self::SOURCE_SSL_KEY_SYMBOL => 80000, self::SOURCE_SSL_SYMBOL => 80000, self::SOURCE_SSL_VERIFY_SERVER_CERT_SYMBOL => 80000, self::SOURCE_TLS_CIPHERSUITES_SYMBOL => 80000, self::SOURCE_TLS_VERSION_SYMBOL => 80000, self::SOURCE_USER_SYMBOL => 80000, self::SOURCE_ZSTD_COMPRESSION_LEVEL_SYMBOL => 80000, self::SRID_SYMBOL => 80000, self::STREAM_SYMBOL => 80019, self::SYSTEM_SYMBOL => 80000, self::THREAD_PRIORITY_SYMBOL => 80000, self::TIES_SYMBOL => 80000, self::TLS_SYMBOL => 80016, self::UNBOUNDED_SYMBOL => 80000, self::VCPU_SYMBOL => 80000, self::VISIBLE_SYMBOL => 80000, self::WINDOW_SYMBOL => 80000, self::ZONE_SYMBOL => 80022, ); /** * Identifier-like strings that may represent underscore-prefixed charset names. * * Includes charsets from both MySQL 5 and 8; via "SHOW CHARACTER SET"/docs: * https://dev.mysql.com/doc/refman/5.7/en/charset-charsets.html * https://dev.mysql.com/doc/refman/8.4/en/charset-charsets.html * * @TODO: Make the list respect the MySQL version. The _utf8 underscore charset * exists only on MySQL 5, and maybe some others are version-dependant too. * We can check this using SHOW CHARACTER SET on different MySQL versions. */ const UNDERSCORE_CHARSETS = array( '_armscii8' => true, '_ascii' => true, '_big5' => true, '_binary' => true, '_cp1250' => true, '_cp1251' => true, '_cp1256' => true, '_cp1257' => true, '_cp850' => true, '_cp852' => true, '_cp866' => true, '_cp932' => true, '_dec8' => true, '_eucjpms' => true, '_euckr' => true, '_gb18030' => true, '_gb2312' => true, '_gbk' => true, '_geostd8' => true, '_greek' => true, '_hebrew' => true, '_hp8' => true, '_keybcs2' => true, '_koi8r' => true, '_koi8u' => true, '_latin1' => true, '_latin2' => true, '_latin5' => true, '_latin7' => true, '_macce' => true, '_macroman' => true, '_sjis' => true, '_swe7' => true, '_tis620' => true, '_ucs2' => true, '_ujis' => true, '_utf16' => true, '_utf16le' => true, '_utf32' => true, '_utf8' => true, '_utf8mb3' => true, '_utf8mb4' => true, ); /** * The SQL payload to tokenize. * * @var string */ private $sql; /** * Byte length of the SQL payload. * * @var int */ private $sql_length; /** * The version of the MySQL server that the SQL payload is intended for. * * This is used to determine which tokens are valid for the given MySQL * version, and how some tokens should be interpreted. * * @var int */ private $mysql_version; /** * The SQL modes that should be considered active during tokenization. * * This is an integer that represents currently active SQL modes as a bitmask. * The SQL modes are defined as "SQL_MODE_"-prefixed constants in this class. * The list of the SQL modes isn't exhaustive, as only some affect tokenization. * * @var int */ private $sql_modes = 0; /** * How many bytes from the original SQL payload have been read and tokenized. * * This is an internal cursor that is used to track the current position in * the SQL payload during tokenization. When used as an index in the SQL * payload, it points to the next byte to read. * * @var int */ private $bytes_already_read = 0; /** * Byte offset in the SQL payload where current token starts. * * This is used to extract the token bytes after the token is processed. * The bytes of the current token are represented by "$this->sql" in range * from "$this->token_starts_at" to "$this->bytes_already_read - 1". * * @var int */ private $token_starts_at = 0; /** * The type of the current token. * * When a token is successfully recognized and read, this value is set to the * constant representing the token type. When no token was read yet, or the * end of the SQL payload or an invalid token is reached, this value is null. * * @var int|null */ private $token_type; /** * Whether the tokenizer is inside an active MySQL-specific comment. * * MySQL supports a special comment syntax whose content is recognized as * a comment by most database engines, but can be treated as SQL by MySQL: * * 1. /*! ... - The content is treated as SQL. * 2. /*!12345 - The content is treated as SQL when "MySQL version >= 12345". * * @var bool */ private $in_mysql_comment = false; /** * @param string $sql The SQL payload to tokenize. * @param int $mysql_version The version of the MySQL server that the SQL payload is intended for. * @param string[] $sql_modes The SQL modes that should be considered active during tokenization. */ public function __construct( string $sql, int $mysql_version = 80038, array $sql_modes = array() ) { $this->sql = $sql; $this->sql_length = strlen( $sql ); $this->mysql_version = $mysql_version; foreach ( $sql_modes as $sql_mode ) { $sql_mode = strtoupper( $sql_mode ); if ( 'HIGH_NOT_PRECEDENCE' === $sql_mode ) { $this->sql_modes |= self::SQL_MODE_HIGH_NOT_PRECEDENCE; } elseif ( 'PIPES_AS_CONCAT' === $sql_mode ) { $this->sql_modes |= self::SQL_MODE_PIPES_AS_CONCAT; } elseif ( 'IGNORE_SPACE' === $sql_mode ) { $this->sql_modes |= self::SQL_MODE_IGNORE_SPACE; } elseif ( 'NO_BACKSLASH_ESCAPES' === $sql_mode ) { $this->sql_modes |= self::SQL_MODE_NO_BACKSLASH_ESCAPES; } } } /** * Read the next token from the SQL payload and return it as a token object. * * This method reads bytes from the SQL payload until a token is recognized. * It starts from "$this->sql[ $this->bytes_already_read ]", advances the * number of bytes read, and returns a boolean indicating whether a token * was successfully recognized and read. When the end of the SQL payload * or an invalid token is reached, the method returns false. * * @return bool Whether a token was successfully recognized and read. */ public function next_token(): bool { // We already reached the end of the SQL payload or an invalid token. // Don't attempt to read any more bytes, and bail out immediately. if ( self::EOF === $this->token_type || ( null === $this->token_type && $this->bytes_already_read > 0 ) ) { $this->token_type = null; return false; } // Skip leading whitespace inline for optimal performance. $this->bytes_already_read += strspn( $this->sql, self::WHITESPACE_MASK, $this->bytes_already_read ); do { $this->token_starts_at = $this->bytes_already_read; $this->token_type = $this->read_next_token(); } while ( self::WHITESPACE === $this->token_type || self::COMMENT === $this->token_type || self::MYSQL_COMMENT_START === $this->token_type || self::MYSQL_COMMENT_END === $this->token_type ); // Invalid input. if ( null === $this->token_type ) { return false; } return true; } /** * Return the current token represented as a WP_MySQL_Token object. * * When no token was read yet, or the end of the SQL payload or an invalid * token is reached, the method returns null. * * @TODO: Consider referential stability ($lexer->get_token() === $lexer->get_token()), * or separate getters for the token type and token bytes (no token objects). * * @return WP_MySQL_Token|null An object representing the next recognized token or null. */ public function get_token(): ?WP_MySQL_Token { if ( null === $this->token_type ) { return null; } return new WP_MySQL_Token( $this->token_type, $this->token_starts_at, $this->bytes_already_read - $this->token_starts_at, $this->sql, $this->is_sql_mode_active( self::SQL_MODE_NO_BACKSLASH_ESCAPES ) ); } /** * Read all remaining tokens from the SQL payload and return them as an array. * * This method starts from the current position in the SQL payload, as marked * by "$this->sql[ $this->bytes_already_read ]", and reads all tokens until * the end of the SQL payload is reached, returning an array of token objects. * * When an invalid token is reached, the method stops and returns the partial * sequence of valid tokens. In this case, the EOF token will not be included. * * This method can be used to tokenize the whole SQL payload at once, at the * expense of storing all token objects in memory at the same time. * * @return WP_MySQL_Token[] An array of token objects representing the remaining tokens. */ public function remaining_tokens(): array { $tokens = array(); $no_backslash_escapes_sql_mode_set = $this->is_sql_mode_active( self::SQL_MODE_NO_BACKSLASH_ESCAPES ); while ( true ) { // Bail on EOF, or on a null token type once at least one byte has // been consumed (read_next_token() hit invalid input mid-stream). if ( self::EOF === $this->token_type || ( null === $this->token_type && $this->bytes_already_read > 0 ) ) { $this->token_type = null; break; } // Skip leading whitespace inline for optimal performance. $this->bytes_already_read += strspn( $this->sql, self::WHITESPACE_MASK, $this->bytes_already_read ); do { $this->token_starts_at = $this->bytes_already_read; $this->token_type = $this->read_next_token(); } while ( self::WHITESPACE === $this->token_type || self::COMMENT === $this->token_type || self::MYSQL_COMMENT_START === $this->token_type || self::MYSQL_COMMENT_END === $this->token_type ); if ( null === $this->token_type ) { break; } $tokens[] = new WP_MySQL_Token( $this->token_type, $this->token_starts_at, $this->bytes_already_read - $this->token_starts_at, $this->sql, $no_backslash_escapes_sql_mode_set ); if ( self::EOF === $this->token_type ) { $this->token_type = null; break; } } return $tokens; } /** * The version of the MySQL server that the SQL payload is intended for. * * This represents the MySQL server version that the lexer is set up to * consider when tokenizing the SQL payload. * * @return int The MySQL server version that the lexer is set up to consider. */ public function get_mysql_version(): int { return $this->mysql_version; } /** * Whether an SQL mode is set to be considered as active during tokenization. * The SQL modes are defined as "SQL_MODE_"-prefixed constants in this class. * * @param int $mode The SQL mode to check, an "SQL_MODE_"-prefixed constant. * @return bool Whether the given SQL mode is active. */ public function is_sql_mode_active( int $mode ): bool { return ( $this->sql_modes & $mode ) !== 0; } /** * Get the numeric token ID for a given token name. * * @param string $token_name The name of the token. * @return int|null The token ID for the given token name; null when not found. */ public static function get_token_id( string $token_name ): ?int { $constant_name = self::class . '::' . $token_name; if ( ! defined( $constant_name ) ) { return null; } return constant( $constant_name ); } /** * Get the name of a token for a given token ID. * * This method is intended to be used only for testing and debugging purposes, * when tokens need to be presented by their names in a human-readable form. * It should not be used in production code, as it's not performance-optimized. * * @param int $token_id The numeric token ID. * @return string The token name for the given token ID; null when not found. */ public static function get_token_name( int $token_id ): ?string { $reflection = new ReflectionClass( self::class ); // Reverse the array, as some constant values in the class can conflict, // and tokens are defined at the end of the class constant definitions. // @TODO: Consider are more robust way to determine the token name. // E.g., prefix all token constant names with a common prefix. $constants = array_reverse( $reflection->getConstants() ); $token_name = array_search( $token_id, $constants, true ); return $token_name ? $token_name : null; } private function read_next_token(): ?int { $byte = $this->sql[ $this->bytes_already_read ] ?? null; $next_byte = $this->sql[ $this->bytes_already_read + 1 ] ?? null; // A map for a single-byte symbol fast path. static $single_byte_ops = array( '(' => self::OPEN_PAR_SYMBOL, ')' => self::CLOSE_PAR_SYMBOL, ',' => self::COMMA_SYMBOL, ';' => self::SEMICOLON_SYMBOL, '+' => self::PLUS_OPERATOR, '~' => self::BITWISE_NOT_OPERATOR, '%' => self::MOD_OPERATOR, '^' => self::BITWISE_XOR_OPERATOR, '?' => self::PARAM_MARKER, '{' => self::OPEN_CURLY_SYMBOL, '}' => self::CLOSE_CURLY_SYMBOL, '=' => self::EQUAL_OPERATOR, ); // Fast path for keywords and identifiers. // `$byte > "\x7F"` catches any non-ASCII byte (0x80-0xFF); read_identifier() // restricts the accepted identifier codepoints to U+0080-U+FFFF. // `"'" !== $next_byte` defers x'..', n'..' and similar special // literals to their dedicated branches below; only single quotes // form those, regardless of SQL mode. if ( ( ( $byte >= 'a' && $byte <= 'z' ) || ( $byte >= 'A' && $byte <= 'Z' ) || $byte > "\x7F" ) && "'" !== $next_byte ) { $started_at = $this->bytes_already_read; $type = $this->read_identifier(); if ( self::IDENTIFIER === $type // When preceded by a dot, it is always an identifier. && ! ( $started_at > 0 && '.' === $this->sql[ $started_at - 1 ] ) ) { // Inline the keyword lookup on the hot identifier path: most // identifiers are not keywords, so this avoids two method calls // (token-bytes extraction + keyword determination) per token. $keyword = self::TOKENS[ strtoupper( substr( $this->sql, $started_at, $this->bytes_already_read - $started_at ) ) ] ?? self::IDENTIFIER; if ( self::IDENTIFIER !== $keyword ) { $type = $this->resolve_keyword_type( $keyword ); } } } elseif ( null !== $byte && isset( $single_byte_ops[ $byte ] ) ) { // Fast path for single-byte symbols. $this->bytes_already_read += 1; $type = $single_byte_ops[ $byte ]; } elseif ( "'" === $byte || '"' === $byte || '`' === $byte ) { $type = $this->read_quoted_text(); } elseif ( null !== $byte && strspn( $byte, self::DIGIT_MASK ) > 0 ) { $type = $this->read_number(); } elseif ( '.' === $byte ) { if ( null !== $next_byte && strspn( $next_byte, self::DIGIT_MASK ) > 0 ) { $type = $this->read_number(); } else { $this->bytes_already_read += 1; $type = self::DOT_SYMBOL; } } elseif ( ':' === $byte ) { $this->bytes_already_read += 1; // Consume the ':'. if ( '=' === $next_byte ) { $this->bytes_already_read += 1; // Consume the '='. $type = self::ASSIGN_OPERATOR; } else { $type = self::COLON_SYMBOL; } } elseif ( '<' === $byte ) { $this->bytes_already_read += 1; // Consume the '<'. if ( '=' === $next_byte ) { $this->bytes_already_read += 1; // Consume the '='. if ( '>' === ( $this->sql[ $this->bytes_already_read ] ?? null ) ) { $this->bytes_already_read += 1; // Consume the '>'. $type = self::NULL_SAFE_EQUAL_OPERATOR; } else { $type = self::LESS_OR_EQUAL_OPERATOR; } } elseif ( '>' === $next_byte ) { $this->bytes_already_read += 1; // Consume the '>'. $type = self::NOT_EQUAL_OPERATOR; } elseif ( '<' === $next_byte ) { $this->bytes_already_read += 1; // Consume the '<'. $type = self::SHIFT_LEFT_OPERATOR; } else { $type = self::LESS_THAN_OPERATOR; } } elseif ( '>' === $byte ) { $this->bytes_already_read += 1; // Consume the '>'. if ( '=' === $next_byte ) { $this->bytes_already_read += 1; // Consume the '='. $type = self::GREATER_OR_EQUAL_OPERATOR; } elseif ( '>' === $next_byte ) { $this->bytes_already_read += 1; // Consume the '>'. $type = self::SHIFT_RIGHT_OPERATOR; } else { $type = self::GREATER_THAN_OPERATOR; } } elseif ( '!' === $byte ) { $this->bytes_already_read += 1; // Consume the '!'. if ( '=' === $next_byte ) { $this->bytes_already_read += 1; // Consume the '='. $type = self::NOT_EQUAL_OPERATOR; } else { $type = self::LOGICAL_NOT_OPERATOR; } } elseif ( '-' === $byte ) { if ( '-' === $next_byte && $this->bytes_already_read + 2 < $this->sql_length && strspn( $this->sql[ $this->bytes_already_read + 2 ], self::WHITESPACE_MASK ) > 0 ) { $type = $this->read_line_comment(); } elseif ( '>' === $next_byte ) { $this->bytes_already_read += 2; // Consume the '->'. if ( '>' === ( $this->sql[ $this->bytes_already_read ] ?? null ) ) { $this->bytes_already_read += 1; // Consume the '>'. if ( $this->mysql_version >= 50713 ) { $type = self::JSON_UNQUOTED_SEPARATOR_SYMBOL; } else { return null; // Invalid input. } } else { if ( $this->mysql_version >= 50708 ) { $type = self::JSON_SEPARATOR_SYMBOL; } else { return null; // Invalid input. } } } else { $this->bytes_already_read += 1; // Consume the '-'. $type = self::MINUS_OPERATOR; } } elseif ( '*' === $byte ) { $this->bytes_already_read += 1; if ( '/' === $next_byte && $this->in_mysql_comment ) { $this->bytes_already_read += 1; // Consume the '/'. $type = self::MYSQL_COMMENT_END; $this->in_mysql_comment = false; } else { $type = self::MULT_OPERATOR; } } elseif ( '/' === $byte ) { if ( '*' === $next_byte ) { if ( '!' === ( $this->sql[ $this->bytes_already_read + 2 ] ?? null ) ) { $type = $this->read_mysql_comment(); } else { $this->bytes_already_read += 2; // Consume the '/*'. $this->read_comment_content(); $type = self::COMMENT; } } else { $this->bytes_already_read += 1; $type = self::DIV_OPERATOR; } } elseif ( '&' === $byte ) { $this->bytes_already_read += 1; // Consume the '&'. if ( '&' === $next_byte ) { $this->bytes_already_read += 1; // Consume the '&'. $type = self::LOGICAL_AND_OPERATOR; } else { $type = self::BITWISE_AND_OPERATOR; } } elseif ( '|' === $byte ) { $this->bytes_already_read += 1; // Consume the '|'. if ( '|' === $next_byte ) { $this->bytes_already_read += 1; // Consume the '|'. $type = $this->is_sql_mode_active( self::SQL_MODE_PIPES_AS_CONCAT ) ? self::CONCAT_PIPES_SYMBOL : self::LOGICAL_OR_OPERATOR; } else { $type = self::BITWISE_OR_OPERATOR; } } elseif ( '@' === $byte ) { $this->bytes_already_read += 1; // Consume the '@'. if ( '@' === $next_byte ) { $this->bytes_already_read += 1; // Consume the second '@'. $type = self::AT_AT_SIGN_SYMBOL; } else { /** * Check whether the '@' marks an unquoted user-defined variable: * https://dev.mysql.com/doc/refman/8.4/en/user-variables.html * * Rules: * 1. Starts with a '@'. * 2. Allowed following characters are ASCII a-z, A-Z, 0-9, _, ., $. */ $length = strspn( $this->sql, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.$', $this->bytes_already_read ); if ( $length > 0 ) { $this->bytes_already_read += $length; $type = self::AT_TEXT_SUFFIX; } else { $type = self::AT_SIGN_SYMBOL; } } } elseif ( '\\' === $byte ) { $this->bytes_already_read += 1; // Consume the '\'. if ( 'N' === $next_byte ) { $this->bytes_already_read += 1; // Consume the 'N'. $type = self::NULL2_SYMBOL; } else { return null; // Invalid input. } } elseif ( '#' === $byte ) { $type = $this->read_line_comment(); } elseif ( null !== $byte && strspn( $byte, self::WHITESPACE_MASK ) > 0 ) { $this->bytes_already_read += strspn( $this->sql, self::WHITESPACE_MASK, $this->bytes_already_read ); $type = self::WHITESPACE; } elseif ( ( 'x' === $byte || 'X' === $byte || 'b' === $byte || 'B' === $byte ) && "'" === $next_byte ) { $type = $this->read_number(); } elseif ( ( 'n' === $byte || 'N' === $byte ) && "'" === $next_byte ) { $this->bytes_already_read += 1; // n/N $type = $this->read_quoted_text( "'" ); if ( self::SINGLE_QUOTED_TEXT === $type ) { $type = self::NCHAR_TEXT; } } elseif ( null === $byte ) { $type = self::EOF; } else { $started_at = $this->bytes_already_read; $type = $this->read_identifier(); if ( self::IDENTIFIER === $type ) { // When preceded by a dot, it is always an identifier. if ( $started_at > 0 && '.' === $this->sql[ $started_at - 1 ] ) { $type = self::IDENTIFIER; } elseif ( '_' === $byte && isset( self::UNDERSCORE_CHARSETS[ strtolower( $this->get_current_token_bytes() ) ] ) ) { $type = self::UNDERSCORE_CHARSET; } else { $type = $this->determine_identifier_or_keyword_type( $this->get_current_token_bytes() ); } } } return $type; } private function get_current_token_bytes(): string { return substr( $this->sql, $this->token_starts_at, $this->bytes_already_read - $this->token_starts_at ); } /** * Read an unquoted identifier. * * This function reads characters that are allowed in an unquoted identifier. * An identifier cannot consist solely of digits, but this function doesn't * ensure that explicitly, as numbers are processed before identifiers in * the tokenization process, recognizing all digit-only sequences as numbers. * * Rules: * 1. Allowed characters are ASCII a-z, A-Z, 0-9, _, $, and Unicode U+0080-U+FFFF. * 2. Unquoted identifiers may begin with a digit but may not consist solely of digits. * * See: * https://dev.mysql.com/doc/refman/8.4/en/identifiers.html */ private function read_identifier(): ?int { $started_at = $this->bytes_already_read; while ( true ) { // First, let's try to parse an ASCII sequence. $this->bytes_already_read += strspn( $this->sql, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$', $this->bytes_already_read ); // Check if the following byte can be part of a multibyte character // in the range of U+0080 to U+FFFF before looking at further bytes. // If it can't, bail out early to avoid unnecessary UTF-8 decoding. // Identifiers are usually ASCII-only, so we can optimize for that. $byte_1 = ord( $this->sql[ $this->bytes_already_read ] ?? "\0" ); if ( $byte_1 < 0xC2 || $byte_1 > 0xEF ) { break; } // Look for a valid 2-byte UTF-8 symbol. Covers range U+0080 - U+07FF. $byte_2 = ord( $this->sql[ $this->bytes_already_read + 1 ] ?? "\0" ); if ( $byte_1 <= 0xDF && $byte_2 >= 0x80 && $byte_2 <= 0xBF ) { $this->bytes_already_read += 2; continue; } // Look for a valid 3-byte UTF-8 symbol in range U+0800 - U+FFFF. $byte_3 = ord( $this->sql[ $this->bytes_already_read + 2 ] ?? "\0" ); if ( $byte_1 <= 0xEF && $byte_2 >= 0x80 && $byte_2 <= 0xBF && $byte_3 >= 0x80 && $byte_3 <= 0xBF // Exclude surrogate range U+D800 to U+DFFF: && ! ( 0xED === $byte_1 && $byte_2 >= 0xA0 ) // Exclude overlong encodings: && ! ( 0xE0 === $byte_1 && $byte_2 < 0xA0 ) ) { $this->bytes_already_read += 3; continue; } // Not a valid identifier character. break; } // An identifier cannot consist solely of digits, but we don't need to // ensure that explicitly, as numbers are processed before identifiers. return $this->bytes_already_read - $started_at > 0 ? self::IDENTIFIER : null; // Invalid input. } private function read_number(): ?int { // @TODO: Support numeric-only identifier parts after "." (e.g., 1ea10.1). $byte = $this->sql[ $this->bytes_already_read ] ?? null; $next_byte = $this->sql[ $this->bytes_already_read + 1 ] ?? null; $third_byte = $this->sql[ $this->bytes_already_read + 2 ] ?? null; if ( // HEX number in the form of 0xN. ( '0' === $byte && 'x' === $next_byte && null !== $third_byte && strspn( $third_byte, self::HEX_DIGIT_MASK ) > 0 ) // HEX number in the form of x'N' or X'N'. || ( ( 'x' === $byte || 'X' === $byte ) && "'" === $next_byte ) ) { $is_quoted = "'" === $next_byte; $this->bytes_already_read += 2; // Consume "0x" or "x'". $this->bytes_already_read += strspn( $this->sql, self::HEX_DIGIT_MASK, $this->bytes_already_read ); if ( $is_quoted ) { if ( $this->bytes_already_read >= $this->sql_length || "'" !== $this->sql[ $this->bytes_already_read ] ) { return null; // Invalid input. } $this->bytes_already_read += 1; // Consume the "'". } $type = self::HEX_NUMBER; } elseif ( // BIN number in the form of 0bN. ( '0' === $byte && 'b' === $next_byte && ( '0' === $third_byte || '1' === $third_byte ) ) // BIN number in the form of b'N' or B'N'. || ( ( 'b' === $byte || 'B' === $byte ) && "'" === $next_byte ) ) { $is_quoted = "'" === $next_byte; $this->bytes_already_read += 2; // Consume "0b" or "b'". $this->bytes_already_read += strspn( $this->sql, '01', $this->bytes_already_read ); if ( $is_quoted ) { if ( $this->bytes_already_read >= $this->sql_length || "'" !== $this->sql[ $this->bytes_already_read ] ) { return null; // Invalid input. } $this->bytes_already_read += 1; // Consume the "'". } $type = self::BIN_NUMBER; } else { // Here, we have a sequence starting with N or .N, where N is a digit. // 1. Try integer first. $this->bytes_already_read += strspn( $this->sql, self::DIGIT_MASK, $this->bytes_already_read ); $type = self::INT_NUMBER; // 2. In case of N. or .N, it's a decimal or float number. if ( '.' === ( $this->sql[ $this->bytes_already_read ] ?? null ) ) { $this->bytes_already_read += 1; $type = self::DECIMAL_NUMBER; $this->bytes_already_read += strspn( $this->sql, self::DIGIT_MASK, $this->bytes_already_read ); } // 3. When exponent is present, it's a float number. $byte = $this->sql[ $this->bytes_already_read ] ?? null; $next_byte = $this->sql[ $this->bytes_already_read + 1 ] ?? null; $has_exponent = ( 'e' === $byte || 'E' === $byte ) && null !== $next_byte && ( strspn( $next_byte, self::DIGIT_MASK ) > 0 || ( ( '+' === $next_byte || '-' === $next_byte ) && $this->bytes_already_read + 2 < $this->sql_length && strspn( $this->sql[ $this->bytes_already_read + 2 ], self::DIGIT_MASK ) > 0 ) ); if ( $has_exponent ) { $this->bytes_already_read += 1; // Consume the 'e' or 'E'. $this->bytes_already_read += 1; // Consume the '+', '-', or digit. $this->bytes_already_read += strspn( $this->sql, self::DIGIT_MASK, $this->bytes_already_read ); $type = self::FLOAT_NUMBER; } } /* * In MySQL, when an input matches both a number and an identifier, the * number always wins. However, if the number is followed by a non-numeric * identifier-like character, then it is recognized as an identifier... * Unless it's a float number, which ignores any subsequent input. * * Examples: * - "1234" (integer) vs. "1234a" (identifier) * - "0b01" (bin) vs. "0b012" (identifier) * - "0xa1" (hex) vs. "0xa1x" (identifier) * - "12.3" (decimal) vs. "12.3a" (identifier) * - "1e10" (float) vs. "1e10a" (float, followed by identifier) */ $text = $this->get_current_token_bytes(); $possible_identifier_prefix = self::INT_NUMBER === $type || ( '0' === $text[0] && ( 'b' === $text[1] || 'x' === $text[1] ) ); /* * When we match some subsequent identifier bytes, it's an identifier. * Note that the "$this->read_identifier()" method doesn't check that * the identifier doesn't consist solely of digits. This is an advantage * here, as we can look only at subsequent bytes instead of backtracking * to the beginning of the number (for valid identifiers like 0b019). */ if ( $possible_identifier_prefix && self::IDENTIFIER === $this->read_identifier() ) { $type = self::IDENTIFIER; } // Determine integer type. if ( self::INT_NUMBER === $type ) { // Fast path for most integers. $bytes = $this->get_current_token_bytes(); if ( strlen( $bytes ) < 10 ) { return self::INT_NUMBER; } // Remove leading zeros. $bytes = substr( $bytes, strspn( $bytes, '0' ) ); $length = strlen( $bytes ); // Determine integer type based on its length and value. if ( $length < 10 ) { return self::INT_NUMBER; } elseif ( 10 === $length ) { return strcmp( $bytes, '2147483647' ) > 0 ? self::LONG_NUMBER : self::INT_NUMBER; } elseif ( $length < 19 ) { return self::LONG_NUMBER; } elseif ( 19 === $length ) { return strcmp( $bytes, '9223372036854775807' ) > 0 ? self::ULONGLONG_NUMBER : self::LONG_NUMBER; } elseif ( 20 === $length ) { return strcmp( $bytes, '18446744073709551615' ) > 0 ? self::DECIMAL_NUMBER : self::ULONGLONG_NUMBER; } else { return self::DECIMAL_NUMBER; } } return $type; } /** * Quoted literals and identifiers: * https://dev.mysql.com/doc/refman/8.4/en/string-literals.html * https://dev.mysql.com/doc/refman/8.4/en/identifiers.html * * Rules: * 1. Quotes can be escaped by doubling them ('', "", ``). * 2. Backslashes escape the next character, unless NO_BACKSLASH_ESCAPES is set. */ private function read_quoted_text(): ?int { $quote = $this->sql[ $this->bytes_already_read ]; $this->bytes_already_read += 1; // Consume the quote. $no_backslash_escapes = $this->is_sql_mode_active( self::SQL_MODE_NO_BACKSLASH_ESCAPES ); // We need to look for the closing quote in a loop, as it can be escaped, // in which case the escape sequence is consumed and the loop continues. $at = $this->bytes_already_read; while ( true ) { $quote_at = strpos( $this->sql, $quote, $at ); if ( false === $quote_at ) { return null; // Invalid input. } $at = $quote_at; /* * By default, quotes can be escaped with a "\". * When NO_BACKSLASH_ESCAPES SQL mode is active, the "\" treated as * a regular character. * * The quote is escaped only when the number of preceding backslashes * is odd - "\" is an escape sequence, "\\" is an escaped backslash, * "\\\" is an escaped backslash and an escape sequence, and so on. * * The `($at - $i - 1) >= 0` guard prevents PHP's negative-string- * offset wraparound (PHP 7.1+) when the closing-quote candidate * sits at the very start of the input. The `?? null` covers * positive out-of-range indexes belt-and-suspenders. */ if ( ! $no_backslash_escapes ) { $i = 0; while ( ( $at - $i - 1 ) >= 0 && '\\' === ( $this->sql[ $at - $i - 1 ] ?? null ) ) { $i += 1; } if ( 1 === $i % 2 ) { $at += 1; continue; } } // Check if the quote is doubled. if ( ( $this->sql[ $at + 1 ] ?? null ) === $quote ) { $at += 2; continue; } break; } $at += 1; $this->bytes_already_read = $at; if ( '`' === $quote ) { return self::BACK_TICK_QUOTED_ID; } elseif ( '"' === $quote ) { return self::DOUBLE_QUOTED_TEXT; } else { return self::SINGLE_QUOTED_TEXT; } } private function read_line_comment(): int { $this->bytes_already_read += strcspn( $this->sql, "\r\n", $this->bytes_already_read ); return self::COMMENT; } private function read_mysql_comment(): int { // @TODO: Consider supporting optimizer hints (/*+ ... */) or document // that they are not supported. // @TODO: Implement six-digit version number support (from MySQL 8.4). // MySQL-specific comment in one of the following forms: // 1. /*! ... */ - The content is treated as SQL. // 2. /*!12345 ... */ - The content is treated as SQL when "MySQL version >= 12345". $this->bytes_already_read += 3; // Consume the '/*!'. // Check if the next 5 characters are digits. $digit_count = strspn( $this->sql, self::DIGIT_MASK, $this->bytes_already_read, 5 ); $is_version_comment = 5 === $digit_count; // For version comments, extract the version number. $version = $is_version_comment ? (int) substr( $this->sql, $this->bytes_already_read, $digit_count ) : 0; if ( $this->mysql_version < $version ) { // Version not satisfied. Treat the content as a regular comment. $this->read_comment_content(); return self::COMMENT; } else { // Version satisfied or not specified. Treat the content as SQL code. $this->bytes_already_read += $digit_count; // Skip the version number. $this->in_mysql_comment = true; return self::MYSQL_COMMENT_START; } } private function read_comment_content(): void { $comment_end = strpos( $this->sql, '*/', $this->bytes_already_read ); if ( false === $comment_end ) { $this->bytes_already_read = $this->sql_length; } else { $this->bytes_already_read = $comment_end + 2; } } private function determine_identifier_or_keyword_type( string $value ): int { $type = self::TOKENS[ strtoupper( $value ) ] ?? self::IDENTIFIER; if ( self::IDENTIFIER === $type ) { return self::IDENTIFIER; } return $this->resolve_keyword_type( $type ); } /** * Resolve a keyword token id matched in self::TOKENS, applying version gating, * function-call lookahead, the SQL_MODE_HIGH_NOT_PRECEDENCE rule, and synonyms. * * @param int $type A token id already matched in self::TOKENS (never IDENTIFIER). */ private function resolve_keyword_type( int $type ): int { // Apply MySQL version specifics (positive number: >= , negative number: < ). if ( isset( self::VERSIONS[ $type ] ) ) { $version = self::VERSIONS[ $type ]; if ( $this->mysql_version < $version || -$version >= $this->mysql_version ) { return self::IDENTIFIER; } } // Apply MySQL version ranges manually. if ( self::MAX_STATEMENT_TIME_SYMBOL === $type && ! ( $this->mysql_version >= 50704 && $this->mysql_version < 50708 ) ) { return self::IDENTIFIER; } if ( self::NONBLOCKING_SYMBOL === $type && ! ( $this->mysql_version >= 50700 && $this->mysql_version < 50706 ) ) { return self::IDENTIFIER; } if ( self::REMOTE_SYMBOL === $type && ( $this->mysql_version >= 80003 && $this->mysql_version < 80014 ) ) { return self::IDENTIFIER; } // Determine function calls. if ( isset( self::FUNCTIONS[ $type ] ) ) { // Skip any whitespace character if the SQL mode says they should be ignored. if ( $this->is_sql_mode_active( self::SQL_MODE_IGNORE_SPACE ) ) { $this->bytes_already_read += strspn( $this->sql, self::WHITESPACE_MASK, $this->bytes_already_read ); } if ( '(' !== ( $this->sql[ $this->bytes_already_read ] ?? null ) ) { return self::IDENTIFIER; } } // With "SQL_MODE_HIGH_NOT_PRECEDENCE" enabled, "NOT" needs to be emitted as a higher priority NOT2 symbol. if ( self::NOT_SYMBOL === $type && $this->is_sql_mode_active( self::SQL_MODE_HIGH_NOT_PRECEDENCE ) ) { $type = self::NOT2_SYMBOL; } // Apply synonyms. return self::SYNONYMS[ $type ] ?? $type; } }