github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/util/composite_clusterby_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 "github.com/matrixorigin/matrixone/pkg/sql/plan/function" 19 "strconv" 20 21 "github.com/fagongzi/util/format" 22 "github.com/matrixorigin/matrixone/pkg/catalog" 23 "github.com/matrixorigin/matrixone/pkg/container/batch" 24 "github.com/matrixorigin/matrixone/pkg/container/vector" 25 "github.com/matrixorigin/matrixone/pkg/vm/process" 26 ) 27 28 func JudgeIsCompositeClusterByColumn(s string) bool { 29 if len(s) < len(catalog.PrefixCBColName) { 30 return false 31 } 32 return s[0:len(catalog.PrefixCBColName)] == catalog.PrefixCBColName 33 } 34 35 func BuildCompositeClusterByColumnName(s []string) string { 36 var name string 37 name = catalog.PrefixCBColName 38 for _, single := range s { 39 lenNum := format.Int64ToString(int64(len(single))) 40 for num := 0; num < 3-len(lenNum); num++ { 41 name += string('0') 42 } 43 name += lenNum 44 name += single 45 } 46 return name 47 } 48 49 func SplitCompositeClusterByColumnName(s string) []string { 50 var names []string 51 for next := len(catalog.PrefixCBColName); next < len(s); { 52 strLen, _ := strconv.Atoi(s[next : next+3]) 53 names = append(names, s[next+3:next+3+strLen]) 54 next += strLen + 3 55 } 56 57 return names 58 } 59 60 func GetClusterByFirstColumn(cbName string) string { 61 if !JudgeIsCompositeClusterByColumn(cbName) { 62 return cbName 63 } else { 64 return SplitCompositeClusterByColumnName(cbName)[0] 65 } 66 } 67 68 func GetClusterByColumnOrder(cbName, colName string) int { 69 if len(cbName) == 0 || len(colName) == 0 { 70 return -1 71 } 72 if cbName == colName { 73 return 0 74 } 75 if !JudgeIsCompositeClusterByColumn(cbName) { 76 return -1 77 } 78 idx := 0 79 for next := len(catalog.PrefixCBColName); next < len(cbName); { 80 strLen, _ := strconv.Atoi(cbName[next : next+3]) 81 if cbName[next+3:next+3+strLen] == colName { 82 return idx 83 } 84 next += strLen + 3 85 idx++ 86 } 87 return -1 88 } 89 90 // build the clusterBy key's vector of the cluster table according to the composite column name, and append the result vector to batch 91 // cbName: column name of composite column 92 func FillCompositeClusterByBatch(bat *batch.Batch, cbName string, proc *process.Process) error { 93 names := SplitCompositeClusterByColumnName(cbName) 94 return FillCompositeKeyBatch(bat, cbName, names, proc) 95 } 96 97 // build the vector of the composite key, and append the result vector to batch 98 // ckeyName: column name of composite column 99 // keyParts: parts of the composite column 100 func FillCompositeKeyBatch(bat *batch.Batch, ckeyName string, keyParts []string, proc *process.Process) error { 101 cCBVectorMap := make(map[string]*vector.Vector) 102 for num, attrName := range bat.Attrs { 103 for _, elem := range keyParts { 104 if attrName == elem { 105 cCBVectorMap[elem] = bat.Vecs[num] 106 } 107 } 108 } 109 vs := make([]*vector.Vector, 0) 110 for _, elem := range keyParts { 111 v := cCBVectorMap[elem] 112 vs = append(vs, v) 113 } 114 vec, err := function.RunFunctionDirectly(proc, function.SerialFunctionEncodeID, vs, bat.RowCount()) 115 if err != nil { 116 return err 117 } 118 bat.Attrs = append(bat.Attrs, ckeyName) 119 bat.Vecs = append(bat.Vecs, vec) 120 return nil 121 }