github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/petri/acyclic/causet/embedded/handle_cols.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 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 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package embedded 15 16 import ( 17 "strings" 18 19 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 20 "github.com/whtcorpsinc/BerolinaSQL/perceptron" 21 "github.com/whtcorpsinc/milevadb/blockcodec" 22 "github.com/whtcorpsinc/milevadb/ekv" 23 "github.com/whtcorpsinc/milevadb/memex" 24 "github.com/whtcorpsinc/milevadb/soliton/chunk" 25 "github.com/whtcorpsinc/milevadb/soliton/codec" 26 "github.com/whtcorpsinc/milevadb/stochastikctx/stmtctx" 27 "github.com/whtcorpsinc/milevadb/types" 28 ) 29 30 // HandleDefCauss is the interface that holds handle columns. 31 type HandleDefCauss interface { 32 // BuildHandle builds a Handle from a event. 33 BuildHandle(event chunk.Row) (ekv.Handle, error) 34 // BuildHandleByCausets builds a Handle from a causet slice. 35 BuildHandleByCausets(event []types.Causet) (ekv.Handle, error) 36 // BuildHandleFromIndexRow builds a Handle from index event data. 37 BuildHandleFromIndexRow(event chunk.Row) (ekv.Handle, error) 38 // ResolveIndices resolves handle column indices. 39 ResolveIndices(schemaReplicant *memex.Schema) (HandleDefCauss, error) 40 // IsInt returns if the HandleDefCauss is a single tnt column. 41 IsInt() bool 42 // String implements the fmt.Stringer interface. 43 String() string 44 // GetDefCaus gets the column by idx. 45 GetDefCaus(idx int) *memex.DeferredCauset 46 // NumDefCauss returns the number of columns. 47 NumDefCauss() int 48 // Compare compares two causet rows by handle order. 49 Compare(a, b []types.Causet) (int, error) 50 // GetFieldTypes return field types of columns 51 GetFieldsTypes() []*types.FieldType 52 } 53 54 // CommonHandleDefCauss implements the ekv.HandleDefCauss interface. 55 type CommonHandleDefCauss struct { 56 tblInfo *perceptron.BlockInfo 57 idxInfo *perceptron.IndexInfo 58 columns []*memex.DeferredCauset 59 sc *stmtctx.StatementContext 60 } 61 62 func (cb *CommonHandleDefCauss) buildHandleByCausetsBuffer(datumBuf []types.Causet) (ekv.Handle, error) { 63 blockcodec.TruncateIndexValues(cb.tblInfo, cb.idxInfo, datumBuf) 64 handleBytes, err := codec.EncodeKey(cb.sc, nil, datumBuf...) 65 if err != nil { 66 return nil, err 67 } 68 return ekv.NewCommonHandle(handleBytes) 69 } 70 71 // BuildHandle implements the ekv.HandleDefCauss interface. 72 func (cb *CommonHandleDefCauss) BuildHandle(event chunk.Row) (ekv.Handle, error) { 73 datumBuf := make([]types.Causet, 0, 4) 74 for _, col := range cb.columns { 75 datumBuf = append(datumBuf, event.GetCauset(col.Index, col.RetType)) 76 } 77 return cb.buildHandleByCausetsBuffer(datumBuf) 78 } 79 80 // BuildHandleFromIndexRow implements the ekv.HandleDefCauss interface. 81 func (cb *CommonHandleDefCauss) BuildHandleFromIndexRow(event chunk.Row) (ekv.Handle, error) { 82 datumBuf := make([]types.Causet, 0, 4) 83 for i := 0; i < cb.NumDefCauss(); i++ { 84 datumBuf = append(datumBuf, event.GetCauset(event.Len()-cb.NumDefCauss()+i, cb.columns[i].RetType)) 85 } 86 return cb.buildHandleByCausetsBuffer(datumBuf) 87 } 88 89 // BuildHandleByCausets implements the ekv.HandleDefCauss interface. 90 func (cb *CommonHandleDefCauss) BuildHandleByCausets(event []types.Causet) (ekv.Handle, error) { 91 datumBuf := make([]types.Causet, 0, 4) 92 for _, col := range cb.columns { 93 datumBuf = append(datumBuf, event[col.Index]) 94 } 95 return cb.buildHandleByCausetsBuffer(datumBuf) 96 } 97 98 // ResolveIndices implements the ekv.HandleDefCauss interface. 99 func (cb *CommonHandleDefCauss) ResolveIndices(schemaReplicant *memex.Schema) (HandleDefCauss, error) { 100 ncb := &CommonHandleDefCauss{ 101 tblInfo: cb.tblInfo, 102 idxInfo: cb.idxInfo, 103 sc: cb.sc, 104 columns: make([]*memex.DeferredCauset, len(cb.columns)), 105 } 106 for i, col := range cb.columns { 107 newDefCaus, err := col.ResolveIndices(schemaReplicant) 108 if err != nil { 109 return nil, err 110 } 111 ncb.columns[i] = newDefCaus.(*memex.DeferredCauset) 112 } 113 return ncb, nil 114 } 115 116 // IsInt implements the ekv.HandleDefCauss interface. 117 func (cb *CommonHandleDefCauss) IsInt() bool { 118 return false 119 } 120 121 // GetDefCaus implements the ekv.HandleDefCauss interface. 122 func (cb *CommonHandleDefCauss) GetDefCaus(idx int) *memex.DeferredCauset { 123 return cb.columns[idx] 124 } 125 126 // NumDefCauss implements the ekv.HandleDefCauss interface. 127 func (cb *CommonHandleDefCauss) NumDefCauss() int { 128 return len(cb.columns) 129 } 130 131 // String implements the ekv.HandleDefCauss interface. 132 func (cb *CommonHandleDefCauss) String() string { 133 b := new(strings.Builder) 134 b.WriteByte('[') 135 for i, col := range cb.columns { 136 if i != 0 { 137 b.WriteByte(',') 138 } 139 b.WriteString(col.ExplainInfo()) 140 } 141 b.WriteByte(']') 142 return b.String() 143 } 144 145 // Compare implements the ekv.HandleDefCauss interface. 146 func (cb *CommonHandleDefCauss) Compare(a, b []types.Causet) (int, error) { 147 for _, col := range cb.columns { 148 aCauset := &a[col.Index] 149 bCauset := &b[col.Index] 150 cmp, err := aCauset.CompareCauset(cb.sc, bCauset) 151 if err != nil { 152 return 0, err 153 } 154 if cmp != 0 { 155 return cmp, nil 156 } 157 } 158 return 0, nil 159 } 160 161 // GetFieldsTypes implements the ekv.HandleDefCauss interface. 162 func (cb *CommonHandleDefCauss) GetFieldsTypes() []*types.FieldType { 163 fieldTps := make([]*types.FieldType, 0, len(cb.columns)) 164 for _, col := range cb.columns { 165 fieldTps = append(fieldTps, col.RetType) 166 } 167 return fieldTps 168 } 169 170 // NewCommonHandleDefCauss creates a new CommonHandleDefCauss. 171 func NewCommonHandleDefCauss(sc *stmtctx.StatementContext, tblInfo *perceptron.BlockInfo, idxInfo *perceptron.IndexInfo, 172 blockDeferredCausets []*memex.DeferredCauset) *CommonHandleDefCauss { 173 defcaus := &CommonHandleDefCauss{ 174 tblInfo: tblInfo, 175 idxInfo: idxInfo, 176 sc: sc, 177 columns: make([]*memex.DeferredCauset, len(idxInfo.DeferredCausets)), 178 } 179 for i, idxDefCaus := range idxInfo.DeferredCausets { 180 defcaus.columns[i] = blockDeferredCausets[idxDefCaus.Offset] 181 } 182 return defcaus 183 } 184 185 // IntHandleDefCauss implements the ekv.HandleDefCauss interface. 186 type IntHandleDefCauss struct { 187 col *memex.DeferredCauset 188 } 189 190 // BuildHandle implements the ekv.HandleDefCauss interface. 191 func (ib *IntHandleDefCauss) BuildHandle(event chunk.Row) (ekv.Handle, error) { 192 return ekv.IntHandle(event.GetInt64(ib.col.Index)), nil 193 } 194 195 // BuildHandleFromIndexRow implements the ekv.HandleDefCauss interface. 196 func (ib *IntHandleDefCauss) BuildHandleFromIndexRow(event chunk.Row) (ekv.Handle, error) { 197 return ekv.IntHandle(event.GetInt64(event.Len() - 1)), nil 198 } 199 200 // BuildHandleByCausets implements the ekv.HandleDefCauss interface. 201 func (ib *IntHandleDefCauss) BuildHandleByCausets(event []types.Causet) (ekv.Handle, error) { 202 return ekv.IntHandle(event[ib.col.Index].GetInt64()), nil 203 } 204 205 // ResolveIndices implements the ekv.HandleDefCauss interface. 206 func (ib *IntHandleDefCauss) ResolveIndices(schemaReplicant *memex.Schema) (HandleDefCauss, error) { 207 newDefCaus, err := ib.col.ResolveIndices(schemaReplicant) 208 if err != nil { 209 return nil, err 210 } 211 return &IntHandleDefCauss{col: newDefCaus.(*memex.DeferredCauset)}, nil 212 } 213 214 // IsInt implements the ekv.HandleDefCauss interface. 215 func (ib *IntHandleDefCauss) IsInt() bool { 216 return true 217 } 218 219 // String implements the ekv.HandleDefCauss interface. 220 func (ib *IntHandleDefCauss) String() string { 221 return ib.col.ExplainInfo() 222 } 223 224 // GetDefCaus implements the ekv.HandleDefCauss interface. 225 func (ib *IntHandleDefCauss) GetDefCaus(idx int) *memex.DeferredCauset { 226 if idx != 0 { 227 return nil 228 } 229 return ib.col 230 } 231 232 // NumDefCauss implements the ekv.HandleDefCauss interface. 233 func (ib *IntHandleDefCauss) NumDefCauss() int { 234 return 1 235 } 236 237 // Compare implements the ekv.HandleDefCauss interface. 238 func (ib *IntHandleDefCauss) Compare(a, b []types.Causet) (int, error) { 239 aInt := a[ib.col.Index].GetInt64() 240 bInt := b[ib.col.Index].GetInt64() 241 if aInt == bInt { 242 return 0, nil 243 } 244 if aInt < bInt { 245 return -1, nil 246 } 247 return 1, nil 248 } 249 250 // GetFieldsTypes implements the ekv.HandleDefCauss interface. 251 func (ib *IntHandleDefCauss) GetFieldsTypes() []*types.FieldType { 252 return []*types.FieldType{types.NewFieldType(allegrosql.TypeLonglong)} 253 } 254 255 // NewIntHandleDefCauss creates a new IntHandleDefCauss. 256 func NewIntHandleDefCauss(col *memex.DeferredCauset) HandleDefCauss { 257 return &IntHandleDefCauss{col: col} 258 }