vitessio/vitess · error
VT13001
VT13001
Error message
Unknown SelectStatement type - %T
What it means
VT13001 panic in isMergeable: the planner's switch over sqlparser.SelectStatement types has a default case, meaning an unhandled SelectStatement AST node type was encountered while deciding whether a statement is mergeable. This is an internal completeness check — the parser should never produce a statement type the planner does not know.
Source
Thrown at go/vt/vtgate/planbuilder/operators/subquery_planning.go:72
// TODO: we could also support the case where all the columns of a multi-column vindex are used in the grouping
return slices.ContainsFunc(node.GroupBy.Exprs, validVindex)
}
// if we have grouping, we have already checked that it's safe, and don't need to check for aggregations
// but if we don't have groupings, we need to check if there are aggregations that will mess with us
if ctx.ContainsAggr(node.SelectExprs) {
return false
}
if ctx.ContainsAggr(node.Having) {
return false
}
return true
case *sqlparser.Union:
return isMergeable(ctx, node.Left, op) && isMergeable(ctx, node.Right, op)
default:
panic(vterrors.VT13001(fmt.Sprintf("Unknown SelectStatement type - %T", node)))
}
}
func settleSubqueries(ctx *plancontext.PlanningContext, op Operator) Operator {
visit := func(op Operator, lhsTables semantics.TableSet, isRoot bool) (Operator, *ApplyResult) {
switch op := op.(type) {
case *SubQueryContainer:
outer := op.Outer
for _, subq := range op.Inner {
subq.Outer = subq.settle(ctx, outer)
outer = subq
}
return outer, Rewrote("extracted subqueries from subquery container")
case *Projection:
ap, err := op.GetAliasedProjections()
if err != nil {
panic(err)
}View on GitHub (pinned to 01a25a7d17)
Solutions
- File a bug with the SQL statement and stack trace at the Vitess repository
- Upgrade to the latest Vitess release where newer statement types may be handled
- Rewrite the query using more standard SELECT/UNION syntax
- As a workaround, run the statement directly against MySQL bypassing vtgate planning if applicable
Defensive patterns
Strategy: fallback
Try / catch
err := doQuery(q)
if err != nil && strings.Contains(err.Error(), "VT13001") && strings.Contains(err.Error(), "Unknown SelectStatement type") {
// report bug; try a simplified/standard rewrite of the statement
return doQuery(simplifyStatement(q))
} Prevention
- Keep Vitess and its SQL parser up to date
- Avoid bleeding-edge SQL syntax unsupported by the planner
- Test new syntax against vtgate before adoption
- Report unhandled statement types upstream with repro SQL
When it happens
Trigger: isMergeable (via IsMergeable or recursion on Union operands) receives a SelectStatement implementation not covered by the switch cases (Select, Union, etc.), typically after a new AST node type is added to the parser without planner support.
Common situations: Seen in Vitess development when new SQL syntax is added to the parser; extremely rare for users, but could be reported when running newly parsed exotic statements (e.g. new table expression types) through the planner.
Related errors
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/5227cfd39188a46f.
Report an issue: GitHub.