github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/colexec/update/update.go (about) 1 // Copyright 2021 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package update 16 17 import ( 18 "bytes" 19 "sync/atomic" 20 21 "github.com/matrixorigin/matrixone/pkg/sql/colexec" 22 "github.com/matrixorigin/matrixone/pkg/sql/plan" 23 24 "github.com/matrixorigin/matrixone/pkg/common/moerr" 25 26 "github.com/matrixorigin/matrixone/pkg/vm/process" 27 ) 28 29 // var nullRowid [16]byte 30 31 func String(arg any, buf *bytes.Buffer) { 32 buf.WriteString("update rows") 33 } 34 35 func Prepare(_ *process.Process, _ any) error { 36 return nil 37 } 38 39 func Call(_ int, proc *process.Process, arg any, isFirst bool, isLast bool) (bool, error) { 40 41 p := arg.(*Argument) 42 bat := proc.Reg.InputBatch 43 44 // last batch of block 45 if bat == nil { 46 return true, nil 47 } 48 49 // empty batch 50 if len(bat.Zs) == 0 { 51 return false, nil 52 } 53 54 defer bat.Clean(proc.Mp()) 55 var affectedRows uint64 56 var err error 57 updateCtx := p.UpdateCtx 58 59 // check parent, if have any null, throw error 60 // can not check here. because 'update c1 set a = null where a =1' is ok. that's not constraint fail 61 // for _, idx := range updateCtx.ParentIdx { 62 // if nulls.Any(bat.Vecs[idx].Nsp) { 63 // return false, moerr.NewInternalError(proc.Ctx, "Cannot add or update a child row: a foreign key constraint fails") 64 // } 65 // } 66 67 // check child on restrict, if is not all null, throw error 68 for _, idx := range updateCtx.OnRestrictIdx { 69 if bat.Vecs[idx].Length() != bat.Vecs[idx].Nsp.Np.Count() { 70 return false, moerr.NewInternalError(proc.Ctx, "Cannot delete or update a parent row: a foreign key constraint fails") 71 } 72 } 73 74 // delete old unique index 75 _, err = colexec.FilterAndDelByRowId(proc, bat, updateCtx.IdxIdx, updateCtx.IdxSource) 76 if err != nil { 77 return false, err 78 } 79 80 // update child table(which ref on delete cascade) 81 _, err = colexec.FilterAndUpdateByRowId(p.Engine, proc, bat, updateCtx.OnCascadeIdx, updateCtx.OnCascadeSource, 82 updateCtx.OnCascadeRef, updateCtx.OnCascadeTableDef, updateCtx.OnCascadeUpdateCol, nil, updateCtx.OnCascadeUniqueSource) 83 if err != nil { 84 return false, err 85 } 86 87 // update child table(which ref on delete set null) 88 _, err = colexec.FilterAndUpdateByRowId(p.Engine, proc, bat, updateCtx.OnSetIdx, updateCtx.OnSetSource, 89 updateCtx.OnSetRef, updateCtx.OnSetTableDef, updateCtx.OnSetUpdateCol, nil, updateCtx.OnSetUniqueSource) 90 if err != nil { 91 return false, err 92 } 93 94 // update origin table 95 affectedRows, err = colexec.FilterAndUpdateByRowId(p.Engine, proc, bat, updateCtx.Idxs, updateCtx.Source, 96 updateCtx.Ref, updateCtx.TableDefs, updateCtx.UpdateCol, updateCtx.ParentIdx, updateCtx.UniqueSource) 97 if err != nil { 98 return false, err 99 } 100 atomic.AddUint64(&p.AffectedRows, affectedRows) 101 return false, nil 102 } 103 104 // Get the primary key name of the table 105 func GetTablePriKeyName(pKeyDef *plan.PrimaryKeyDef, cPkeyCol *plan.ColDef) string { 106 if pKeyDef != nil && len(pKeyDef.Names) == 1 { 107 return pKeyDef.Names[0] 108 } 109 110 if cPkeyCol != nil { 111 return cPkeyCol.Name 112 } 113 114 return "" 115 }