Skip to content

Commit

Permalink
*: add foreign key constraint check when execute insert statement (#3…
Browse files Browse the repository at this point in the history
  • Loading branch information
crazycs520 authored Sep 23, 2022
1 parent 4e1860b commit 858b8a3
Show file tree
Hide file tree
Showing 16 changed files with 1,225 additions and 9 deletions.
10 changes: 10 additions & 0 deletions errors.toml
Original file line number Diff line number Diff line change
Expand Up @@ -1936,6 +1936,16 @@ error = '''
Key part '%-.192s' length cannot be 0
'''

["planner:1451"]
error = '''
Cannot delete or update a parent row: a foreign key constraint fails (%.192s)
'''

["planner:1452"]
error = '''
Cannot add or update a child row: a foreign key constraint fails (%.192s)
'''

["planner:1462"]
error = '''
`%-.192s`.`%-.192s` contains view recursion
Expand Down
19 changes: 19 additions & 0 deletions executor/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,10 @@ func (a *ExecStmt) Exec(ctx context.Context) (_ sqlexec.RecordSet, err error) {
}

if handled, result, err := a.handleNoDelay(ctx, e, isPessimistic); handled || err != nil {
if err != nil {
return result, err
}
err = a.handleForeignKeyTrigger(ctx, e)
return result, err
}

Expand All @@ -555,6 +559,21 @@ func (a *ExecStmt) Exec(ctx context.Context) (_ sqlexec.RecordSet, err error) {
}, nil
}

func (a *ExecStmt) handleForeignKeyTrigger(ctx context.Context, e Executor) error {
exec, ok := e.(WithForeignKeyTrigger)
if !ok {
return nil
}
fkChecks := exec.GetFKChecks()
for _, fkCheck := range fkChecks {
err := fkCheck.doCheck(ctx)
if err != nil {
return err
}
}
return nil
}

func (a *ExecStmt) handleNoDelay(ctx context.Context, e Executor, isPessimistic bool) (handled bool, rs sqlexec.RecordSet, err error) {
sc := a.Ctx.GetSessionVars().StmtCtx
defer func() {
Expand Down
5 changes: 5 additions & 0 deletions executor/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,11 @@ func (b *executorBuilder) buildInsert(v *plannercore.Insert) Executor {
b.err = err
return nil
}
ivs.fkChecks, err = buildFKCheckExecs(b.ctx, ivs.Table, v.FKChecks)
if err != nil {
b.err = err
return nil
}

if v.IsReplace {
return b.buildReplace(ivs)
Expand Down
Loading

0 comments on commit 858b8a3

Please sign in to comment.