{"record":{"id":"cd85206906e19b95","repo":"vitessio/vitess","slug":"keyword-q-must-be-lowercase-in-table","errorCode":null,"errorMessage":"keyword %q must be lowercase in table","messagePattern":"keyword %q must be lowercase in table","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/sqlparser/keywords.go","lineNumber":877,"sourceCode":"\t}\n\treturn table\n}\n\nfunc (cit *caseInsensitiveTable) LookupString(name string) (int, bool) {\n\thash := fnv1aIstr(offset64, name)\n\tif candidate, ok := cit.h[hash]; ok {\n\t\treturn candidate.id, candidate.matchStr(name)\n\t}\n\treturn 0, false\n}\n\nfunc init() {\n\tfor _, kw := range keywords {\n\t\tif kw.id == UNUSED {\n\t\t\tcontinue\n\t\t}\n\t\tif kw.name != strings.ToLower(kw.name) {\n\t\t\tpanic(fmt.Sprintf(\"keyword %q must be lowercase in table\", kw.name))\n\t\t}\n\t\tkeywordStrings[kw.id] = kw.name\n\t\tkeywordVals[kw.name] = kw.id\n\t}\n\n\tkeywordLookupTable = buildCaseInsensitiveTable(keywords)\n}\n\n// KeywordString returns the string corresponding to the given keyword\nfunc KeywordString(id int) string {\n\tstr, ok := keywordStrings[id]\n\tif !ok {\n\t\treturn \"\"\n\t}\n\treturn str\n}\n\nconst (","sourceCodeStart":859,"sourceCodeEnd":895,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/sqlparser/keywords.go#L859-L895","documentation":"The init() in keywords.go validates that every keyword with a non-UNUSED id is stored lowercase, since keyword matching is done case-insensitively and keywordStrings/keywordVals maps assume canonical lowercase names. A non-lowercase keyword means lookups of the upper/mixed-case form would silently miss.","triggerScenarios":"Adding a keyword entry like {id: SELECT, name: \"Select\"} or \"SELECT\" to the keywords slice; any edit introducing capital letters into kw.name.","commonSituations":"Copy-pasting keyword names from documentation or other SQL dialects (e.g. mixed-case T-SQL keywords) directly into the table.","solutions":["Lowercase the keyword's name field in the keywords table","Ensure keywordVals map keys and keywordStrings values stay consistent by re-running go test ./go/vt/sqlparser"],"exampleFix":"// before\n{id: GROUPREPLACE, name: \"GroupReplace\"}\n// after\n{id: GROUPREPLACE, name: \"groupreplace\"}","handlingStrategy":"validation","validationCode":"for _, kw := range keywords {\n    if kw.id != UNUSED && kw.name != strings.ToLower(kw.name) {\n        return fmt.Errorf(\"keyword %q must be lowercase\", kw.name)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always author keyword names in lowercase and rely on case-insensitive lookup","Add a CI test asserting all keyword names are lowercase","Copy keyword names only from the existing lowercase table, not from docs"],"tags":["sqlparser","keyword-table","invariant-violation","panic","init"],"backgroundTag":"naming-convention-violation","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}