{"record":{"id":"dc6b01bf97689157","repo":"vitessio/vitess","slug":"invalid-expression-v","errorCode":null,"errorMessage":"invalid expression: %v","messagePattern":"invalid expression: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go","lineNumber":432,"sourceCode":"\t}\n\treturn sel, fromTable.String(), nil\n}\n\nfunc (tpb *tablePlanBuilder) analyzeExprs(selExprs []sqlparser.SelectExpr) error {\n\tfor _, selExpr := range selExprs {\n\t\tcexpr, err := tpb.analyzeExpr(selExpr)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\ttpb.colExprs = append(tpb.colExprs, cexpr)\n\t}\n\treturn nil\n}\n\nfunc (tpb *tablePlanBuilder) analyzeExpr(selExpr sqlparser.SelectExpr) (*colExpr, error) {\n\taliased, ok := selExpr.(*sqlparser.AliasedExpr)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"invalid expression: %v\", sqlparser.String(selExpr))\n\t}\n\tas := aliased.As\n\tif as.IsEmpty() {\n\t\t// Require all non-trivial expressions to have an alias.\n\t\tif colAs, ok := aliased.Expr.(*sqlparser.ColName); ok && colAs.Qualifier.IsEmpty() {\n\t\t\tas = colAs.Name\n\t\t} else {\n\t\t\treturn nil, fmt.Errorf(\"expression needs an alias: %v\", sqlparser.String(aliased))\n\t\t}\n\t}\n\tcexpr := &colExpr{\n\t\tcolName:    as,\n\t\treferences: make(map[string]bool),\n\t}\n\tif expr, ok := aliased.Expr.(*sqlparser.ConvertUsingExpr); ok {\n\t\t// Here we find the actual column name in the convert, in case\n\t\t// this is a column rename and the AS is the new column.\n\t\t// For example, in convert(c1 using utf8mb4) as c2, we want to find","sourceCodeStart":414,"sourceCodeEnd":450,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go#L414-L450","documentation":"analyzeExpr requires every select expression to be either a plain *sqlparser.AliasedExpr column/aliased expression. Any other SelectExpr kind (e.g. a star expression `*` or `t.*`) cannot be converted into an explicit column plan and triggers this error.","triggerScenarios":"A filter select list contains `SELECT *` or `table.*` (StarExpr) instead of explicitly enumerated columns.","commonSituations":"Users writing MoveTables filter rules with `SELECT *`; code generators emitting star selects; schema changes that encouraged wildcard selects.","solutions":["Enumerate columns explicitly in the select list instead of using *","Regenerate the plan after adding new columns so the explicit list stays current","Use the keyspace_id() function or plain column names supported by the plan builder"],"exampleFix":"// before\nSELECT * FROM t\n// after\nSELECT id, name, keyspace_id() as keyspace_id FROM t","handlingStrategy":"validation","validationCode":"for _, e := range sel.SelectExprs {\n    if _, ok := e.(*sqlparser.AliasedExpr); !ok {\n        return fmt.Errorf(\"select list must be explicit columns/aliased exprs; got %T\", e)\n    }\n}","typeGuard":"func allAliasedExprs(exprs []sqlparser.SelectExpr) bool {\n    for _, e := range exprs {\n        if _, ok := e.(*sqlparser.AliasedExpr); !ok { return false }\n    }\n    return true\n}","tryCatchPattern":"plan, err := buildReplicatorPlan(...)\nif err != nil && strings.Contains(err.Error(), \"invalid expression\") {\n    // rewrite select list without star expressions and retry\n}","preventionTips":["Never use SELECT * in filter rules; enumerate columns","Regenerate rules after schema changes","Preflight-parse filter select lists"],"tags":["sqlparser","vreplication","select-list","plan-builder"],"backgroundTag":"unsupported-sql-construct","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}