{"record":{"id":"2ba27378e536b3e5","repo":"vitessio/vitess","slug":"unsupported-distinct-expression-usage-v","errorCode":null,"errorMessage":"unsupported distinct expression usage: %v","messagePattern":"unsupported distinct expression usage: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go","lineNumber":492,"sourceCode":"\t\tcexpr.references[as.String()] = true\n\t\treturn cexpr, nil\n\t}\n\tif expr, ok := aliased.Expr.(*sqlparser.FuncExpr); ok {\n\t\tswitch fname := expr.Name.Lowered(); fname {\n\t\tcase \"keyspace_id\":\n\t\t\tif len(expr.Exprs) != 0 {\n\t\t\t\treturn nil, fmt.Errorf(\"unsupported multiple keyspace_id expressions: %v\", sqlparser.String(expr))\n\t\t\t}\n\n\t\t\ttpb.sendSelect.AddSelectExpr(&sqlparser.AliasedExpr{Expr: aliased.Expr})\n\t\t\t// The vstreamer responds with \"keyspace_id\" as the field name for this request.\n\t\t\tcexpr.expr = &sqlparser.ColName{Name: sqlparser.NewIdentifierCI(\"keyspace_id\")}\n\t\t\treturn cexpr, nil\n\t\t}\n\t}\n\tif expr, ok := aliased.Expr.(sqlparser.AggrFunc); ok {\n\t\tif sqlparser.IsDistinct(expr) {\n\t\t\treturn nil, fmt.Errorf(\"unsupported distinct expression usage: %v\", sqlparser.String(expr))\n\t\t}\n\t\tswitch fname := expr.AggrName(); fname {\n\t\tcase \"count\":\n\t\t\tif _, ok := expr.(*sqlparser.CountStar); !ok {\n\t\t\t\treturn nil, fmt.Errorf(\"only count(*) is supported: %v\", sqlparser.String(expr))\n\t\t\t}\n\t\t\tcexpr.operation = opCount\n\t\t\treturn cexpr, nil\n\t\tcase \"sum\":\n\t\t\tif len(expr.GetArgs()) != 1 {\n\t\t\t\treturn nil, fmt.Errorf(\"unsupported multiple columns in sum clause: %v\", sqlparser.String(expr))\n\t\t\t}\n\t\t\tinnerCol, ok := expr.GetArg().(*sqlparser.ColName)\n\t\t\tif !ok {\n\t\t\t\treturn nil, fmt.Errorf(\"unsupported non-column name in sum clause: %v\", sqlparser.String(expr))\n\t\t\t}\n\t\t\tif !innerCol.Qualifier.IsEmpty() {\n\t\t\t\treturn nil, fmt.Errorf(\"unsupported qualifier for column: %v\", sqlparser.String(innerCol))","sourceCodeStart":474,"sourceCodeEnd":510,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go#L474-L510","documentation":"Aggregate functions with DISTINCT (e.g. `COUNT(DISTINCT x)`) are not supported by the vstreamer plan builder because distinct aggregation cannot be streamed incrementally. Only non-distinct aggregates — specifically `COUNT(*)` — are allowed.","triggerScenarios":"A filter select list contains `SUM(DISTINCT col)`, `COUNT(DISTINCT col)`, `AVG(DISTINCT col)`, etc.","commonSituations":"Porting analytical queries into replication filter rules; users expecting full aggregate support in MoveTables filters.","solutions":["Remove the DISTINCT keyword from the aggregate","Use plain `COUNT(*)` if counting is the goal — it is the only supported aggregate form","Perform distinct aggregation outside the replication pipeline, e.g. in a downstream query"],"exampleFix":"// before\nSELECT COUNT(DISTINCT uid) AS c FROM t\n// after\nSELECT COUNT(*) AS c FROM t","handlingStrategy":"validation","validationCode":"for _, e := range sel.SelectExprs {\n    ae, ok := e.(*sqlparser.AliasedExpr)\n    if !ok { continue }\n    if ag, ok := ae.Expr.(sqlparser.AggrFunc); ok {\n        if sqlparser.IsDistinct(ag) {\n            return fmt.Errorf(\"DISTINCT aggregates unsupported: %v\", sqlparser.String(ae))\n        }\n    }\n}","typeGuard":"func isSupportedAggregate(e sqlparser.Expr) bool {\n    cs, ok := e.(*sqlparser.CountStar)\n    return ok && cs != nil\n}","tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"distinct expression\") {\n    return fmt.Errorf(\"remove DISTINCT from aggregates in filter select list: %w\", err)\n}","preventionTips":["Never use DISTINCT inside aggregates in filter rules","Limit filter aggregates to COUNT(*)","Move complex aggregation to downstream queries, not replication filters"],"tags":["vreplication","aggregate","distinct","unsupported-sql"],"backgroundTag":"unsupported-aggregate-expression","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}