// Encodes datum at the end of key, using direction `dir` for the encoding. // It takes in an inclusive key and returns an inclusive key if // isLastEndConstraint is not set, and an exclusive key otherwise (the idea is // that, for inclusive constraints, the value for the last column in the // constraint needs to be adapted to an exclusive span.EndKey). func encodeInclusiveEndValue( key roachpb.Key, datum parser.Datum, dir encoding.Direction, isLastEndConstraint bool, ) roachpb.Key { // Since the end of a span is exclusive, if the last constraint is an // inclusive one, we might need to make the key exclusive by applying a // PrefixEnd(). We normally avoid doing this by transforming "a = x" to // "a = x±1" for the last end constraint, depending on the encoding direction // (since this keeps the key nice and pretty-printable). // However, we might not be able to do the ±1. needExclusiveKey := false if isLastEndConstraint { if dir == encoding.Ascending { if datum.IsMax() || !datum.HasNext() { needExclusiveKey = true } else { datum = datum.Next() } } else { if datum.IsMin() || !datum.HasPrev() { needExclusiveKey = true } else { datum = datum.Prev() } } } key, err := sqlbase.EncodeTableKey(key, datum, dir) if err != nil { panic(err) } if needExclusiveKey { key = key.PrefixEnd() } return key }
func checkKeyCount(t *testing.T, kvDB *client.DB, prefix roachpb.Key, numKeys int) { if kvs, err := kvDB.Scan(context.TODO(), prefix, prefix.PrefixEnd(), 0); err != nil { t.Fatal(err) } else if l := numKeys; len(kvs) != l { t.Fatalf("expected %d key value pairs, but got %d", l, len(kvs)) } }
// TODO(dt): Batch checks of many rows. func (f baseFKHelper) check(values parser.DTuple) (parser.DTuple, error) { var key roachpb.Key if values != nil { keyBytes, _, err := sqlbase.EncodeIndexKey( f.searchTable, f.searchIdx, f.ids, values, f.searchPrefix) if err != nil { return nil, err } key = roachpb.Key(keyBytes) } else { key = roachpb.Key(f.searchPrefix) } spans := roachpb.Spans{roachpb.Span{Key: key, EndKey: key.PrefixEnd()}} if err := f.rf.StartScan(f.txn, spans, true /* limit batches */, 1); err != nil { return nil, err } return f.rf.NextRowDecoded() }