{"record":{"id":"1a9b275f2e81aa80","repo":"vitessio/vitess","slug":"unsupported-select-expression-v","errorCode":null,"errorMessage":"unsupported select expression: %v","messagePattern":"unsupported select expression: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtctl/workflow/utils.go","lineNumber":320,"sourceCode":"\t\tcase *sqlparser.AliasedExpr:\n\t\t\tmatch := selExpr.As\n\t\t\tif match.IsEmpty() {\n\t\t\t\tif colExpr, ok := selExpr.Expr.(*sqlparser.ColName); ok {\n\t\t\t\t\tmatch = colExpr.Name\n\t\t\t\t} else {\n\t\t\t\t\t// Cannot match against a complex expression.\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tif match.Equal(col) {\n\t\t\t\tcolExpr, ok := selExpr.Expr.(*sqlparser.ColName)\n\t\t\t\tif !ok {\n\t\t\t\t\treturn nil, fmt.Errorf(\"vindex column cannot be a complex expression: %v\", sqlparser.String(selExpr))\n\t\t\t\t}\n\t\t\t\treturn colExpr, nil\n\t\t\t}\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"unsupported select expression: %v\", sqlparser.String(selExpr))\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"could not find vindex column %v\", sqlparser.String(col))\n}\n\nfunc shouldInclude(table string, excludes []string) bool {\n\t// We filter out internal tables elsewhere when processing SchemaDefinition\n\t// structures built from the GetSchema database related API calls. In this\n\t// case, however, the table list comes from the user via the -tables flag\n\t// so we need to filter out internal table names here in case a user has\n\t// explicitly specified some.\n\t// This could happen if there's some automated tooling that creates the list of\n\t// tables to explicitly specify.\n\t// But given that this should never be done in practice, we ignore the request.\n\tif schema.IsInternalOperationTableName(table) {\n\t\treturn false\n\t}\n\treturn !slices.Contains(excludes, table)","sourceCodeStart":302,"sourceCodeEnd":338,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctl/workflow/utils.go#L302-L338","documentation":"matchColInSelect walks the select expressions of a workflow source query and only supports StarExpr and simple AliasedExpr column references. Any other expression type (subqueries, literals, function calls without alias handling, etc.) hits the default branch and is rejected with this error. It is a deliberate limitation of the query-rewrite-rule generator.","triggerScenarios":"A workflow (MoveTables/Reshard) filter or rule select contains an unsupported expression type in the select list — e.g. `select count(*) from t`, a scalar subquery, or a bare literal — and generateRule calls matchColInSelect to locate a vindex column there.","commonSituations":"Copy-pasting analytical SELECT queries into migration/reshard filter rules; auto-generated rules containing aggregates; older configs written for other tools being reused with vitess workflows.","solutions":["Replace the unsupported select expression with a plain column or `select <cols> from <table>` list.","Use `select *` or an explicit column list limited to the columns the workflow needs (including the vindex columns).","Split complex queries out of the workflow definition; workflows copy tables, they do not run arbitrary queries."],"exampleFix":"// before\nrule := \"select count(*) from t\"\n// error: unsupported select expression: count(*)\n// after\nrule := \"select col1, col2 from t\"","handlingStrategy":"validation","validationCode":"// keep workflow select lists to StarExpr or column refs only\nre := regexp.MustCompile(`(?i)\\b(count|sum|avg|min|max)\\s*\\(|\\(\\s*select\\b`)\nif re.MatchString(rule) {\n    return fmt.Errorf(\"workflow select must not contain expressions: %s\", rule)\n}","typeGuard":"func isSupportedSelectExpr(e sqlparser.SelectExpr) bool {\n    switch e.(type) {\n    case *sqlparser.StarExpr:\n        return true\n    case *sqlparser.AliasedExpr:\n        return true\n    }\n    return false\n}","tryCatchPattern":null,"preventionTips":["Use simple `select cols from table` lists in MoveTables/Reshard rules.","Never paste analytical or aggregate queries into workflow definitions.","Let the workflow tooling generate default rules instead of hand-writing them."],"tags":["go","workflow","sql-parsing"],"backgroundTag":"unsupported-select-expression","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}