{"record":{"id":"0d8c627f03f655cc","repo":"vitessio/vitess","slug":"unsupported-type-t-0d8c62","errorCode":null,"errorMessage":"unsupported type: %T","messagePattern":"unsupported type: %T","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtgate/evalengine/eval_numeric.go","lineNumber":364,"sourceCode":"\t\t\t\tf, _ := e.Float64()\n\t\t\t\treturn newEvalInt64(floatToInt64(f))\n\t\t\tdefault:\n\t\t\t\tpanic(\"unsupported\")\n\t\t\t}\n\t\tcase json.TypeString:\n\t\t\ti, _ := fastparse.ParseInt64(e.Raw(), 10)\n\t\t\treturn newEvalInt64(i)\n\t\tdefault:\n\t\t\treturn newEvalInt64(0)\n\t\t}\n\tcase *evalTemporal:\n\t\treturn newEvalInt64(e.toInt64())\n\tcase *evalEnum:\n\t\treturn newEvalInt64(enumNumeric(e.value))\n\tcase *evalSet:\n\t\treturn newEvalInt64(int64(e.set))\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unsupported type: %T\", e))\n\t}\n}\n\nfunc (e *evalInt64) Hash(h *vthash.Hasher) {\n\tif e.i < 0 {\n\t\th.Write16(hashPrefixIntegralNegative)\n\t} else {\n\t\th.Write16(hashPrefixIntegralPositive)\n\t}\n\th.Write64(uint64(e.i))\n}\n\nfunc (e *evalInt64) SQLType() sqltypes.Type {\n\treturn sqltypes.Int64\n}\n\nfunc (e *evalInt64) Size() int32 {\n\treturn 0","sourceCodeStart":346,"sourceCodeEnd":382,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtgate/evalengine/eval_numeric.go#L346-L382","documentation":"evalToInt64's outer type switch converts any eval to an int64; an unhandled eval concrete type reaches the default branch and panics with \"unsupported type: %T\". It signals the eval engine was asked for integer coercion of a type it does not know.","triggerScenarios":"Calling evalToInt64 (via run, evalCoerce, valueToEvalCast, translateIntegral) with an eval type absent from the switch — typically a newly added eval implementation.","commonSituations":"Adding new eval types in the evalengine without updating every conversion helper; internal callers passing composite/tuple values into integer contexts.","solutions":["Add a case for the reported %T type in evalToInt64 in go/vt/vtgate/evalengine/eval_numeric.go","Validate expression operand types earlier (during planning/typing) so unsupported types never reach coercion","Upgrade to a vitess release that supports the type in integer coercion"],"exampleFix":"// before\ndefault:\n    panic(fmt.Sprintf(\"unsupported type: %T\", e))\n// after\ncase *evalMyNewType:\n    return newEvalInt64(e.toInt64())\ndefault:\n    panic(fmt.Sprintf(\"unsupported type: %T\", e))","handlingStrategy":"type-guard","validationCode":"switch v.(type) {\ncase evalNumeric, *evalEnum, *evalSet:\n    // coercible\ndefault:\n    return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, \"type %T not int-coercible\", v)\n}","typeGuard":"func isIntCoercible(e eval) bool {\n    switch e.(type) {\n    case evalNumeric, *evalEnum, *evalSet:\n        return true\n    default:\n        return false\n    }\n}","tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        err = vterrors.Errorf(vtrpcpb.Code_INTERNAL, \"evalToInt64: %v\", r)\n    }\n}()","preventionTips":["Extend all five conversion helpers (float/decimal/int64/etc.) whenever a new eval type is added","Gate non-scalar types out during expression analysis/typing","Use %T in panic messages to make triage immediate"],"tags":["go","panic","evalengine","type-coercion"],"backgroundTag":"unsupported-type-coercion","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}