vitessio/vitess · error
unsupported
Error message
unsupported
What it means
evalToNumeric converts any eval value to a numeric one for arithmetic and comparisons, with a default case that panics('unsupported') for eval types that have no numeric representation (e.g. JSON, tuples, geometry). The dispatch layer must filter such types before calling. Hitting it means an unsupported eval type leaked into numeric arithmetic — normally guarded by earlier type checks.
Source
Thrown at go/vt/vtgate/evalengine/eval_numeric.go:169
f, _ := fastparse.ParseFloat64(e.Raw())
return &evalFloat{f: f}
default:
return &evalFloat{f: 0}
}
case *evalTemporal:
if preciseDatetime {
if e.prec == 0 {
return newEvalInt64(e.toInt64())
}
return newEvalDecimalWithPrec(e.toDecimal(), int32(e.prec))
}
return &evalFloat{f: e.toFloat()}
case *evalEnum:
return &evalFloat{f: float64(enumNumeric(e.value))}
case *evalSet:
return &evalFloat{f: float64(e.set)}
default:
panic("unsupported")
}
}
func evalToFloat(e eval) (*evalFloat, bool) {
switch e := e.(type) {
case *evalFloat:
return e, true
case evalNumeric:
return e.toFloat()
case *evalBytes:
if e.isHexLiteral() {
hex, ok := e.toNumericHex()
if !ok {
// overflow
return newEvalFloat(0), false
}
f, ok := hex.toFloat()
if !ok {View on GitHub (pinned to 01a25a7d17)
Solutions
- Ensure the query/operator validates operand types before arithmetic (e.g. JSON operands should be extracted with JSON_EXTRACT/CAST first)
- Wrap the offending operand with an explicit CAST to a numeric type in the SQL query
- If adding a new eval type, add a case in evalToNumeric (eval_numeric.go:~140) defining its numeric conversion
- Report the exact query to Vitess with a stack trace if it panics on stock code — it likely indicates a missing type check
Example fix
// before SELECT json_col + 1 FROM t; // after SELECT CAST(json_col AS DECIMAL) + 1 FROM t; -- or use JSON_EXTRACT(json_col, '$')
Defensive patterns
Strategy: type-guard
Validate before calling
// SQL: cast non-numeric operands before arithmetic SELECT CAST(json_col AS UNSIGNED) + 1 FROM t;
Type guard
// Go: reject non-numeric evals before evalToNumeric
func isArithmeticOperand(e eval) bool {
switch e.(type) {
case *evalJSON, *evalTuple:
return false
}
return true
} Try / catch
func safeToNumeric(e eval) (n eval, err error) {
defer func() {
if r := recover(); r != nil {
err = vterrors.Errorf(vtrpcpb.Code_INTERNAL, "numeric conversion failed: %v", r)
}
}()
return evalToNumeric(e), nil
} Prevention
- Never apply arithmetic operators to JSON/tuple/geometry expressions; extract and CAST first
- Validate operand types at typechecking time so evalToNumeric only sees numeric-capable evals
- When adding eval types, update evalToNumeric's switch in the same change and add pair tests with all arithmetic ops
When it happens
Trigger: Arithmetic operators (subtractNumericWithError, divideNumericWithError, modNumericWithError), evalCompare, or eval dispatch calling evalToNumeric on a type like *evalJSON or *evalTuple that wasn't rejected earlier — e.g. `json_col + 1` on a code path that skipped the type-error check, or a new eval type missing from the switch.
Common situations: Queries applying arithmetic to non-numeric values (JSON columns, comparisons after schema/type changes) that slip past the engine's type validation; engine development adding new eval types.
Related errors
- unreachable
- malformed hex literal from parser
- bad unsigned integer type
- bad type aggregation for signed/unsigned types
- unreachable
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/6ec4a11eef07926f.
Report an issue: GitHub.