{"record":{"id":"d1b5b760c81a4f4d","repo":"vitessio/vitess","slug":"vt12001","errorCode":"VT12001","errorMessage":"update information schema tables","messagePattern":"update information schema tables","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtgate/planbuilder/operators/ast_to_op.go","lineNumber":445,"sourceCode":"\twhereClause *sqlparser.Where,\n) (semantics.TableInfo, *QueryTable) {\n\talTbl, ok := tableExpr.(*sqlparser.AliasedTableExpr)\n\tif !ok {\n\t\tpanic(vterrors.VT13001(\"expected AliasedTableExpr\"))\n\t}\n\ttblName, ok := alTbl.Expr.(sqlparser.TableName)\n\tif !ok {\n\t\tpanic(vterrors.VT13001(\"expected TableName\"))\n\t}\n\n\ttableID := ctx.SemTable.TableSetFor(alTbl)\n\ttableInfo, err := ctx.SemTable.TableInfoFor(tableID)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tif tableInfo.IsInfSchema() {\n\t\tpanic(vterrors.VT12001(\"update information schema tables\"))\n\t}\n\n\tvar predicates []sqlparser.Expr\n\tif whereClause != nil {\n\t\tpredicates = sqlparser.SplitAndExpression(nil, whereClause.Expr)\n\t}\n\tqt := &QueryTable{\n\t\tID:         tableID,\n\t\tAlias:      alTbl,\n\t\tTable:      tblName,\n\t\tPredicates: predicates,\n\t}\n\treturn tableInfo, qt\n}\n\nfunc addColumnEquality(ctx *plancontext.PlanningContext, expr sqlparser.Expr) {\n\tswitch expr := expr.(type) {\n\tcase *sqlparser.ComparisonExpr:","sourceCodeStart":427,"sourceCodeEnd":463,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtgate/planbuilder/operators/ast_to_op.go#L427-L463","documentation":"VT12001 is Vitess's 'feature not supported online' error. During INSERT/UPDATE planning, createQueryTableForDML checks the target table and raises VT12001 when the target is an information_schema table, because DML against information_schema cannot be planned or executed by Vitess. Unlike the other panics, this is an intentional, user-facing error for unsupported DML targets.","triggerScenarios":"Running an UPDATE (via createOperatorFromInsert/DML planning) whose target table resolves to an information_schema table through the semantic table analysis — e.g., `UPDATE information_schema.tables SET ...`.","commonSituations":"Migration scripts or ORM tooling that issues DML against information_schema tables; applications assuming MySQL semantics where such statements may parse but have no effect; tools auto-generating SQL from metadata queries.","solutions":["Remove or rewrite the statement — DML against information_schema is not allowed","If the intent was metadata inspection, use SELECT instead of UPDATE/INSERT/DELETE","Adjust application/tooling configuration to exclude system schema tables from DML generation","In MySQL directly (not through Vitess), such DML would require SUPER and is generally pointless — redesign the workflow"],"exampleFix":"// before\nUPDATE information_schema.tables SET table_comment = 'x' WHERE table_name = 't';\n// after\n-- alter the actual table instead\nALTER TABLE `t` COMMENT = 'x';","handlingStrategy":"try-catch","validationCode":"// Inspect the query target before sending DML\nfunc isSystemSchemaDML(q string) bool {\n\tparsed, err := sqlparser.Parse(q)\n\tif err != nil {\n\t\treturn false\n\t}\n\ttbls := sqlparser.GetTablesets(parsed)\n\tfor _, t := range tbls {\n\t\tif strings.EqualFold(t.Qualifier.String(), \"information_schema\") ||\n\t\t\tstrings.EqualFold(t.Qualifier.String(), \"performance_schema\") ||\n\t\t\tstrings.EqualFold(t.Qualifier.String(), \"mysql\") {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}","typeGuard":"func targetsInfoSchema(stmt sqlparser.Statement) bool {\n\ttbl, ok := stmt.(*sqlparser.Update)\n\tif !ok { return false }\n\tn, err := sqlparser.TableFromStatement(tbl.TableExprs)\n\tif err != nil { return false }\n\treturn strings.EqualFold(n.Qualifier.String(), \"information_schema\")\n}","tryCatchPattern":"_, err := vtgate.Execute(ctx, session, \"UPDATE information_schema.tables SET ...\", nil)\nif err != nil {\n\tvar ec *vterrors.ErrorCode\n\tif errors.As(err, &ec) && ec.Code() == vtrpcpb.Code_NOT_SUPPORTED /* VT12001 */ {\n\t\t// route DML to the real base table instead\n\t}\n}","preventionTips":["Never issue DML against information_schema/performance_schema through Vitess","Exclude system schemas from ORM/migration tooling DML generation","Use ALTER TABLE on the base table to change metadata like comments","Treat VT12001 as a design signal: such operations are unsupported by design, not a transient failure"],"tags":["vtgate","planbuilder","information-schema","unsupported-dml","vt12001"],"backgroundTag":"unsupported-system-table-dml","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}