vitessio/vitess · error
err
Error message
err
What it means
Horizon.AddPredicate is pushing a predicate down into the subquery/derived table below the horizon. To do that it must resolve the expression's table info; if the semantic table lookup fails with anything other than the handled ErrNotSingleTable, the planner panics with the raw error. This is an internal-invariant failure: it means the planner was asked to add a predicate it cannot attribute to a known table.
Source
Thrown at go/vt/vtgate/planbuilder/operators/horizon.go:95
// This logic can also be used to check if this is a derived table that can be had on the left hand side of a vtgate join.
// Since vtgate joins are always nested loop joins, we can't execute them on the RHS
// if they do some things, like LIMIT or GROUP BY on wrong columns
func (h *Horizon) IsMergeable(ctx *plancontext.PlanningContext) bool {
return isMergeable(ctx, h.Query, h)
}
func (h *Horizon) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator {
if _, isUNion := h.Source.(*Union); isUNion {
// If we have a derived table on top of a UNION, we can let the UNION do the expression rewriting
h.Source = h.Source.AddPredicate(ctx, expr)
return h
}
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"))
}View on GitHub (pinned to 01a25a7d17)
Solutions
- Check the inner error message to find which expression/table could not be resolved
- Ensure the expression's columns have been rewritten via semantics.RewriteDerivedTableExpression before calling AddPredicate
- Verify the predicate passes semantic analysis (tables present in the scope) before routing it to the Horizon
- If ErrNotSingleTable is expected in your case, the planner already falls back to a filter — this panic means a different resolution bug; file/inspect a Vitess issue with the query
Defensive patterns
Strategy: try-catch
Validate before calling
// Vitess planner code: before calling AddPredicate, ensure the expr resolves
if _, err := ctx.SemTable.TableInfoForExpr(expr); err != nil && !errors.Is(err, semantics.ErrNotSingleTable) {
// handle or reject the expression before it reaches Horizon.AddPredicate
} Try / catch
// Vitess recovers planner panics at the VTGate boundary and converts them to vterrors;
// when extending the planner, wrap experimental calls:
func safeAddPredicate(h *operators.Horizon, ctx *plancontext.PlanningContext, e sqlparser.Expr) (op operators.Operator, err error) {
defer func() { if r := recover(); r != nil { err = fmt.Errorf("AddPredicate panicked: %v", r) } }()
return h.AddPredicate(ctx, e), nil
} Prevention
- Only route predicates that passed semantic analysis to Horizon.AddPredicate
- Treat ErrNotSingleTable explicitly (multi-table predicates go to filters, not the horizon)
- Add unit tests for predicates over derived tables before planner changes
When it happens
Trigger: Calling AddPredicate on a Horizon with an expression whose tables cannot be resolved by ctx.SemTable.TableInfoForExpr (e.g. an expression referencing an unknown/undone table mapping). ErrNotSingleTable is handled (falls back to newFilter); any other error escapes as this panic.
Common situations: Developing new Vitess planner features or rewriting expressions so they reference tables not registered in the SemTable; bugs in derived-table expression rewriting that leave dangling column references.
Related errors
- uncaught panic: %v, vtgate: %v
- unreachable
- This should never happen.
- bad unsigned integer type
- bad type aggregation for signed/unsigned types
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/1237f48afbc7f9f2.
Report an issue: GitHub.