[Tarantool-patches] [PATCH v2] Split box/hash.test.lua to a set of small independent tests
Alexander Tikhonov
avtikhon at tarantool.org
Thu Mar 19 17:22:09 MSK 2020
Sergey, thanks for the patch, LGTM,
Отправлено из мобильной Почты Mail.ru
четверг, 19 марта 2020 г., 13:25 +0300 от Sergey Bronnikov <sergeyb at tarantool.org>:
>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@
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.tarantool.org/pipermail/tarantool-patches/attachments/20200319/c96c6cc4/attachment.html>
More information about the Tarantool-patches
mailing list