vitessio/vitess · error
too many values for set
Error message
too many values for set
What it means
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.
Source
Thrown at go/vt/vtgate/evalengine/eval_set.go:80
// the raw string using the binary collation. This ensures DISTINCT and other hash-based operations
// treat unknown sets as distinct based on their textual representation.
func (e *evalSet) Hash(h *vthash.Hasher) {
// MySQL allows storing an empty set as an empty string, which yields set==0 and string=="";
// unknown sets will have set==0 but non-empty string content.
if e.set == 0 && e.string != "" {
h.Write16(hashPrefixBytes)
colldata.Lookup(collations.CollationBinaryID).Hash(h, hack.StringBytes(e.string), 0)
return
}
h.Write16(hashPrefixIntegralPositive)
h.Write64(e.set)
}
func evalSetBits(values *EnumSetValues, value string) uint64 {
if values != nil && len(*values) > 64 {
// This never would happen as MySQL limits SET
// to 64 elements. Safeguard here just in case though.
panic("too many values for set")
}
set := uint64(0)
for val := range strings.SplitSeq(value, ",") {
idx := valueIdx(values, val)
if idx == -1 {
continue
}
set |= 1 << idx
}
return set
}
View on GitHub (pinned to 01a25a7d17)
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
Example fix
// before
values := make([]string, 100) // invalid SET
// after
if len(values) > 64 {
return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "SET supports at most 64 elements")
} Defensive patterns
Strategy: validation
Validate before calling
if values != nil && len(*values) > 64 {
return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "SET defines %d elements; max is 64", len(*values))
} Type guard
func isValidSetValue(values *EnumSetValues) bool {
return values == nil || len(*values) <= 64
} Try / catch
defer func() {
if r := recover(); r != nil {
err = vterrors.Errorf(vtrpcpb.Code_INTERNAL, "newEvalSet: %v", r)
}
}() Prevention
- 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
When it happens
Trigger: 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.
Common situations: Corrupted or hand-edited schema metadata, a schemaloader bug, or tests constructing SET values artificially with more than 64 elements.
Related errors
- malformed hex literal from parser
- bad unsigned integer type
- bad type aggregation for signed/unsigned types
- unreachable
- unhandled case: evalIsTruthy
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/884d4839dc2ea83b.
Report an issue: GitHub.