github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/colexec/preinsertsecondaryindex/preinsertsecondaryindex.go (about) 1 // Copyright 2022 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 preinsertsecondaryindex 16 17 import ( 18 "bytes" 19 20 "github.com/matrixorigin/matrixone/pkg/catalog" 21 "github.com/matrixorigin/matrixone/pkg/container/batch" 22 "github.com/matrixorigin/matrixone/pkg/container/nulls" 23 "github.com/matrixorigin/matrixone/pkg/container/types" 24 "github.com/matrixorigin/matrixone/pkg/container/vector" 25 "github.com/matrixorigin/matrixone/pkg/sql/util" 26 "github.com/matrixorigin/matrixone/pkg/vm" 27 "github.com/matrixorigin/matrixone/pkg/vm/process" 28 ) 29 30 const ( 31 indexColPos int32 = iota 32 pkColPos 33 rowIdColPos 34 ) 35 36 const argName = "pre_insert_secondary_index" 37 38 func (arg *Argument) String(buf *bytes.Buffer) { 39 buf.WriteString(argName) 40 buf.WriteString(": pre processing insert secondary key") 41 } 42 43 func (arg *Argument) Prepare(proc *process.Process) error { 44 return nil 45 } 46 47 func (arg *Argument) Call(proc *process.Process) (vm.CallResult, error) { 48 if err, isCancel := vm.CancelCheck(proc); isCancel { 49 return vm.CancelResult, err 50 } 51 52 result, err := arg.GetChildren(0).Call(proc) 53 if err != nil { 54 return result, err 55 } 56 analy := proc.GetAnalyze(arg.GetIdx(), arg.GetParallelIdx(), arg.GetParallelMajor()) 57 analy.Start() 58 defer analy.Stop() 59 60 if result.Batch == nil || result.Batch.IsEmpty() || result.Batch.Last() { 61 return result, nil 62 } 63 inputBat := result.Batch 64 var vec *vector.Vector 65 var bitMap *nulls.Nulls 66 67 secondaryColumnPos := arg.PreInsertCtx.Columns 68 pkPos := int(arg.PreInsertCtx.PkColumn) 69 70 if arg.buf != nil { 71 proc.PutBatch(arg.buf) 72 arg.buf = nil 73 } 74 isUpdate := inputBat.Vecs[len(inputBat.Vecs)-1].GetType().Oid == types.T_Rowid 75 if isUpdate { 76 arg.buf = batch.NewWithSize(3) 77 arg.buf.Attrs = []string{catalog.IndexTableIndexColName, catalog.IndexTablePrimaryColName, catalog.Row_ID} 78 } else { 79 arg.buf = batch.NewWithSize(2) 80 arg.buf.Attrs = []string{catalog.IndexTableIndexColName, catalog.IndexTablePrimaryColName} 81 } 82 83 colCount := len(secondaryColumnPos) 84 85 // colCount = 1 means the user chose SK as only PK. 86 // colCount >= 2 is more common. 87 if colCount == 1 { 88 pos := secondaryColumnPos[indexColPos] 89 vec, bitMap, err = util.CompactSingleIndexCol(inputBat.Vecs[pos], proc) 90 if err != nil { 91 return result, err 92 } 93 } else { 94 vs := make([]*vector.Vector, colCount) 95 for vIdx, pIdx := range secondaryColumnPos { 96 vs[vIdx] = inputBat.Vecs[pIdx] 97 } 98 vec, bitMap, err = util.SerialWithoutCompacted(vs, proc, &arg.packer) 99 if err != nil { 100 return result, err 101 } 102 } 103 arg.buf.SetVector(indexColPos, vec) 104 arg.buf.SetRowCount(vec.Length()) 105 106 vec, err = util.CompactPrimaryCol(inputBat.Vecs[pkPos], bitMap, proc) 107 if err != nil { 108 return result, err 109 } 110 arg.buf.SetVector(pkColPos, vec) 111 112 if isUpdate { 113 rowIdInBat := len(inputBat.Vecs) - 1 114 arg.buf.SetVector(rowIdColPos, proc.GetVector(*inputBat.Vecs[rowIdInBat].GetType())) 115 if err = arg.buf.Vecs[rowIdColPos].UnionBatch(inputBat.Vecs[rowIdInBat], 0, inputBat.Vecs[rowIdInBat].Length(), nil, proc.Mp()); err != nil { 116 return result, err 117 } 118 } 119 result.Batch = arg.buf 120 return result, nil 121 }