diff --git a/src/box/index.cc b/src/box/index.cc index 7d18b0039a56f4272f2b30daf709609bd89e92b6..18bc2e353593c3b1b714ef71d5d7b5bfcfffec1f 100644 --- a/src/box/index.cc +++ b/src/box/index.cc @@ -60,7 +60,7 @@ key_validate(struct key_def *key_def, enum iterator_type type, const char *key, /* * Zero key parts are allowed: * - for TREE index, all iterator types, - * - ITERA_ALL iterator type, all index types + * - ITER_ALL iterator type, all index types * - ITER_GE iterator in HASH index (legacy) */ if (key_def->type == TREE || type == ITER_ALL) diff --git a/src/box/memtx_hash.cc b/src/box/memtx_hash.cc index 4443e3f309b3c8abbfb4921d8d3709ba6ee6b627..fc812aab9773f1c4018c1021f910700f3d6ee9d7 100644 --- a/src/box/memtx_hash.cc +++ b/src/box/memtx_hash.cc @@ -171,7 +171,23 @@ hash_iterator_ge(struct iterator *ptr) { assert(ptr->free == hash_iterator_free); struct hash_iterator *it = (struct hash_iterator *) ptr; - struct tuple **res = light_index_itr_get_and_next(it->hash_table, &it->hitr); + struct tuple **res = light_index_itr_get_and_next(it->hash_table, + &it->hitr); + return res ? *res : 0; +} + +struct tuple * +hash_iterator_gt(struct iterator *ptr) +{ + assert(ptr->free == hash_iterator_free); + ptr->next = hash_iterator_ge; + struct hash_iterator *it = (struct hash_iterator *) ptr; + struct tuple **res = light_index_itr_get_and_next(it->hash_table, + &it->hitr); + if (!res) + return 0; + res = light_index_itr_get_and_next(it->hash_table, + &it->hitr); return res ? *res : 0; } @@ -303,7 +319,7 @@ MemtxHash::replace(struct tuple *old_tuple, struct tuple *new_tuple, if (old_tuple) { uint32_t h = tuple_hash(old_tuple, key_def); int res = light_index_delete_value(hash_table, h, old_tuple); - assert(res == 0); + assert(res == 0); (void)res; } return old_tuple; } @@ -337,13 +353,33 @@ MemtxHash::initIterator(struct iterator *ptr, enum iterator_type type, struct hash_iterator *it = (struct hash_iterator *) ptr; switch (type) { + case ITER_GE: + if (part_count != 0) { + light_index_itr_key(it->hash_table, &it->hitr, + key_hash(key, key_def), key); + } else { + light_index_itr_begin(it->hash_table, &it->hitr); + } + it->base.next = hash_iterator_ge; + break; + case ITER_GT: + if (part_count != 0) { + light_index_itr_key(it->hash_table, &it->hitr, + key_hash(key, key_def), key); + it->base.next = hash_iterator_gt; + } else { + light_index_itr_begin(it->hash_table, &it->hitr); + it->base.next = hash_iterator_ge; + } + break; case ITER_ALL: light_index_itr_begin(it->hash_table, &it->hitr); it->base.next = hash_iterator_ge; break; case ITER_EQ: assert(part_count > 0); - light_index_itr_key(it->hash_table, &it->hitr, key_hash(key, key_def), key); + light_index_itr_key(it->hash_table, &it->hitr, + key_hash(key, key_def), key); it->base.next = hash_iterator_eq; break; default: diff --git a/test/big/iterator.result b/test/big/iterator.result index 20228d4002ce0ee24d397ddd3d76bf7f1a7c6464..7820950a4a819b831936fed89be1804a659c5606 100644 --- a/test/big/iterator.result +++ b/test/big/iterator.result @@ -1054,3 +1054,33 @@ space:select({}, {iterator = 'mistake'}) space:drop() --- ... +------------------------------------------------------------------------------- +-- Restore GE iterator for HASH https://github.com/tarantool/tarantool/issues/836 +------------------------------------------------------------------------------- +space = box.schema.space.create('test', {temporary=true}) +--- +... +idx1 = space:create_index('primary', {type='hash',unique=true}) +--- +... +for i = 0,4 do space:insert{i} end +--- +... +space:select(2) +--- +- - [2] +... +space:select(2, {iterator="GE"}) +--- +- - [2] + - [3] + - [4] +... +space:select(2, {iterator="GT"}) +--- +- - [3] + - [4] +... +space:drop() +--- +... diff --git a/test/big/iterator.test.lua b/test/big/iterator.test.lua index b61d8f951f093efc708f938b07471d14e90e7a1a..70ba4bf4aaa8076e6ba0d282f24b150b77996205 100644 --- a/test/big/iterator.test.lua +++ b/test/big/iterator.test.lua @@ -229,3 +229,17 @@ space:select({}, {iterator = 'mistake'}) space:drop() + +------------------------------------------------------------------------------- +-- Restore GE iterator for HASH https://github.com/tarantool/tarantool/issues/836 +------------------------------------------------------------------------------- +space = box.schema.space.create('test', {temporary=true}) +idx1 = space:create_index('primary', {type='hash',unique=true}) + +for i = 0,4 do space:insert{i} end + +space:select(2) +space:select(2, {iterator="GE"}) +space:select(2, {iterator="GT"}) + +space:drop()