github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/soliton/rowDecoder/decoder.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 causetDecoder 15 16 import ( 17 "sort" 18 "time" 19 20 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 21 "github.com/whtcorpsinc/milevadb/blockcodec" 22 "github.com/whtcorpsinc/milevadb/causet" 23 "github.com/whtcorpsinc/milevadb/causet/blocks" 24 "github.com/whtcorpsinc/milevadb/ekv" 25 "github.com/whtcorpsinc/milevadb/memex" 26 "github.com/whtcorpsinc/milevadb/soliton/chunk" 27 "github.com/whtcorpsinc/milevadb/soliton/rowcodec" 28 "github.com/whtcorpsinc/milevadb/stochastikctx" 29 "github.com/whtcorpsinc/milevadb/types" 30 ) 31 32 // DeferredCauset contains the info and generated expr of defCausumn. 33 type DeferredCauset struct { 34 DefCaus *causet.DeferredCauset 35 GenExpr memex.Expression 36 } 37 38 // RowCausetDecoder decodes a byte slice into datums and eval the generated defCausumn value. 39 type RowCausetDecoder struct { 40 tbl causet.Block 41 mutRow chunk.MutRow 42 defCausMap map[int64]DeferredCauset 43 defCausTypes map[int64]*types.FieldType 44 haveGenDeferredCauset bool 45 defaultVals []types.Causet 46 defcaus []*causet.DeferredCauset 47 pkDefCauss []int64 48 } 49 50 // NewRowCausetDecoder returns a new RowCausetDecoder. 51 func NewRowCausetDecoder(tbl causet.Block, defcaus []*causet.DeferredCauset, decodeDefCausMap map[int64]DeferredCauset) *RowCausetDecoder { 52 tblInfo := tbl.Meta() 53 defCausFieldMap := make(map[int64]*types.FieldType, len(decodeDefCausMap)) 54 for id, defCaus := range decodeDefCausMap { 55 defCausFieldMap[id] = &defCaus.DefCaus.DeferredCausetInfo.FieldType 56 } 57 58 tps := make([]*types.FieldType, len(defcaus)) 59 for _, defCaus := range defcaus { 60 tps[defCaus.Offset] = &defCaus.FieldType 61 } 62 var pkDefCauss []int64 63 switch { 64 case tblInfo.IsCommonHandle: 65 pkDefCauss = blocks.TryGetCommonPkDeferredCausetIds(tbl.Meta()) 66 case tblInfo.PKIsHandle: 67 pkDefCauss = []int64{tblInfo.GetPkDefCausInfo().ID} 68 } 69 return &RowCausetDecoder{ 70 tbl: tbl, 71 mutRow: chunk.MutRowFromTypes(tps), 72 defCausMap: decodeDefCausMap, 73 defCausTypes: defCausFieldMap, 74 defaultVals: make([]types.Causet, len(defcaus)), 75 defcaus: defcaus, 76 pkDefCauss: pkDefCauss, 77 } 78 } 79 80 // DecodeAndEvalRowWithMap decodes a byte slice into datums and evaluates the generated defCausumn value. 81 func (rd *RowCausetDecoder) DecodeAndEvalRowWithMap(ctx stochastikctx.Context, handle ekv.Handle, b []byte, decodeLoc, sysLoc *time.Location, event map[int64]types.Causet) (map[int64]types.Causet, error) { 82 var err error 83 if rowcodec.IsNewFormat(b) { 84 event, err = blockcodec.DecodeRowWithMapNew(b, rd.defCausTypes, decodeLoc, event) 85 } else { 86 event, err = blockcodec.DecodeRowWithMap(b, rd.defCausTypes, decodeLoc, event) 87 } 88 if err != nil { 89 return nil, err 90 } 91 event, err = blockcodec.DecodeHandleToCausetMap(handle, rd.pkDefCauss, rd.defCausTypes, decodeLoc, event) 92 if err != nil { 93 return nil, err 94 } 95 for _, dDefCaus := range rd.defCausMap { 96 defCausInfo := dDefCaus.DefCaus.DeferredCausetInfo 97 val, ok := event[defCausInfo.ID] 98 if ok || dDefCaus.GenExpr != nil { 99 rd.mutRow.SetValue(defCausInfo.Offset, val.GetValue()) 100 continue 101 } 102 if dDefCaus.DefCaus.ChangeStateInfo != nil { 103 val, _, err = blocks.GetChangingDefCausVal(ctx, rd.defcaus, dDefCaus.DefCaus, event, rd.defaultVals) 104 } else { 105 // Get the default value of the defCausumn in the generated defCausumn memex. 106 val, err = blocks.GetDefCausDefaultValue(ctx, dDefCaus.DefCaus, rd.defaultVals) 107 } 108 if err != nil { 109 return nil, err 110 } 111 rd.mutRow.SetValue(defCausInfo.Offset, val.GetValue()) 112 } 113 keys := make([]int, 0) 114 ids := make(map[int]int) 115 for k, defCaus := range rd.defCausMap { 116 keys = append(keys, defCaus.DefCaus.Offset) 117 ids[defCaus.DefCaus.Offset] = int(k) 118 } 119 sort.Ints(keys) 120 for _, id := range keys { 121 defCaus := rd.defCausMap[int64(ids[id])] 122 if defCaus.GenExpr == nil { 123 continue 124 } 125 // Eval the defCausumn value 126 val, err := defCaus.GenExpr.Eval(rd.mutRow.ToRow()) 127 if err != nil { 128 return nil, err 129 } 130 val, err = causet.CastValue(ctx, val, defCaus.DefCaus.DeferredCausetInfo, false, true) 131 if err != nil { 132 return nil, err 133 } 134 135 if val.HoTT() == types.HoTTMysqlTime && sysLoc != time.UTC { 136 t := val.GetMysqlTime() 137 if t.Type() == allegrosql.TypeTimestamp { 138 err := t.ConvertTimeZone(sysLoc, time.UTC) 139 if err != nil { 140 return nil, err 141 } 142 val.SetMysqlTime(t) 143 } 144 } 145 rd.mutRow.SetValue(defCaus.DefCaus.Offset, val.GetValue()) 146 147 event[int64(ids[id])] = val 148 } 149 return event, nil 150 } 151 152 // BuildFullDecodeDefCausMap builds a map that contains [defCausumnID -> struct{*causet.DeferredCauset, memex.Expression}] from all defCausumns. 153 func BuildFullDecodeDefCausMap(defcaus []*causet.DeferredCauset, schemaReplicant *memex.Schema) map[int64]DeferredCauset { 154 decodeDefCausMap := make(map[int64]DeferredCauset, len(defcaus)) 155 for _, defCaus := range defcaus { 156 decodeDefCausMap[defCaus.ID] = DeferredCauset{ 157 DefCaus: defCaus, 158 GenExpr: schemaReplicant.DeferredCausets[defCaus.Offset].VirtualExpr, 159 } 160 } 161 return decodeDefCausMap 162 }