{"record":{"id":"7001869f36c9ff04","repo":"vitessio/vitess","slug":"collision-in-caseinsensitivetable","errorCode":null,"errorMessage":"collision in caseInsensitiveTable","messagePattern":"collision in caseInsensitiveTable","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/sqlparser/keywords.go","lineNumber":856,"sourceCode":"\tkeywordVals    = map[string]int{}\n)\n\n// keywordLookupTable is a perfect hash map that maps **case insensitive** keyword names to their ids\nvar keywordLookupTable *caseInsensitiveTable\n\ntype caseInsensitiveTable struct {\n\th map[uint64]keyword\n}\n\nfunc buildCaseInsensitiveTable(keywords []keyword) *caseInsensitiveTable {\n\ttable := &caseInsensitiveTable{\n\t\th: make(map[uint64]keyword, len(keywords)),\n\t}\n\n\tfor _, kw := range keywords {\n\t\thash := fnv1aIstr(offset64, kw.name)\n\t\tif _, exists := table.h[hash]; exists {\n\t\t\tpanic(\"collision in caseInsensitiveTable\")\n\t\t}\n\t\ttable.h[hash] = kw\n\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","sourceCodeStart":838,"sourceCodeEnd":874,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/sqlparser/keywords.go#L838-L874","documentation":"buildCaseInsensitiveTable builds an FNV-1a hash map from keyword name (lowercased) to keyword for case-insensitive SQL keyword lookup. It panics if two keyword entries produce the same FNV-1a hash, because the map could not distinguish them.","triggerScenarios":"Adding a new entry to the `keywords` slice in keywords.go whose lowercased name hashes (via fnv1aIstr) to the same uint64 as an existing entry.","commonSituations":"Contributors adding new SQL keywords or reserved words during a SQL dialect/parser upgrade; a hand-edited keyword table where a name was typoed into colliding with an existing one.","solutions":["Find which two keyword entries collide by logging hash values in the loop before panicking","Rename the newly added keyword or verify its spelling in the keywords table","If the hash function was changed, re-verify collision-freedom or add a secondary key to disambiguate"],"exampleFix":"// before\n{ /* duplicate-hashing keyword entry */ }\n// after\n{ /* keyword renamed so its fnv1aIstr hash is unique */ }","handlingStrategy":"validation","validationCode":"seen := make(map[uint64]string)\nfor _, kw := range keywords {\n    h := fnv1aIstr(offset64, kw.name)\n    if prev, ok := seen[h]; ok {\n        return fmt.Errorf(\"keyword %q collides with %q (hash %d)\", kw.name, prev, h)\n    }\n    seen[h] = kw.name\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Add a unit test that iterates the keywords table and asserts no hash collisions","Log the colliding keyword names in the panic message to speed diagnosis","Never hand-edit keyword names without running the sqlparser test suite"],"tags":["sqlparser","keyword-table","hash-collision","panic","init"],"backgroundTag":"hash-collision","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}