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

  1. Check the error message to see which statement type failed to yield a Select; inspect the query for constructs the planner mishandles
  2. Simplify or rewrite the query (e.g. avoid exotic nesting of derived tables/unions) so a plain SELECT reaches the planner
  3. 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

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.