github.com/vedadiyan/sqlparser@v1.0.0/pkg/sqlparser/keywords.go (about)

     1  /*
     2  Copyright 2021 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package sqlparser
    18  
    19  import (
    20  	"fmt"
    21  	"strings"
    22  )
    23  
    24  type keyword struct {
    25  	name string
    26  	id   int
    27  }
    28  
    29  func (k *keyword) match(input []byte) bool {
    30  	if len(input) != len(k.name) {
    31  		return false
    32  	}
    33  	for i, c := range input {
    34  		if 'A' <= c && c <= 'Z' {
    35  			c += 'a' - 'A'
    36  		}
    37  		if k.name[i] != c {
    38  			return false
    39  		}
    40  	}
    41  	return true
    42  }
    43  
    44  func (k *keyword) matchStr(input string) bool {
    45  	return keywordASCIIMatch(input, k.name)
    46  }
    47  
    48  func keywordASCIIMatch(input string, expected string) bool {
    49  	if len(input) != len(expected) {
    50  		return false
    51  	}
    52  	for i := 0; i < len(input); i++ {
    53  		c := input[i]
    54  		if 'A' <= c && c <= 'Z' {
    55  			c += 'a' - 'A'
    56  		}
    57  		if expected[i] != c {
    58  			return false
    59  		}
    60  	}
    61  	return true
    62  }
    63  
    64  // keywords is a table of mysql keywords that fall into two categories:
    65  // 1) keywords considered reserved by MySQL
    66  // 2) keywords for us to handle specially in sql.y
    67  //
    68  // Those marked as UNUSED are likely reserved keywords. We add them here so that
    69  // when rewriting queries we can properly backtick quote them so they don't cause issues
    70  //
    71  // NOTE: If you add new keywords, add them also to the reserved_keywords or
    72  // non_reserved_keywords grammar in sql.y -- this will allow the keyword to be used
    73  // in identifiers. See the docs for each grammar to determine which one to put it into.
    74  var keywords = []keyword{
    75  	{"_armscii8", UNDERSCORE_ARMSCII8},
    76  	{"_ascii", UNDERSCORE_ASCII},
    77  	{"_big5", UNDERSCORE_BIG5},
    78  	{"_binary", UNDERSCORE_BINARY},
    79  	{"_cp1250", UNDERSCORE_CP1250},
    80  	{"_cp1251", UNDERSCORE_CP1251},
    81  	{"_cp1256", UNDERSCORE_CP1256},
    82  	{"_cp1257", UNDERSCORE_CP1257},
    83  	{"_cp850", UNDERSCORE_CP850},
    84  	{"_cp852", UNDERSCORE_CP852},
    85  	{"_cp866", UNDERSCORE_CP866},
    86  	{"_cp932", UNDERSCORE_CP932},
    87  	{"_dec8", UNDERSCORE_DEC8},
    88  	{"_eucjpms", UNDERSCORE_EUCJPMS},
    89  	{"_euckr", UNDERSCORE_EUCKR},
    90  	{"_gb18030", UNDERSCORE_GB18030},
    91  	{"_gb2312", UNDERSCORE_GB2312},
    92  	{"_gbk", UNDERSCORE_GBK},
    93  	{"_geostd8", UNDERSCORE_GEOSTD8},
    94  	{"_greek", UNDERSCORE_GREEK},
    95  	{"_hebrew", UNDERSCORE_HEBREW},
    96  	{"_hp8", UNDERSCORE_HP8},
    97  	{"_keybcs2", UNDERSCORE_KEYBCS2},
    98  	{"_koi8r", UNDERSCORE_KOI8R},
    99  	{"_koi8u", UNDERSCORE_KOI8U},
   100  	{"_latin1", UNDERSCORE_LATIN1},
   101  	{"_latin2", UNDERSCORE_LATIN2},
   102  	{"_latin5", UNDERSCORE_LATIN5},
   103  	{"_latin7", UNDERSCORE_LATIN7},
   104  	{"_macce", UNDERSCORE_MACCE},
   105  	{"_macroman", UNDERSCORE_MACROMAN},
   106  	{"_sjis", UNDERSCORE_SJIS},
   107  	{"_swe7", UNDERSCORE_SWE7},
   108  	{"_tis620", UNDERSCORE_TIS620},
   109  	{"_ucs2", UNDERSCORE_UCS2},
   110  	{"_ujis", UNDERSCORE_UJIS},
   111  	{"_utf16", UNDERSCORE_UTF16},
   112  	{"_utf16le", UNDERSCORE_UTF16LE},
   113  	{"_utf32", UNDERSCORE_UTF32},
   114  	{"_utf8", UNDERSCORE_UTF8},
   115  	{"_utf8mb4", UNDERSCORE_UTF8MB4},
   116  	{"_utf8mb3", UNDERSCORE_UTF8MB3},
   117  	{"accessible", UNUSED},
   118  	{"action", ACTION},
   119  	{"add", ADD},
   120  	{"after", AFTER},
   121  	{"against", AGAINST},
   122  	{"algorithm", ALGORITHM},
   123  	{"all", ALL},
   124  	{"alter", ALTER},
   125  	{"always", ALWAYS},
   126  	{"analyze", ANALYZE},
   127  	{"and", AND},
   128  	{"array", ARRAY},
   129  	{"as", AS},
   130  	{"asc", ASC},
   131  	{"ascii", ASCII},
   132  	{"asensitive", UNUSED},
   133  	{"auto_increment", AUTO_INCREMENT},
   134  	{"autoextend_size", AUTOEXTEND_SIZE},
   135  	{"avg", AVG},
   136  	{"avg_row_length", AVG_ROW_LENGTH},
   137  	{"before", UNUSED},
   138  	{"begin", BEGIN},
   139  	{"between", BETWEEN},
   140  	{"bigint", BIGINT},
   141  	{"binary", BINARY},
   142  	{"bit", BIT},
   143  	{"bit_and", BIT_AND},
   144  	{"bit_or", BIT_OR},
   145  	{"bit_xor", BIT_XOR},
   146  	{"blob", BLOB},
   147  	{"bool", BOOL},
   148  	{"boolean", BOOLEAN},
   149  	{"both", BOTH},
   150  	{"by", BY},
   151  	{"byte", BYTE},
   152  	{"call", CALL},
   153  	{"cancel", CANCEL},
   154  	{"cascade", CASCADE},
   155  	{"cascaded", CASCADED},
   156  	{"case", CASE},
   157  	{"cast", CAST},
   158  	{"channel", CHANNEL},
   159  	{"change", CHANGE},
   160  	{"char", CHAR},
   161  	{"character", CHARACTER},
   162  	{"charset", CHARSET},
   163  	{"check", CHECK},
   164  	{"checksum", CHECKSUM},
   165  	{"cleanup", CLEANUP},
   166  	{"coalesce", COALESCE},
   167  	{"code", CODE},
   168  	{"collate", COLLATE},
   169  	{"collation", COLLATION},
   170  	{"column", COLUMN},
   171  	{"column_format", COLUMN_FORMAT},
   172  	{"columns", COLUMNS},
   173  	{"comment", COMMENT_KEYWORD},
   174  	{"committed", COMMITTED},
   175  	{"commit", COMMIT},
   176  	{"compact", COMPACT},
   177  	{"complete", COMPLETE},
   178  	{"compressed", COMPRESSED},
   179  	{"compression", COMPRESSION},
   180  	{"condition", UNUSED},
   181  	{"connection", CONNECTION},
   182  	{"consistent", CONSISTENT},
   183  	{"constraint", CONSTRAINT},
   184  	{"continue", UNUSED},
   185  	{"convert", CONVERT},
   186  	{"copy", COPY},
   187  	{"count", COUNT},
   188  	{"cume_dist", CUME_DIST},
   189  	{"substr", SUBSTRING},
   190  	{"subpartition", SUBPARTITION},
   191  	{"subpartitions", SUBPARTITIONS},
   192  	{"substring", SUBSTRING},
   193  	{"srid", SRID},
   194  	{"create", CREATE},
   195  	{"cross", CROSS},
   196  	{"csv", CSV},
   197  	{"current", CURRENT},
   198  	{"current_date", CURRENT_DATE},
   199  	{"current_time", CURRENT_TIME},
   200  	{"current_timestamp", CURRENT_TIMESTAMP},
   201  	{"current_user", CURRENT_USER},
   202  	{"cursor", UNUSED},
   203  	{"data", DATA},
   204  	{"database", DATABASE},
   205  	{"databases", DATABASES},
   206  	{"day", DAY},
   207  	{"day_hour", DAY_HOUR},
   208  	{"day_microsecond", DAY_MICROSECOND},
   209  	{"day_minute", DAY_MINUTE},
   210  	{"day_second", DAY_SECOND},
   211  	{"date", DATE},
   212  	{"datetime", DATETIME},
   213  	{"deallocate", DEALLOCATE},
   214  	{"dec", UNUSED},
   215  	{"decimal", DECIMAL_TYPE},
   216  	{"declare", UNUSED},
   217  	{"default", DEFAULT},
   218  	{"definer", DEFINER},
   219  	{"delay_key_write", DELAY_KEY_WRITE},
   220  	{"delayed", UNUSED},
   221  	{"delete", DELETE},
   222  	{"dense_rank", DENSE_RANK},
   223  	{"desc", DESC},
   224  	{"describe", DESCRIBE},
   225  	{"deterministic", UNUSED},
   226  	{"directory", DIRECTORY},
   227  	{"disable", DISABLE},
   228  	{"discard", DISCARD},
   229  	{"disk", DISK},
   230  	{"distinct", DISTINCT},
   231  	{"distinctrow", DISTINCTROW},
   232  	{"div", DIV},
   233  	{"double", DOUBLE},
   234  	{"do", DO},
   235  	{"drop", DROP},
   236  	{"dumpfile", DUMPFILE},
   237  	{"duplicate", DUPLICATE},
   238  	{"dynamic", DYNAMIC},
   239  	{"each", UNUSED},
   240  	{"else", ELSE},
   241  	{"elseif", UNUSED},
   242  	{"empty", EMPTY},
   243  	{"enable", ENABLE},
   244  	{"enclosed", ENCLOSED},
   245  	{"encryption", ENCRYPTION},
   246  	{"end", END},
   247  	{"enforced", ENFORCED},
   248  	{"engine", ENGINE},
   249  	{"engine_attribute", ENGINE_ATTRIBUTE},
   250  	{"engines", ENGINES},
   251  	{"enum", ENUM},
   252  	{"error", ERROR},
   253  	{"escape", ESCAPE},
   254  	{"escaped", ESCAPED},
   255  	{"event", EVENT},
   256  	{"exchange", EXCHANGE},
   257  	{"exclusive", EXCLUSIVE},
   258  	{"execute", EXECUTE},
   259  	{"exists", EXISTS},
   260  	{"exit", UNUSED},
   261  	{"explain", EXPLAIN},
   262  	{"expansion", EXPANSION},
   263  	{"expire", EXPIRE},
   264  	{"export", EXPORT},
   265  	{"extended", EXTENDED},
   266  	{"extract", EXTRACT},
   267  	{"extractvalue", ExtractValue},
   268  	{"false", FALSE},
   269  	{"fetch", UNUSED},
   270  	{"fields", FIELDS},
   271  	{"first", FIRST},
   272  	{"first_value", FIRST_VALUE},
   273  	{"fixed", FIXED},
   274  	{"float", FLOAT_TYPE},
   275  	{"float4", FLOAT4_TYPE},
   276  	{"float8", FLOAT8_TYPE},
   277  	{"flush", FLUSH},
   278  	{"following", FOLLOWING},
   279  	{"for", FOR},
   280  	{"force", FORCE},
   281  	{"foreign", FOREIGN},
   282  	{"format", FORMAT},
   283  	{"format_bytes", FORMAT_BYTES},
   284  	{"format_pico_time", FORMAT_PICO_TIME},
   285  	{"from", FROM},
   286  	{"full", FULL},
   287  	{"fulltext", FULLTEXT},
   288  	{"function", FUNCTION},
   289  	{"general", GENERAL},
   290  	{"generated", GENERATED},
   291  	{"geometry", GEOMETRY},
   292  	{"geomcollection", GEOMETRYCOLLECTION},
   293  	{"geometrycollection", GEOMETRYCOLLECTION},
   294  	{"get", UNUSED},
   295  	{"get_lock", GET_LOCK},
   296  	{"global", GLOBAL},
   297  	{"gtid_executed", GTID_EXECUTED},
   298  	{"gtid_subset", GTID_SUBSET},
   299  	{"gtid_subtract", GTID_SUBTRACT},
   300  	{"grant", UNUSED},
   301  	{"group", GROUP},
   302  	{"grouping", UNUSED},
   303  	{"groups", UNUSED},
   304  	{"group_concat", GROUP_CONCAT},
   305  	{"hash", HASH},
   306  	{"having", HAVING},
   307  	{"header", HEADER},
   308  	{"high_priority", UNUSED},
   309  	{"hosts", HOSTS},
   310  	{"hour", HOUR},
   311  	{"hour_microsecond", HOUR_MICROSECOND},
   312  	{"hour_minute", HOUR_MINUTE},
   313  	{"hour_second", HOUR_SECOND},
   314  	{"if", IF},
   315  	{"ignore", IGNORE},
   316  	{"import", IMPORT},
   317  	{"in", IN},
   318  	{"index", INDEX},
   319  	{"indexes", INDEXES},
   320  	{"infile", UNUSED},
   321  	{"inout", UNUSED},
   322  	{"inner", INNER},
   323  	{"inplace", INPLACE},
   324  	{"insensitive", UNUSED},
   325  	{"insert", INSERT},
   326  	{"insert_method", INSERT_METHOD},
   327  	{"instant", INSTANT},
   328  	{"invisible", INVISIBLE},
   329  	{"int", INT},
   330  	{"int1", UNUSED},
   331  	{"int2", UNUSED},
   332  	{"int3", UNUSED},
   333  	{"int4", UNUSED},
   334  	{"int8", UNUSED},
   335  	{"integer", INTEGER},
   336  	{"interval", INTERVAL},
   337  	{"into", INTO},
   338  	{"io_after_gtids", UNUSED},
   339  	{"is", IS},
   340  	{"is_free_lock", IS_FREE_LOCK},
   341  	{"is_used_lock", IS_USED_LOCK},
   342  	{"isolation", ISOLATION},
   343  	{"iterate", UNUSED},
   344  	{"invoker", INVOKER},
   345  	{"join", JOIN},
   346  	{"json", JSON},
   347  	{"json_array", JSON_ARRAY},
   348  	{"json_array_append", JSON_ARRAY_APPEND},
   349  	{"json_array_insert", JSON_ARRAY_INSERT},
   350  	{"json_contains", JSON_CONTAINS},
   351  	{"json_contains_path", JSON_CONTAINS_PATH},
   352  	{"json_depth", JSON_DEPTH},
   353  	{"json_extract", JSON_EXTRACT},
   354  	{"json_insert", JSON_INSERT},
   355  	{"json_length", JSON_LENGTH},
   356  	{"json_keys", JSON_KEYS},
   357  	{"json_merge", JSON_MERGE},
   358  	{"json_merge_patch", JSON_MERGE_PATCH},
   359  	{"json_merge_preserve", JSON_MERGE_PRESERVE},
   360  	{"json_object", JSON_OBJECT},
   361  	{"json_overlaps", JSON_OVERLAPS},
   362  	{"json_pretty", JSON_PRETTY},
   363  	{"json_remove", JSON_REMOVE},
   364  	{"json_replace", JSON_REPLACE},
   365  	{"json_search", JSON_SEARCH},
   366  	{"json_schema_valid", JSON_SCHEMA_VALID},
   367  	{"json_schema_validation_report", JSON_SCHEMA_VALIDATION_REPORT},
   368  	{"json_set", JSON_SET},
   369  	{"json_storage_free", JSON_STORAGE_FREE},
   370  	{"json_storage_size", JSON_STORAGE_SIZE},
   371  	{"json_quote", JSON_QUOTE},
   372  	{"json_table", JSON_TABLE},
   373  	{"json_type", JSON_TYPE},
   374  	{"json_value", JSON_VALUE},
   375  	{"json_valid", JSON_VALID},
   376  	{"json_unquote", JSON_UNQUOTE},
   377  	{"key", KEY},
   378  	{"keys", KEYS},
   379  	{"keyspaces", KEYSPACES},
   380  	{"key_block_size", KEY_BLOCK_SIZE},
   381  	{"kill", UNUSED},
   382  	{"lag", LAG},
   383  	{"language", LANGUAGE},
   384  	{"last", LAST},
   385  	{"last_value", LAST_VALUE},
   386  	{"last_insert_id", LAST_INSERT_ID},
   387  	{"lateral", LATERAL},
   388  	{"launch", LAUNCH},
   389  	{"lead", LEAD},
   390  	{"leading", LEADING},
   391  	{"leave", UNUSED},
   392  	{"left", LEFT},
   393  	{"less", LESS},
   394  	{"level", LEVEL},
   395  	{"like", LIKE},
   396  	{"limit", LIMIT},
   397  	{"linear", LINEAR},
   398  	{"lines", LINES},
   399  	{"linestring", LINESTRING},
   400  	{"list", LIST},
   401  	{"load", LOAD},
   402  	{"local", LOCAL},
   403  	{"localtime", LOCALTIME},
   404  	{"localtimestamp", LOCALTIMESTAMP},
   405  	{"locate", LOCATE},
   406  	{"lock", LOCK},
   407  	{"logs", LOGS},
   408  	{"long", UNUSED},
   409  	{"longblob", LONGBLOB},
   410  	{"longtext", LONGTEXT},
   411  	{"loop", UNUSED},
   412  	{"low_priority", LOW_PRIORITY},
   413  	{"ltrim", LTRIM},
   414  	{"min", MIN},
   415  	{"manifest", MANIFEST},
   416  	{"master_bind", UNUSED},
   417  	{"match", MATCH},
   418  	{"max", MAX},
   419  	{"max_rows", MAX_ROWS},
   420  	{"maxvalue", MAXVALUE},
   421  	{"mediumblob", MEDIUMBLOB},
   422  	{"mediumint", MEDIUMINT},
   423  	{"mediumtext", MEDIUMTEXT},
   424  	{"memory", MEMORY},
   425  	{"member", MEMBER},
   426  	{"merge", MERGE},
   427  	{"microsecond", MICROSECOND},
   428  	{"middleint", UNUSED},
   429  	{"min_rows", MIN_ROWS},
   430  	{"minute", MINUTE},
   431  	{"minute_microsecond", MINUTE_MICROSECOND},
   432  	{"minute_second", MINUTE_SECOND},
   433  	{"mod", MOD},
   434  	{"mode", MODE},
   435  	{"modify", MODIFY},
   436  	{"modifies", UNUSED},
   437  	{"multilinestring", MULTILINESTRING},
   438  	{"multipoint", MULTIPOINT},
   439  	{"multipolygon", MULTIPOLYGON},
   440  	{"month", MONTH},
   441  	{"name", NAME},
   442  	{"names", NAMES},
   443  	{"natural", NATURAL},
   444  	{"nchar", NCHAR},
   445  	{"next", NEXT},
   446  	{"nested", NESTED},
   447  	{"no", NO},
   448  	{"none", NONE},
   449  	{"not", NOT},
   450  	{"now", NOW},
   451  	{"no_write_to_binlog", NO_WRITE_TO_BINLOG},
   452  	{"nth_value", NTH_VALUE},
   453  	{"ntile", NTILE},
   454  	{"null", NULL},
   455  	{"nulls", NULLS},
   456  	{"numeric", NUMERIC},
   457  	{"of", OF},
   458  	{"off", OFF},
   459  	{"offset", OFFSET},
   460  	{"on", ON},
   461  	{"only", ONLY},
   462  	{"open", OPEN},
   463  	{"optimize", OPTIMIZE},
   464  	{"optimizer_costs", OPTIMIZER_COSTS},
   465  	{"option", OPTION},
   466  	{"optionally", OPTIONALLY},
   467  	{"or", OR},
   468  	{"order", ORDER},
   469  	{"ordinality", ORDINALITY},
   470  	{"out", UNUSED},
   471  	{"outer", OUTER},
   472  	{"outfile", OUTFILE},
   473  	{"over", OVER},
   474  	{"overwrite", OVERWRITE},
   475  	{"pack_keys", PACK_KEYS},
   476  	{"parser", PARSER},
   477  	{"partial", PARTIAL},
   478  	{"partition", PARTITION},
   479  	{"partitions", PARTITIONS},
   480  	{"partitioning", PARTITIONING},
   481  	{"password", PASSWORD},
   482  	{"path", PATH},
   483  	{"percent_rank", PERCENT_RANK},
   484  	{"plan", PLAN},
   485  	{"plugins", PLUGINS},
   486  	{"point", POINT},
   487  	{"polygon", POLYGON},
   488  	{"position", POSITION},
   489  	{"preceding", PRECEDING},
   490  	{"precision", UNUSED},
   491  	{"prepare", PREPARE},
   492  	{"primary", PRIMARY},
   493  	{"privileges", PRIVILEGES},
   494  	{"processlist", PROCESSLIST},
   495  	{"procedure", PROCEDURE},
   496  	{"ps_current_thread_id", PS_CURRENT_THREAD_ID},
   497  	{"ps_thread_id", PS_THREAD_ID},
   498  	{"queries", QUERIES},
   499  	{"query", QUERY},
   500  	{"range", RANGE},
   501  	{"quarter", QUARTER},
   502  	{"rank", RANK},
   503  	{"ratio", RATIO},
   504  	{"read", READ},
   505  	{"reads", UNUSED},
   506  	{"read_write", UNUSED},
   507  	{"real", REAL},
   508  	{"rebuild", REBUILD},
   509  	{"recursive", RECURSIVE},
   510  	{"redundant", REDUNDANT},
   511  	{"references", REFERENCES},
   512  	{"regexp", REGEXP},
   513  	{"regexp_instr", REGEXP_INSTR},
   514  	{"regexp_like", REGEXP_LIKE},
   515  	{"regexp_replace", REGEXP_REPLACE},
   516  	{"regexp_substr", REGEXP_SUBSTR},
   517  	{"relay", RELAY},
   518  	{"release", RELEASE},
   519  	{"release_all_locks", RELEASE_ALL_LOCKS},
   520  	{"release_lock", RELEASE_LOCK},
   521  	{"remove", REMOVE},
   522  	{"rename", RENAME},
   523  	{"reorganize", REORGANIZE},
   524  	{"repair", REPAIR},
   525  	{"repeat", UNUSED},
   526  	{"repeatable", REPEATABLE},
   527  	{"replace", REPLACE},
   528  	{"require", UNUSED},
   529  	{"resignal", UNUSED},
   530  	{"respect", RESPECT},
   531  	{"restrict", RESTRICT},
   532  	{"return", UNUSED},
   533  	{"returning", RETURNING},
   534  	{"retry", RETRY},
   535  	{"revert", REVERT},
   536  	{"revoke", UNUSED},
   537  	{"right", RIGHT},
   538  	{"rlike", RLIKE},
   539  	{"rollback", ROLLBACK},
   540  	{"row", ROW},
   541  	{"row_format", ROW_FORMAT},
   542  	{"row_number", ROW_NUMBER},
   543  	{"rows", ROWS},
   544  	{"rtrim", RTRIM},
   545  	{"s3", S3},
   546  	{"savepoint", SAVEPOINT},
   547  	{"schema", SCHEMA},
   548  	{"schemas", SCHEMAS},
   549  	{"second", SECOND},
   550  	{"second_microsecond", SECOND_MICROSECOND},
   551  	{"secondary_engine_attribute", SECONDARY_ENGINE_ATTRIBUTE},
   552  	{"security", SECURITY},
   553  	{"select", SELECT},
   554  	{"sensitive", UNUSED},
   555  	{"separator", SEPARATOR},
   556  	{"sequence", SEQUENCE},
   557  	{"serializable", SERIALIZABLE},
   558  	{"session", SESSION},
   559  	{"set", SET},
   560  	{"share", SHARE},
   561  	{"shared", SHARED},
   562  	{"show", SHOW},
   563  	{"signal", UNUSED},
   564  	{"signed", SIGNED},
   565  	{"simple", SIMPLE},
   566  	{"slow", SLOW},
   567  	{"smallint", SMALLINT},
   568  	{"snapshot", SNAPSHOT},
   569  	{"spatial", SPATIAL},
   570  	{"specific", UNUSED},
   571  	{"sql", SQL},
   572  	{"sqlexception", UNUSED},
   573  	{"sqlstate", UNUSED},
   574  	{"sqlwarning", UNUSED},
   575  	{"sql_big_result", UNUSED},
   576  	{"sql_cache", SQL_CACHE},
   577  	{"sql_calc_found_rows", SQL_CALC_FOUND_ROWS},
   578  	{"sql_no_cache", SQL_NO_CACHE},
   579  	{"sql_small_result", UNUSED},
   580  	{"ssl", UNUSED},
   581  	{"start", START},
   582  	{"starting", STARTING},
   583  	{"stats_auto_recalc", STATS_AUTO_RECALC},
   584  	{"stats_persistent", STATS_PERSISTENT},
   585  	{"stats_sample_pages", STATS_SAMPLE_PAGES},
   586  	{"status", STATUS},
   587  	{"std", STD},
   588  	{"stddev", STDDEV},
   589  	{"stddev_pop", STDDEV_POP},
   590  	{"stddev_samp", STDDEV_SAMP},
   591  	{"storage", STORAGE},
   592  	{"stored", STORED},
   593  	{"straight_join", STRAIGHT_JOIN},
   594  	{"stream", STREAM},
   595  	{"sum", SUM},
   596  	{"system", UNUSED},
   597  	{"table", TABLE},
   598  	{"tables", TABLES},
   599  	{"tablespace", TABLESPACE},
   600  	{"temporary", TEMPORARY},
   601  	{"temptable", TEMPTABLE},
   602  	{"terminated", TERMINATED},
   603  	{"text", TEXT},
   604  	{"than", THAN},
   605  	{"then", THEN},
   606  	{"throttle", THROTTLE},
   607  	{"time", TIME},
   608  	{"timestamp", TIMESTAMP},
   609  	{"timestampadd", TIMESTAMPADD},
   610  	{"timestampdiff", TIMESTAMPDIFF},
   611  	{"tinyblob", TINYBLOB},
   612  	{"tinyint", TINYINT},
   613  	{"tinytext", TINYTEXT},
   614  	{"to", TO},
   615  	{"trailing", TRAILING},
   616  	{"transaction", TRANSACTION},
   617  	{"tree", TREE},
   618  	{"traditional", TRADITIONAL},
   619  	{"trigger", TRIGGER},
   620  	{"triggers", TRIGGERS},
   621  	{"true", TRUE},
   622  	{"truncate", TRUNCATE},
   623  	{"trim", TRIM},
   624  	{"unbounded", UNBOUNDED},
   625  	{"uncommitted", UNCOMMITTED},
   626  	{"undefined", UNDEFINED},
   627  	{"undo", UNUSED},
   628  	{"unicode", UNICODE},
   629  	{"union", UNION},
   630  	{"unique", UNIQUE},
   631  	{"unlock", UNLOCK},
   632  	{"unsigned", UNSIGNED},
   633  	{"unthrottle", UNTHROTTLE},
   634  	{"update", UPDATE},
   635  	{"updatexml", UpdateXML},
   636  	{"upgrade", UPGRADE},
   637  	{"usage", UNUSED},
   638  	{"use", USE},
   639  	{"user", USER},
   640  	{"user_resources", USER_RESOURCES},
   641  	{"using", USING},
   642  	{"utc_date", UTC_DATE},
   643  	{"utc_time", UTC_TIME},
   644  	{"utc_timestamp", UTC_TIMESTAMP},
   645  	{"validation", VALIDATION},
   646  	{"values", VALUES},
   647  	{"var_pop", VAR_POP},
   648  	{"var_samp", VAR_SAMP},
   649  	{"variables", VARIABLES},
   650  	{"varbinary", VARBINARY},
   651  	{"varchar", VARCHAR},
   652  	{"varcharacter", UNUSED},
   653  	{"variance", VARIANCE},
   654  	{"varying", UNUSED},
   655  	{"vexplain", VEXPLAIN},
   656  	{"vgtid_executed", VGTID_EXECUTED},
   657  	{"virtual", VIRTUAL},
   658  	{"vindex", VINDEX},
   659  	{"vindexes", VINDEXES},
   660  	{"view", VIEW},
   661  	{"vitess", VITESS},
   662  	{"vitess_keyspaces", VITESS_KEYSPACES},
   663  	{"vitess_metadata", VITESS_METADATA},
   664  	{"vitess_migration", VITESS_MIGRATION},
   665  	{"vitess_migrations", VITESS_MIGRATIONS},
   666  	{"vitess_replication_status", VITESS_REPLICATION_STATUS},
   667  	{"vitess_shards", VITESS_SHARDS},
   668  	{"vitess_tablets", VITESS_TABLETS},
   669  	{"vitess_target", VITESS_TARGET},
   670  	{"vitess_throttled_apps", VITESS_THROTTLED_APPS},
   671  	{"vitess_throttler", VITESS_THROTTLER},
   672  	{"vschema", VSCHEMA},
   673  	{"vstream", VSTREAM},
   674  	{"vtexplain", VTEXPLAIN},
   675  	{"warnings", WARNINGS},
   676  	{"wait_for_executed_gtid_set", WAIT_FOR_EXECUTED_GTID_SET},
   677  	{"wait_until_sql_thread_after_gtids", WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS},
   678  	{"weight_string", WEIGHT_STRING},
   679  	{"when", WHEN},
   680  	{"where", WHERE},
   681  	{"while", UNUSED},
   682  	{"window", WINDOW},
   683  	{"with", WITH},
   684  	{"without", WITHOUT},
   685  	{"work", WORK},
   686  	{"write", WRITE},
   687  	{"visible", VISIBLE},
   688  	{"xor", XOR},
   689  	{"year", YEAR},
   690  	{"year_month", YEAR_MONTH},
   691  	{"zerofill", ZEROFILL},
   692  }
   693  
   694  // keywordStrings contains the reverse mapping of token to keyword strings
   695  var keywordStrings = map[int]string{}
   696  var keywordVals = map[string]int{}
   697  
   698  // keywordLookupTable is a perfect hash map that maps **case insensitive** keyword names to their ids
   699  var keywordLookupTable *caseInsensitiveTable
   700  
   701  type caseInsensitiveTable struct {
   702  	h map[uint64]keyword
   703  }
   704  
   705  func buildCaseInsensitiveTable(keywords []keyword) *caseInsensitiveTable {
   706  	table := &caseInsensitiveTable{
   707  		h: make(map[uint64]keyword, len(keywords)),
   708  	}
   709  
   710  	for _, kw := range keywords {
   711  		hash := fnv1aIstr(offset64, kw.name)
   712  		if _, exists := table.h[hash]; exists {
   713  			panic("collision in caseInsensitiveTable")
   714  		}
   715  		table.h[hash] = kw
   716  	}
   717  	return table
   718  }
   719  
   720  func (cit *caseInsensitiveTable) LookupString(name string) (int, bool) {
   721  	hash := fnv1aIstr(offset64, name)
   722  	if candidate, ok := cit.h[hash]; ok {
   723  		return candidate.id, candidate.matchStr(name)
   724  	}
   725  	return 0, false
   726  }
   727  
   728  func (cit *caseInsensitiveTable) Lookup(name []byte) (int, bool) {
   729  	hash := fnv1aI(offset64, name)
   730  	if candidate, ok := cit.h[hash]; ok {
   731  		return candidate.id, candidate.match(name)
   732  	}
   733  	return 0, false
   734  }
   735  
   736  func init() {
   737  	for _, kw := range keywords {
   738  		if kw.id == UNUSED {
   739  			continue
   740  		}
   741  		if kw.name != strings.ToLower(kw.name) {
   742  			panic(fmt.Sprintf("keyword %q must be lowercase in table", kw.name))
   743  		}
   744  		keywordStrings[kw.id] = kw.name
   745  		keywordVals[kw.name] = kw.id
   746  	}
   747  
   748  	keywordLookupTable = buildCaseInsensitiveTable(keywords)
   749  }
   750  
   751  // KeywordString returns the string corresponding to the given keyword
   752  func KeywordString(id int) string {
   753  	str, ok := keywordStrings[id]
   754  	if !ok {
   755  		return ""
   756  	}
   757  	return str
   758  }
   759  
   760  const offset64 = uint64(14695981039346656037)
   761  const prime64 = uint64(1099511628211)
   762  
   763  func fnv1aI(h uint64, s []byte) uint64 {
   764  	for _, c := range s {
   765  		if 'A' <= c && c <= 'Z' {
   766  			c += 'a' - 'A'
   767  		}
   768  		h = (h ^ uint64(c)) * prime64
   769  	}
   770  	return h
   771  }
   772  
   773  func fnv1aIstr(h uint64, s string) uint64 {
   774  	for i := 0; i < len(s); i++ {
   775  		c := s[i]
   776  		if 'A' <= c && c <= 'Z' {
   777  			c += 'a' - 'A'
   778  		}
   779  		h = (h ^ uint64(c)) * prime64
   780  	}
   781  	return h
   782  }