vitessio/vitess · error
only count(*) is supported: %v
Error message
only count(*) is supported: %v
What it means
VReplication's table plan builder only supports the simplest form of COUNT in a filtered replication SELECT: COUNT(*). Any argumented count, e.g. COUNT(col) or COUNT(DISTINCT col), is rejected because the generated materialization logic cannot evaluate per-row counting. The error is returned by analyzeExpr when an aggregate named 'count' is not a *sqlparser.CountStar.
Source
Thrown at go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go:497
case "keyspace_id":
if len(expr.Exprs) != 0 {
return nil, fmt.Errorf("unsupported multiple keyspace_id expressions: %v", sqlparser.String(expr))
}
tpb.sendSelect.AddSelectExpr(&sqlparser.AliasedExpr{Expr: aliased.Expr})
// The vstreamer responds with "keyspace_id" as the field name for this request.
cexpr.expr = &sqlparser.ColName{Name: sqlparser.NewIdentifierCI("keyspace_id")}
return cexpr, nil
}
}
if expr, ok := aliased.Expr.(sqlparser.AggrFunc); ok {
if sqlparser.IsDistinct(expr) {
return nil, fmt.Errorf("unsupported distinct expression usage: %v", sqlparser.String(expr))
}
switch fname := expr.AggrName(); fname {
case "count":
if _, ok := expr.(*sqlparser.CountStar); !ok {
return nil, fmt.Errorf("only count(*) is supported: %v", sqlparser.String(expr))
}
cexpr.operation = opCount
return cexpr, nil
case "sum":
if len(expr.GetArgs()) != 1 {
return nil, fmt.Errorf("unsupported multiple columns in sum clause: %v", sqlparser.String(expr))
}
innerCol, ok := expr.GetArg().(*sqlparser.ColName)
if !ok {
return nil, fmt.Errorf("unsupported non-column name in sum clause: %v", sqlparser.String(expr))
}
if !innerCol.Qualifier.IsEmpty() {
return nil, fmt.Errorf("unsupported qualifier for column: %v", sqlparser.String(innerCol))
}
cexpr.operation = opSum
cexpr.expr = innerCol
tpb.addCol(innerCol.Name)
cexpr.references[innerCol.Name.String()] = trueView on GitHub (pinned to 01a25a7d17)
Solutions
- Rewrite the select list to use COUNT(*) instead of COUNT(col) or COUNT(DISTINCT col).
- If you need per-column counts, compute them outside vreplication (e.g. via a separate query or aggregation engine).
- Remove DISTINCT from the aggregate — distinct usage is rejected separately.
- Check that the query you passed to MoveTables/Materialize only uses supported aggregates (count(*) and single-column sum).
Example fix
// before select count(user_id) as cnt from t // after select count(*) as cnt from t
Defensive patterns
Strategy: validation
Validate before calling
// Go: reject argumented COUNT before submitting to the workflow
func validCount(e sqlparser.Expr) bool {
ag, ok := e.(*sqlparser.AliasedExpr)
if !ok { return true }
cs, ok := ag.Expr.(*sqlparser.CountStar)
return ok && cs != nil
} Type guard
func isCountStar(n sqlparser.SQLNode) bool { _, ok := n.(*sqlparser.CountStar); return ok } Prevention
- Only use COUNT(*) in materialize/vreplication select lists.
- Never apply DISTINCT to count in workflow queries.
- Keep workflow queries minimal; do complex analytics with VTGate afterward.
When it happens
Trigger: Running a Materialize / vreplication workflow whose SELECT list contains COUNT(col), COUNT(1), COUNT(DISTINCT x), or COUNT(*) with any non-star argument; analyzeExpr is called via analyzeExprs while building the table plan.
Common situations: Users copying a hand-written analytics query into a Materialize source; upgrading a workflow that previously used a plain count and someone changed it to count a column; tools generating 'SELECT COUNT(id) FROM t' as a convenience.
Related errors
- unsupported multiple columns in sum clause: %v
- unsupported non-column name in sum clause: %v
- unsupported aggregation function: %v
- group by expression is not allowed to reference an aggregate
- unsupported subquery: %v
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/ad22c3e8f67ab03d.
Report an issue: GitHub.