Sergey, thanks for the patch, LGTM, Отправлено из мобильной Почты Mail.ru четверг, 19 марта 2020 г., 13:25 +0300 от Sergey Bronnikov : >Splitted single hash.test.lua to a set of small independent tests. > >GitHub branch: https://github.com/tarantool/tarantool/tree/ligurio/hash_test_split > >--- > test/box/hash.result | 873 -------------------------- > test/box/hash.test.lua | 364 ----------- > test/box/hash_32bit_delete.result | 70 +++ > test/box/hash_32bit_delete.test.lua | 29 + > test/box/hash_32bit_insert.result | 38 ++ > test/box/hash_32bit_insert.test.lua | 16 + > test/box/hash_32bit_replace.result | 56 ++ > test/box/hash_32bit_replace.test.lua | 25 + > test/box/hash_32bit_select.result | 70 +++ > test/box/hash_32bit_select.test.lua | 29 + > test/box/hash_64bit_delete.result | 111 ++++ > test/box/hash_64bit_delete.test.lua | 42 ++ > test/box/hash_64bit_insert.result | 54 ++ > test/box/hash_64bit_insert.test.lua | 20 + > test/box/hash_64bit_replace.result | 68 ++ > test/box/hash_64bit_replace.test.lua | 28 + > test/box/hash_64bit_select.result | 94 +++ > test/box/hash_64bit_select.test.lua | 37 ++ > test/box/hash_collation.result | 62 ++ > test/box/hash_collation.test.lua | 22 + > test/box/hash_gh-1467.result | 17 + > test/box/hash_gh-1467.test.lua | 6 + > test/box/hash_gh-3907.result | 48 ++ > test/box/hash_gh-3907.test.lua | 15 + > test/box/hash_gh-616.result | 17 + > test/box/hash_gh-616.test.lua | 7 + > test/box/hash_iterate.result | 21 + > test/box/hash_iterate.test.lua | 6 + > test/box/hash_multipart.result | 7 - > test/box/hash_multipart.test.lua | 2 - > test/box/hash_not_a_multikey.result | 17 + > test/box/hash_not_a_multikey.test.lua | 6 + > test/box/hash_replace.result | 256 ++++++++ > test/box/hash_replace.test.lua | 88 +++ > test/box/hash_string_delete.result | 62 ++ > test/box/hash_string_delete.test.lua | 24 + > test/box/hash_string_insert.result | 32 + > test/box/hash_string_insert.test.lua | 13 + > test/box/hash_string_replace.result | 47 ++ > test/box/hash_string_replace.test.lua | 19 + > test/box/hash_string_select.result | 63 ++ > test/box/hash_string_select.test.lua | 25 + > test/box/hash_with_function.result | 26 + > test/box/hash_with_function.test.lua | 9 + > 44 files changed, 1695 insertions(+), 1246 deletions(-) > delete mode 100644 test/box/hash.result > delete mode 100644 test/box/hash.test.lua > create mode 100644 test/box/hash_32bit_delete.result > create mode 100644 test/box/hash_32bit_delete.test.lua > create mode 100644 test/box/hash_32bit_insert.result > create mode 100644 test/box/hash_32bit_insert.test.lua > create mode 100644 test/box/hash_32bit_replace.result > create mode 100644 test/box/hash_32bit_replace.test.lua > create mode 100644 test/box/hash_32bit_select.result > create mode 100644 test/box/hash_32bit_select.test.lua > create mode 100644 test/box/hash_64bit_delete.result > create mode 100644 test/box/hash_64bit_delete.test.lua > create mode 100644 test/box/hash_64bit_insert.result > create mode 100644 test/box/hash_64bit_insert.test.lua > create mode 100644 test/box/hash_64bit_replace.result > create mode 100644 test/box/hash_64bit_replace.test.lua > create mode 100644 test/box/hash_64bit_select.result > create mode 100644 test/box/hash_64bit_select.test.lua > create mode 100644 test/box/hash_collation.result > create mode 100644 test/box/hash_collation.test.lua > create mode 100644 test/box/hash_gh-1467.result > create mode 100644 test/box/hash_gh-1467.test.lua > create mode 100644 test/box/hash_gh-3907.result > create mode 100644 test/box/hash_gh-3907.test.lua > create mode 100644 test/box/hash_gh-616.result > create mode 100644 test/box/hash_gh-616.test.lua > create mode 100644 test/box/hash_iterate.result > create mode 100644 test/box/hash_iterate.test.lua > create mode 100644 test/box/hash_not_a_multikey.result > create mode 100644 test/box/hash_not_a_multikey.test.lua > create mode 100644 test/box/hash_replace.result > create mode 100644 test/box/hash_replace.test.lua > create mode 100644 test/box/hash_string_delete.result > create mode 100644 test/box/hash_string_delete.test.lua > create mode 100644 test/box/hash_string_insert.result > create mode 100644 test/box/hash_string_insert.test.lua > create mode 100644 test/box/hash_string_replace.result > create mode 100644 test/box/hash_string_replace.test.lua > create mode 100644 test/box/hash_string_select.result > create mode 100644 test/box/hash_string_select.test.lua > create mode 100644 test/box/hash_with_function.result > create mode 100644 test/box/hash_with_function.test.lua > >diff --git a/test/box/hash.result b/test/box/hash.result >deleted file mode 100644 >index 5e1441ecc..000000000 >--- a/test/box/hash.result >+++ /dev/null >@@ -1,873 +0,0 @@ >---============================================================================= >--- 32-bit hash tests >---============================================================================= >-------------------------------------------------------------------------------- >--- 32-bit hash insert fields tests >-------------------------------------------------------------------------------- >-hash = box.schema.space.create('tweedledum') >---- >-... >-tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >---- >-... >-bsize = tmp:bsize() >---- >-... >--- Insert valid fields >-hash:insert{0, 'value1 v1.0', 'value2 v1.0'} >---- >-- [0, 'value1 v1.0', 'value2 v1.0'] >-... >-hash:insert{1, 'value1 v1.0', 'value2 v1.0'} >---- >-- [1, 'value1 v1.0', 'value2 v1.0'] >-... >-hash:insert{2, 'value1 v1.0', 'value2 v1.0'} >---- >-- [2, 'value1 v1.0', 'value2 v1.0'] >-... >-hash:insert{3, 'value1 v1.0', 'value2 v1.0'} >---- >-- [3, 'value1 v1.0', 'value2 v1.0'] >-... >-tmp:bsize() > bsize >---- >-- true >-... >--- Insert invalid fields >-hash:insert{'invalid key', 'value1 v1.0', 'value2 v1.0'} >---- >-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned' >-... >-------------------------------------------------------------------------------- >--- 32-bit hash replace fields tests >-------------------------------------------------------------------------------- >--- Replace valid fields >-hash:replace{3, 'value1 v1.31', 'value2 1.12'} >---- >-- [3, 'value1 v1.31', 'value2 1.12'] >-... >-hash:replace{1, 'value1 v1.32', 'value2 1.72'} >---- >-- [1, 'value1 v1.32', 'value2 1.72'] >-... >-hash:replace{2, 'value1 v1.43', 'value2 1.92'} >---- >-- [2, 'value1 v1.43', 'value2 1.92'] >-... >--- Replace invalid fields >-hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'} >---- >-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned' >-... >-------------------------------------------------------------------------------- >--- 32-bit hash select fields test >-------------------------------------------------------------------------------- >--- select by valid keys >-hash.index['primary']:get{0} >---- >-- [0, 'value1 v1.0', 'value2 v1.0'] >-... >-hash.index['primary']:get{1} >---- >-- [1, 'value1 v1.32', 'value2 1.72'] >-... >-hash.index['primary']:get{2} >---- >-- [2, 'value1 v1.43', 'value2 1.92'] >-... >-hash.index['primary']:get{3} >---- >-- [3, 'value1 v1.31', 'value2 1.12'] >-... >-hash.index['primary']:get{4} >---- >-... >-hash.index['primary']:get{5} >---- >-... >--- select by invalid keys >-hash.index['primary']:get{'invalid key'} >---- >-- error: 'Supplied key type of part 0 does not match index part type: expected unsigned' >-... >-hash.index['primary']:get{1, 2} >---- >-- error: Invalid key part count in an exact match (expected 1, got 2) >-... >-------------------------------------------------------------------------------- >--- 32-bit hash delete fields test >-------------------------------------------------------------------------------- >--- delete by valid keys >-hash:delete{0} >---- >-- [0, 'value1 v1.0', 'value2 v1.0'] >-... >-hash:delete{1} >---- >-- [1, 'value1 v1.32', 'value2 1.72'] >-... >-hash:delete{2} >---- >-- [2, 'value1 v1.43', 'value2 1.92'] >-... >-hash:delete{3} >---- >-- [3, 'value1 v1.31', 'value2 1.12'] >-... >-hash:delete{4} >---- >-... >-hash:delete{5} >---- >-... >--- delete by invalid keys >-hash:delete{'invalid key'} >---- >-- error: 'Supplied key type of part 0 does not match index part type: expected unsigned' >-... >-hash:delete{1, 2} >---- >-- error: Invalid key part count in an exact match (expected 1, got 2) >-... >-hash:truncate() >---- >-... >---============================================================================= >--- 64-bit hash tests >---============================================================================= >-------------------------------------------------------------------------------- >--- 64-bit hash inset fields tests >-------------------------------------------------------------------------------- >--- Insert valid fields >-hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'} >---- >-- [0, 'value1 v1.0', 'value2 v1.0'] >-... >-hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'} >---- >-- [1, 'value1 v1.0', 'value2 v1.0'] >-... >-hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'} >---- >-- [2, 'value1 v1.0', 'value2 v1.0'] >-... >-hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'} >---- >-- [3, 'value1 v1.0', 'value2 v1.0'] >-... >--- Insert invalid fields >-hash:insert{100, 'value1 v1.0', 'value2 v1.0'} >---- >-- [100, 'value1 v1.0', 'value2 v1.0'] >-... >-hash:insert{101, 'value1 v1.0', 'value2 v1.0'} >---- >-- [101, 'value1 v1.0', 'value2 v1.0'] >-... >-hash:insert{102, 'value1 v1.0', 'value2 v1.0'} >---- >-- [102, 'value1 v1.0', 'value2 v1.0'] >-... >-hash:insert{103, 'value1 v1.0', 'value2 v1.0'} >---- >-- [103, 'value1 v1.0', 'value2 v1.0'] >-... >-hash:insert{'invalid key', 'value1 v1.0', 'value2 v1.0'} >---- >-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned' >-... >-------------------------------------------------------------------------------- >--- 64-bit hash replace fields tests >-------------------------------------------------------------------------------- >--- Replace valid fields >-hash:replace{3ULL, 'value1 v1.31', 'value2 1.12'} >---- >-- [3, 'value1 v1.31', 'value2 1.12'] >-... >-hash:replace{1ULL, 'value1 v1.32', 'value2 1.72'} >---- >-- [1, 'value1 v1.32', 'value2 1.72'] >-... >-hash:replace{2ULL, 'value1 v1.43', 'value2 1.92'} >---- >-- [2, 'value1 v1.43', 'value2 1.92'] >-... >--- Replace invalid fields >-hash:replace{3, 'value1 v1.31', 'value2 1.12'} >---- >-- [3, 'value1 v1.31', 'value2 1.12'] >-... >-hash:replace{1, 'value1 v1.32', 'value2 1.72'} >---- >-- [1, 'value1 v1.32', 'value2 1.72'] >-... >-hash:replace{2, 'value1 v1.43', 'value2 1.92'} >---- >-- [2, 'value1 v1.43', 'value2 1.92'] >-... >-hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'} >---- >-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned' >-... >-------------------------------------------------------------------------------- >--- 64-bit hash select fields test >-------------------------------------------------------------------------------- >--- select by valid keys >-hash.index['primary']:get{0ULL} >---- >-- [0, 'value1 v1.0', 'value2 v1.0'] >-... >-hash.index['primary']:get{1ULL} >---- >-- [1, 'value1 v1.32', 'value2 1.72'] >-... >-hash.index['primary']:get{2ULL} >---- >-- [2, 'value1 v1.43', 'value2 1.92'] >-... >-hash.index['primary']:get{3ULL} >---- >-- [3, 'value1 v1.31', 'value2 1.12'] >-... >-hash.index['primary']:get{4ULL} >---- >-... >-hash.index['primary']:get{5ULL} >---- >-... >--- select by valid NUM keys >-hash.index['primary']:get{0} >---- >-- [0, 'value1 v1.0', 'value2 v1.0'] >-... >-hash.index['primary']:get{1} >---- >-- [1, 'value1 v1.32', 'value2 1.72'] >-... >-hash.index['primary']:get{2} >---- >-- [2, 'value1 v1.43', 'value2 1.92'] >-... >-hash.index['primary']:get{3} >---- >-- [3, 'value1 v1.31', 'value2 1.12'] >-... >-hash.index['primary']:get{4} >---- >-... >-hash.index['primary']:get{5} >---- >-... >--- select by invalid keys >-hash.index['primary']:get{'invalid key'} >---- >-- error: 'Supplied key type of part 0 does not match index part type: expected unsigned' >-... >-hash.index['primary']:get{'00000001', '00000002'} >---- >-- error: Invalid key part count in an exact match (expected 1, got 2) >-... >-------------------------------------------------------------------------------- >--- 64-bit hash delete fields test >-------------------------------------------------------------------------------- >--- delete by valid keys >-hash:delete{0ULL} >---- >-- [0, 'value1 v1.0', 'value2 v1.0'] >-... >-hash:delete{1ULL} >---- >-- [1, 'value1 v1.32', 'value2 1.72'] >-... >-hash:delete{2ULL} >---- >-- [2, 'value1 v1.43', 'value2 1.92'] >-... >-hash:delete{3ULL} >---- >-- [3, 'value1 v1.31', 'value2 1.12'] >-... >-hash:delete{4ULL} >---- >-... >-hash:delete{5ULL} >---- >-... >-hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'} >---- >-- [0, 'value1 v1.0', 'value2 v1.0'] >-... >-hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'} >---- >-- [1, 'value1 v1.0', 'value2 v1.0'] >-... >-hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'} >---- >-- [2, 'value1 v1.0', 'value2 v1.0'] >-... >-hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'} >---- >-- [3, 'value1 v1.0', 'value2 v1.0'] >-... >--- delete by valid NUM keys >-hash:delete{0} >---- >-- [0, 'value1 v1.0', 'value2 v1.0'] >-... >-hash:delete{1} >---- >-- [1, 'value1 v1.0', 'value2 v1.0'] >-... >-hash:delete{2} >---- >-- [2, 'value1 v1.0', 'value2 v1.0'] >-... >-hash:delete{3} >---- >-- [3, 'value1 v1.0', 'value2 v1.0'] >-... >-hash:delete{4} >---- >-... >-hash:delete{5} >---- >-... >--- delete by invalid keys >-hash:delete{'invalid key'} >---- >-- error: 'Supplied key type of part 0 does not match index part type: expected unsigned' >-... >-hash:delete{'00000001', '00000002'} >---- >-- error: Invalid key part count in an exact match (expected 1, got 2) >-... >-hash:truncate() >---- >-... >---============================================================================= >--- String hash tests >---============================================================================= >-------------------------------------------------------------------------------- >--- String hash inset fields tests >-------------------------------------------------------------------------------- >-hash.index['primary']:drop() >---- >-... >-tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'string'}, unique = true }) >---- >-... >--- Insert valid fields >-hash:insert{'key 0', 'value1 v1.0', 'value2 v1.0'} >---- >-- ['key 0', 'value1 v1.0', 'value2 v1.0'] >-... >-hash:insert{'key 1', 'value1 v1.0', 'value2 v1.0'} >---- >-- ['key 1', 'value1 v1.0', 'value2 v1.0'] >-... >-hash:insert{'key 2', 'value1 v1.0', 'value2 v1.0'} >---- >-- ['key 2', 'value1 v1.0', 'value2 v1.0'] >-... >-hash:insert{'key 3', 'value1 v1.0', 'value2 v1.0'} >---- >-- ['key 3', 'value1 v1.0', 'value2 v1.0'] >-... >-------------------------------------------------------------------------------- >--- String hash replace fields tests >-------------------------------------------------------------------------------- >--- Replace valid fields >-hash:replace{'key 3', 'value1 v1.31', 'value2 1.12'} >---- >-- ['key 3', 'value1 v1.31', 'value2 1.12'] >-... >-hash:replace{'key 1', 'value1 v1.32', 'value2 1.72'} >---- >-- ['key 1', 'value1 v1.32', 'value2 1.72'] >-... >-hash:replace{'key 2', 'value1 v1.43', 'value2 1.92'} >---- >-- ['key 2', 'value1 v1.43', 'value2 1.92'] >-... >-------------------------------------------------------------------------------- >--- String hash select fields test >-------------------------------------------------------------------------------- >--- select by valid keys >-hash.index['primary']:get{'key 0'} >---- >-- ['key 0', 'value1 v1.0', 'value2 v1.0'] >-... >-hash.index['primary']:get{'key 1'} >---- >-- ['key 1', 'value1 v1.32', 'value2 1.72'] >-... >-hash.index['primary']:get{'key 2'} >---- >-- ['key 2', 'value1 v1.43', 'value2 1.92'] >-... >-hash.index['primary']:get{'key 3'} >---- >-- ['key 3', 'value1 v1.31', 'value2 1.12'] >-... >-hash.index['primary']:get{'key 4'} >---- >-... >-hash.index['primary']:get{'key 5'} >---- >-... >--- select by invalid keys >-hash.index['primary']:get{'key 1', 'key 2'} >---- >-- error: Invalid key part count in an exact match (expected 1, got 2) >-... >-------------------------------------------------------------------------------- >--- String hash delete fields test >-------------------------------------------------------------------------------- >--- delete by valid keys >-hash:delete{'key 0'} >---- >-- ['key 0', 'value1 v1.0', 'value2 v1.0'] >-... >-hash:delete{'key 1'} >---- >-- ['key 1', 'value1 v1.32', 'value2 1.72'] >-... >-hash:delete{'key 2'} >---- >-- ['key 2', 'value1 v1.43', 'value2 1.92'] >-... >-hash:delete{'key 3'} >---- >-- ['key 3', 'value1 v1.31', 'value2 1.12'] >-... >-hash:delete{'key 4'} >---- >-... >-hash:delete{'key 5'} >---- >-... >--- delete by invalid keys >-hash:delete{'key 1', 'key 2'} >---- >-- error: Invalid key part count in an exact match (expected 1, got 2) >-... >-hash:truncate() >---- >-... >-------------------------------------------------------------------------------- >--- Collation test >-------------------------------------------------------------------------------- >-hash.index['primary']:drop() >---- >-... >-tmp = hash:create_index('primary', { type = 'hash', parts = {{1, 'string', collation = 'unicode_ci'}}, unique = true}) >---- >-... >-tmp = hash:create_index('secondary', { type = 'hash', parts = {{2, 'scalar', collation = 'unicode_ci'}}, unique = true}) >---- >-... >-hash:insert{'Ёж', 'Hedgehog'} >---- >-- ['Ёж', 'Hedgehog'] >-... >-hash:insert{'Ёлка', 'Spruce'} >---- >-- ['Ёлка', 'Spruce'] >-... >-hash:insert{'Jogurt', 'Йогурт'} >---- >-- ['Jogurt', 'Йогурт'] >-... >-hash:insert{'Один', 1} >---- >-- ['Один', 1] >-... >-hash.index.primary:get('ёж') >---- >-- ['Ёж', 'Hedgehog'] >-... >-hash.index.primary:get('елка') >---- >-- ['Ёлка', 'Spruce'] >-... >-hash.index.secondary:get('spruce') >---- >-- ['Ёлка', 'Spruce'] >-... >-hash.index.secondary:get('йогурт') >---- >-- ['Jogurt', 'Йогурт'] >-... >-hash.index.secondary:get(1) >---- >-- ['Один', 1] >-... >-hash.index.secondary:get('иогурт') >---- >-... >-hash.index.secondary:get(2) >---- >-... >------------------------- >--- hash::replace tests >------------------------- >-hash.index['secondary']:drop() >---- >-... >-hash.index['primary']:drop() >---- >-... >-tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >---- >-... >-tmp = hash:create_index('field1', { type = 'hash', parts = {2, 'unsigned'}, unique = true }) >---- >-... >-tmp = hash:create_index('field2', { type = 'hash', parts = {3, 'unsigned'}, unique = true }) >---- >-... >-tmp = hash:create_index('field3', { type = 'hash', parts = {4, 'unsigned'}, unique = true }) >---- >-... >-hash:insert{0, 0, 0, 0} >---- >-- [0, 0, 0, 0] >-... >-hash:insert{1, 1, 1, 1} >---- >-- [1, 1, 1, 1] >-... >-hash:insert{2, 2, 2, 2} >---- >-- [2, 2, 2, 2] >-... >--- OK >-hash:replace{1, 1, 1, 1} >---- >-- [1, 1, 1, 1] >-... >-hash.index['primary']:get{10} >---- >-... >-hash.index['field1']:get{10} >---- >-... >-hash.index['field2']:get{10} >---- >-... >-hash.index['field3']:get{10} >---- >-... >-hash.index['primary']:get{1} >---- >-- [1, 1, 1, 1] >-... >-hash.index['field1']:get{1} >---- >-- [1, 1, 1, 1] >-... >-hash.index['field2']:get{1} >---- >-- [1, 1, 1, 1] >-... >-hash.index['field3']:get{1} >---- >-- [1, 1, 1, 1] >-... >--- OK >-hash:insert{10, 10, 10, 10} >---- >-- [10, 10, 10, 10] >-... >-hash:delete{10} >---- >-- [10, 10, 10, 10] >-... >-hash.index['primary']:get{10} >---- >-... >-hash.index['field1']:get{10} >---- >-... >-hash.index['field2']:get{10} >---- >-... >-hash.index['field3']:get{10} >---- >-... >--- TupleFound (primary key) >-hash:insert{1, 10, 10, 10} >---- >-- error: Duplicate key exists in unique index 'primary' in space 'tweedledum' >-... >-hash.index['primary']:get{10} >---- >-... >-hash.index['field1']:get{10} >---- >-... >-hash.index['field2']:get{10} >---- >-... >-hash.index['field3']:get{10} >---- >-... >-hash.index['primary']:get{1} >---- >-- [1, 1, 1, 1] >-... >--- TupleNotFound (primary key) >-hash:replace{10, 10, 10, 10} >---- >-- [10, 10, 10, 10] >-... >-hash.index['primary']:get{10} >---- >-- [10, 10, 10, 10] >-... >-hash.index['field1']:get{10} >---- >-- [10, 10, 10, 10] >-... >-hash.index['field2']:get{10} >---- >-- [10, 10, 10, 10] >-... >-hash.index['field3']:get{10} >---- >-- [10, 10, 10, 10] >-... >--- TupleFound (key --1) >-hash:insert{10, 0, 10, 10} >---- >-- error: Duplicate key exists in unique index 'primary' in space 'tweedledum' >-... >-hash.index['primary']:get{10} >---- >-- [10, 10, 10, 10] >-... >-hash.index['field1']:get{10} >---- >-- [10, 10, 10, 10] >-... >-hash.index['field2']:get{10} >---- >-- [10, 10, 10, 10] >-... >-hash.index['field3']:get{10} >---- >-- [10, 10, 10, 10] >-... >-hash.index['field1']:get{0} >---- >-- [0, 0, 0, 0] >-... >--- TupleFound (key --1) >--- hash:replace_if_exists(2, 0, 10, 10) >-hash.index['primary']:get{10} >---- >-- [10, 10, 10, 10] >-... >-hash.index['field1']:get{10} >---- >-- [10, 10, 10, 10] >-... >-hash.index['field2']:get{10} >---- >-- [10, 10, 10, 10] >-... >-hash.index['field3']:get{10} >---- >-- [10, 10, 10, 10] >-... >-hash.index['field1']:get{0} >---- >-- [0, 0, 0, 0] >-... >--- TupleFound (key --3) >-hash:insert{10, 10, 10, 0} >---- >-- error: Duplicate key exists in unique index 'primary' in space 'tweedledum' >-... >-hash.index['primary']:get{10} >---- >-- [10, 10, 10, 10] >-... >-hash.index['field1']:get{10} >---- >-- [10, 10, 10, 10] >-... >-hash.index['field2']:get{10} >---- >-- [10, 10, 10, 10] >-... >-hash.index['field3']:get{10} >---- >-- [10, 10, 10, 10] >-... >-hash.index['field3']:get{0} >---- >-- [0, 0, 0, 0] >-... >--- TupleFound (key --3) >--- hash:replace_if_exists(2, 10, 10, 0) >-hash.index['primary']:get{10} >---- >-- [10, 10, 10, 10] >-... >-hash.index['field1']:get{10} >---- >-- [10, 10, 10, 10] >-... >-hash.index['field2']:get{10} >---- >-- [10, 10, 10, 10] >-... >-hash.index['field3']:get{10} >---- >-- [10, 10, 10, 10] >-... >-hash.index['field3']:get{0} >---- >-- [0, 0, 0, 0] >-... >-hash:drop() >---- >-... >-hash = box.schema.space.create('tweedledum') >---- >-... >-hi = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >---- >-... >-hash:insert{0} >---- >-- [0] >-... >-hash:insert{16} >---- >-- [16] >-... >-for _, tuple in hi:pairs(nil, {iterator = box.index.ALL}) do hash:delete{tuple[1]} end >---- >-... >-hash:drop() >---- >-... >--- >--- gh-616 "1-based indexing and 0-based error message >--- >-_ = box.schema.create_space('test') >---- >-... >-_ = box.space.test:create_index('i',{parts={1,'string'}}) >---- >-... >-box.space.test:insert{1} >---- >-- error: 'Tuple field 1 type does not match one required by operation: expected string' >-... >-box.space.test:drop() >---- >-... >--- gh-1467: invalid iterator type >-space = box.schema.space.create('test') >---- >-... >-index = space:create_index('primary', { type = 'hash' }) >---- >-... >-space:select({1}, {iterator = 'BITS_ALL_SET' } ) >---- >-- error: Index 'primary' (HASH) of space 'test' (memtx) does not support requested >- iterator type >-... >-space:drop() >---- >-... >--- gh-3907: check that integer numbers stored as MP_FLOAT/MP_DOUBLE >--- are hashed as MP_INT/MP_UINT. >-ffi = require('ffi') >---- >-... >-s = box.schema.space.create('test') >---- >-... >-_ = s:create_index('primary', {type = 'hash', parts = {1, 'number'}}) >---- >-... >-s:insert{ffi.new('double', 0)} >---- >-- [0] >-... >-s:insert{ffi.new('double', -1)} >---- >-- [-1] >-... >-s:insert{ffi.new('double', 9007199254740992)} >---- >-- [9007199254740992] >-... >-s:insert{ffi.new('double', -9007199254740994)} >---- >-- [-9007199254740994] >-... >-s:get(0LL) >---- >-- [0] >-... >-s:get(-1LL) >---- >-- [-1] >-... >-s:get(9007199254740992LL) >---- >-- [9007199254740992] >-... >-s:get(-9007199254740994LL) >---- >-- [-9007199254740994] >-... >-s:drop() >---- >-... >--- Hash index cannot be multikey. >-s = box.schema.space.create('test') >---- >-... >-_ = s:create_index('primary') >---- >-... >-_ = s:create_index('hash', {type = 'hash', parts = {{'[2][*]', 'unsigned'}}}) >---- >-- error: 'Can''t create or modify index ''hash'' in space ''test'': HASH index cannot >- be multikey' >-... >-s:drop() >---- >-... >--- Hash index can not use function. >-s = box.schema.space.create('withdata') >---- >-... >-lua_code = [[function(tuple) return tuple[1] + tuple[2] end]] >---- >-... >-box.schema.func.create('s', {body = lua_code, is_deterministic = true, is_sandboxed = true}) >---- >-... >-_ = s:create_index('pk') >---- >-... >-_ = s:create_index('idx', {type = 'hash', func = box.func.s.id, parts = {{1, 'unsigned'}}}) >---- >-- error: 'Can''t create or modify index ''idx'' in space ''withdata'': HASH index >- can not use a function' >-... >-s:drop() >---- >-... >-box.schema.func.drop('s') >---- >-... >diff --git a/test/box/hash.test.lua b/test/box/hash.test.lua >deleted file mode 100644 >index 78c831f77..000000000 >--- a/test/box/hash.test.lua >+++ /dev/null >@@ -1,364 +0,0 @@ >---============================================================================= >--- 32-bit hash tests >---============================================================================= >-------------------------------------------------------------------------------- >--- 32-bit hash insert fields tests >-------------------------------------------------------------------------------- >-hash = box.schema.space.create('tweedledum') >-tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >- >-bsize = tmp:bsize() >- >--- Insert valid fields >-hash:insert{0, 'value1 v1.0', 'value2 v1.0'} >-hash:insert{1, 'value1 v1.0', 'value2 v1.0'} >-hash:insert{2, 'value1 v1.0', 'value2 v1.0'} >-hash:insert{3, 'value1 v1.0', 'value2 v1.0'} >- >-tmp:bsize() > bsize >- >--- Insert invalid fields >-hash:insert{'invalid key', 'value1 v1.0', 'value2 v1.0'} >- >-------------------------------------------------------------------------------- >--- 32-bit hash replace fields tests >-------------------------------------------------------------------------------- >- >--- Replace valid fields >-hash:replace{3, 'value1 v1.31', 'value2 1.12'} >-hash:replace{1, 'value1 v1.32', 'value2 1.72'} >-hash:replace{2, 'value1 v1.43', 'value2 1.92'} >- >--- Replace invalid fields >-hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'} >- >-------------------------------------------------------------------------------- >--- 32-bit hash select fields test >-------------------------------------------------------------------------------- >- >--- select by valid keys >-hash.index['primary']:get{0} >-hash.index['primary']:get{1} >-hash.index['primary']:get{2} >-hash.index['primary']:get{3} >-hash.index['primary']:get{4} >-hash.index['primary']:get{5} >- >--- select by invalid keys >-hash.index['primary']:get{'invalid key'} >-hash.index['primary']:get{1, 2} >- >-------------------------------------------------------------------------------- >--- 32-bit hash delete fields test >-------------------------------------------------------------------------------- >- >--- delete by valid keys >-hash:delete{0} >-hash:delete{1} >-hash:delete{2} >-hash:delete{3} >-hash:delete{4} >-hash:delete{5} >- >--- delete by invalid keys >-hash:delete{'invalid key'} >-hash:delete{1, 2} >- >-hash:truncate() >- >---============================================================================= >--- 64-bit hash tests >---============================================================================= >-------------------------------------------------------------------------------- >--- 64-bit hash inset fields tests >-------------------------------------------------------------------------------- >- >--- Insert valid fields >-hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'} >-hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'} >-hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'} >-hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'} >- >--- Insert invalid fields >-hash:insert{100, 'value1 v1.0', 'value2 v1.0'} >-hash:insert{101, 'value1 v1.0', 'value2 v1.0'} >-hash:insert{102, 'value1 v1.0', 'value2 v1.0'} >-hash:insert{103, 'value1 v1.0', 'value2 v1.0'} >-hash:insert{'invalid key', 'value1 v1.0', 'value2 v1.0'} >- >-------------------------------------------------------------------------------- >--- 64-bit hash replace fields tests >-------------------------------------------------------------------------------- >- >--- Replace valid fields >-hash:replace{3ULL, 'value1 v1.31', 'value2 1.12'} >-hash:replace{1ULL, 'value1 v1.32', 'value2 1.72'} >-hash:replace{2ULL, 'value1 v1.43', 'value2 1.92'} >- >--- Replace invalid fields >-hash:replace{3, 'value1 v1.31', 'value2 1.12'} >-hash:replace{1, 'value1 v1.32', 'value2 1.72'} >-hash:replace{2, 'value1 v1.43', 'value2 1.92'} >-hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'} >- >-------------------------------------------------------------------------------- >--- 64-bit hash select fields test >-------------------------------------------------------------------------------- >- >--- select by valid keys >-hash.index['primary']:get{0ULL} >-hash.index['primary']:get{1ULL} >-hash.index['primary']:get{2ULL} >-hash.index['primary']:get{3ULL} >-hash.index['primary']:get{4ULL} >-hash.index['primary']:get{5ULL} >- >--- select by valid NUM keys >-hash.index['primary']:get{0} >-hash.index['primary']:get{1} >-hash.index['primary']:get{2} >-hash.index['primary']:get{3} >-hash.index['primary']:get{4} >-hash.index['primary']:get{5} >- >--- select by invalid keys >-hash.index['primary']:get{'invalid key'} >-hash.index['primary']:get{'00000001', '00000002'} >- >-------------------------------------------------------------------------------- >--- 64-bit hash delete fields test >-------------------------------------------------------------------------------- >- >--- delete by valid keys >-hash:delete{0ULL} >-hash:delete{1ULL} >-hash:delete{2ULL} >-hash:delete{3ULL} >-hash:delete{4ULL} >-hash:delete{5ULL} >- >-hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'} >-hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'} >-hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'} >-hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'} >- >--- delete by valid NUM keys >-hash:delete{0} >-hash:delete{1} >-hash:delete{2} >-hash:delete{3} >-hash:delete{4} >-hash:delete{5} >- >--- delete by invalid keys >-hash:delete{'invalid key'} >-hash:delete{'00000001', '00000002'} >-hash:truncate() >- >---============================================================================= >--- String hash tests >---============================================================================= >-------------------------------------------------------------------------------- >--- String hash inset fields tests >-------------------------------------------------------------------------------- >-hash.index['primary']:drop() >-tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'string'}, unique = true }) >- >--- Insert valid fields >-hash:insert{'key 0', 'value1 v1.0', 'value2 v1.0'} >-hash:insert{'key 1', 'value1 v1.0', 'value2 v1.0'} >-hash:insert{'key 2', 'value1 v1.0', 'value2 v1.0'} >-hash:insert{'key 3', 'value1 v1.0', 'value2 v1.0'} >- >-------------------------------------------------------------------------------- >--- String hash replace fields tests >-------------------------------------------------------------------------------- >- >--- Replace valid fields >-hash:replace{'key 3', 'value1 v1.31', 'value2 1.12'} >-hash:replace{'key 1', 'value1 v1.32', 'value2 1.72'} >-hash:replace{'key 2', 'value1 v1.43', 'value2 1.92'} >- >-------------------------------------------------------------------------------- >--- String hash select fields test >-------------------------------------------------------------------------------- >- >--- select by valid keys >-hash.index['primary']:get{'key 0'} >-hash.index['primary']:get{'key 1'} >-hash.index['primary']:get{'key 2'} >-hash.index['primary']:get{'key 3'} >-hash.index['primary']:get{'key 4'} >-hash.index['primary']:get{'key 5'} >- >--- select by invalid keys >-hash.index['primary']:get{'key 1', 'key 2'} >- >-------------------------------------------------------------------------------- >--- String hash delete fields test >-------------------------------------------------------------------------------- >- >--- delete by valid keys >-hash:delete{'key 0'} >-hash:delete{'key 1'} >-hash:delete{'key 2'} >-hash:delete{'key 3'} >-hash:delete{'key 4'} >-hash:delete{'key 5'} >- >--- delete by invalid keys >-hash:delete{'key 1', 'key 2'} >-hash:truncate() >- >-------------------------------------------------------------------------------- >--- Collation test >-------------------------------------------------------------------------------- >-hash.index['primary']:drop() >-tmp = hash:create_index('primary', { type = 'hash', parts = {{1, 'string', collation = 'unicode_ci'}}, unique = true}) >-tmp = hash:create_index('secondary', { type = 'hash', parts = {{2, 'scalar', collation = 'unicode_ci'}}, unique = true}) >- >-hash:insert{'Ёж', 'Hedgehog'} >-hash:insert{'Ёлка', 'Spruce'} >-hash:insert{'Jogurt', 'Йогурт'} >-hash:insert{'Один', 1} >- >-hash.index.primary:get('ёж') >-hash.index.primary:get('елка') >-hash.index.secondary:get('spruce') >-hash.index.secondary:get('йогурт') >-hash.index.secondary:get(1) >-hash.index.secondary:get('иогурт') >-hash.index.secondary:get(2) >- >------------------------- >--- hash::replace tests >------------------------- >-hash.index['secondary']:drop() >-hash.index['primary']:drop() >-tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >-tmp = hash:create_index('field1', { type = 'hash', parts = {2, 'unsigned'}, unique = true }) >-tmp = hash:create_index('field2', { type = 'hash', parts = {3, 'unsigned'}, unique = true }) >-tmp = hash:create_index('field3', { type = 'hash', parts = {4, 'unsigned'}, unique = true }) >- >-hash:insert{0, 0, 0, 0} >-hash:insert{1, 1, 1, 1} >-hash:insert{2, 2, 2, 2} >- >--- OK >-hash:replace{1, 1, 1, 1} >-hash.index['primary']:get{10} >-hash.index['field1']:get{10} >-hash.index['field2']:get{10} >-hash.index['field3']:get{10} >-hash.index['primary']:get{1} >-hash.index['field1']:get{1} >-hash.index['field2']:get{1} >-hash.index['field3']:get{1} >- >--- OK >-hash:insert{10, 10, 10, 10} >-hash:delete{10} >-hash.index['primary']:get{10} >-hash.index['field1']:get{10} >-hash.index['field2']:get{10} >-hash.index['field3']:get{10} >- >--- TupleFound (primary key) >-hash:insert{1, 10, 10, 10} >-hash.index['primary']:get{10} >-hash.index['field1']:get{10} >-hash.index['field2']:get{10} >-hash.index['field3']:get{10} >-hash.index['primary']:get{1} >- >--- TupleNotFound (primary key) >-hash:replace{10, 10, 10, 10} >-hash.index['primary']:get{10} >-hash.index['field1']:get{10} >-hash.index['field2']:get{10} >-hash.index['field3']:get{10} >- >--- TupleFound (key --1) >-hash:insert{10, 0, 10, 10} >-hash.index['primary']:get{10} >-hash.index['field1']:get{10} >-hash.index['field2']:get{10} >-hash.index['field3']:get{10} >-hash.index['field1']:get{0} >- >--- TupleFound (key --1) >--- hash:replace_if_exists(2, 0, 10, 10) >-hash.index['primary']:get{10} >-hash.index['field1']:get{10} >-hash.index['field2']:get{10} >-hash.index['field3']:get{10} >-hash.index['field1']:get{0} >- >--- TupleFound (key --3) >-hash:insert{10, 10, 10, 0} >-hash.index['primary']:get{10} >-hash.index['field1']:get{10} >-hash.index['field2']:get{10} >-hash.index['field3']:get{10} >-hash.index['field3']:get{0} >- >--- TupleFound (key --3) >--- hash:replace_if_exists(2, 10, 10, 0) >-hash.index['primary']:get{10} >-hash.index['field1']:get{10} >-hash.index['field2']:get{10} >-hash.index['field3']:get{10} >-hash.index['field3']:get{0} >- >-hash:drop() >- >-hash = box.schema.space.create('tweedledum') >-hi = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >-hash:insert{0} >-hash:insert{16} >-for _, tuple in hi:pairs(nil, {iterator = box.index.ALL}) do hash:delete{tuple[1]} end >-hash:drop() >- >--- >--- gh-616 "1-based indexing and 0-based error message >--- >-_ = box.schema.create_space('test') >-_ = box.space.test:create_index('i',{parts={1,'string'}}) >-box.space.test:insert{1} >-box.space.test:drop() >- >--- gh-1467: invalid iterator type >-space = box.schema.space.create('test') >-index = space:create_index('primary', { type = 'hash' }) >-space:select({1}, {iterator = 'BITS_ALL_SET' } ) >-space:drop() >- >--- gh-3907: check that integer numbers stored as MP_FLOAT/MP_DOUBLE >--- are hashed as MP_INT/MP_UINT. >-ffi = require('ffi') >-s = box.schema.space.create('test') >-_ = s:create_index('primary', {type = 'hash', parts = {1, 'number'}}) >-s:insert{ffi.new('double', 0)} >-s:insert{ffi.new('double', -1)} >-s:insert{ffi.new('double', 9007199254740992)} >-s:insert{ffi.new('double', -9007199254740994)} >-s:get(0LL) >-s:get(-1LL) >-s:get(9007199254740992LL) >-s:get(-9007199254740994LL) >-s:drop() >- >--- Hash index cannot be multikey. >-s = box.schema.space.create('test') >-_ = s:create_index('primary') >-_ = s:create_index('hash', {type = 'hash', parts = {{'[2][*]', 'unsigned'}}}) >-s:drop() >- >--- Hash index can not use function. >-s = box.schema.space.create('withdata') >-lua_code = [[function(tuple) return tuple[1] + tuple[2] end]] >-box.schema.func.create('s', {body = lua_code, is_deterministic = true, is_sandboxed = true}) >-_ = s:create_index('pk') >-_ = s:create_index('idx', {type = 'hash', func = box.func.s.id, parts = {{1, 'unsigned'}}}) >-s:drop() >-box.schema.func.drop('s') >diff --git a/test/box/hash_32bit_delete.result b/test/box/hash_32bit_delete.result >new file mode 100644 >index 000000000..b35143b10 >--- /dev/null >+++ b/test/box/hash_32bit_delete.result >@@ -0,0 +1,70 @@ >+-- test-run result file version 2 >+------------------------------------------------------------------------------- >+-- 32-bit hash insert fields tests >+------------------------------------------------------------------------------- >+hash = box.schema.space.create('tweedledum') >+ | --- >+ | ... >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+ | --- >+ | ... >+ >+-- Insert valid fields >+hash:insert{0, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [0, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{1, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [1, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{2, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [2, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{3, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [3, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+ >+------------------------------------------------------------------------------- >+-- 32-bit hash delete fields test >+------------------------------------------------------------------------------- >+ >+-- delete by valid keys >+hash:delete{0} >+ | --- >+ | - [0, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:delete{1} >+ | --- >+ | - [1, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:delete{2} >+ | --- >+ | - [2, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:delete{3} >+ | --- >+ | - [3, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:delete{4} >+ | --- >+ | ... >+hash:delete{5} >+ | --- >+ | ... >+ >+-- delete by invalid keys >+hash:delete{'invalid key'} >+ | --- >+ | - error: 'Supplied key type of part 0 does not match index part type: expected unsigned' >+ | ... >+hash:delete{1, 2} >+ | --- >+ | - error: Invalid key part count in an exact match (expected 1, got 2) >+ | ... >+ >+hash:drop() >+ | --- >+ | ... >diff --git a/test/box/hash_32bit_delete.test.lua b/test/box/hash_32bit_delete.test.lua >new file mode 100644 >index 000000000..682e0bc96 >--- /dev/null >+++ b/test/box/hash_32bit_delete.test.lua >@@ -0,0 +1,29 @@ >+------------------------------------------------------------------------------- >+-- 32-bit hash insert fields tests >+------------------------------------------------------------------------------- >+hash = box.schema.space.create('tweedledum') >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+ >+-- Insert valid fields >+hash:insert{0, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{1, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{2, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{3, 'value1 v1.0', 'value2 v1.0'} >+ >+------------------------------------------------------------------------------- >+-- 32-bit hash delete fields test >+------------------------------------------------------------------------------- >+ >+-- delete by valid keys >+hash:delete{0} >+hash:delete{1} >+hash:delete{2} >+hash:delete{3} >+hash:delete{4} >+hash:delete{5} >+ >+-- delete by invalid keys >+hash:delete{'invalid key'} >+hash:delete{1, 2} >+ >+hash:drop() >diff --git a/test/box/hash_32bit_insert.result b/test/box/hash_32bit_insert.result >new file mode 100644 >index 000000000..72c7c4842 >--- /dev/null >+++ b/test/box/hash_32bit_insert.result >@@ -0,0 +1,38 @@ >+-- test-run result file version 2 >+------------------------------------------------------------------------------- >+-- 32-bit hash insert fields tests >+------------------------------------------------------------------------------- >+hash = box.schema.space.create('tweedledum') >+ | --- >+ | ... >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+ | --- >+ | ... >+ >+-- Insert valid fields >+hash:insert{0, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [0, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{1, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [1, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{2, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [2, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{3, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [3, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+ >+-- Insert invalid fields >+hash:insert{'invalid key', 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - error: 'Tuple field 1 type does not match one required by operation: expected unsigned' >+ | ... >+ >+hash:drop() >+ | --- >+ | ... >diff --git a/test/box/hash_32bit_insert.test.lua b/test/box/hash_32bit_insert.test.lua >new file mode 100644 >index 000000000..308b27d3e >--- /dev/null >+++ b/test/box/hash_32bit_insert.test.lua >@@ -0,0 +1,16 @@ >+------------------------------------------------------------------------------- >+-- 32-bit hash insert fields tests >+------------------------------------------------------------------------------- >+hash = box.schema.space.create('tweedledum') >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+ >+-- Insert valid fields >+hash:insert{0, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{1, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{2, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{3, 'value1 v1.0', 'value2 v1.0'} >+ >+-- Insert invalid fields >+hash:insert{'invalid key', 'value1 v1.0', 'value2 v1.0'} >+ >+hash:drop() >diff --git a/test/box/hash_32bit_replace.result b/test/box/hash_32bit_replace.result >new file mode 100644 >index 000000000..a1feba851 >--- /dev/null >+++ b/test/box/hash_32bit_replace.result >@@ -0,0 +1,56 @@ >+-- test-run result file version 2 >+------------------------------------------------------------------------------- >+-- 32-bit hash insert fields tests >+------------------------------------------------------------------------------- >+hash = box.schema.space.create('tweedledum') >+ | --- >+ | ... >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+ | --- >+ | ... >+ >+-- Insert valid fields >+hash:insert{0, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [0, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{1, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [1, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{2, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [2, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{3, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [3, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+ >+------------------------------------------------------------------------------- >+-- 32-bit hash replace fields tests >+------------------------------------------------------------------------------- >+ >+-- Replace valid fields >+hash:replace{3, 'value1 v1.31', 'value2 1.12'} >+ | --- >+ | - [3, 'value1 v1.31', 'value2 1.12'] >+ | ... >+hash:replace{1, 'value1 v1.32', 'value2 1.72'} >+ | --- >+ | - [1, 'value1 v1.32', 'value2 1.72'] >+ | ... >+hash:replace{2, 'value1 v1.43', 'value2 1.92'} >+ | --- >+ | - [2, 'value1 v1.43', 'value2 1.92'] >+ | ... >+ >+-- Replace invalid fields >+hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - error: 'Tuple field 1 type does not match one required by operation: expected unsigned' >+ | ... >+ >+hash:drop() >+ | --- >+ | ... >diff --git a/test/box/hash_32bit_replace.test.lua b/test/box/hash_32bit_replace.test.lua >new file mode 100644 >index 000000000..a00b02185 >--- /dev/null >+++ b/test/box/hash_32bit_replace.test.lua >@@ -0,0 +1,25 @@ >+------------------------------------------------------------------------------- >+-- 32-bit hash insert fields tests >+------------------------------------------------------------------------------- >+hash = box.schema.space.create('tweedledum') >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+ >+-- Insert valid fields >+hash:insert{0, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{1, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{2, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{3, 'value1 v1.0', 'value2 v1.0'} >+ >+------------------------------------------------------------------------------- >+-- 32-bit hash replace fields tests >+------------------------------------------------------------------------------- >+ >+-- Replace valid fields >+hash:replace{3, 'value1 v1.31', 'value2 1.12'} >+hash:replace{1, 'value1 v1.32', 'value2 1.72'} >+hash:replace{2, 'value1 v1.43', 'value2 1.92'} >+ >+-- Replace invalid fields >+hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'} >+ >+hash:drop() >diff --git a/test/box/hash_32bit_select.result b/test/box/hash_32bit_select.result >new file mode 100644 >index 000000000..f80df9bbd >--- /dev/null >+++ b/test/box/hash_32bit_select.result >@@ -0,0 +1,70 @@ >+-- test-run result file version 2 >+------------------------------------------------------------------------------- >+-- 32-bit hash insert fields tests >+------------------------------------------------------------------------------- >+hash = box.schema.space.create('tweedledum') >+ | --- >+ | ... >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+ | --- >+ | ... >+ >+-- Insert valid fields >+hash:insert{0, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [0, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{1, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [1, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{2, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [2, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{3, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [3, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+ >+------------------------------------------------------------------------------- >+-- 32-bit hash select fields test >+------------------------------------------------------------------------------- >+ >+-- select by valid keys >+hash.index['primary']:get{0} >+ | --- >+ | - [0, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash.index['primary']:get{1} >+ | --- >+ | - [1, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash.index['primary']:get{2} >+ | --- >+ | - [2, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash.index['primary']:get{3} >+ | --- >+ | - [3, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash.index['primary']:get{4} >+ | --- >+ | ... >+hash.index['primary']:get{5} >+ | --- >+ | ... >+ >+-- select by invalid keys >+hash.index['primary']:get{'invalid key'} >+ | --- >+ | - error: 'Supplied key type of part 0 does not match index part type: expected unsigned' >+ | ... >+hash.index['primary']:get{1, 2} >+ | --- >+ | - error: Invalid key part count in an exact match (expected 1, got 2) >+ | ... >+ >+hash:drop() >+ | --- >+ | ... >diff --git a/test/box/hash_32bit_select.test.lua b/test/box/hash_32bit_select.test.lua >new file mode 100644 >index 000000000..e077cc48d >--- /dev/null >+++ b/test/box/hash_32bit_select.test.lua >@@ -0,0 +1,29 @@ >+------------------------------------------------------------------------------- >+-- 32-bit hash insert fields tests >+------------------------------------------------------------------------------- >+hash = box.schema.space.create('tweedledum') >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+ >+-- Insert valid fields >+hash:insert{0, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{1, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{2, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{3, 'value1 v1.0', 'value2 v1.0'} >+ >+------------------------------------------------------------------------------- >+-- 32-bit hash select fields test >+------------------------------------------------------------------------------- >+ >+-- select by valid keys >+hash.index['primary']:get{0} >+hash.index['primary']:get{1} >+hash.index['primary']:get{2} >+hash.index['primary']:get{3} >+hash.index['primary']:get{4} >+hash.index['primary']:get{5} >+ >+-- select by invalid keys >+hash.index['primary']:get{'invalid key'} >+hash.index['primary']:get{1, 2} >+ >+hash:drop() >diff --git a/test/box/hash_64bit_delete.result b/test/box/hash_64bit_delete.result >new file mode 100644 >index 000000000..88079e6f2 >--- /dev/null >+++ b/test/box/hash_64bit_delete.result >@@ -0,0 +1,111 @@ >+-- test-run result file version 2 >+------------------------------------------------------------------------------- >+-- 64-bit hash insert fields tests >+------------------------------------------------------------------------------- >+hash = box.schema.space.create('tweedledum') >+ | --- >+ | ... >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+ | --- >+ | ... >+ >+-- Insert valid fields >+hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [0, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [1, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [2, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [3, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+ >+------------------------------------------------------------------------------- >+-- 64-bit hash delete fields test >+------------------------------------------------------------------------------- >+ >+-- delete by valid keys >+hash:delete{0ULL} >+ | --- >+ | - [0, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:delete{1ULL} >+ | --- >+ | - [1, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:delete{2ULL} >+ | --- >+ | - [2, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:delete{3ULL} >+ | --- >+ | - [3, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:delete{4ULL} >+ | --- >+ | ... >+hash:delete{5ULL} >+ | --- >+ | ... >+ >+hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [0, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [1, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [2, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [3, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+ >+-- delete by valid NUM keys >+hash:delete{0} >+ | --- >+ | - [0, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:delete{1} >+ | --- >+ | - [1, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:delete{2} >+ | --- >+ | - [2, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:delete{3} >+ | --- >+ | - [3, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:delete{4} >+ | --- >+ | ... >+hash:delete{5} >+ | --- >+ | ... >+ >+-- delete by invalid keys >+hash:delete{'invalid key'} >+ | --- >+ | - error: 'Supplied key type of part 0 does not match index part type: expected unsigned' >+ | ... >+hash:delete{'00000001', '00000002'} >+ | --- >+ | - error: Invalid key part count in an exact match (expected 1, got 2) >+ | ... >+ >+hash:drop() >+ | --- >+ | ... >diff --git a/test/box/hash_64bit_delete.test.lua b/test/box/hash_64bit_delete.test.lua >new file mode 100644 >index 000000000..75675381f >--- /dev/null >+++ b/test/box/hash_64bit_delete.test.lua >@@ -0,0 +1,42 @@ >+------------------------------------------------------------------------------- >+-- 64-bit hash insert fields tests >+------------------------------------------------------------------------------- >+hash = box.schema.space.create('tweedledum') >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+ >+-- Insert valid fields >+hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'} >+ >+------------------------------------------------------------------------------- >+-- 64-bit hash delete fields test >+------------------------------------------------------------------------------- >+ >+-- delete by valid keys >+hash:delete{0ULL} >+hash:delete{1ULL} >+hash:delete{2ULL} >+hash:delete{3ULL} >+hash:delete{4ULL} >+hash:delete{5ULL} >+ >+hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'} >+ >+-- delete by valid NUM keys >+hash:delete{0} >+hash:delete{1} >+hash:delete{2} >+hash:delete{3} >+hash:delete{4} >+hash:delete{5} >+ >+-- delete by invalid keys >+hash:delete{'invalid key'} >+hash:delete{'00000001', '00000002'} >+ >+hash:drop() >diff --git a/test/box/hash_64bit_insert.result b/test/box/hash_64bit_insert.result >new file mode 100644 >index 000000000..3f1275576 >--- /dev/null >+++ b/test/box/hash_64bit_insert.result >@@ -0,0 +1,54 @@ >+-- test-run result file version 2 >+------------------------------------------------------------------------------- >+-- 64-bit hash insert fields tests >+------------------------------------------------------------------------------- >+hash = box.schema.space.create('tweedledum') >+ | --- >+ | ... >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+ | --- >+ | ... >+ >+-- Insert valid fields >+hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [0, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [1, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [2, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [3, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+ >+-- Insert invalid fields >+hash:insert{100, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [100, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{101, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [101, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{102, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [102, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{103, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [103, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{'invalid key', 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - error: 'Tuple field 1 type does not match one required by operation: expected unsigned' >+ | ... >+ >+hash:drop() >+ | --- >+ | ... >diff --git a/test/box/hash_64bit_insert.test.lua b/test/box/hash_64bit_insert.test.lua >new file mode 100644 >index 000000000..c69214b4e >--- /dev/null >+++ b/test/box/hash_64bit_insert.test.lua >@@ -0,0 +1,20 @@ >+------------------------------------------------------------------------------- >+-- 64-bit hash insert fields tests >+------------------------------------------------------------------------------- >+hash = box.schema.space.create('tweedledum') >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+ >+-- Insert valid fields >+hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'} >+ >+-- Insert invalid fields >+hash:insert{100, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{101, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{102, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{103, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{'invalid key', 'value1 v1.0', 'value2 v1.0'} >+ >+hash:drop() >diff --git a/test/box/hash_64bit_replace.result b/test/box/hash_64bit_replace.result >new file mode 100644 >index 000000000..0bf900818 >--- /dev/null >+++ b/test/box/hash_64bit_replace.result >@@ -0,0 +1,68 @@ >+-- test-run result file version 2 >+------------------------------------------------------------------------------- >+-- 64-bit hash insert fields tests >+------------------------------------------------------------------------------- >+hash = box.schema.space.create('tweedledum') >+ | --- >+ | ... >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+ | --- >+ | ... >+ >+-- Insert valid fields >+hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [0, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [1, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [2, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [3, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+ >+------------------------------------------------------------------------------- >+-- 64-bit hash replace fields tests >+------------------------------------------------------------------------------- >+ >+-- Replace valid fields >+hash:replace{3ULL, 'value1 v1.31', 'value2 1.12'} >+ | --- >+ | - [3, 'value1 v1.31', 'value2 1.12'] >+ | ... >+hash:replace{1ULL, 'value1 v1.32', 'value2 1.72'} >+ | --- >+ | - [1, 'value1 v1.32', 'value2 1.72'] >+ | ... >+hash:replace{2ULL, 'value1 v1.43', 'value2 1.92'} >+ | --- >+ | - [2, 'value1 v1.43', 'value2 1.92'] >+ | ... >+ >+-- Replace invalid fields >+hash:replace{3, 'value1 v1.31', 'value2 1.12'} >+ | --- >+ | - [3, 'value1 v1.31', 'value2 1.12'] >+ | ... >+hash:replace{1, 'value1 v1.32', 'value2 1.72'} >+ | --- >+ | - [1, 'value1 v1.32', 'value2 1.72'] >+ | ... >+hash:replace{2, 'value1 v1.43', 'value2 1.92'} >+ | --- >+ | - [2, 'value1 v1.43', 'value2 1.92'] >+ | ... >+hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - error: 'Tuple field 1 type does not match one required by operation: expected unsigned' >+ | ... >+ >+hash:drop() >+ | --- >+ | ... >diff --git a/test/box/hash_64bit_replace.test.lua b/test/box/hash_64bit_replace.test.lua >new file mode 100644 >index 000000000..4213110bc >--- /dev/null >+++ b/test/box/hash_64bit_replace.test.lua >@@ -0,0 +1,28 @@ >+------------------------------------------------------------------------------- >+-- 64-bit hash insert fields tests >+------------------------------------------------------------------------------- >+hash = box.schema.space.create('tweedledum') >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+ >+-- Insert valid fields >+hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'} >+ >+------------------------------------------------------------------------------- >+-- 64-bit hash replace fields tests >+------------------------------------------------------------------------------- >+ >+-- Replace valid fields >+hash:replace{3ULL, 'value1 v1.31', 'value2 1.12'} >+hash:replace{1ULL, 'value1 v1.32', 'value2 1.72'} >+hash:replace{2ULL, 'value1 v1.43', 'value2 1.92'} >+ >+-- Replace invalid fields >+hash:replace{3, 'value1 v1.31', 'value2 1.12'} >+hash:replace{1, 'value1 v1.32', 'value2 1.72'} >+hash:replace{2, 'value1 v1.43', 'value2 1.92'} >+hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'} >+ >+hash:drop() >diff --git a/test/box/hash_64bit_select.result b/test/box/hash_64bit_select.result >new file mode 100644 >index 000000000..74dd56727 >--- /dev/null >+++ b/test/box/hash_64bit_select.result >@@ -0,0 +1,94 @@ >+-- test-run result file version 2 >+------------------------------------------------------------------------------- >+-- 64-bit hash insert fields tests >+------------------------------------------------------------------------------- >+hash = box.schema.space.create('tweedledum') >+ | --- >+ | ... >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+ | --- >+ | ... >+ >+-- Insert valid fields >+hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [0, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [1, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [2, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - [3, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+ >+------------------------------------------------------------------------------- >+-- 64-bit hash select fields test >+------------------------------------------------------------------------------- >+ >+-- select by valid keys >+hash.index['primary']:get{0ULL} >+ | --- >+ | - [0, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash.index['primary']:get{1ULL} >+ | --- >+ | - [1, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash.index['primary']:get{2ULL} >+ | --- >+ | - [2, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash.index['primary']:get{3ULL} >+ | --- >+ | - [3, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash.index['primary']:get{4ULL} >+ | --- >+ | ... >+hash.index['primary']:get{5ULL} >+ | --- >+ | ... >+ >+-- select by valid NUM keys >+hash.index['primary']:get{0} >+ | --- >+ | - [0, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash.index['primary']:get{1} >+ | --- >+ | - [1, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash.index['primary']:get{2} >+ | --- >+ | - [2, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash.index['primary']:get{3} >+ | --- >+ | - [3, 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash.index['primary']:get{4} >+ | --- >+ | ... >+hash.index['primary']:get{5} >+ | --- >+ | ... >+ >+-- select by invalid keys >+hash.index['primary']:get{'invalid key'} >+ | --- >+ | - error: 'Supplied key type of part 0 does not match index part type: expected unsigned' >+ | ... >+hash.index['primary']:get{'00000001', '00000002'} >+ | --- >+ | - error: Invalid key part count in an exact match (expected 1, got 2) >+ | ... >+ >+hash:drop() >+ | --- >+ | ... >diff --git a/test/box/hash_64bit_select.test.lua b/test/box/hash_64bit_select.test.lua >new file mode 100644 >index 000000000..724fb24be >--- /dev/null >+++ b/test/box/hash_64bit_select.test.lua >@@ -0,0 +1,37 @@ >+------------------------------------------------------------------------------- >+-- 64-bit hash insert fields tests >+------------------------------------------------------------------------------- >+hash = box.schema.space.create('tweedledum') >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+ >+-- Insert valid fields >+hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'} >+hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'} >+ >+------------------------------------------------------------------------------- >+-- 64-bit hash select fields test >+------------------------------------------------------------------------------- >+ >+-- select by valid keys >+hash.index['primary']:get{0ULL} >+hash.index['primary']:get{1ULL} >+hash.index['primary']:get{2ULL} >+hash.index['primary']:get{3ULL} >+hash.index['primary']:get{4ULL} >+hash.index['primary']:get{5ULL} >+ >+-- select by valid NUM keys >+hash.index['primary']:get{0} >+hash.index['primary']:get{1} >+hash.index['primary']:get{2} >+hash.index['primary']:get{3} >+hash.index['primary']:get{4} >+hash.index['primary']:get{5} >+ >+-- select by invalid keys >+hash.index['primary']:get{'invalid key'} >+hash.index['primary']:get{'00000001', '00000002'} >+ >+hash:drop() >diff --git a/test/box/hash_collation.result b/test/box/hash_collation.result >new file mode 100644 >index 000000000..ea80b577d >--- /dev/null >+++ b/test/box/hash_collation.result >@@ -0,0 +1,62 @@ >+-- test-run result file version 2 >+------------------------------------------------------------------------------- >+-- Collation test >+------------------------------------------------------------------------------- >+ >+hash = box.schema.space.create('tweedledum') >+ | --- >+ | ... >+tmp = hash:create_index('primary', { type = 'hash', parts = {{1, 'string', collation = 'unicode_ci'}}, unique = true}) >+ | --- >+ | ... >+tmp = hash:create_index('secondary', { type = 'hash', parts = {{2, 'scalar', collation = 'unicode_ci'}}, unique = true}) >+ | --- >+ | ... >+ >+hash:insert{'Ёж', 'Hedgehog'} >+ | --- >+ | - ['Ёж', 'Hedgehog'] >+ | ... >+hash:insert{'Ёлка', 'Spruce'} >+ | --- >+ | - ['Ёлка', 'Spruce'] >+ | ... >+hash:insert{'Jogurt', 'Йогурт'} >+ | --- >+ | - ['Jogurt', 'Йогурт'] >+ | ... >+hash:insert{'Один', 1} >+ | --- >+ | - ['Один', 1] >+ | ... >+ >+hash.index.primary:get('ёж') >+ | --- >+ | - ['Ёж', 'Hedgehog'] >+ | ... >+hash.index.primary:get('елка') >+ | --- >+ | - ['Ёлка', 'Spruce'] >+ | ... >+hash.index.secondary:get('spruce') >+ | --- >+ | - ['Ёлка', 'Spruce'] >+ | ... >+hash.index.secondary:get('йогурт') >+ | --- >+ | - ['Jogurt', 'Йогурт'] >+ | ... >+hash.index.secondary:get(1) >+ | --- >+ | - ['Один', 1] >+ | ... >+hash.index.secondary:get('иогурт') >+ | --- >+ | ... >+hash.index.secondary:get(2) >+ | --- >+ | ... >+ >+hash:drop() >+ | --- >+ | ... >diff --git a/test/box/hash_collation.test.lua b/test/box/hash_collation.test.lua >new file mode 100644 >index 000000000..f9bca79f6 >--- /dev/null >+++ b/test/box/hash_collation.test.lua >@@ -0,0 +1,22 @@ >+------------------------------------------------------------------------------- >+-- Collation test >+------------------------------------------------------------------------------- >+ >+hash = box.schema.space.create('tweedledum') >+tmp = hash:create_index('primary', { type = 'hash', parts = {{1, 'string', collation = 'unicode_ci'}}, unique = true}) >+tmp = hash:create_index('secondary', { type = 'hash', parts = {{2, 'scalar', collation = 'unicode_ci'}}, unique = true}) >+ >+hash:insert{'Ёж', 'Hedgehog'} >+hash:insert{'Ёлка', 'Spruce'} >+hash:insert{'Jogurt', 'Йогурт'} >+hash:insert{'Один', 1} >+ >+hash.index.primary:get('ёж') >+hash.index.primary:get('елка') >+hash.index.secondary:get('spruce') >+hash.index.secondary:get('йогурт') >+hash.index.secondary:get(1) >+hash.index.secondary:get('иогурт') >+hash.index.secondary:get(2) >+ >+hash:drop() >diff --git a/test/box/hash_gh-1467.result b/test/box/hash_gh-1467.result >new file mode 100644 >index 000000000..a2c736a11 >--- /dev/null >+++ b/test/box/hash_gh-1467.result >@@ -0,0 +1,17 @@ >+-- test-run result file version 2 >+-- gh-1467: invalid iterator type >+ >+space = box.schema.space.create('test') >+ | --- >+ | ... >+index = space:create_index('primary', { type = 'hash' }) >+ | --- >+ | ... >+space:select({1}, {iterator = 'BITS_ALL_SET' } ) >+ | --- >+ | - error: Index 'primary' (HASH) of space 'test' (memtx) does not support requested >+ | iterator type >+ | ... >+space:drop() >+ | --- >+ | ... >diff --git a/test/box/hash_gh-1467.test.lua b/test/box/hash_gh-1467.test.lua >new file mode 100644 >index 000000000..d98c31734 >--- /dev/null >+++ b/test/box/hash_gh-1467.test.lua >@@ -0,0 +1,6 @@ >+-- gh-1467: invalid iterator type >+ >+space = box.schema.space.create('test') >+index = space:create_index('primary', { type = 'hash' }) >+space:select({1}, {iterator = 'BITS_ALL_SET' } ) >+space:drop() >diff --git a/test/box/hash_gh-3907.result b/test/box/hash_gh-3907.result >new file mode 100644 >index 000000000..4ce7e40f4 >--- /dev/null >+++ b/test/box/hash_gh-3907.result >@@ -0,0 +1,48 @@ >+-- test-run result file version 2 >+-- gh-3907: check that integer numbers stored as MP_FLOAT/MP_DOUBLE >+-- are hashed as MP_INT/MP_UINT. >+ >+ffi = require('ffi') >+ | --- >+ | ... >+s = box.schema.space.create('test') >+ | --- >+ | ... >+_ = s:create_index('primary', {type = 'hash', parts = {1, 'number'}}) >+ | --- >+ | ... >+s:insert{ffi.new('double', 0)} >+ | --- >+ | - [0] >+ | ... >+s:insert{ffi.new('double', -1)} >+ | --- >+ | - [-1] >+ | ... >+s:insert{ffi.new('double', 9007199254740992)} >+ | --- >+ | - [9007199254740992] >+ | ... >+s:insert{ffi.new('double', -9007199254740994)} >+ | --- >+ | - [-9007199254740994] >+ | ... >+s:get(0LL) >+ | --- >+ | - [0] >+ | ... >+s:get(-1LL) >+ | --- >+ | - [-1] >+ | ... >+s:get(9007199254740992LL) >+ | --- >+ | - [9007199254740992] >+ | ... >+s:get(-9007199254740994LL) >+ | --- >+ | - [-9007199254740994] >+ | ... >+s:drop() >+ | --- >+ | ... >diff --git a/test/box/hash_gh-3907.test.lua b/test/box/hash_gh-3907.test.lua >new file mode 100644 >index 000000000..2bef03b0d >--- /dev/null >+++ b/test/box/hash_gh-3907.test.lua >@@ -0,0 +1,15 @@ >+-- gh-3907: check that integer numbers stored as MP_FLOAT/MP_DOUBLE >+-- are hashed as MP_INT/MP_UINT. >+ >+ffi = require('ffi') >+s = box.schema.space.create('test') >+_ = s:create_index('primary', {type = 'hash', parts = {1, 'number'}}) >+s:insert{ffi.new('double', 0)} >+s:insert{ffi.new('double', -1)} >+s:insert{ffi.new('double', 9007199254740992)} >+s:insert{ffi.new('double', -9007199254740994)} >+s:get(0LL) >+s:get(-1LL) >+s:get(9007199254740992LL) >+s:get(-9007199254740994LL) >+s:drop() >diff --git a/test/box/hash_gh-616.result b/test/box/hash_gh-616.result >new file mode 100644 >index 000000000..d5ee1eed9 >--- /dev/null >+++ b/test/box/hash_gh-616.result >@@ -0,0 +1,17 @@ >+-- test-run result file version 2 >+-- >+-- gh-616 "1-based indexing and 0-based error message >+-- >+_ = box.schema.create_space('test') >+ | --- >+ | ... >+_ = box.space.test:create_index('i',{parts={1,'string'}}) >+ | --- >+ | ... >+box.space.test:insert{1} >+ | --- >+ | - error: 'Tuple field 1 type does not match one required by operation: expected string' >+ | ... >+box.space.test:drop() >+ | --- >+ | ... >diff --git a/test/box/hash_gh-616.test.lua b/test/box/hash_gh-616.test.lua >new file mode 100644 >index 000000000..8ea5f725a >--- /dev/null >+++ b/test/box/hash_gh-616.test.lua >@@ -0,0 +1,7 @@ >+-- >+-- gh-616 "1-based indexing and 0-based error message >+-- >+_ = box.schema.create_space('test') >+_ = box.space.test:create_index('i',{parts={1,'string'}}) >+box.space.test:insert{1} >+box.space.test:drop() >diff --git a/test/box/hash_iterate.result b/test/box/hash_iterate.result >new file mode 100644 >index 000000000..64660ad6d >--- /dev/null >+++ b/test/box/hash_iterate.result >@@ -0,0 +1,21 @@ >+-- test-run result file version 2 >+hash = box.schema.space.create('tweedledum') >+ | --- >+ | ... >+hi = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+ | --- >+ | ... >+hash:insert{0} >+ | --- >+ | - [0] >+ | ... >+hash:insert{16} >+ | --- >+ | - [16] >+ | ... >+for _, tuple in hi:pairs(nil, {iterator = box.index.ALL}) do hash:delete{tuple[1]} end >+ | --- >+ | ... >+hash:drop() >+ | --- >+ | ... >diff --git a/test/box/hash_iterate.test.lua b/test/box/hash_iterate.test.lua >new file mode 100644 >index 000000000..1ee758a66 >--- /dev/null >+++ b/test/box/hash_iterate.test.lua >@@ -0,0 +1,6 @@ >+hash = box.schema.space.create('tweedledum') >+hi = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+hash:insert{0} >+hash:insert{16} >+for _, tuple in hi:pairs(nil, {iterator = box.index.ALL}) do hash:delete{tuple[1]} end >+hash:drop() >diff --git a/test/box/hash_multipart.result b/test/box/hash_multipart.result >index 3de8ee3be..e94313b62 100644 >--- a/test/box/hash_multipart.result >+++ b/test/box/hash_multipart.result >@@ -131,13 +131,6 @@ hash.index['unique']:select{1, 'baz'} > - error: 'Supplied key type of part 1 does not match index part type: expected unsigned' > ... > -- cleanup >-hash:truncate() >---- >-... >-hash:len() >---- >-- 0 >-... > hash:drop() > --- > ... >diff --git a/test/box/hash_multipart.test.lua b/test/box/hash_multipart.test.lua >index 8b40504b1..c0a871bee 100644 >--- a/test/box/hash_multipart.test.lua >+++ b/test/box/hash_multipart.test.lua >@@ -53,6 +53,4 @@ hash.index['unique']:get{1} > hash.index['unique']:select{1, 'baz'} >  > -- cleanup >-hash:truncate() >-hash:len() > hash:drop() >diff --git a/test/box/hash_not_a_multikey.result b/test/box/hash_not_a_multikey.result >new file mode 100644 >index 000000000..334aa676d >--- /dev/null >+++ b/test/box/hash_not_a_multikey.result >@@ -0,0 +1,17 @@ >+-- test-run result file version 2 >+-- Hash index cannot be multikey. >+ >+s = box.schema.space.create('test') >+ | --- >+ | ... >+_ = s:create_index('primary') >+ | --- >+ | ... >+_ = s:create_index('hash', {type = 'hash', parts = {{'[2][*]', 'unsigned'}}}) >+ | --- >+ | - error: 'Can''t create or modify index ''hash'' in space ''test'': HASH index cannot >+ | be multikey' >+ | ... >+s:drop() >+ | --- >+ | ... >diff --git a/test/box/hash_not_a_multikey.test.lua b/test/box/hash_not_a_multikey.test.lua >new file mode 100644 >index 000000000..bd82dfb83 >--- /dev/null >+++ b/test/box/hash_not_a_multikey.test.lua >@@ -0,0 +1,6 @@ >+-- Hash index cannot be multikey. >+ >+s = box.schema.space.create('test') >+_ = s:create_index('primary') >+_ = s:create_index('hash', {type = 'hash', parts = {{'[2][*]', 'unsigned'}}}) >+s:drop() >diff --git a/test/box/hash_replace.result b/test/box/hash_replace.result >new file mode 100644 >index 000000000..1b45f7914 >--- /dev/null >+++ b/test/box/hash_replace.result >@@ -0,0 +1,256 @@ >+-- test-run result file version 2 >+------------------------ >+-- hash::replace tests >+------------------------ >+ >+hash = box.schema.space.create('tweedledum') >+ | --- >+ | ... >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+ | --- >+ | ... >+tmp = hash:create_index('field1', { type = 'hash', parts = {2, 'unsigned'}, unique = true }) >+ | --- >+ | ... >+tmp = hash:create_index('field2', { type = 'hash', parts = {3, 'unsigned'}, unique = true }) >+ | --- >+ | ... >+tmp = hash:create_index('field3', { type = 'hash', parts = {4, 'unsigned'}, unique = true }) >+ | --- >+ | ... >+ >+hash:insert{0, 0, 0, 0} >+ | --- >+ | - [0, 0, 0, 0] >+ | ... >+hash:insert{1, 1, 1, 1} >+ | --- >+ | - [1, 1, 1, 1] >+ | ... >+hash:insert{2, 2, 2, 2} >+ | --- >+ | - [2, 2, 2, 2] >+ | ... >+ >+-- OK >+hash:replace{1, 1, 1, 1} >+ | --- >+ | - [1, 1, 1, 1] >+ | ... >+hash.index['primary']:get{10} >+ | --- >+ | ... >+hash.index['field1']:get{10} >+ | --- >+ | ... >+hash.index['field2']:get{10} >+ | --- >+ | ... >+hash.index['field3']:get{10} >+ | --- >+ | ... >+hash.index['primary']:get{1} >+ | --- >+ | - [1, 1, 1, 1] >+ | ... >+hash.index['field1']:get{1} >+ | --- >+ | - [1, 1, 1, 1] >+ | ... >+hash.index['field2']:get{1} >+ | --- >+ | - [1, 1, 1, 1] >+ | ... >+hash.index['field3']:get{1} >+ | --- >+ | - [1, 1, 1, 1] >+ | ... >+ >+-- OK >+hash:insert{10, 10, 10, 10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash:delete{10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash.index['primary']:get{10} >+ | --- >+ | ... >+hash.index['field1']:get{10} >+ | --- >+ | ... >+hash.index['field2']:get{10} >+ | --- >+ | ... >+hash.index['field3']:get{10} >+ | --- >+ | ... >+ >+-- TupleFound (primary key) >+hash:insert{1, 10, 10, 10} >+ | --- >+ | - error: Duplicate key exists in unique index 'primary' in space 'tweedledum' >+ | ... >+hash.index['primary']:get{10} >+ | --- >+ | ... >+hash.index['field1']:get{10} >+ | --- >+ | ... >+hash.index['field2']:get{10} >+ | --- >+ | ... >+hash.index['field3']:get{10} >+ | --- >+ | ... >+hash.index['primary']:get{1} >+ | --- >+ | - [1, 1, 1, 1] >+ | ... >+ >+-- TupleNotFound (primary key) >+hash:replace{10, 10, 10, 10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash.index['primary']:get{10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash.index['field1']:get{10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash.index['field2']:get{10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash.index['field3']:get{10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+ >+-- TupleFound (key --1) >+hash:insert{10, 0, 10, 10} >+ | --- >+ | - error: Duplicate key exists in unique index 'primary' in space 'tweedledum' >+ | ... >+hash.index['primary']:get{10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash.index['field1']:get{10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash.index['field2']:get{10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash.index['field3']:get{10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash.index['field1']:get{0} >+ | --- >+ | - [0, 0, 0, 0] >+ | ... >+ >+-- TupleFound (key --1) >+-- hash:replace_if_exists(2, 0, 10, 10) >+hash.index['primary']:get{10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash.index['field1']:get{10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash.index['field2']:get{10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash.index['field3']:get{10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash.index['field1']:get{0} >+ | --- >+ | - [0, 0, 0, 0] >+ | ... >+ >+-- TupleFound (key --3) >+hash:insert{10, 10, 10, 0} >+ | --- >+ | - error: Duplicate key exists in unique index 'primary' in space 'tweedledum' >+ | ... >+hash.index['primary']:get{10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash.index['field1']:get{10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash.index['field2']:get{10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash.index['field3']:get{10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash.index['field3']:get{0} >+ | --- >+ | - [0, 0, 0, 0] >+ | ... >+ >+-- TupleFound (key --3) >+-- hash:replace_if_exists(2, 10, 10, 0) >+hash.index['primary']:get{10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash.index['field1']:get{10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash.index['field2']:get{10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash.index['field3']:get{10} >+ | --- >+ | - [10, 10, 10, 10] >+ | ... >+hash.index['field3']:get{0} >+ | --- >+ | - [0, 0, 0, 0] >+ | ... >+ >+hash:drop() >+ | --- >+ | ... >+ >+hash = box.schema.space.create('tweedledum') >+ | --- >+ | ... >+hi = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+ | --- >+ | ... >+hash:insert{0} >+ | --- >+ | - [0] >+ | ... >+hash:insert{16} >+ | --- >+ | - [16] >+ | ... >+for _, tuple in hi:pairs(nil, {iterator = box.index.ALL}) do hash:delete{tuple[1]} end >+ | --- >+ | ... >+hash:drop() >+ | --- >+ | ... >diff --git a/test/box/hash_replace.test.lua b/test/box/hash_replace.test.lua >new file mode 100644 >index 000000000..d876f1f12 >--- /dev/null >+++ b/test/box/hash_replace.test.lua >@@ -0,0 +1,88 @@ >+------------------------ >+-- hash::replace tests >+------------------------ >+ >+hash = box.schema.space.create('tweedledum') >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+tmp = hash:create_index('field1', { type = 'hash', parts = {2, 'unsigned'}, unique = true }) >+tmp = hash:create_index('field2', { type = 'hash', parts = {3, 'unsigned'}, unique = true }) >+tmp = hash:create_index('field3', { type = 'hash', parts = {4, 'unsigned'}, unique = true }) >+ >+hash:insert{0, 0, 0, 0} >+hash:insert{1, 1, 1, 1} >+hash:insert{2, 2, 2, 2} >+ >+-- OK >+hash:replace{1, 1, 1, 1} >+hash.index['primary']:get{10} >+hash.index['field1']:get{10} >+hash.index['field2']:get{10} >+hash.index['field3']:get{10} >+hash.index['primary']:get{1} >+hash.index['field1']:get{1} >+hash.index['field2']:get{1} >+hash.index['field3']:get{1} >+ >+-- OK >+hash:insert{10, 10, 10, 10} >+hash:delete{10} >+hash.index['primary']:get{10} >+hash.index['field1']:get{10} >+hash.index['field2']:get{10} >+hash.index['field3']:get{10} >+ >+-- TupleFound (primary key) >+hash:insert{1, 10, 10, 10} >+hash.index['primary']:get{10} >+hash.index['field1']:get{10} >+hash.index['field2']:get{10} >+hash.index['field3']:get{10} >+hash.index['primary']:get{1} >+ >+-- TupleNotFound (primary key) >+hash:replace{10, 10, 10, 10} >+hash.index['primary']:get{10} >+hash.index['field1']:get{10} >+hash.index['field2']:get{10} >+hash.index['field3']:get{10} >+ >+-- TupleFound (key --1) >+hash:insert{10, 0, 10, 10} >+hash.index['primary']:get{10} >+hash.index['field1']:get{10} >+hash.index['field2']:get{10} >+hash.index['field3']:get{10} >+hash.index['field1']:get{0} >+ >+-- TupleFound (key --1) >+-- hash:replace_if_exists(2, 0, 10, 10) >+hash.index['primary']:get{10} >+hash.index['field1']:get{10} >+hash.index['field2']:get{10} >+hash.index['field3']:get{10} >+hash.index['field1']:get{0} >+ >+-- TupleFound (key --3) >+hash:insert{10, 10, 10, 0} >+hash.index['primary']:get{10} >+hash.index['field1']:get{10} >+hash.index['field2']:get{10} >+hash.index['field3']:get{10} >+hash.index['field3']:get{0} >+ >+-- TupleFound (key --3) >+-- hash:replace_if_exists(2, 10, 10, 0) >+hash.index['primary']:get{10} >+hash.index['field1']:get{10} >+hash.index['field2']:get{10} >+hash.index['field3']:get{10} >+hash.index['field3']:get{0} >+ >+hash:drop() >+ >+hash = box.schema.space.create('tweedledum') >+hi = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true }) >+hash:insert{0} >+hash:insert{16} >+for _, tuple in hi:pairs(nil, {iterator = box.index.ALL}) do hash:delete{tuple[1]} end >+hash:drop() >diff --git a/test/box/hash_string_delete.result b/test/box/hash_string_delete.result >new file mode 100644 >index 000000000..3458f3c68 >--- /dev/null >+++ b/test/box/hash_string_delete.result >@@ -0,0 +1,62 @@ >+-- test-run result file version 2 >+hash = box.schema.space.create('tweedledum') >+ | --- >+ | ... >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'string'}, unique = true }) >+ | --- >+ | ... >+ >+-- Insert valid fields >+hash:insert{'key 0', 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - ['key 0', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{'key 1', 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - ['key 1', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{'key 2', 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - ['key 2', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{'key 3', 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - ['key 3', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+ >+------------------------------------------------------------------------------- >+-- String hash delete fields test >+------------------------------------------------------------------------------- >+ >+-- delete by valid keys >+hash:delete{'key 0'} >+ | --- >+ | - ['key 0', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:delete{'key 1'} >+ | --- >+ | - ['key 1', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:delete{'key 2'} >+ | --- >+ | - ['key 2', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:delete{'key 3'} >+ | --- >+ | - ['key 3', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:delete{'key 4'} >+ | --- >+ | ... >+hash:delete{'key 5'} >+ | --- >+ | ... >+ >+-- delete by invalid keys >+hash:delete{'key 1', 'key 2'} >+ | --- >+ | - error: Invalid key part count in an exact match (expected 1, got 2) >+ | ... >+hash:drop() >+ | --- >+ | ... >diff --git a/test/box/hash_string_delete.test.lua b/test/box/hash_string_delete.test.lua >new file mode 100644 >index 000000000..612217ec9 >--- /dev/null >+++ b/test/box/hash_string_delete.test.lua >@@ -0,0 +1,24 @@ >+hash = box.schema.space.create('tweedledum') >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'string'}, unique = true }) >+ >+-- Insert valid fields >+hash:insert{'key 0', 'value1 v1.0', 'value2 v1.0'} >+hash:insert{'key 1', 'value1 v1.0', 'value2 v1.0'} >+hash:insert{'key 2', 'value1 v1.0', 'value2 v1.0'} >+hash:insert{'key 3', 'value1 v1.0', 'value2 v1.0'} >+ >+------------------------------------------------------------------------------- >+-- String hash delete fields test >+------------------------------------------------------------------------------- >+ >+-- delete by valid keys >+hash:delete{'key 0'} >+hash:delete{'key 1'} >+hash:delete{'key 2'} >+hash:delete{'key 3'} >+hash:delete{'key 4'} >+hash:delete{'key 5'} >+ >+-- delete by invalid keys >+hash:delete{'key 1', 'key 2'} >+hash:drop() >diff --git a/test/box/hash_string_insert.result b/test/box/hash_string_insert.result >new file mode 100644 >index 000000000..50a52b6a8 >--- /dev/null >+++ b/test/box/hash_string_insert.result >@@ -0,0 +1,32 @@ >+-- test-run result file version 2 >+------------------------------------------------------------------------------- >+-- String hash inset fields tests >+------------------------------------------------------------------------------- >+hash = box.schema.space.create('tweedledum') >+ | --- >+ | ... >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'string'}, unique = true }) >+ | --- >+ | ... >+ >+-- Insert valid fields >+hash:insert{'key 0', 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - ['key 0', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{'key 1', 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - ['key 1', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{'key 2', 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - ['key 2', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{'key 3', 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - ['key 3', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+ >+hash:drop() >+ | --- >+ | ... >diff --git a/test/box/hash_string_insert.test.lua b/test/box/hash_string_insert.test.lua >new file mode 100644 >index 000000000..9788abc0d >--- /dev/null >+++ b/test/box/hash_string_insert.test.lua >@@ -0,0 +1,13 @@ >+------------------------------------------------------------------------------- >+-- String hash inset fields tests >+------------------------------------------------------------------------------- >+hash = box.schema.space.create('tweedledum') >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'string'}, unique = true }) >+ >+-- Insert valid fields >+hash:insert{'key 0', 'value1 v1.0', 'value2 v1.0'} >+hash:insert{'key 1', 'value1 v1.0', 'value2 v1.0'} >+hash:insert{'key 2', 'value1 v1.0', 'value2 v1.0'} >+hash:insert{'key 3', 'value1 v1.0', 'value2 v1.0'} >+ >+hash:drop() >diff --git a/test/box/hash_string_replace.result b/test/box/hash_string_replace.result >new file mode 100644 >index 000000000..1fb525d71 >--- /dev/null >+++ b/test/box/hash_string_replace.result >@@ -0,0 +1,47 @@ >+-- test-run result file version 2 >+hash = box.schema.space.create('tweedledum') >+ | --- >+ | ... >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'string'}, unique = true }) >+ | --- >+ | ... >+ >+-- Insert valid fields >+hash:insert{'key 0', 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - ['key 0', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{'key 1', 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - ['key 1', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{'key 2', 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - ['key 2', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{'key 3', 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - ['key 3', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+ >+------------------------------------------------------------------------------- >+-- String hash replace fields tests >+------------------------------------------------------------------------------- >+ >+-- Replace valid fields >+hash:replace{'key 3', 'value1 v1.31', 'value2 1.12'} >+ | --- >+ | - ['key 3', 'value1 v1.31', 'value2 1.12'] >+ | ... >+hash:replace{'key 1', 'value1 v1.32', 'value2 1.72'} >+ | --- >+ | - ['key 1', 'value1 v1.32', 'value2 1.72'] >+ | ... >+hash:replace{'key 2', 'value1 v1.43', 'value2 1.92'} >+ | --- >+ | - ['key 2', 'value1 v1.43', 'value2 1.92'] >+ | ... >+ >+hash:drop() >+ | --- >+ | ... >diff --git a/test/box/hash_string_replace.test.lua b/test/box/hash_string_replace.test.lua >new file mode 100644 >index 000000000..db5cfa93e >--- /dev/null >+++ b/test/box/hash_string_replace.test.lua >@@ -0,0 +1,19 @@ >+hash = box.schema.space.create('tweedledum') >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'string'}, unique = true }) >+ >+-- Insert valid fields >+hash:insert{'key 0', 'value1 v1.0', 'value2 v1.0'} >+hash:insert{'key 1', 'value1 v1.0', 'value2 v1.0'} >+hash:insert{'key 2', 'value1 v1.0', 'value2 v1.0'} >+hash:insert{'key 3', 'value1 v1.0', 'value2 v1.0'} >+ >+------------------------------------------------------------------------------- >+-- String hash replace fields tests >+------------------------------------------------------------------------------- >+ >+-- Replace valid fields >+hash:replace{'key 3', 'value1 v1.31', 'value2 1.12'} >+hash:replace{'key 1', 'value1 v1.32', 'value2 1.72'} >+hash:replace{'key 2', 'value1 v1.43', 'value2 1.92'} >+ >+hash:drop() >diff --git a/test/box/hash_string_select.result b/test/box/hash_string_select.result >new file mode 100644 >index 000000000..16cb22d3c >--- /dev/null >+++ b/test/box/hash_string_select.result >@@ -0,0 +1,63 @@ >+-- test-run result file version 2 >+hash = box.schema.space.create('tweedledum') >+ | --- >+ | ... >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'string'}, unique = true }) >+ | --- >+ | ... >+ >+-- Insert valid fields >+hash:insert{'key 0', 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - ['key 0', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{'key 1', 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - ['key 1', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{'key 2', 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - ['key 2', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash:insert{'key 3', 'value1 v1.0', 'value2 v1.0'} >+ | --- >+ | - ['key 3', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+ >+------------------------------------------------------------------------------- >+-- String hash select fields test >+------------------------------------------------------------------------------- >+ >+-- select by valid keys >+hash.index['primary']:get{'key 0'} >+ | --- >+ | - ['key 0', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash.index['primary']:get{'key 1'} >+ | --- >+ | - ['key 1', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash.index['primary']:get{'key 2'} >+ | --- >+ | - ['key 2', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash.index['primary']:get{'key 3'} >+ | --- >+ | - ['key 3', 'value1 v1.0', 'value2 v1.0'] >+ | ... >+hash.index['primary']:get{'key 4'} >+ | --- >+ | ... >+hash.index['primary']:get{'key 5'} >+ | --- >+ | ... >+ >+-- select by invalid keys >+hash.index['primary']:get{'key 1', 'key 2'} >+ | --- >+ | - error: Invalid key part count in an exact match (expected 1, got 2) >+ | ... >+ >+hash:drop() >+ | --- >+ | ... >diff --git a/test/box/hash_string_select.test.lua b/test/box/hash_string_select.test.lua >new file mode 100644 >index 000000000..ef3f10018 >--- /dev/null >+++ b/test/box/hash_string_select.test.lua >@@ -0,0 +1,25 @@ >+hash = box.schema.space.create('tweedledum') >+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'string'}, unique = true }) >+ >+-- Insert valid fields >+hash:insert{'key 0', 'value1 v1.0', 'value2 v1.0'} >+hash:insert{'key 1', 'value1 v1.0', 'value2 v1.0'} >+hash:insert{'key 2', 'value1 v1.0', 'value2 v1.0'} >+hash:insert{'key 3', 'value1 v1.0', 'value2 v1.0'} >+ >+------------------------------------------------------------------------------- >+-- String hash select fields test >+------------------------------------------------------------------------------- >+ >+-- select by valid keys >+hash.index['primary']:get{'key 0'} >+hash.index['primary']:get{'key 1'} >+hash.index['primary']:get{'key 2'} >+hash.index['primary']:get{'key 3'} >+hash.index['primary']:get{'key 4'} >+hash.index['primary']:get{'key 5'} >+ >+-- select by invalid keys >+hash.index['primary']:get{'key 1', 'key 2'} >+ >+hash:drop() >diff --git a/test/box/hash_with_function.result b/test/box/hash_with_function.result >new file mode 100644 >index 000000000..cac268281 >--- /dev/null >+++ b/test/box/hash_with_function.result >@@ -0,0 +1,26 @@ >+-- test-run result file version 2 >+-- Hash index can not use function. >+ >+s = box.schema.space.create('withdata') >+ | --- >+ | ... >+lua_code = [[function(tuple) return tuple[1] + tuple[2] end]] >+ | --- >+ | ... >+box.schema.func.create('s', {body = lua_code, is_deterministic = true, is_sandboxed = true}) >+ | --- >+ | ... >+_ = s:create_index('pk') >+ | --- >+ | ... >+_ = s:create_index('idx', {type = 'hash', func = box.func.s.id, parts = {{1, 'unsigned'}}}) >+ | --- >+ | - error: 'Can''t create or modify index ''idx'' in space ''withdata'': HASH index >+ | can not use a function' >+ | ... >+s:drop() >+ | --- >+ | ... >+box.schema.func.drop('s') >+ | --- >+ | ... >diff --git a/test/box/hash_with_function.test.lua b/test/box/hash_with_function.test.lua >new file mode 100644 >index 000000000..9653de68e >--- /dev/null >+++ b/test/box/hash_with_function.test.lua >@@ -0,0 +1,9 @@ >+-- Hash index can not use function. >+ >+s = box.schema.space.create('withdata') >+lua_code = [[function(tuple) return tuple[1] + tuple[2] end]] >+box.schema.func.create('s', {body = lua_code, is_deterministic = true, is_sandboxed = true}) >+_ = s:create_index('pk') >+_ = s:create_index('idx', {type = 'hash', func = box.func.s.id, parts = {{1, 'unsigned'}}}) >+s:drop() >+box.schema.func.drop('s') >-- >2.23.0 > > >-- >sergeyb@