{"record":{"id":"ccccebf3080cda2b","repo":"vitessio/vitess","slug":"unsupported-select-from-dual","errorCode":null,"errorMessage":"unsupported select from dual","messagePattern":"unsupported select from dual","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go","lineNumber":402,"sourceCode":"\t\tCollationEnv:            tpb.collationEnv,\n\t\tWorkflowConfig:          tpb.workflowConfig,\n\t}\n}\n\nfunc analyzeSelectFrom(query string, parser *sqlparser.Parser) (sel *sqlparser.Select, from string, err error) {\n\tstatement, err := parser.Parse(query)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\tsel, ok := statement.(*sqlparser.Select)\n\tif !ok {\n\t\treturn nil, \"\", errors.New(\"unsupported non-select statement\")\n\t}\n\tif sel.Distinct {\n\t\treturn nil, \"\", errors.New(\"unsupported distinct clause\")\n\t}\n\tif len(sel.From) == 0 {\n\t\treturn nil, \"\", errors.New(\"unsupported select from dual\")\n\t}\n\tif len(sel.From) > 1 {\n\t\treturn nil, \"\", errors.New(\"unsupported multi-table usage\")\n\t}\n\tnode, ok := sel.From[0].(*sqlparser.AliasedTableExpr)\n\tif !ok {\n\t\treturn nil, \"\", fmt.Errorf(\"unsupported from expression (%T)\", sel.From[0])\n\t}\n\tfromTable := sqlparser.GetTableName(node.Expr)\n\tif fromTable.IsEmpty() {\n\t\treturn nil, \"\", fmt.Errorf(\"unsupported from source (%T)\", node.Expr)\n\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)","sourceCodeStart":384,"sourceCodeEnd":420,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go#L384-L420","documentation":"analyzeSelectFrom requires the select's FROM clause to reference an actual table. A select with no FROM (i.e. 'select 1 from dual' / 'select expr') has no source table for a replication plan and is rejected with this error.","triggerScenarios":"A filter rule whose query is 'select 1', 'select now()' or any FROM-less select (sqlparser yields an empty sel.From).","commonSituations":"Placeholder/test queries pasted into filter rules; generated rules where the table name was accidentally dropped.","solutions":["Include a real table in the filter rule: 'select * from <table> where ...'","Fix rule generation so the table name is always interpolated into the filter query","Validate filter rules before submitting them to MoveTables/Reshard"],"exampleFix":"// before\n\"filter\": \"select 1\"\n// after\n\"filter\": \"select * from t where ...\"","handlingStrategy":"validation","validationCode":"sel := stmt.(*sqlparser.Select)\nif len(sel.From) == 0 || sel.From[0].SQLNode() == nil {\n    return errors.New(\"filter rule must select from a table\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include a real table name in filter queries","Verify generated rules interpolate the table name","Reject FROM-less selects in filter-rule validation tooling"],"tags":["vreplication","filter","sql-parsing"],"backgroundTag":"invalid-filter-rule","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}