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

  1. Restructure the query so the needed column is already in the horizon's SELECT list
  2. Avoid forcing the derived table to merge (e.g. simplify the subquery) so the planner pushes projections into the route instead
  3. 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

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


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/de1573a2b865668c. Report an issue: GitHub.