{"record":{"id":"0778f1dcc2e6ad75","repo":"vitessio/vitess","slug":"unreachable-0778f1","errorCode":null,"errorMessage":"unreachable","messagePattern":"unreachable","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtgate/evalengine/eval_temporal.go","lineNumber":53,"sourceCode":"\tprec uint8\n\tdt   datetime.DateTime\n}\n\nfunc (e *evalTemporal) Hash(h *vthash.Hasher) {\n\th.Write16(hashPrefixDate)\n\te.dt.Hash(h)\n}\n\nfunc (e *evalTemporal) ToRawBytes() []byte {\n\tswitch e.t {\n\tcase sqltypes.Date:\n\t\treturn e.dt.Date.Format()\n\tcase sqltypes.Datetime, sqltypes.Timestamp:\n\t\treturn e.dt.Format(e.prec)\n\tcase sqltypes.Time:\n\t\treturn e.dt.Time.Format(e.prec)\n\tdefault:\n\t\tpanic(\"unreachable\")\n\t}\n}\n\nfunc (e *evalTemporal) SQLType() sqltypes.Type {\n\treturn e.t\n}\n\nfunc (e *evalTemporal) Size() int32 {\n\treturn int32(e.prec)\n}\n\nfunc (e *evalTemporal) Scale() int32 {\n\treturn 0\n}\n\nfunc (e *evalTemporal) toInt64() int64 {\n\tswitch e.SQLType() {\n\tcase sqltypes.Date:","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtgate/evalengine/eval_temporal.go#L35-L71","documentation":"evalTemporal.ToRawBytes serializes a temporal value by its SQL type (Date, Datetime, Timestamp, Time). Any other type reaching it hits default and panics \"unreachable\" — the type is expected to be one of the four temporal types by construction.","triggerScenarios":"An *evalTemporal constructed with an unexpected sqltypes.Type (e.g. someone built it with a non-temporal type), then ToRawBytes is called — e.g. from addInterval during date arithmetic.","commonSituations":"Refactors constructing evalTemporal with a raw type from a query result not validated as temporal; new temporal-like SQL types not yet handled.","solutions":["Validate the sqltypes.Type when constructing evalTemporal so only Date/Datetime/Timestamp/Time are accepted","Add the new temporal type to the switch if a new one was introduced","Check the value's type before calling addInterval/ToRawBytes"],"exampleFix":"// before\npanic(\"unreachable\")\n// after\ndefault:\n    return e.dt.Format(e.prec) // or return an error for unknown types","handlingStrategy":"validation","validationCode":"switch t {\ncase sqltypes.Date, sqltypes.Datetime, sqltypes.Timestamp, sqltypes.Time:\n    // ok\ndefault:\n    return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, \"%v is not a temporal type\", t)\n}","typeGuard":"func isTemporalType(t sqltypes.Type) bool {\n    switch t {\n    case sqltypes.Date, sqltypes.Datetime, sqltypes.Timestamp, sqltypes.Time:\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, \"ToRawBytes: %v\", r)\n    }\n}()","preventionTips":["Validate the SQL type when constructing evalTemporal, rejecting non-temporal types","Update temporal switches when new temporal types are introduced","Embed e.SQLType() in unreachable panics for faster diagnosis"],"tags":["go","panic","evalengine","temporal"],"backgroundTag":"unreachable-code-panic","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}