func (d *ddl) buildFKInfo(fkName model.CIStr, keys []*ast.IndexColName, refer *ast.ReferenceDef) (*model.FKInfo, error) { fkID, err := d.genGlobalID() if err != nil { return nil, errors.Trace(err) } var fkInfo model.FKInfo fkInfo.ID = fkID fkInfo.Name = fkName fkInfo.RefTable = refer.Table.Name fkInfo.Cols = make([]model.CIStr, len(keys)) for i, key := range keys { fkInfo.Cols[i] = key.Column.Name } fkInfo.RefCols = make([]model.CIStr, len(refer.IndexColNames)) for i, key := range refer.IndexColNames { fkInfo.RefCols[i] = key.Column.Name } fkInfo.OnDelete = int(refer.OnDelete.ReferOpt) fkInfo.OnUpdate = int(refer.OnUpdate.ReferOpt) return &fkInfo, nil }
func (d *ddl) onCreateForeignKey(t *meta.Meta, job *model.Job) error { schemaID := job.SchemaID tblInfo, err := d.getTableInfo(t, job) if err != nil { return errors.Trace(err) } var fkInfo model.FKInfo err = job.DecodeArgs(&fkInfo) if err != nil { job.State = model.JobCancelled return errors.Trace(err) } fkInfo.ID = allocateIndexID(tblInfo) tblInfo.ForeignKeys = append(tblInfo.ForeignKeys, &fkInfo) ver, err := updateSchemaVersion(t, job) if err != nil { return errors.Trace(err) } switch fkInfo.State { case model.StateNone: // We just support record the foreign key, so we just make it public. // none -> public job.SchemaState = model.StatePublic fkInfo.State = model.StatePublic err = t.UpdateTable(schemaID, tblInfo) if err != nil { return errors.Trace(err) } // Finish this job. job.State = model.JobDone addTableHistoryInfo(job, ver, tblInfo) return nil default: return ErrInvalidForeignKeyState.Gen("invalid fk state %v", fkInfo.State) } }