github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/util/composite_primary_key_util.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 util 16 17 import ( 18 "strconv" 19 20 "github.com/matrixorigin/matrixone/pkg/common/moerr" 21 "github.com/matrixorigin/matrixone/pkg/container/nulls" 22 23 "github.com/fagongzi/util/format" 24 "github.com/matrixorigin/matrixone/pkg/catalog" 25 "github.com/matrixorigin/matrixone/pkg/container/batch" 26 "github.com/matrixorigin/matrixone/pkg/container/vector" 27 "github.com/matrixorigin/matrixone/pkg/pb/plan" 28 "github.com/matrixorigin/matrixone/pkg/vm/process" 29 ) 30 31 func ExtractCompositePrimaryKeyColumnFromColDefs(colDefs []*plan.ColDef) ([]*plan.ColDef, *plan.ColDef) { 32 for num := range colDefs { 33 isCPkey := JudgeIsCompositePrimaryKeyColumn(colDefs[num].Name) 34 if isCPkey { 35 cPKC := colDefs[num] 36 colDefs = append(colDefs[:num], colDefs[num+1:]...) 37 return colDefs, cPKC 38 } 39 } 40 return colDefs, nil 41 } 42 43 // this func can't judge index table col is compound or not 44 func JudgeIsCompositePrimaryKeyColumn(s string) bool { 45 if len(s) < len(catalog.PrefixPriColName) { 46 return false 47 } 48 return s[0:len(catalog.PrefixPriColName)] == catalog.PrefixPriColName 49 } 50 51 func BuildCompositePrimaryKeyColumnName(s []string) string { 52 var name string 53 name = catalog.PrefixPriColName 54 for _, single := range s { 55 lenNum := format.Int64ToString(int64(len(single))) 56 for num := 0; num < 3-len(lenNum); num++ { 57 name += string('0') 58 } 59 name += lenNum 60 name += single 61 } 62 return name 63 } 64 65 func SplitCompositePrimaryKeyColumnName(s string) []string { 66 var names []string 67 for next := len(catalog.PrefixPriColName); next < len(s); { 68 strLen, _ := strconv.Atoi(s[next : next+3]) 69 names = append(names, s[next+3:next+3+strLen]) 70 next += strLen + 3 71 } 72 73 return names 74 } 75 76 // Build composite primary key batch 77 func FillCompositePKeyBatch(bat *batch.Batch, p *plan.ColDef, proc *process.Process) error { 78 names := SplitCompositePrimaryKeyColumnName(p.Name) 79 cPkeyVecMap := make(map[string]*vector.Vector) 80 for num, attrName := range bat.Attrs { 81 for _, name := range names { 82 if attrName == name { 83 cPkeyVecMap[name] = bat.Vecs[num] 84 } 85 } 86 } 87 vs := make([]*vector.Vector, 0) 88 for _, name := range names { 89 v := cPkeyVecMap[name] 90 vs = append(vs, v) 91 } 92 for _, v := range vs { 93 if nulls.Any(v.Nsp) { 94 return moerr.NewConstraintViolation(proc.Ctx, "composite pkey don't support null value") 95 } 96 } 97 vec, _ := serialWithCompacted(vs, proc) 98 bat.Attrs = append(bat.Attrs, p.Name) 99 bat.Vecs = append(bat.Vecs, vec) 100 return nil 101 }