vitessio/vitess · error
keyword %q must be lowercase in table
Error message
keyword %q must be lowercase in table
What it means
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.
Source
Thrown at go/vt/sqlparser/keywords.go:877
}
return table
}
func (cit *caseInsensitiveTable) LookupString(name string) (int, bool) {
hash := fnv1aIstr(offset64, name)
if candidate, ok := cit.h[hash]; ok {
return candidate.id, candidate.matchStr(name)
}
return 0, false
}
func init() {
for _, kw := range keywords {
if kw.id == UNUSED {
continue
}
if kw.name != strings.ToLower(kw.name) {
panic(fmt.Sprintf("keyword %q must be lowercase in table", kw.name))
}
keywordStrings[kw.id] = kw.name
keywordVals[kw.name] = kw.id
}
keywordLookupTable = buildCaseInsensitiveTable(keywords)
}
// KeywordString returns the string corresponding to the given keyword
func KeywordString(id int) string {
str, ok := keywordStrings[id]
if !ok {
return ""
}
return str
}
const (View on GitHub (pinned to 01a25a7d17)
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
Example fix
// before
{id: GROUPREPLACE, name: "GroupReplace"}
// after
{id: GROUPREPLACE, name: "groupreplace"} Defensive patterns
Strategy: validation
Validate before calling
for _, kw := range keywords {
if kw.id != UNUSED && kw.name != strings.ToLower(kw.name) {
return fmt.Errorf("keyword %q must be lowercase", kw.name)
}
} Prevention
- 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
When it happens
Trigger: Adding a keyword entry like {id: SELECT, name: "Select"} or "SELECT" to the keywords slice; any edit introducing capital letters into kw.name.
Common situations: Copy-pasting keyword names from documentation or other SQL dialects (e.g. mixed-case T-SQL keywords) directly into the table.
Related errors
- collision in caseInsensitiveTable
- trying to add to missing group %v
- [BUG] tried to replace 'ASTType' on 'ValueContainer'
- invalid IntervalDateExpr syntax
- IntervalDateExpr.Unit is not set
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/cd85206906e19b95.
Report an issue: GitHub.