{"record":{"id":"884d4839dc2ea83b","repo":"vitessio/vitess","slug":"too-many-values-for-set","errorCode":null,"errorMessage":"too many values for set","messagePattern":"too many values for set","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtgate/evalengine/eval_set.go","lineNumber":80,"sourceCode":"// the raw string using the binary collation. This ensures DISTINCT and other hash-based operations\n// treat unknown sets as distinct based on their textual representation.\nfunc (e *evalSet) Hash(h *vthash.Hasher) {\n\t// MySQL allows storing an empty set as an empty string, which yields set==0 and string==\"\";\n\t// unknown sets will have set==0 but non-empty string content.\n\tif e.set == 0 && e.string != \"\" {\n\t\th.Write16(hashPrefixBytes)\n\t\tcolldata.Lookup(collations.CollationBinaryID).Hash(h, hack.StringBytes(e.string), 0)\n\t\treturn\n\t}\n\th.Write16(hashPrefixIntegralPositive)\n\th.Write64(e.set)\n}\n\nfunc evalSetBits(values *EnumSetValues, value string) uint64 {\n\tif values != nil && len(*values) > 64 {\n\t\t// This never would happen as MySQL limits SET\n\t\t// to 64 elements. Safeguard here just in case though.\n\t\tpanic(\"too many values for set\")\n\t}\n\n\tset := uint64(0)\n\tfor val := range strings.SplitSeq(value, \",\") {\n\t\tidx := valueIdx(values, val)\n\t\tif idx == -1 {\n\t\t\tcontinue\n\t\t}\n\t\tset |= 1 << idx\n\t}\n\n\treturn set\n}\n","sourceCodeStart":62,"sourceCodeEnd":94,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtgate/evalengine/eval_set.go#L62-L94","documentation":"evalSetBits converts a string to a SET bitmask by assigning one bit per element. MySQL limits SET columns to 64 elements; if the supplied EnumSetValues has more than 64 entries the function panics \"too many values for set\" as a safeguard against impossible schema state.","triggerScenarios":"newEvalSet called with an *EnumSetValues containing >64 entries — i.e. schema metadata for a SET column with more than 64 members, which MySQL itself never produces.","commonSituations":"Corrupted or hand-edited schema metadata, a schemaloader bug, or tests constructing SET values artificially with more than 64 elements.","solutions":["Fix the schema metadata so the SET column defines at most 64 elements","In test/tooling code that builds EnumSetValues, cap at 64 values","If you control the call site, validate len(*values) <= 64 before constructing the set"],"exampleFix":"// before\nvalues := make([]string, 100) // invalid SET\n// after\nif len(values) > 64 {\n    return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, \"SET supports at most 64 elements\")\n}","handlingStrategy":"validation","validationCode":"if values != nil && len(*values) > 64 {\n    return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, \"SET defines %d elements; max is 64\", len(*values))\n}","typeGuard":"func isValidSetValue(values *EnumSetValues) bool {\n    return values == nil || len(*values) <= 64\n}","tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        err = vterrors.Errorf(vtrpcpb.Code_INTERNAL, \"newEvalSet: %v\", r)\n    }\n}()","preventionTips":["Validate SET column definitions (<=64 elements) at schema load time","Cap generated/test SET metadata at 64 entries","Treat >64-element SET metadata as a schema corruption signal and log it"],"tags":["go","panic","evalengine","set-type"],"backgroundTag":"set-column-limit-exceeded","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}