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  }