// SetFromBuffer initializes the EncDatum with an encoding that is possibly // followed by other data. Similar to SetEncoded, except that this function // figures out where the encoding stops and returns a slice for the rest of the // buffer. func (ed *EncDatum) SetFromBuffer( typ ColumnType_Kind, enc DatumEncoding, buf []byte, ) (remaining []byte, err error) { var encLen int switch enc { case DatumEncoding_ASCENDING_KEY, DatumEncoding_DESCENDING_KEY: encLen, err = encoding.PeekLength(buf) case DatumEncoding_VALUE: encLen, err = roachpb.PeekValueLength(buf) default: panic(fmt.Sprintf("unknown encoding %s", ed.encoding)) } if err != nil { return nil, err } ed.SetEncoded(typ, enc, buf[:encLen]) return buf[encLen:], nil }
// processValueTuple processes the given values (of columns family.ColumnIDs), // setting values in the rf.row accordingly. The key is only used for logging. func (rf *RowFetcher) processValueTuple( family *ColumnFamilyDescriptor, kv client.KeyValue, debugStrings bool, prettyKeyPrefix string, ) (prettyKey string, prettyValue string, err error) { prettyKey = prettyKeyPrefix if debugStrings { rf.prettyValueBuf.Reset() } tupleBytes, err := kv.Value.GetTuple() if err != nil { return "", "", err } var colIDRaw int64 var value parser.Datum for len(tupleBytes) > 0 { tupleBytes, _, colIDRaw, err = encoding.DecodeNonsortingVarint(tupleBytes) if err != nil { return "", "", err } if colIDRaw < 0 || colIDRaw > math.MaxUint32 { return "", "", util.Errorf("invalid column-id: %d", colIDRaw) } idx, ok := rf.colIdxMap[ColumnID(colIDRaw)] // TODO(dan): Ideally rowFetcher would generate EncDatums instead of Datums // and that would make the logic simpler. We won't need valNeededForCol at // all, it would be up to the user of the class to decide if they want to // decode them or not. if !ok || !rf.valNeededForCol[idx] { // This column wasn't requested, so read its length and skip it. i, err := roachpb.PeekValueLength(tupleBytes) if err != nil { return "", "", err } tupleBytes = tupleBytes[i:] if log.V(3) { log.Infof("Scan %s -> [%d] (skipped)", kv.Key, colIDRaw) } continue } if debugStrings { prettyKey = fmt.Sprintf("%s/%s", prettyKey, rf.desc.Columns[idx].Name) } kind := rf.cols[idx].Type.Kind.ToDatumType() value, tupleBytes, err = DecodeTableValue(&rf.alloc, kind, tupleBytes) if err != nil { return "", "", err } if debugStrings { fmt.Fprintf(&rf.prettyValueBuf, "/%v", value) } if rf.row[idx] != nil { panic(fmt.Sprintf("duplicate value for column %d", idx)) } rf.row[idx] = value if log.V(3) { log.Infof("Scan %d -> %v", idx, value) } } if debugStrings { prettyValue = rf.prettyValueBuf.String() } return prettyKey, prettyValue, nil }