vitessio/vitess · error
err
Error message
err
What it means
This is an internal planner panic: getFirstSelect calls sqlparser.GetFirstSelect on a table statement (SELECT/UNION) and, if that helper returns an error, re-panics with the raw error. GetFirstSelect only fails for statement kinds it cannot extract a *sqlparser.Select from (e.g. non-Select table statements such as certain parenthesized or non-select statements passed where a SELECT is expected), so in practice this surfaces as an unexpected internal error rather than a user-facing code.
Source
Thrown at go/vt/vtgate/planbuilder/operators/expressions.go:128
}
post := func(cursor *sqlparser.CopyOnWriteCursor) {
if replace != nil {
cursor.Replace(replace)
replace = nil
}
}
output := sqlparser.CopyOnRewrite(in, pre, post, ctx.SemTable.CopySemanticInfo).(sqlparser.Expr)
if in != output {
// we need to do this, since one simplification might lead to another
return simplifyPredicates(ctx, output)
}
return output
}
func getFirstSelect(selStmt sqlparser.TableStatement) *sqlparser.Select {
firstSelect, err := sqlparser.GetFirstSelect(selStmt)
if err != nil {
panic(err)
}
return firstSelect
}
View on GitHub (pinned to 01a25a7d17)
Solutions
- Check the error message to see which statement type failed to yield a Select; inspect the query for constructs the planner mishandles
- Simplify or rewrite the query (e.g. avoid exotic nesting of derived tables/unions) so a plain SELECT reaches the planner
- If reproducible with a normal query, file a Vitess bug with the query and stack trace - this path should not fail for valid SELECTs
Defensive patterns
Strategy: try-catch
Type guard
func isSelect(stmt sqlparser.TableStatement) bool {
_, ok := stmt.(*sqlparser.Select)
return ok
} Try / catch
defer func() {
if r := recover(); r != nil {
log.Error("planner internal panic in getFirstSelect", slog.Any("panic", r))
return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "planning failed: %v", r)
}
}() Prevention
- Only pass *sqlparser.Select statements (or verified select-containing statements) into planner helpers
- Recover panics at the planner boundary and map them to INTERNAL gRPC errors
- Add unit tests for derived-table/union planning with varied statement shapes
When it happens
Trigger: Passing a sqlparser.TableStatement that is not (or does not contain) a *sqlparser.Select into planner helpers such as pushUnionInsideDerived, checkUnionColumnByName, FindCol, GetSelectExprs, columnMismatch, or planQuery.
Common situations: Developers extending planbuilder who feed a UNION/parenthesized node or new AST statement type into helpers expecting a Select; planner bugs where an unsupported statement shape reaches derived-table planning.
Related errors
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/9331d301a7bed9ed.
Report an issue: GitHub.