Tarantool development patches archive
 help / color / mirror / Atom feed
* [Tarantool-patches] [PATCH v1] Split box/hash.test.lua to a set of small independent tests
@ 2020-03-17 15:11 Sergey Bronnikov
  2020-03-18  8:00 ` Sergey Bronnikov
  0 siblings, 1 reply; 4+ messages in thread
From: Sergey Bronnikov @ 2020-03-17 15:11 UTC (permalink / raw)
  To: tarantool-patches

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@

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Tarantool-patches] [PATCH v1] Split box/hash.test.lua to a set of small independent tests
  2020-03-17 15:11 [Tarantool-patches] [PATCH v1] Split box/hash.test.lua to a set of small independent tests Sergey Bronnikov
@ 2020-03-18  8:00 ` Sergey Bronnikov
  2020-03-18 11:30   ` Oleg Piskunov
  0 siblings, 1 reply; 4+ messages in thread
From: Sergey Bronnikov @ 2020-03-18  8:00 UTC (permalink / raw)
  To: tarantool-patches; +Cc: Oleg Piskunov

CCed: A. Tikhonov, A. Turenko and O. Piskunov

On 18:11 Tue 17 Mar , Sergey Bronnikov wrote:
> 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@

-- 
sergeyb@

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Tarantool-patches] [PATCH v1] Split box/hash.test.lua to a set of small independent tests
  2020-03-18  8:00 ` Sergey Bronnikov
@ 2020-03-18 11:30   ` Oleg Piskunov
  2020-03-19 10:26     ` Sergey Bronnikov
  0 siblings, 1 reply; 4+ messages in thread
From: Oleg Piskunov @ 2020-03-18 11:30 UTC (permalink / raw)
  To: Sergey Bronnikov; +Cc: tarantool-patches

[-- Attachment #1: Type: text/plain, Size: 100645 bytes --]


Hi,
 
Sergey, need to change cleanup for most splitted tests.
Please chenge «truncate()» to «drop()»
 
Regards,
Oleg
  
>Среда, 18 марта 2020, 11:00 +03:00 от Sergey Bronnikov <sergeyb@tarantool.org>:
> 
>CCed: A. Tikhonov, A. Turenko and O. Piskunov
>
>On 18:11 Tue 17 Mar , Sergey Bronnikov wrote:
>> 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@
>--
>sergeyb@ 
 
 
--
Oleg Piskunov
 

[-- Attachment #2: Type: text/html, Size: 117743 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Tarantool-patches] [PATCH v1] Split box/hash.test.lua to a set of small independent tests
  2020-03-18 11:30   ` Oleg Piskunov
@ 2020-03-19 10:26     ` Sergey Bronnikov
  0 siblings, 0 replies; 4+ messages in thread
From: Sergey Bronnikov @ 2020-03-19 10:26 UTC (permalink / raw)
  To: Oleg Piskunov; +Cc: tarantool-patches

Hi,

On 14:30 Wed 18 Mar , Oleg Piskunov wrote:
> 
> Hi,
>
> Sergey, need to change cleanup for most splitted tests.
> Please chenge «truncate()» to «drop()»

Oleg, thanks for the review, I’ve fixed tests.

> Regards,
> Oleg

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-03-19 10:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-17 15:11 [Tarantool-patches] [PATCH v1] Split box/hash.test.lua to a set of small independent tests Sergey Bronnikov
2020-03-18  8:00 ` Sergey Bronnikov
2020-03-18 11:30   ` Oleg Piskunov
2020-03-19 10:26     ` Sergey Bronnikov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox