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

  1. Ensure the query/operator validates operand types before arithmetic (e.g. JSON operands should be extracted with JSON_EXTRACT/CAST first)
  2. Wrap the offending operand with an explicit CAST to a numeric type in the SQL query
  3. If adding a new eval type, add a case in evalToNumeric (eval_numeric.go:~140) defining its numeric conversion
  4. 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

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


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/6ec4a11eef07926f. Report an issue: GitHub.