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

  1. Rewrite the filter's SELECT to reference exactly one plain table: select <cols> from <table> [where <literal-predicates>]
  2. Remove joins/subqueries — perform them downstream in the VStream consumer
  3. Verify GetTableName on the FROM expression yields a real table name (no derived tables)
  4. 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

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


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/26f68dd268db2f2c. Report an issue: GitHub.