diff --git a/clientv3/integration/kv_test.go b/clientv3/integration/kv_test.go index e8d22e538..636bcd27a 100644 --- a/clientv3/integration/kv_test.go +++ b/clientv3/integration/kv_test.go @@ -403,6 +403,21 @@ func TestKVRange(t *testing.T) { 0, []clientv3.OpOption{clientv3.WithPrefix(), clientv3.WithSort(clientv3.SortByKey, clientv3.SortAscend)}, + []*mvccpb.KeyValue{ + {Key: []byte("a"), Value: nil, CreateRevision: 2, ModRevision: 2, Version: 1}, + {Key: []byte("b"), Value: nil, CreateRevision: 3, ModRevision: 3, Version: 1}, + {Key: []byte("c"), Value: nil, CreateRevision: 4, ModRevision: 6, Version: 3}, + {Key: []byte("foo"), Value: nil, CreateRevision: 7, ModRevision: 7, Version: 1}, + {Key: []byte("foo/abc"), Value: nil, CreateRevision: 8, ModRevision: 8, Version: 1}, + {Key: []byte("fop"), Value: nil, CreateRevision: 9, ModRevision: 9, Version: 1}, + }, + }, + // fetch keyspace with empty key using WithFromKey + { + "", "", + 0, + []clientv3.OpOption{clientv3.WithFromKey(), clientv3.WithSort(clientv3.SortByKey, clientv3.SortAscend)}, + []*mvccpb.KeyValue{ {Key: []byte("a"), Value: nil, CreateRevision: 2, ModRevision: 2, Version: 1}, {Key: []byte("b"), Value: nil, CreateRevision: 3, ModRevision: 3, Version: 1}, diff --git a/clientv3/op.go b/clientv3/op.go index a3e7d3e77..13507c99a 100644 --- a/clientv3/op.go +++ b/clientv3/op.go @@ -392,7 +392,14 @@ func WithRange(endKey string) OpOption { // WithFromKey specifies the range of 'Get', 'Delete', 'Watch' requests // to be equal or greater than the key in the argument. -func WithFromKey() OpOption { return WithRange("\x00") } +func WithFromKey() OpOption { + return func(op *Op) { + if len(op.key) == 0 { + op.key = []byte{0} + } + op.end = []byte("\x00") + } +} // WithSerializable makes 'Get' request serializable. By default, // it's linearizable. Serializable requests are better for lower latency