{"record":{"id":"73561644dec7ea6e","repo":"vitessio/vitess","slug":"vt03015","errorCode":"VT03015","errorMessage":"column has duplicate set values: '%v'","messagePattern":"column has duplicate set values: '(.+?)'","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtgate/planbuilder/operators/update.go","lineNumber":1127,"sourceCode":"\treturn selExprs, offset\n}\n\nfunc createAssignmentExpressions(\n\tctx *plancontext.PlanningContext,\n\tassignments []SetExpr,\n\tvcol sqlparser.IdentifierCI,\n\tsubQueriesArgOnChangedVindex []string,\n\tvindexValueMap map[string]evalengine.Expr,\n\tcompExprs []sqlparser.Expr,\n) ([]string, []sqlparser.Expr) {\n\t// Searching in order of columns in colvindex.\n\tfound := false\n\tfor _, assignment := range assignments {\n\t\tif !vcol.Equal(assignment.Name.Name) {\n\t\t\tcontinue\n\t\t}\n\t\tif found {\n\t\t\tpanic(vterrors.VT03015(assignment.Name.Name))\n\t\t}\n\t\tfound = true\n\t\tpv, err := evalengine.Translate(assignment.Expr.EvalExpr, &evalengine.Config{\n\t\t\tResolveType: ctx.TypeForExpr,\n\t\t\tCollation:   ctx.SemTable.Collation,\n\t\t\tEnvironment: ctx.VSchema.Environment(),\n\t\t})\n\t\tif err != nil {\n\t\t\tpanic(invalidUpdateExpr(assignment.Name.Name.String(), assignment.Expr.EvalExpr))\n\t\t}\n\n\t\tif assignment.Expr.Info != nil {\n\t\t\tsqe, ok := assignment.Expr.Info.(SubQueryExpression)\n\t\t\tif ok {\n\t\t\t\tfor _, sq := range sqe {\n\t\t\t\t\tsubQueriesArgOnChangedVindex = append(subQueriesArgOnChangedVindex, sq.ArgName)\n\t\t\t\t}\n\t\t\t}","sourceCodeStart":1109,"sourceCodeEnd":1145,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtgate/planbuilder/operators/update.go#L1109-L1145","documentation":"The SET clause of an UPDATE assigns a value to the same vindex column more than once (e.g. SET vcol = 1, vcol = 2). Vitess cannot evaluate a single value for the vindex mapping, so it panics with VT03015 reporting the duplicated column.","triggerScenarios":"createAssignmentExpressions finds two assignments for the same virtual/vindex column while iterating the UPDATE's assignments.","commonSituations":"Dynamically generated UPDATE statements appending SET clauses; ORMs concatenating partial updates; hand-written SQL with accidental duplicate assignments.","solutions":["Remove duplicate assignments so each vindex column appears at most once in SET","Deduplicate SET clauses when building SQL dynamically","Last assignment wins in MySQL, so keep only the final intended assignment"],"exampleFix":"// before\nUPDATE t SET vk = 1, vk = 2 WHERE id = 3;\n// after\nUPDATE t SET vk = 2 WHERE id = 3;","handlingStrategy":"validation","validationCode":"// deduplicate SET targets before executing\nseen := map[string]bool{}\nfor _, a := range stmt.Exprs {\n    name := a.Name.Name.String()\n    if seen[name] {\n        return fmt.Errorf(\"duplicate SET assignment for %s\", name)\n    }\n    seen[name] = true\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"duplicate set values\") {\n    // rebuild the UPDATE with deduplicated SET clause\n}","preventionTips":["Deduplicate SET clauses when constructing SQL dynamically","Configure ORMs to emit one assignment per changed column","Lint generated SQL for duplicate assignments in tests"],"tags":["vitess","vtgate","update","sql-syntax","vindex"],"backgroundTag":"duplicate-set-value","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}