vitessio/vitess · warning
error getting select: %s
Error message
error getting select: %s
What it means
After parsing the synthetic tenant query ('select * from t where <col> = <lit>'), getTenantClause asserts the AST node is a *sqlparser.Select. A successfully parsed statement that is not a Select indicates the constructed SQL was not a plain SELECT (unexpected, given the fixed template), so the function bails with this error, reporting the tenant id value in the message.
Source
Thrown at go/vt/vtctl/workflow/utils.go:873
case querypb.Type_INT64:
_, err := strconv.Atoi(vrOptions.TenantId)
if err != nil {
return nil, fmt.Errorf("tenant id is not a valid int: %s", vrOptions.TenantId)
}
tenantId = vrOptions.TenantId
case querypb.Type_VARCHAR:
tenantId = sqltypes.EncodeStringSQL(vrOptions.TenantId)
default:
return nil, fmt.Errorf("unsupported tenant column type: %s", tenantColumnType)
}
stmt, err := parser.Parse(fmt.Sprintf("select * from t where %s = %s", sqlescape.EscapeID(tenantColumnName), tenantId))
if err != nil {
return nil, err
}
sel, ok := stmt.(*sqlparser.Select)
if !ok {
return nil, fmt.Errorf("error getting select: %s", tenantId)
}
return &sel.Where.Expr, nil
}
func changeKeyspaceRouting(ctx context.Context, ts *topo.Server, tabletTypes []topodatapb.TabletType,
sourceKeyspace, targetKeyspace, reason string,
) error {
routes := make(map[string]string)
for _, tabletType := range tabletTypes {
suffix := getTabletTypeSuffix(tabletType)
routes[sourceKeyspace+suffix] = targetKeyspace
}
if err := updateKeyspaceRoutingRules(ctx, ts, reason, routes); err != nil {
return err
}
return ts.RebuildSrvVSchema(ctx, nil)
}
View on GitHub (pinned to 01a25a7d17)
Solutions
- Verify the tenant column name is a plain identifier; quote with backticks if it contains special characters (sqlescape.EscapeID handles this).
- Retry with a simple alphanumeric tenant column name to isolate the problem.
- If reproducible, file a Vitess bug with the tenant column name/type and tenant id used.
- Check the wrapped parser error (returned first) for the root cause of the unexpected parse.
Example fix
// before tenant_column: "select *" // odd column name confuses generated SQL // after --tenant-column tenant_id
Defensive patterns
Strategy: try-catch
Try / catch
expr, err := getTenantClause(...)
if err != nil {
if strings.Contains(err.Error(), "error getting select") {
log.Errorf("tenant clause builder produced non-SELECT AST (tenantId=%v): %v", tenantID, err)
}
return err
} Prevention
- Keep tenant column names as simple identifiers; escape special names with sqlescape.EscapeID
- Treat this as an internal invariant failure — capture inputs and file a Vitess issue if seen
- Check the underlying parser error returned before this branch for the real cause
When it happens
Trigger: Practically only when the parsed statement is something other than a Select — e.g. the generated WHERE text leads the parser to produce a non-Select AST (set/other statement) — an internal invariant failure in the tenant clause builder.
Common situations: Rarely seen in the field; would surface as an internal error while building tenant-filtered MoveTables streams, typically after unusual tenant column names or values edge their way into the generated SQL.
Related errors
- tenant id is not a valid int: %s
- unsupported tenant column type: %s
- value %s is not a valid int
- unsupported data type: %s
- unexpected: %+v
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/b8d7480842e2e02e.
Report an issue: GitHub.