vitessio/vitess · error
VT13001
VT13001
Error message
can't add new columns to Horizon (errNoNewColumns)
What it means
Horizon.AddColumn refuses to add brand-new columns to an already-finalized Horizon; the Horizon's projection is fixed at planning time and only existing select expressions can be reused (reuse=true). Panics with errNoNewColumns (VT13001) when reuse is false. VT13001 signals an unsupported/unimplemented code path in the planner.
Source
Thrown at go/vt/vtgate/planbuilder/operators/horizon.go:108
tableInfo, err := ctx.SemTable.TableInfoForExpr(expr)
if err != nil {
if errors.Is(err, semantics.ErrNotSingleTable) {
return newFilter(h, expr)
}
panic(err)
}
newExpr := semantics.RewriteDerivedTableExpression(expr, tableInfo)
if ctx.ContainsAggr(newExpr) {
return newFilter(h, expr)
}
h.Source = h.Source.AddPredicate(ctx, newExpr)
return h
}
func (h *Horizon) AddColumn(ctx *plancontext.PlanningContext, reuse bool, _ bool, expr *sqlparser.AliasedExpr) int {
if !reuse {
panic(errNoNewColumns)
}
col, ok := expr.Expr.(*sqlparser.ColName)
if !ok {
panic(vterrors.VT13001("cannot push non-ColName expression to horizon"))
}
offset := h.FindCol(ctx, col, false)
if offset < 0 {
panic(errNoNewColumns)
}
return offset
}
func (h *Horizon) AddWSColumn(ctx *plancontext.PlanningContext, offset int, underRoute bool) int {
cols := h.GetColumns(ctx)
if offset >= len(cols) {
panic(errNoNewColumns)
}
View on GitHub (pinned to 01a25a7d17)
Solutions
- Restructure the query so the needed column is already in the horizon's SELECT list
- Avoid forcing the derived table to merge (e.g. simplify the subquery) so the planner pushes projections into the route instead
- If seen from a Vitess release, check release notes/known issues — this indicates an unsupported planning path; file an issue with the query
Defensive patterns
Strategy: type-guard
Validate before calling
// caller side (planner code): only call with reuse=true for Horizon
if !reuse && isHorizon(op) { return ErrUnsupportedColumnAdd } Type guard
func canReuseColumnOnHorizon(h *operators.Horizon, ctx *plancontext.PlanningContext, expr *sqlparser.AliasedExpr) bool {
return h.FindCol(ctx, expr.Expr.(*sqlparser.ColName), false) >= 0
} Prevention
- Never call Horizon.AddColumn with reuse=false
- Check IsMergeable() before attempting to push projections through a horizon
- Keep needed columns in the inner SELECT list
When it happens
Trigger: Calling Horizon.AddColumn with reuse=false. The planner only supports reusing existing columns on a Horizon; any caller demanding a new column hits this panic.
Common situations: Planner code paths (subquery/derived-table projection, join column wiring) trying to push a projection that the horizon doesn't already expose — usually a query shape Vitess cannot yet merge, e.g. complex derived tables that need extra columns pulled up.
Related errors
- VT09015
- VT13001
- query not supported by vexec
- Not implemented, post_header_length!=8
- Not implemented, post_header_length==6
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/de1573a2b865668c.
Report an issue: GitHub.