github.com/matrixorigin/matrixone@v1.2.0/pkg/partition/partition.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 partition 16 17 import ( 18 "bytes" 19 20 "github.com/matrixorigin/matrixone/pkg/common/moerr" 21 "github.com/matrixorigin/matrixone/pkg/container/nulls" 22 "github.com/matrixorigin/matrixone/pkg/container/types" 23 "github.com/matrixorigin/matrixone/pkg/container/vector" 24 ) 25 26 func genericPartition[T types.FixedSizeT](sels []int64, diffs []bool, partitions []int64, vec *vector.Vector) []int64 { 27 partitions = partitions[:0] 28 if len(sels) == 0 { 29 return partitions 30 } 31 diffs[0] = true 32 diffs = diffs[:len(sels)] 33 34 if vec.IsConst() { 35 if vec.IsConstNull() { 36 for i := range sels { 37 diffs[i] = false 38 } 39 } 40 partitions = append(partitions, 0) 41 42 } else { 43 var n bool 44 var v T 45 46 vs := vector.MustFixedCol[T](vec) 47 nsp := vec.GetNulls() 48 if nsp.Any() { 49 for i, sel := range sels { 50 w := vs[sel] 51 isNull := nulls.Contains(nsp, uint64(sel)) 52 if n != isNull { 53 diffs[i] = true 54 } else if n && isNull { 55 diffs[i] = false 56 } else { 57 diffs[i] = diffs[i] || (v != vs[sel]) 58 } 59 n = isNull 60 v = w 61 } 62 } else { 63 for i, sel := range sels { 64 w := vs[sel] 65 diffs[i] = diffs[i] || (v != w) 66 v = w 67 } 68 } 69 70 for i, j := int64(0), int64(len(diffs)); i < j; i++ { 71 if diffs[i] { 72 partitions = append(partitions, i) 73 } 74 } 75 } 76 77 return partitions 78 } 79 80 func bytesPartition(sels []int64, diffs []bool, partitions []int64, vec *vector.Vector) []int64 { 81 partitions = partitions[:0] 82 if len(sels) == 0 { 83 return partitions 84 } 85 diffs[0] = true 86 diffs = diffs[:len(sels)] 87 88 if vec.IsConst() { 89 if vec.IsConstNull() { 90 for i := range sels { 91 diffs[i] = false 92 } 93 } 94 partitions = append(partitions, 0) 95 96 } else { 97 var n bool 98 var v []byte 99 100 vs := vector.MustBytesCol(vec) 101 nsp := vec.GetNulls() 102 if nsp.Any() { 103 for i, sel := range sels { 104 w := vs[sel] 105 isNull := nulls.Contains(nsp, uint64(sel)) 106 if n != isNull { 107 diffs[i] = true 108 } else if n && isNull { 109 diffs[i] = false 110 } else { 111 diffs[i] = diffs[i] || !(bytes.Equal(v, vs[sel])) 112 } 113 n = isNull 114 v = w 115 } 116 } else { 117 for i, sel := range sels { 118 w := vs[sel] 119 diffs[i] = diffs[i] || !(bytes.Equal(v, w)) 120 v = w 121 } 122 } 123 for i, j := int64(0), int64(len(diffs)); i < j; i++ { 124 if diffs[i] { 125 partitions = append(partitions, i) 126 } 127 } 128 } 129 130 return partitions 131 } 132 133 // Partitions will return the rowSels; vs[rowSel] != vs[last_rowSel]. 134 // by default, the 0th row is always not equal to the one before it 135 // (though it doesn't exist) 136 func Partition(sels []int64, diffs []bool, partitions []int64, vec *vector.Vector) []int64 { 137 switch vec.GetType().Oid { 138 case types.T_bool: 139 return genericPartition[bool](sels, diffs, partitions, vec) 140 case types.T_bit: 141 return genericPartition[uint64](sels, diffs, partitions, vec) 142 case types.T_int8: 143 return genericPartition[int8](sels, diffs, partitions, vec) 144 case types.T_int16: 145 return genericPartition[int16](sels, diffs, partitions, vec) 146 case types.T_int32: 147 return genericPartition[int32](sels, diffs, partitions, vec) 148 case types.T_int64: 149 return genericPartition[int64](sels, diffs, partitions, vec) 150 case types.T_uint8: 151 return genericPartition[uint8](sels, diffs, partitions, vec) 152 case types.T_uint16: 153 return genericPartition[uint16](sels, diffs, partitions, vec) 154 case types.T_uint32: 155 return genericPartition[uint32](sels, diffs, partitions, vec) 156 case types.T_uint64: 157 return genericPartition[uint64](sels, diffs, partitions, vec) 158 case types.T_float32: 159 return genericPartition[float32](sels, diffs, partitions, vec) 160 case types.T_float64: 161 return genericPartition[float64](sels, diffs, partitions, vec) 162 case types.T_date: 163 return genericPartition[types.Date](sels, diffs, partitions, vec) 164 case types.T_datetime: 165 return genericPartition[types.Datetime](sels, diffs, partitions, vec) 166 case types.T_time: 167 return genericPartition[types.Time](sels, diffs, partitions, vec) 168 case types.T_timestamp: 169 return genericPartition[types.Timestamp](sels, diffs, partitions, vec) 170 case types.T_enum: 171 return genericPartition[types.Enum](sels, diffs, partitions, vec) 172 case types.T_decimal64: 173 return genericPartition[types.Decimal64](sels, diffs, partitions, vec) 174 case types.T_decimal128: 175 return genericPartition[types.Decimal128](sels, diffs, partitions, vec) 176 case types.T_char, types.T_varchar, types.T_json, types.T_text, 177 types.T_array_float32, types.T_array_float64: 178 return bytesPartition(sels, diffs, partitions, vec) 179 //Used by ORDER_BY SQL clause. 180 //Byte partition logic doesn't use byte.Compare or Str. 181 //Hence, we can use bytesPartition here. 182 default: 183 panic(moerr.NewNotSupportedNoCtx(vec.GetType().Oid.String())) 184 } 185 }