{"record":{"id":"db3157097578222a","repo":"vitessio/vitess","slug":"errunsupportedqueryconstruct","errorCode":"ErrUnsupportedQueryConstruct","errorMessage":"%w: DELETE must not have USING clause (have: %v): %v","messagePattern":"%w: DELETE must not have USING clause \\(have: (.+?)\\): (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtctl/workflow/vexec/query_planner.go","lineNumber":157,"sourceCode":"\n// QueryParams is part of the QueryPlanner interface. A VReplicationQueryPlanner\n// will attach the following WHERE clauses iff (a) DBName, Workflow are set,\n// respectively, and (b) db_name and workflow do not appear in the original\n// query's WHERE clause:\n//\n//\tWHERE (db_name = {{ .DBName }} AND)? (workflow = {{ .Workflow }} AND)? {{ .OriginalWhere }}\nfunc (planner *VReplicationQueryPlanner) QueryParams() QueryParams {\n\treturn QueryParams{\n\t\tDBName:         planner.dbname,\n\t\tDBNameColumn:   \"db_name\",\n\t\tWorkflow:       planner.workflow,\n\t\tWorkflowColumn: \"workflow\",\n\t}\n}\n\nfunc (planner *VReplicationQueryPlanner) planDelete(del *sqlparser.Delete) (*FixedQueryPlan, error) {\n\tif del.Targets != nil {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"%w: DELETE must not have USING clause (have: %v): %v\",\n\t\t\tErrUnsupportedQueryConstruct,\n\t\t\tdel.Targets,\n\t\t\tsqlparser.String(del),\n\t\t)\n\t}\n\n\tif del.Partitions != nil {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"%w: DELETE must not have explicit partitions (have: %v): %v\",\n\t\t\tErrUnsupportedQueryConstruct,\n\t\t\tdel.Partitions,\n\t\t\tsqlparser.String(del),\n\t\t)\n\t}\n\n\tif del.OrderBy != nil || del.Limit != nil {\n\t\treturn nil, fmt.Errorf(","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctl/workflow/vexec/query_planner.go#L139-L175","documentation":"The VReplication query planner supports only simple DELETE statements; a DELETE with a USING clause (multi-table delete targets) is rejected as ErrUnsupportedQueryConstruct. The error includes the offending targets and the full SQL text.","triggerScenarios":"Calling PlanQuery with a parsed *sqlparser.Delete whose Targets field is non-nil, i.e. SQL of the form DELETE t1 FROM t1 USING ... / DELETE t1, t2 FROM ...","commonSituations":"Copying multi-table DELETE statements written for direct MySQL use into a VReplication workflow context; generated SQL from ORMs that emit USING-style deletes.","solutions":["Rewrite the statement as a single-table DELETE with a WHERE clause (optionally using subqueries)","Remove the USING / multi-table target syntax before passing to PlanQuery","Run such deletes outside the VReplication planner (e.g. directly on the shard via vtgate) if multi-table semantics are required"],"exampleFix":"// before\nDELETE FROM _vt.vreplication USING _vt.copy_state WHERE copy_state.vrepl_id = _vt.vreplication.id\n// after\nDELETE FROM _vt.copy_state WHERE vrepl_id IN (SELECT id FROM _vt.vreplication WHERE ...)","handlingStrategy":"validation","validationCode":"if del, ok := stmt.(*sqlparser.Delete); ok && del.Targets != nil {\n    return fmt.Errorf(\"DELETE with USING clause is not supported\")\n}","typeGuard":"func isSimpleDelete(stmt sqlparser.Statement) bool {\n    del, ok := stmt.(*sqlparser.Delete)\n    return ok && del.Targets == nil\n}","tryCatchPattern":"plan, err := planner.PlanQuery(ctx, stmt)\nif errors.Is(err, vexec.ErrUnsupportedQueryConstruct) {\n    return fmt.Errorf(\"rewrite DELETE as single-table delete: %w\", err)\n}","preventionTips":["Write single-table DELETEs with WHERE clauses only","Replace multi-table delete patterns with subquery-based deletes","Lint workflow SQL for USING/multi-table delete syntax before planning"],"tags":["go","vreplication","sql","delete","unsupported-construct"],"backgroundTag":"unsupported-sql-construct","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}