vitessio/vitess · error
unsupported non-select statement
Error message
unsupported non-select statement
What it means
analyzeSelectFrom only accepts sqlparser.Select statements for vreplication filter rules. Any other statement type (INSERT, UPDATE, SET, SHOW, etc.) cannot define a replication source table and is rejected with this error.
Source
Thrown at go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go:396
Stats: tpb.stats,
FieldsToSkip: fieldsToSkip,
HasExtraSourcePkColumns: len(tpb.extraSourcePkCols) > 0,
TablePlanBuilder: tpb,
PartialInserts: make(map[string]*sqlparser.ParsedQuery, 0),
PartialUpdates: make(map[string]*sqlparser.ParsedQuery, 0),
CollationEnv: tpb.collationEnv,
WorkflowConfig: tpb.workflowConfig,
}
}
func analyzeSelectFrom(query string, parser *sqlparser.Parser) (sel *sqlparser.Select, from string, err error) {
statement, err := parser.Parse(query)
if err != nil {
return nil, "", err
}
sel, ok := statement.(*sqlparser.Select)
if !ok {
return nil, "", errors.New("unsupported non-select statement")
}
if sel.Distinct {
return nil, "", errors.New("unsupported distinct clause")
}
if len(sel.From) == 0 {
return nil, "", errors.New("unsupported select from dual")
}
if len(sel.From) > 1 {
return nil, "", errors.New("unsupported multi-table usage")
}
node, ok := sel.From[0].(*sqlparser.AliasedTableExpr)
if !ok {
return nil, "", fmt.Errorf("unsupported from expression (%T)", sel.From[0])
}
fromTable := sqlparser.GetTableName(node.Expr)
if fromTable.IsEmpty() {
return nil, "", fmt.Errorf("unsupported from source (%T)", node.Expr)
}View on GitHub (pinned to 01a25a7d17)
Solutions
- Use a simple single SELECT statement as the filter rule (e.g. 'select * from t where ...')
- Remove any UPDATE/SET/SHOW/UNION statements from the filter configuration
- For filtered rows, express the condition in the SELECT's WHERE clause instead
Example fix
// before "filter": "update t set flag=1" // after "filter": "select * from t where flag=1"
Defensive patterns
Strategy: validation
Validate before calling
stmt, err := parser.Parse(filterQuery)
if err != nil { return err }
if _, ok := stmt.(*sqlparser.Select); !ok {
return errors.New("filter rule must be a SELECT")
} Prevention
- Only put single SELECT statements in filter rules
- Handle row filtering via WHERE clauses, not DML/DDL
- Validate all rule SQL in deployment scripts
When it happens
Trigger: A filter rule query parses into a non-Select AST node, e.g. 'update t set ...', 'set @x=1', 'show tables', or a parenthesized/union construct that is not a plain *sqlparser.Select.
Common situations: Misconfigured filter rules accidentally containing DDL/DML; copy-paste of maintenance SQL into filter config; UNION queries that the builder cannot treat as a simple select.
Related errors
- unsupported mix of '*' and columns
- unsupported qualifier for '*' expression
- unsupported distinct clause
- unsupported select from dual
- unexpected event on table %s
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/91072a26319a5d35.
Report an issue: GitHub.