// DecodeRow decodes a byte slice into datums. // Row layout: colID1, value1, colID2, value2, ..... func DecodeRow(b []byte, cols map[int64]*types.FieldType) (map[int64]types.Datum, error) { if b == nil { return nil, nil } if len(b) == 1 && b[0] == codec.NilFlag { return nil, nil } row := make(map[int64]types.Datum, len(cols)) cnt := 0 var ( data []byte err error ) for len(b) > 0 { // Get col id. data, b, err = codec.CutOne(b) if err != nil { return nil, errors.Trace(err) } _, cid, err := codec.DecodeOne(data) if err != nil { return nil, errors.Trace(err) } // Get col value. data, b, err = codec.CutOne(b) if err != nil { return nil, errors.Trace(err) } id := cid.GetInt64() ft, ok := cols[id] if ok { _, v, err := codec.DecodeOne(data) if err != nil { return nil, errors.Trace(err) } v, err = Unflatten(v, ft, false) if err != nil { return nil, errors.Trace(err) } row[id] = v cnt++ if cnt == len(cols) { // Get enough data. break } } } return row, nil }
// CutRow cut encoded row into byte slices and return interested columns' byte slice. // Row layout: colID1, value1, colID2, value2, ..... func CutRow(data []byte, cols map[int64]*types.FieldType) (map[int64][]byte, error) { if data == nil { return nil, nil } if len(data) == 1 && data[0] == codec.NilFlag { return nil, nil } row := make(map[int64][]byte, len(cols)) cnt := 0 var ( b []byte err error ) for len(data) > 0 { // Get col id. b, data, err = codec.CutOne(data) if err != nil { return nil, errors.Trace(err) } _, cid, err := codec.DecodeOne(b) if err != nil { return nil, errors.Trace(err) } // Get col value. b, data, err = codec.CutOne(data) if err != nil { return nil, errors.Trace(err) } id := cid.GetInt64() _, ok := cols[id] if ok { row[id] = b cnt++ if cnt == len(cols) { break } } } return row, nil }
// CutIndexKey cuts encoded index key into colIDs to bytes slices map. // The returned value b is the remaining bytes of the key which would be empty if it is unique index or handle data // if it is non-unique index. func CutIndexKey(key kv.Key, colIDs []int64) (values map[int64][]byte, b []byte, err error) { b = key[prefixLen+idLen:] values = make(map[int64][]byte) for _, id := range colIDs { var val []byte val, b, err = codec.CutOne(b) if err != nil { return nil, nil, errors.Trace(err) } values[id] = val } return }