{"record":{"id":"de1573a2b865668c","repo":"vitessio/vitess","slug":"vt13001-de1573","errorCode":"VT13001","errorMessage":"can't add new columns to Horizon (errNoNewColumns)","messagePattern":"can't add new columns to Horizon \\(errNoNewColumns\\)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtgate/planbuilder/operators/horizon.go","lineNumber":108,"sourceCode":"\ttableInfo, err := ctx.SemTable.TableInfoForExpr(expr)\n\tif err != nil {\n\t\tif errors.Is(err, semantics.ErrNotSingleTable) {\n\t\t\treturn newFilter(h, expr)\n\t\t}\n\t\tpanic(err)\n\t}\n\n\tnewExpr := semantics.RewriteDerivedTableExpression(expr, tableInfo)\n\tif ctx.ContainsAggr(newExpr) {\n\t\treturn newFilter(h, expr)\n\t}\n\th.Source = h.Source.AddPredicate(ctx, newExpr)\n\treturn h\n}\n\nfunc (h *Horizon) AddColumn(ctx *plancontext.PlanningContext, reuse bool, _ bool, expr *sqlparser.AliasedExpr) int {\n\tif !reuse {\n\t\tpanic(errNoNewColumns)\n\t}\n\tcol, ok := expr.Expr.(*sqlparser.ColName)\n\tif !ok {\n\t\tpanic(vterrors.VT13001(\"cannot push non-ColName expression to horizon\"))\n\t}\n\toffset := h.FindCol(ctx, col, false)\n\tif offset < 0 {\n\t\tpanic(errNoNewColumns)\n\t}\n\treturn offset\n}\n\nfunc (h *Horizon) AddWSColumn(ctx *plancontext.PlanningContext, offset int, underRoute bool) int {\n\tcols := h.GetColumns(ctx)\n\tif offset >= len(cols) {\n\t\tpanic(errNoNewColumns)\n\t}\n","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtgate/planbuilder/operators/horizon.go#L90-L126","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"// caller side (planner code): only call with reuse=true for Horizon\nif !reuse && isHorizon(op) { return ErrUnsupportedColumnAdd }","typeGuard":"func canReuseColumnOnHorizon(h *operators.Horizon, ctx *plancontext.PlanningContext, expr *sqlparser.AliasedExpr) bool {\n    return h.FindCol(ctx, expr.Expr.(*sqlparser.ColName), false) >= 0\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["planner","projection","vt13001","unsupported"],"backgroundTag":"projection-pushdown-unsupported","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}