// DecodeIndexKey decodes the values that are a part of the specified index // key. ValTypes is a slice returned from makeKeyVals. The remaining bytes in the // index key are returned which will either be an encoded column ID for the // primary key index, the primary key suffix for non-unique secondary indexes // or unique secondary indexes containing NULL or empty. If the given descriptor // does not match the key, false is returned with no error. func DecodeIndexKey( a *DatumAlloc, desc *TableDescriptor, indexID IndexID, valTypes []parser.Type, vals []parser.Datum, colDirs []encoding.Direction, key []byte, ) ([]byte, bool, error) { var decodedTableID ID var decodedIndexID IndexID var err error if index, err := desc.FindIndexByID(indexID); err == nil && len(index.Interleave.Ancestors) > 0 { for _, ancestor := range index.Interleave.Ancestors { key, decodedTableID, decodedIndexID, err = DecodeTableIDIndexID(key) if err != nil { return nil, false, err } if decodedTableID != ancestor.TableID || decodedIndexID != ancestor.IndexID { return nil, false, nil } length := int(ancestor.SharedPrefixLen) key, err = DecodeKeyVals(a, valTypes[:length], vals[:length], colDirs[:length], key) if err != nil { return nil, false, err } valTypes, vals, colDirs = valTypes[length:], vals[length:], colDirs[length:] // We reuse NotNullDescending as the interleave sentinel, consume it. var ok bool key, ok = encoding.DecodeIfNotNull(key) if !ok { return nil, false, nil } } } key, decodedTableID, decodedIndexID, err = DecodeTableIDIndexID(key) if err != nil { return nil, false, err } if decodedTableID != desc.ID || decodedIndexID != indexID { return nil, false, nil } key, err = DecodeKeyVals(a, valTypes, vals, colDirs, key) if err != nil { return nil, false, err } // We're expecting a column family id next (a varint). If descNotNull is // actually next, then this key is for a child table. if _, ok := encoding.DecodeIfNotNull(key); ok { return nil, false, nil } return key, true, nil }
// DecodeIndexKeyPrefix decodes the prefix of an index key and returns the // index id and a slice for the rest of the key. // // Don't use this function in the scan "hot path". func DecodeIndexKeyPrefix( a *DatumAlloc, desc *TableDescriptor, key []byte, ) (indexID IndexID, remaining []byte, err error) { // TODO(dan): This whole operation is n^2 because of the interleaves // bookkeeping. We could improve it to n with a prefix tree of components. interleaves := append([]IndexDescriptor{desc.PrimaryIndex}, desc.Indexes...) for component := 0; ; component++ { var tableID ID key, tableID, indexID, err = DecodeTableIDIndexID(key) if err != nil { return 0, nil, err } if tableID == desc.ID { // Once desc's table id has been decoded, there can be no more // interleaves. break } for i := len(interleaves) - 1; i >= 0; i-- { if len(interleaves[i].Interleave.Ancestors) <= component || interleaves[i].Interleave.Ancestors[component].TableID != tableID || interleaves[i].Interleave.Ancestors[component].IndexID != indexID { // This component, and thus this interleave, doesn't match what was // decoded, remove it. copy(interleaves[i:], interleaves[i+1:]) interleaves = interleaves[:len(interleaves)-1] } } // The decoded key doesn't many any known interleaves if len(interleaves) == 0 { return 0, nil, errors.Errorf("no known interleaves for key") } // Anything left has the same SharedPrefixLen at index `component`, so just // use the first one. for i := uint32(0); i < interleaves[0].Interleave.Ancestors[component].SharedPrefixLen; i++ { l, err := encoding.PeekLength(key) if err != nil { return 0, nil, err } key = key[l:] } // We reuse NotNullDescending as the interleave sentinel, consume it. var ok bool key, ok = encoding.DecodeIfNotNull(key) if !ok { return 0, nil, errors.Errorf("invalid interleave key") } } return indexID, key, err }