{"record":{"id":"8808dee2b73b1224","repo":"vitessio/vitess","slug":"err-8808de","errorCode":null,"errorMessage":"err","messagePattern":"err","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtgate/planbuilder/operators/horizon_expanding.go","lineNumber":272,"sourceCode":"\t\t\tnewExprs = append(newExprs, newExpr)\n\t\t\taggr.SubQueryExpression = append(aggr.SubQueryExpression, subqs...)\n\t\t} else {\n\t\t\tnewExprs = append(newExprs, expr)\n\t\t}\n\t}\n\tif len(aggr.SubQueryExpression) > 0 {\n\t\taggr.setPushColumn(newExprs)\n\t}\n\n\treturn aggr\n}\n\nfunc addAllColumnsToAggregator(ctx *plancontext.PlanningContext, a *Aggregator, qp *QueryProjection) {\nouter:\n\tfor colIdx, expr := range qp.SelectExprs {\n\t\tae, err := expr.GetAliasedExpr()\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\taddedToCol := false\n\t\tfor idx, groupBy := range a.Grouping {\n\t\t\tif ctx.SemTable.EqualsExprWithDeps(groupBy.Inner, ae.Expr) {\n\t\t\t\tif !addedToCol {\n\t\t\t\t\ta.Columns = append(a.Columns, ae)\n\t\t\t\t\taddedToCol = true\n\t\t\t\t}\n\t\t\t\tif groupBy.ColOffset < 0 {\n\t\t\t\t\ta.Grouping[idx].ColOffset = colIdx\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif addedToCol {\n\t\t\tcontinue\n\t\t}\n\t\tfor idx, aggr := range a.Aggregations {\n\t\t\tif ctx.SemTable.EqualsExprWithDeps(aggr.Original.Expr, ae.Expr) && aggr.ColOffset < 0 {","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtgate/planbuilder/operators/horizon_expanding.go#L254-L290","documentation":"This is an unrecoverable panic raised inside the VTGate planning stage while adding columns to an Aggregator operator. `expr.GetAliasedExpr()` fails when a select expression is not a plain aliased expression at this point of horizon expansion, indicating an internal planner invariant violation rather than an invalid user query. The original error is re-panicked so planning aborts instead of producing a wrong plan.","triggerScenarios":"A query containing an aggregation reaches addAllColumnsToAggregator (via createProjectionWithAggr) and one of the QueryProjection SelectExprs cannot be converted to an *sqlparser.AliasedExpr by GetAliasedExpr() — e.g. an unexpected expression shape survives earlier planning phases.","commonSituations":"Complex or unusual SELECT expressions combined with GROUP BY that the planner's earlier rewrite stages did not normalize; often hit during development of new SQL features or by fuzzer-generated queries rather than ordinary application SQL.","solutions":["Capture the failing query and file a bug with the Vitess project — this panic indicates a planner bug, not user error","Simplify the query: rewrite complex SELECT expressions so each is a plain column reference or explicitly aliased expression","Try restructuring the aggregation (e.g. move expressions into a derived table and aggregate over it)","Check the Vitess version and upgrade — such invariant panics are frequently fixed in newer releases"],"exampleFix":"// before (query that may trigger)\nSELECT a+b, COUNT(*) FROM t GROUP BY a+b;\n// after (pre-alias so planner sees a plain aliased expr)\nSELECT (a+b) AS s, COUNT(*) FROM t GROUP BY s;","handlingStrategy":"validation","validationCode":"// Run the query with ONLY_FULL_GROUP_BY against a plain MySQL first;\n// only plain aliased expressions in the SELECT list of aggregated queries.\nfunc hasPlainAliasedSelectExprs(sel *sqlparser.Select) bool {\n  for _, e := range sel.SelectExprs {\n    if _, ok := e.(*sqlparser.AliasedExpr); !ok { return false }\n  }\n  return true\n}","typeGuard":"if ae, ok := expr.(sqlparser.SelectExpr); ok {\n  if _, isAliased := ae.GetAliasedExpr(); isAliased == false { /* avoid path */ }\n}","tryCatchPattern":"// In Vitess code paths that call planning, recover planner panics:\nfunc safePlan(q string) (plan any, err error) {\n  defer func() {\n    if r := recover(); r != nil { err = fmt.Errorf(\"planning failed: %v\", r) }\n  }()\n  return planQuery(q)\n}","preventionTips":["Keep SELECT expressions explicitly aliased in GROUP BY queries","Test aggregation queries against a real MySQL with ONLY_FULL_GROUP_BY before Vitess","Pin a known-good Vitess version and read release notes for planner fixes","Report panics with full query + version to Vitess rather than working around silently"],"tags":["go","panic","query-planning","aggregation"],"backgroundTag":"internal-planner-panic","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}