vitessio/vitess · error
BUG: sqlparser emitted unknown type
Error message
BUG: sqlparser emitted unknown type
What it means
When compiling a CONVERT/CAST expression, the evalengine switches over the target type name sqlparser emitted (CHAR, SIGNED, UNSIGNED, DATE, etc.) and panics if the name is none of the known ones. The message asserts that sqlparser should never produce an unknown conversion type, so this panic indicates a bug in the parser-to-evalengine contract rather than bad user input.
Source
Thrown at go/vt/vtgate/evalengine/expr_convert.go:152
return nil, nil
case "DATE":
if d := evalToDate(e, env.now, env.sqlmode.AllowZeroDate()); d != nil {
return d, nil
}
return nil, nil
case "TIME":
p := ptr.Unwrap(c.Length, 0)
if p > 6 {
return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Too-big precision %d specified for 'CONVERT'. Maximum is 6.", p)
}
if t := evalToTime(e, p); t != nil {
return t, nil
}
return nil, nil
case "YEAR":
return nil, c.returnUnsupportedError()
default:
panic("BUG: sqlparser emitted unknown type")
}
}
func (c *ConvertExpr) convertToBinaryType(tt sqltypes.Type) sqltypes.Type {
if c.Length != nil {
if *c.Length > 64*1024 {
return sqltypes.Blob
}
} else if tt == sqltypes.Blob || tt == sqltypes.TypeJSON {
return sqltypes.Blob
}
return sqltypes.VarBinary
}
func (c *ConvertExpr) convertToCharType(tt sqltypes.Type) sqltypes.Type {
if c.Length != nil {
col := colldata.Lookup(c.Collation)
length := *c.Length * col.Charset().MaxWidth()View on GitHub (pinned to 01a25a7d17)
Solutions
- Print the offending type name from the AST to identify the unhandled case
- Add a case for the new type in ConvertExpr's compile/convert switch in expr_convert.go
- Return a proper 'unsupported conversion' error (like the YEAR case does) instead of panicking for legitimately unsupported types
- Align sqlparser and evalengine versions
Example fix
// before
case "YEAR":
return nil, c.returnUnsupportedError()
default:
panic("BUG: sqlparser emitted unknown type")
// after
case "YEAR":
return nil, c.returnUnsupportedError()
case "NEWTYPE":
return convertNewType(...)
default:
return nil, c.returnUnsupportedError() // or keep panic, but handle the new type Defensive patterns
Strategy: validation
Validate before calling
// Validate CAST target types against known conversions before issuing the query
var castableTypes = map[string]bool{"CHAR": true, "SIGNED": true, "UNSIGNED": true, "DATE": true, "DATETIME": true, "TIME": true, "BINARY": true, "JSON": true, "DECIMAL": true, "FLOAT": true, "DOUBLE": true}
func isCastable(t string) bool { return castableTypes[strings.ToUpper(t)] } Type guard
func isKnownConvertType(t sqlparser.ConvertType) bool {
return isCastable(t.Type)
} Try / catch
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("convert eval panic: %v", r)
}
}() Prevention
- Restrict CAST/CONVERT usage to types supported by your Vitess version
- Handle new sqlparser cast types in expr_convert.go as part of the same upgrade
- Prefer returning an unsupported-conversion error over panicking for new types
- Test all CAST targets in expression evaluation tests
When it happens
Trigger: Evaluating a CAST/CONVERT whose target type string from the parsed AST does not match any case in ConvertExpr's switch — e.g., a newly added sqlparser convert type not yet handled, or a hand-built ConvertExpr with a typo'd type name.
Common situations: New MySQL cast types added to sqlparser (or Vitess version skew) where evalengine lags; tests constructing ConvertExpr manually; custom forks adding CAST types.
Related errors
- invalid IntervalDateExpr syntax
- IntervalDateExpr.Unit is not set
- switch should be exhaustive
- no columns available
- unknown ASTStep
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/b8756ec13743079c.
Report an issue: GitHub.