CCed: A. Tikhonov, A. Turenko and O. Piskunov
> 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_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 | 66 ++
> test/box/hash_string_delete.test.lua | 26 +
> 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 +
> 42 files changed, 1701 insertions(+), 1237 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..d26a9a03d
> --- /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:truncate()
> + | ---
> + | ...
> diff --git a/test/box/hash_32bit_delete.test.lua b/test/box/hash_32bit_delete.test.lua
> new file mode 100644
> index 000000000..aabfd4d38
> --- /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:truncate()
> diff --git a/test/box/hash_32bit_insert.result b/test/box/hash_32bit_insert.result
> new file mode 100644
> index 000000000..3badfe032
> --- /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:truncate()
> + | ---
> + | ...
> diff --git a/test/box/hash_32bit_insert.test.lua b/test/box/hash_32bit_insert.test.lua
> new file mode 100644
> index 000000000..1067e5e73
> --- /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:truncate()
> diff --git a/test/box/hash_32bit_replace.result b/test/box/hash_32bit_replace.result
> new file mode 100644
> index 000000000..6f8577199
> --- /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:truncate()
> + | ---
> + | ...
> diff --git a/test/box/hash_32bit_replace.test.lua b/test/box/hash_32bit_replace.test.lua
> new file mode 100644
> index 000000000..f7a567c9c
> --- /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:truncate()
> diff --git a/test/box/hash_32bit_select.result b/test/box/hash_32bit_select.result
> new file mode 100644
> index 000000000..2ecd06233
> --- /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:truncate()
> + | ---
> + | ...
> diff --git a/test/box/hash_32bit_select.test.lua b/test/box/hash_32bit_select.test.lua
> new file mode 100644
> index 000000000..e9eb463b3
> --- /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:truncate()
> diff --git a/test/box/hash_64bit_delete.result b/test/box/hash_64bit_delete.result
> new file mode 100644
> index 000000000..2202f9408
> --- /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:truncate()
> + | ---
> + | ...
> diff --git a/test/box/hash_64bit_delete.test.lua b/test/box/hash_64bit_delete.test.lua
> new file mode 100644
> index 000000000..2b4e608c4
> --- /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:truncate()
> diff --git a/test/box/hash_64bit_insert.result b/test/box/hash_64bit_insert.result
> new file mode 100644
> index 000000000..fafc73530
> --- /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:truncate()
> + | ---
> + | ...
> diff --git a/test/box/hash_64bit_insert.test.lua b/test/box/hash_64bit_insert.test.lua
> new file mode 100644
> index 000000000..deab22e9f
> --- /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:truncate()
> diff --git a/test/box/hash_64bit_replace.result b/test/box/hash_64bit_replace.result
> new file mode 100644
> index 000000000..d4bc537dc
> --- /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:truncate()
> + | ---
> + | ...
> diff --git a/test/box/hash_64bit_replace.test.lua b/test/box/hash_64bit_replace.test.lua
> new file mode 100644
> index 000000000..79a4e3430
> --- /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:truncate()
> diff --git a/test/box/hash_64bit_select.result b/test/box/hash_64bit_select.result
> new file mode 100644
> index 000000000..051da2dec
> --- /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:truncate()
> + | ---
> + | ...
> diff --git a/test/box/hash_64bit_select.test.lua b/test/box/hash_64bit_select.test.lua
> new file mode 100644
> index 000000000..804fcc462
> --- /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:truncate()
> diff --git a/test/box/hash_collation.result b/test/box/hash_collation.result
> new file mode 100644
> index 000000000..6ec04f490
> --- /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:truncate()
> + | ---
> + | ...
> diff --git a/test/box/hash_collation.test.lua b/test/box/hash_collation.test.lua
> new file mode 100644
> index 000000000..1f7a16bb2
> --- /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:truncate()
> 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_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..8cffb9ba7
> --- /dev/null
> +++ b/test/box/hash_string_delete.result
> @@ -0,0 +1,66 @@
> +-- 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:truncate()
> + | ---
> + | ...
> +
> +hash:truncate()
> + | ---
> + | ...
> diff --git a/test/box/hash_string_delete.test.lua b/test/box/hash_string_delete.test.lua
> new file mode 100644
> index 000000000..e862d87c3
> --- /dev/null
> +++ b/test/box/hash_string_delete.test.lua
> @@ -0,0 +1,26 @@
> +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:truncate()
> +
> +hash:truncate()
> diff --git a/test/box/hash_string_insert.result b/test/box/hash_string_insert.result
> new file mode 100644
> index 000000000..fcd0b3a32
> --- /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:truncate()
> + | ---
> + | ...
> diff --git a/test/box/hash_string_insert.test.lua b/test/box/hash_string_insert.test.lua
> new file mode 100644
> index 000000000..0778ccb1d
> --- /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:truncate()
> diff --git a/test/box/hash_string_replace.result b/test/box/hash_string_replace.result
> new file mode 100644
> index 000000000..487e37e3a
> --- /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:truncate()
> + | ---
> + | ...
> diff --git a/test/box/hash_string_replace.test.lua b/test/box/hash_string_replace.test.lua
> new file mode 100644
> index 000000000..95226ae43
> --- /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:truncate()
> diff --git a/test/box/hash_string_select.result b/test/box/hash_string_select.result
> new file mode 100644
> index 000000000..ed45b99c3
> --- /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:truncate()
> + | ---
> + | ...
> diff --git a/test/box/hash_string_select.test.lua b/test/box/hash_string_select.test.lua
> new file mode 100644
> index 000000000..b7db916f0
> --- /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:truncate()
> 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@