vitessio/vitess · error
unsupported: %v
Error message
unsupported: %v
What it means
The vstreamer planbuilder only supports SELECT statements whose FROM clause starts with a single plain (possibly aliased) table expression, because VStream filters translate to simple table selects. Any other first FROM item (subquery, join, parenthesized expr) or an empty/complex table name makes analyzeSelect reject the whole select as unsupported.
Source
Thrown at go/vt/vttablet/tabletserver/vstreamer/planbuilder.go:550
return nil, fromTable, err
}
sel, ok := statement.(*sqlparser.Select)
if !ok {
return nil, fromTable, fmt.Errorf("unsupported: %v", sqlparser.String(statement))
}
if len(sel.From) == 0 {
return nil, fromTable, fmt.Errorf("unsupported select from dual: %v", sqlparser.String(sel))
}
if len(sel.From) > 1 {
return nil, fromTable, fmt.Errorf("unsupported: %v", sqlparser.String(sel))
}
node, ok := sel.From[0].(*sqlparser.AliasedTableExpr)
if !ok {
return nil, fromTable, fmt.Errorf("unsupported: %v", sqlparser.String(sel))
}
fromTable = sqlparser.GetTableName(node.Expr)
if fromTable.IsEmpty() {
return nil, fromTable, fmt.Errorf("unsupported: %v", sqlparser.String(sel))
}
return sel, fromTable, nil
}
// isConvertColumnUsingUTF8 returns 'true' when given column needs to be converted as UTF8
// while read from source table
func (plan *Plan) isConvertColumnUsingUTF8(columnName string) bool {
if plan.convertUsingUTF8Columns == nil {
return false
}
return plan.convertUsingUTF8Columns[columnName]
}
// setConvertColumnUsingUTF8 marks given column as needs to be converted as UTF8
// while read from source table
func (plan *Plan) setConvertColumnUsingUTF8(columnName string) {
if plan.convertUsingUTF8Columns == nil {
plan.convertUsingUTF8Columns = map[string]bool{}View on GitHub (pinned to 01a25a7d17)
Solutions
- Rewrite the filter's SELECT to reference exactly one plain table: select <cols> from <table> [where <literal-predicates>]
- Remove joins/subqueries — perform them downstream in the VStream consumer
- Verify GetTableName on the FROM expression yields a real table name (no derived tables)
- Check planbuilder.go analyzeSelect for the currently supported grammar subset
Example fix
// before filter: select t1.a, t2.b from t1 join t2 on t1.id=t2.id // after filter: select t1.a, t1.b from t1
Defensive patterns
Strategy: validation
Validate before calling
// check filter SELECT before installing
stmt, err := sqlparser.Parse(rule.Filter)
if err != nil { return err }
sel, ok := stmt.(*sqlparser.Select)
if !ok { return fmt.Errorf("not a select") }
if _, ok := sel.From[0].(*sqlparser.AliasedTableExpr); !ok || len(sel.From) != 1 {
return fmt.Errorf("filter must select from a single table")
} Prevention
- Write filters as single-table SELECTs only
- No joins, subqueries, or derived tables in filters
- Do complex processing in the consumer, not the filter
When it happens
Trigger: A VReplication/VStream filter rule's SELECT contains a subquery, JOIN, or non-table expression as sel.From[0]; or the extracted table name is empty (e.g. FROM (SELECT ...)).
Common situations: Custom VStream filters with fancy SQL; users expecting vstreamer to handle joins like a full query engine; filter rules written with derived tables.
Related errors
- VStreamer is not open
- only integer literals are supported
- only the integer literal 1 is supported
- VStreamer is not open
- stream needs a position or a table to copy
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/26f68dd268db2f2c.
Report an issue: GitHub.