vitessio/vitess · error
vtexplain: unsupported statement type +%v
Error message
vtexplain: unsupported statement type +%v
What it means
In handleSelect, vtexplain accepts only *sqlparser.Select, *sqlparser.ParenSelect and *sqlparser.Union as the statement to analyze; any other AST node type falls into the default branch and is rejected with this message including the reflect type. It is an internal guard for the select-explaining path.
Source
Thrown at go/vt/vtexplain/vtexplain_vttablet.go:628
// Parse the select statement to figure out the table and columns
// that were referenced so that the synthetic response has the
// expected field names and types.
stmt, err := t.vte.env.Parser().Parse(query)
if err != nil {
return nil, err
}
var selStmt *sqlparser.Select
switch stmt := stmt.(type) {
case *sqlparser.Select:
selStmt = stmt
case *sqlparser.Union:
selStmt, err = sqlparser.GetFirstSelect(stmt)
if err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("vtexplain: unsupported statement type +%v", reflect.TypeOf(stmt))
}
// Gen4 supports more complex queries so we now need to
// handle multiple FROM clauses
tables := make([]*sqlparser.AliasedTableExpr, 0, len(selStmt.From))
for _, from := range selStmt.From {
tables = append(tables, getTables(from)...)
}
tableColumnMap := map[sqlparser.IdentifierCS]map[string]querypb.Type{}
for _, table := range tables {
if table == nil {
continue
}
tableName := sqlparser.String(sqlparser.GetTableName(table.Expr))
columns, exists := t.vte.getGlobalTabletEnv().tableColumns[tableName]
if !exists && tableName != "" {View on GitHub (pinned to 01a25a7d17)
Solutions
- Ensure only SELECT/UNION statements reach handleSelect.
- Update vtexplain to handle the new statement AST type in the switch.
- Use HandleQuery which routes by statement type instead of calling handleSelect directly.
Defensive patterns
Strategy: validation
Validate before calling
switch stmt.(type) {
case *sqlparser.Select, *sqlparser.ParenSelect, *sqlparser.Union:
// safe to pass to handleSelect
default:
return fmt.Errorf("not a select: %T", stmt)
} Type guard
func isExplainableSelect(stmt sqlparser.Statement) bool {
switch stmt.(type) {
case *sqlparser.Select, *sqlparser.ParenSelect, *sqlparser.Union:
return true
}
return false
} Try / catch
res, err := tablet.handleSelect(query)
if err != nil {
if strings.Contains(err.Error(), "unsupported statement type") {
// route to a different handler or skip
}
} Prevention
- Route statements by sqlparser.Preview before invoking handleSelect.
- Handle new parser statement types when upgrading Vitess.
- Only call handleSelect via HandleQuery routing.
When it happens
Trigger: A statement typed as select-like but whose AST is none of Select/ParenSelect/Union (e.g. a SHOW or other statement that reached handleSelect), producing reflect type output in the error.
Common situations: Routing bugs in tools built on vtexplain; newer parser statement kinds not yet handled; passing arbitrary statements into the explain-select path programmatically.
Related errors
- unsupported query %s
- table expression is complex
- cannot find serving, non-primary tablet in keyspace=%s: %w
- GetSchema(%s): %w
- GetSrvVSchema(%s): %w
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/41075b01d9c76393.
Report an issue: GitHub.