{"record":{"id":"8e769f68c739eb35","repo":"vitessio/vitess","slug":"unsupported-construct-v","errorCode":null,"errorMessage":"unsupported construct: %v","messagePattern":"unsupported construct: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vttablet/tabletmanager/vreplication/controller_plan.go","lineNumber":189,"sourceCode":"\ttableName, err := ins.Table.TableName()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif tableName.Qualifier.String() != sidecar.GetName() && tableName.Qualifier.String() != sidecar.DefaultName {\n\t\treturn nil, fmt.Errorf(\"invalid database name: %s\", tableName.Qualifier.String())\n\t}\n\tswitch tableName.Name.String() {\n\tcase reshardingJournalTableName:\n\t\treturn &controllerPlan{\n\t\t\topcode: reshardingJournalQuery,\n\t\t}, nil\n\tcase vreplicationTableName:\n\t\t// no-op\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"invalid table name: %s\", tableName.Name.String())\n\t}\n\tif ins.Action != sqlparser.InsertAct {\n\t\treturn nil, fmt.Errorf(\"unsupported construct: %v\", sqlparser.String(ins))\n\t}\n\tif ins.Ignore {\n\t\treturn nil, fmt.Errorf(\"unsupported construct: %v\", sqlparser.String(ins))\n\t}\n\tif ins.Partitions != nil {\n\t\treturn nil, fmt.Errorf(\"unsupported construct: %v\", sqlparser.String(ins))\n\t}\n\tif ins.OnDup != nil {\n\t\treturn nil, fmt.Errorf(\"unsupported construct: %v\", sqlparser.String(ins))\n\t}\n\trows, ok := ins.Rows.(sqlparser.Values)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"unsupported construct: %v\", sqlparser.String(ins))\n\t}\n\tidPos := 0\n\tif len(ins.Columns) != 0 {\n\t\tidPos = -1\n\t\tfor i, col := range ins.Columns {","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vttablet/tabletmanager/vreplication/controller_plan.go#L171-L207","documentation":"Returned by vreplication controller plan building when the statement contains a construct the planner cannot translate into a vreplication plan, wrapping or naming the unsupported construct.","triggerScenarios":"A `REPLACE INTO _vt.vreplication ...` statement (or other non-InsertAct action) passed to the vreplication engine's exec path.","commonSituations":"Using MySQL's REPLACE INTO as a shortcut for upsert; generated scripts using REPLACE; translation of application SQL into vexec without adjusting syntax.","solutions":["Rewrite as a plain `INSERT INTO _vt.vreplication ...`.","Use `update _vt.vreplication set ... where id=...` instead of REPLACE to modify existing rows.","Ensure unique ids so plain INSERT succeeds (vreplication ids are explicit, not auto-increment)."],"exampleFix":"// before\nreplace into _vt.vreplication(id, message) values (1, 'x')\n// after\ninsert into _vt.vreplication(id, message) values (1, 'x')","handlingStrategy":"validation","validationCode":"if strings.HasPrefix(strings.ToUpper(stmt), \"REPLACE \") {\n    return fmt.Errorf(\"REPLACE not supported by vreplication engine; use INSERT or UPDATE\")\n}","typeGuard":null,"tryCatchPattern":"plan, err := buildInsertPlan(ins, sidecar)\nif err != nil && strings.Contains(err.Error(), \"unsupported construct\") {\n    return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, \"plain INSERT only; rewrite REPLACE statements\")\n}","preventionTips":["Ban REPLACE INTO in scripts that target _vt tables.","Use explicit INSERT with unique ids; ids are caller-provided, not auto-increment.","Code-review any generated SQL sent through VExec."],"tags":["sql","vreplication","parser"],"backgroundTag":"unsupported-sql-construct","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}