{"record":{"id":"0fa444a2c5a85d64","repo":"vitessio/vitess","slug":"unsupported-non-column-name-or-alias-in-group-by-c","errorCode":null,"errorMessage":"unsupported non-column name or alias in group by clause: %v","messagePattern":"unsupported non-column name or alias in group by clause: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go","lineNumber":557,"sourceCode":"}\n\n// addCol adds the specified column to the send query\n// if it's not already present.\nfunc (tpb *tablePlanBuilder) addCol(ident sqlparser.IdentifierCI) {\n\ttpb.sendSelect.AddSelectExpr(&sqlparser.AliasedExpr{\n\t\tExpr: &sqlparser.ColName{Name: ident},\n\t})\n}\n\nfunc (tpb *tablePlanBuilder) analyzeGroupBy(groupBy *sqlparser.GroupBy) error {\n\tif groupBy == nil {\n\t\t// If there's no grouping, the it's an insertNormal.\n\t\treturn nil\n\t}\n\tfor _, expr := range groupBy.Exprs {\n\t\tcolname, ok := expr.(*sqlparser.ColName)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"unsupported non-column name or alias in group by clause: %v\", sqlparser.String(expr))\n\t\t}\n\t\tcexpr := tpb.findCol(colname.Name)\n\t\tif cexpr == nil {\n\t\t\treturn fmt.Errorf(\"group by expression does not reference an alias in the select list: %v\", sqlparser.String(expr))\n\t\t}\n\t\tif cexpr.operation != opExpr {\n\t\t\treturn fmt.Errorf(\"group by expression is not allowed to reference an aggregate expression: %v\", sqlparser.String(expr))\n\t\t}\n\t\tcexpr.isGrouped = true\n\t}\n\t// If all colExprs are grouped, then it's an insertIgnore.\n\ttpb.onInsert = insertIgnore\n\tfor _, cExpr := range tpb.colExprs {\n\t\tif !cExpr.isGrouped {\n\t\t\t// If some colExprs are not grouped, then it's an insertOnDup.\n\t\t\ttpb.onInsert = insertOnDup\n\t\t\tbreak\n\t\t}","sourceCodeStart":539,"sourceCodeEnd":575,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go#L539-L575","documentation":"GROUP BY in a vreplication table plan may only reference columns by name (a *sqlparser.ColName). Arbitrary expressions, literals, or positional references in GROUP BY are rejected because the builder resolves each group-by item against select-list aliases via findCol.","triggerScenarios":"Materialize/vreplication SELECT with GROUP BY <expr>, e.g. GROUP BY UPPER(name), GROUP BY 1, or GROUP BY a+b; analyzeGroupBy's type assertion to *sqlparser.ColName fails.","commonSituations":"Queries copied from engines supporting GROUP BY expressions/positions; users grouping by computed values without aliasing them in the select list.","solutions":["Group only by a column name that also appears (aliased) in the SELECT list.","Create an aliased select item for the computed value first, then GROUP BY that alias: SELECT UPPER(name) AS uname ... GROUP BY uname.","Remove numeric positional group-by items and use explicit column names."],"exampleFix":"// before\nselect upper(name) from t group by 1\n// after\nselect upper(name) as uname from t group by uname","handlingStrategy":"validation","validationCode":"// Require every GROUP BY item to be a plain column name\nfunc validGroupBy(sel *sqlparser.Select) bool {\n    for _, e := range sel.GroupBy.Exprs {\n        if _, ok := e.(*sqlparser.ColName); !ok { return false }\n    }\n    return true\n}","typeGuard":"func isGroupableCol(n sqlparser.SQLNode) bool { _, ok := n.(*sqlparser.ColName); return ok }","tryCatchPattern":null,"preventionTips":["Never use expressions, literals, or positions in GROUP BY for workflow queries.","Alias computed select items and group by the alias name."],"tags":["vreplication","sql","group-by","vttablet"],"backgroundTag":"unsupported-group-by-expression","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}