diff --git a/changelogs/unreleased/gh-7483-ignore-mpack-types.md b/changelogs/unreleased/gh-7483-ignore-mpack-types.md
new file mode 100644
index 0000000000000000000000000000000000000000..780672671bae16f46e4491f25aa32b307f47a877
--- /dev/null
+++ b/changelogs/unreleased/gh-7483-ignore-mpack-types.md
@@ -0,0 +1,4 @@
+## bugfix/box
+
+* Fixed the inability to insert an integral number into a double-formatted
+  field (gh-7483).
diff --git a/src/box/field_def.c b/src/box/field_def.c
index 6b14c009204b1961304fd13bb70627052360dcf3..469fd0fc22bffb72045518b76c2e582b4fd3dbb7 100644
--- a/src/box/field_def.c
+++ b/src/box/field_def.c
@@ -69,7 +69,8 @@ const uint32_t field_mp_type[] = {
 	/* [FIELD_TYPE_STRING]   =  */ 1U << MP_STR,
 	/* [FIELD_TYPE_NUMBER]   =  */ (1U << MP_UINT) | (1U << MP_INT) |
 		(1U << MP_FLOAT) | (1U << MP_DOUBLE),
-	/* [FIELD_TYPE_DOUBLE]   =  */ 1U << MP_DOUBLE,
+	/* [FIELD_TYPE_DOUBLE]   =  */ (1U << MP_UINT) | (1U << MP_INT) |
+		(1U << MP_FLOAT) | (1U << MP_DOUBLE),
 	/* [FIELD_TYPE_INTEGER]  =  */ (1U << MP_UINT) | (1U << MP_INT),
 	/* [FIELD_TYPE_BOOLEAN]  =  */ 1U << MP_BOOL,
 	/* [FIELD_TYPE_VARBINARY] =  */ 1U << MP_BIN,
diff --git a/src/box/key_def.h b/src/box/key_def.h
index 03d6718a779faac65c6b5dba70937dc153932e73..942e8868daa4c780a22e47f9ef5792f4a4879da6 100644
--- a/src/box/key_def.h
+++ b/src/box/key_def.h
@@ -1071,6 +1071,7 @@ tuple_compare_with_key(struct tuple *tuple, hint_t tuple_hint,
 
 /**
  * Compute hash of a tuple field.
+ * @param type - type of the field key part
  * @param ph1 - pointer to running hash
  * @param pcarry - pointer to carry
  * @param field - pointer to field data
@@ -1082,7 +1083,7 @@ tuple_compare_with_key(struct tuple *tuple, hint_t tuple_hint,
  */
 uint32_t
 tuple_hash_field(uint32_t *ph1, uint32_t *pcarry, const char **field,
-		 struct coll *coll);
+		 enum field_type type, struct coll *coll);
 
 /**
  * Compute hash of a key part.
diff --git a/src/box/tuple_bloom.c b/src/box/tuple_bloom.c
index 25fca26861a4e421592013ee0c2f1a3fe2db75a5..f92ace38c4bdcb4534769b4b4c27a7abf59fc390 100644
--- a/src/box/tuple_bloom.c
+++ b/src/box/tuple_bloom.c
@@ -141,6 +141,7 @@ tuple_bloom_builder_add_key(struct tuple_bloom_builder *builder,
 
 	for (uint32_t i = 0; i < key_def->part_count; i++) {
 		total_size += tuple_hash_field(&h, &carry, &key,
+					       key_def->parts[i].type,
 					       key_def->parts[i].coll);
 		uint32_t hash = PMurHash32_Result(h, carry, total_size);
 		if (tuple_hash_array_add(&builder->parts[i], hash) != 0)
@@ -249,6 +250,7 @@ tuple_bloom_maybe_has_key(const struct tuple_bloom *bloom,
 
 	for (uint32_t i = 0; i < part_count; i++) {
 		total_size += tuple_hash_field(&h, &carry, &key,
+					       key_def->parts[i].type,
 					       key_def->parts[i].coll);
 		uint32_t hash = PMurHash32_Result(h, carry, total_size);
 		if (!bloom_maybe_has(&bloom->parts[i], hash))
diff --git a/src/box/tuple_compare.cc b/src/box/tuple_compare.cc
index fc34797a425acc96cce25019a68bef3e06d44169..83d0cc0b1191aa4eca6d26dc1e7b29ebeb74db88 100644
--- a/src/box/tuple_compare.cc
+++ b/src/box/tuple_compare.cc
@@ -105,6 +105,23 @@ mp_extension_class(const char *data)
 	return mp_ext_classes[type];
 }
 
+/*
+ * @brief Read the msgpack value at \p field (whatever it is: int, uint, float
+ *        or double) as double.
+ * @param field the field to read the value from
+ * @retval the read-and-cast result
+ */
+static double
+mp_read_as_double(const char *field)
+{
+	double result = NAN;
+	assert(mp_classof(mp_typeof(*field)) == MP_CLASS_NUMBER);
+	/* This can only fail on non-numeric msgpack field, so it shouldn't. */
+	if (mp_read_double_lossy(&field, &result) == -1)
+		unreachable();
+	return result;
+}
+
 static int
 mp_compare_bool(const char *field_a, const char *field_b)
 {
@@ -114,10 +131,10 @@ mp_compare_bool(const char *field_a, const char *field_b)
 }
 
 static int
-mp_compare_double(const char *field_a, const char *field_b)
+mp_compare_as_double(const char *field_a, const char *field_b)
 {
-	double a_val = mp_decode_double(&field_a);
-	double b_val = mp_decode_double(&field_b);
+	double a_val = mp_read_as_double(field_a);
+	double b_val = mp_read_as_double(field_b);
 	return COMPARE_RESULT(a_val, b_val);
 }
 
@@ -492,7 +509,7 @@ tuple_compare_field(const char *field_a, const char *field_b,
 	case FIELD_TYPE_NUMBER:
 		return mp_compare_number(field_a, field_b);
 	case FIELD_TYPE_DOUBLE:
-		return mp_compare_double(field_a, field_b);
+		return mp_compare_as_double(field_a, field_b);
 	case FIELD_TYPE_BOOLEAN:
 		return mp_compare_bool(field_a, field_b);
 	case FIELD_TYPE_VARBINARY:
@@ -532,7 +549,7 @@ tuple_compare_field_with_type(const char *field_a, enum mp_type a_type,
 		return mp_compare_number_with_type(field_a, a_type,
 						   field_b, b_type);
 	case FIELD_TYPE_DOUBLE:
-		return mp_compare_double(field_a, field_b);
+		return mp_compare_as_double(field_a, field_b);
 	case FIELD_TYPE_BOOLEAN:
 		return mp_compare_bool(field_a, field_b);
 	case FIELD_TYPE_VARBINARY:
@@ -1837,8 +1854,7 @@ field_hint_integer(const char *field)
 static inline hint_t
 field_hint_double(const char *field)
 {
-	assert(mp_typeof(*field) == MP_DOUBLE);
-	return hint_double(mp_decode_double(&field));
+	return hint_double(mp_read_as_double(field));
 }
 
 static inline hint_t
diff --git a/src/box/tuple_hash.cc b/src/box/tuple_hash.cc
index 9d6f9ba10ce6bb515e97199f0e6ce23ba59bf236..1c921dda125a72f3a10d3c0b76cd6f90aaa2cb23 100644
--- a/src/box/tuple_hash.cc
+++ b/src/box/tuple_hash.cc
@@ -46,6 +46,17 @@ template <int TYPE>
 static inline uint32_t
 field_hash(uint32_t *ph, uint32_t *pcarry, const char **field)
 {
+	/*
+	 * For string key field we should hash the string contents excluding
+	 * MsgPack format identifier. The overload is defined below.
+	 */
+	static_assert(TYPE != FIELD_TYPE_STRING, "See the comment above.");
+	/*
+	 * For double key field we should cast the MsgPack value (whatever it
+	 * is: int, uint, float or double) to double, encode it as msgpack
+	 * double and hash it. No overload for it now.
+	 */
+	static_assert(TYPE != FIELD_TYPE_DOUBLE, "See the comment above.");
 	/*
 	* (!) All fields, except TYPE_STRING hashed **including** MsgPack format
 	* identifier (e.g. 0xcc). This was done **intentionally**
@@ -221,7 +232,7 @@ template <bool has_optional_parts, bool has_json_paths>
 uint32_t
 tuple_hash_slowpath(struct tuple *tuple, struct key_def *key_def);
 
-uint32_t
+static uint32_t
 key_hash_slowpath(const char *key, struct key_def *key_def);
 
 void
@@ -276,12 +287,41 @@ key_def_set_hash_func(struct key_def *key_def) {
 
 uint32_t
 tuple_hash_field(uint32_t *ph1, uint32_t *pcarry, const char **field,
-		 struct coll *coll)
+		 enum field_type type, struct coll *coll)
 {
-	char buf[9]; /* enough to store MP_INT/MP_UINT */
+	char buf[9]; /* enough to store MP_INT/MP_UINT/MP_DOUBLE */
 	const char *f = *field;
 	uint32_t size;
 
+	/*
+	 * MsgPack values of double key field are casted to double, encoded
+	 * as msgpack double and hashed. This assures the same value being
+	 * written as int, uint, float or double has the same hash for this
+	 * type of key.
+	 *
+	 * We create and hash msgpack instead of just hashing the double itself
+	 * for backward compatibility: so a user having a vinyl database with
+	 * double-key index won't have to rebuild it after tarantool update.
+	 *
+	 * XXX: It looks like something like this should also be done for
+	 * number key fields so that e. g. zero given as int, uint, float,
+	 * double and decimal have the same hash.
+	 */
+	if (type == FIELD_TYPE_DOUBLE) {
+		double value;
+		/*
+		 * This will only fail if the mp_type is not numeric, which is
+		 * impossible here (see field_mp_plain_type_is_compatible).
+		 */
+		if (mp_read_double_lossy(&f, &value) == -1)
+			unreachable();
+		char *double_msgpack_end = mp_encode_double(buf, value);
+		size = double_msgpack_end - buf;
+		assert(size <= sizeof(buf));
+		PMurHash32_Process(ph1, pcarry, buf, size);
+		return size;
+	}
+
 	switch (mp_typeof(**field)) {
 	case MP_STR:
 		/*
@@ -355,7 +395,7 @@ tuple_hash_key_part(uint32_t *ph1, uint32_t *pcarry, struct tuple *tuple,
 	const char *field = tuple_field_by_part(tuple, part, multikey_idx);
 	if (field == NULL)
 		return tuple_hash_null(ph1, pcarry);
-	return tuple_hash_field(ph1, pcarry, &field, part->coll);
+	return tuple_hash_field(ph1, pcarry, &field, part->type, part->coll);
 }
 
 template <bool has_optional_parts, bool has_json_paths>
@@ -386,6 +426,7 @@ tuple_hash_slowpath(struct tuple *tuple, struct key_def *key_def)
 		total_size += tuple_hash_null(&h, &carry);
 	} else {
 		total_size += tuple_hash_field(&h, &carry, &field,
+					       key_def->parts[0].type,
 					       key_def->parts[0].coll);
 	}
 	for (uint32_t part_id = 1; part_id < key_def->part_count; part_id++) {
@@ -409,6 +450,7 @@ tuple_hash_slowpath(struct tuple *tuple, struct key_def *key_def)
 		} else {
 			total_size +=
 				tuple_hash_field(&h, &carry, &field,
+						 key_def->parts[part_id].type,
 						 key_def->parts[part_id].coll);
 		}
 		prev_fieldno = key_def->parts[part_id].fieldno;
@@ -417,7 +459,7 @@ tuple_hash_slowpath(struct tuple *tuple, struct key_def *key_def)
 	return PMurHash32_Result(h, carry, total_size);
 }
 
-uint32_t
+static uint32_t
 key_hash_slowpath(const char *key, struct key_def *key_def)
 {
 	uint32_t h = HASH_SEED;
@@ -426,7 +468,8 @@ key_hash_slowpath(const char *key, struct key_def *key_def)
 
 	for (struct key_part *part = key_def->parts;
 	     part < key_def->parts + key_def->part_count; part++) {
-		total_size += tuple_hash_field(&h, &carry, &key, part->coll);
+		total_size += tuple_hash_field(&h, &carry, &key, part->type,
+					       part->coll);
 	}
 
 	return PMurHash32_Result(h, carry, total_size);
diff --git a/test/engine-luatest/gh_7483_insert_int_into_double_field_test.lua b/test/engine-luatest/gh_7483_insert_int_into_double_field_test.lua
new file mode 100644
index 0000000000000000000000000000000000000000..56e1044c6f578cbf167c1d9d428d1e2956c0a76c
--- /dev/null
+++ b/test/engine-luatest/gh_7483_insert_int_into_double_field_test.lua
@@ -0,0 +1,67 @@
+local server = require('luatest.server')
+local t = require('luatest')
+
+local g = t.group('gh-7483-insert-int-into-double-field-test', {
+    {engine = 'memtx', index_type = 'tree'},
+    {engine = 'memtx', index_type = 'hash'},
+    {engine = 'vinyl', index_type = 'tree'},
+})
+
+g.before_all(function(cg)
+    cg.server = server:new()
+    cg.server:start()
+end)
+
+g.after_all(function(cg)
+    cg.server:drop()
+end)
+
+g.after_each(function(cg)
+    cg.server:exec(function()
+        if box.space.s ~= nil then
+            box.space.s:drop()
+        end
+    end)
+end)
+
+g.test_insert_int_into_double_field = function(cg)
+    cg.server:exec(function (engine, index_type)
+        local ffi = require('ffi')
+
+        local s = box.schema.space.create('s', { engine = engine })
+        s:create_index('s_idx', {type = index_type, parts = {1, 'double'}})
+
+        -- For double-typed key we cast it to double before hashing.
+        -- So 1 and 1.0 are interpret as the same value.
+        local int_1 = 1
+        local double_1 = ffi.new('double', 1.0)
+        local errdup = 'Duplicate key exists in unique index "s_idx" in space '
+                       ..'"s" with old tuple - '
+
+        -- Ok, new integer (1).
+        s:insert({int_1})
+
+        -- Fail, duplicate of 1.
+        t.assert_error_msg_contains(errdup, s.insert, s, {double_1})
+
+        -- Select the integer.
+        t.assert_equals(s:select({double_1}), {{int_1}});
+
+        -- 2 ** 63 - 1 can't be directly converted to double,
+        -- it becomes 2 ** 63 on cast.
+        local int_2e63_minus_1 = 0x7fffffffffffffffULL
+        local double_2e63 = ffi.new('double', int_2e63_minus_1)
+
+        -- Successfully insert the integer into the double field.
+        s:insert({int_2e63_minus_1})
+
+        -- Insert of double-casted integer should fail since it's recognized as
+        -- a duplicate of the integer inserted above (despite the fact that
+        -- integer is not exactly equal to the resulting double, it becomes
+        -- equal on cast to double in index).
+        t.assert_error_msg_contains(errdup, s.insert, s, {double_2e63})
+
+        -- Select of the double should retrieve the inserted integer.
+        t.assert_equals(s:select({double_2e63}), {{int_2e63_minus_1}})
+    end, {cg.params.engine, cg.params.index_type})
+end
diff --git a/test/engine/insert.result b/test/engine/insert.result
index ffff3df85d3c29b1acab9b85a652d3cd9fe48246..f8d128e0cbcabb22f8797b0a07efcce674293933 100644
--- a/test/engine/insert.result
+++ b/test/engine/insert.result
@@ -746,8 +746,7 @@ _ = s:create_index('ii')
 ---
 ...
 --
--- If number of Lua type NUMBER is not integer, than it could be
--- inserted in DOUBLE field.
+-- A number of Lua type NUMBER can be inserted in DOUBLE field.
 --
 s:insert({1, 1.1})
 ---
@@ -762,33 +761,31 @@ s:insert({3, -3.0009})
 - [3, -3.0009]
 ...
 --
--- Integers of Lua type NUMBER and CDATA of type int64 or uint64
--- cannot be inserted into this field.
+-- Integers of Lua type NUMBER and CDATA of type int64 or uint64 can
+-- also be inserted even if they can't be loselessly converted to
+-- double. They're stored in the space "as is".
 --
 s:insert({4, 1})
 ---
-- error: 'Tuple field 2 (d) type does not match one required by operation: expected
-    double, got unsigned'
+- [4, 1]
 ...
-s:insert({5, -9223372036854775800ULL})
+s:insert({5, 9223372036854775800ULL})
 ---
-- error: 'Tuple field 2 (d) type does not match one required by operation: expected
-    double, got unsigned'
+- [5, 9223372036854775800]
 ...
 s:insert({6, 18000000000000000000ULL})
 ---
-- error: 'Tuple field 2 (d) type does not match one required by operation: expected
-    double, got unsigned'
+- [6, 18000000000000000000]
 ...
 --
--- To insert an integer, we must cast it to a CDATA of type DOUBLE
--- using ffi.cast(). Non-integers can also be inserted this way.
+-- One can also cast a value to CDATA of type DOUBLE using ffi.cast().
+-- Non-integers can also be inserted this way.
 --
 s:insert({7, ffi.cast('double', 1)})
 ---
 - [7, 1]
 ...
-s:insert({8, ffi.cast('double', -9223372036854775808)})
+s:insert({8, ffi.cast('double', -9223372036854775800LL)})
 ---
 - [8, -9223372036854775808]
 ...
@@ -813,6 +810,9 @@ s:select()
 - - [1, 1.1]
   - [2, 2.5]
   - [3, -3.0009]
+  - [4, 1]
+  - [5, 9223372036854775800]
+  - [6, 18000000000000000000]
   - [7, 1]
   - [8, -9223372036854775808]
   - [9, 123]
@@ -829,13 +829,13 @@ dd:select(1.1)
 - - [1, 1.1]
   - [11, 1.1]
 ...
-dd:select(1)
+dd:select(-9223372036854775800LL)
 ---
-- error: 'Supplied key type of part 0 does not match index part type: expected double'
+- - [8, -9223372036854775808]
 ...
-dd:select(ffi.cast('double', 1))
+dd:select(ffi.cast('double', -9223372036854775800LL))
 ---
-- - [7, 1]
+- - [8, -9223372036854775808]
 ...
 -- Make sure the comparisons work correctly.
 dd:select(1.1, {iterator = 'ge'})
@@ -844,6 +844,8 @@ dd:select(1.1, {iterator = 'ge'})
   - [11, 1.1]
   - [2, 2.5]
   - [9, 123]
+  - [5, 9223372036854775800]
+  - [6, 18000000000000000000]
   - [10, 18000000000000000000]
 ...
 dd:select(1.1, {iterator = 'le'})
@@ -851,6 +853,7 @@ dd:select(1.1, {iterator = 'le'})
 - - [11, 1.1]
   - [1, 1.1]
   - [7, 1]
+  - [4, 1]
   - [12, -3.0009]
   - [3, -3.0009]
   - [8, -9223372036854775808]
@@ -859,11 +862,14 @@ dd:select(ffi.cast('double', 1.1), {iterator = 'gt'})
 ---
 - - [2, 2.5]
   - [9, 123]
+  - [5, 9223372036854775800]
+  - [6, 18000000000000000000]
   - [10, 18000000000000000000]
 ...
 dd:select(ffi.cast('double', 1.1), {iterator = 'lt'})
 ---
 - - [7, 1]
+  - [4, 1]
   - [12, -3.0009]
   - [3, -3.0009]
   - [8, -9223372036854775808]
@@ -874,6 +880,8 @@ dd:select(1.1, {iterator = 'all'})
   - [11, 1.1]
   - [2, 2.5]
   - [9, 123]
+  - [5, 9223372036854775800]
+  - [6, 18000000000000000000]
   - [10, 18000000000000000000]
 ...
 dd:select(1.1, {iterator = 'eq'})
@@ -886,6 +894,14 @@ dd:select(1.1, {iterator = 'req'})
 - - [11, 1.1]
   - [1, 1.1]
 ...
+s:delete(4)
+---
+- [4, 1]
+...
+s:delete(6)
+---
+- [6, 18000000000000000000]
+...
 s:delete(11)
 ---
 - [11, 1.1]
@@ -900,31 +916,27 @@ ddd = s:create_index('ddd', {parts = {{2, 'double'}}})
 ...
 s:update(1, {{'=', 2, 2}})
 ---
-- error: 'Tuple field 2 (d) type does not match one required by operation: expected
-    double, got unsigned'
+- [1, 2]
 ...
 s:insert({22, 22})
 ---
-- error: 'Tuple field 2 (d) type does not match one required by operation: expected
-    double, got unsigned'
+- [22, 22]
 ...
 s:upsert({10, 100}, {{'=', 2, 2}})
 ---
-- error: 'Tuple field 2 (d) type does not match one required by operation: expected
-    double, got unsigned'
+- error: Duplicate key exists in unique index "ddd" in space "s" with old tuple -
+    [1, 2] and new tuple - [10, 2]
 ...
-s:upsert({100, 100}, {{'=', 2, 2}})
+s:upsert({101, 100}, {{'=', 2, 11}})
 ---
-- error: 'Tuple field 2 (d) type does not match one required by operation: expected
-    double, got unsigned'
 ...
 ddd:update(1, {{'=', 1, 70}})
 ---
-- error: 'Supplied key type of part 0 does not match index part type: expected double'
+- error: Attempt to modify a tuple field which is part of primary index in space 's'
 ...
 ddd:delete(1)
 ---
-- error: 'Supplied key type of part 0 does not match index part type: expected double'
+- [7, 1]
 ...
 s:update(2, {{'=', 2, 2.55}})
 ---
@@ -948,13 +960,13 @@ s:get(10)
 ---
 - [10, 2.2]
 ...
-ddd:update(1.1, {{'=', 3, 111}})
+ddd:update(2, {{'=', 3, 111}})
 ---
-- [1, 1.1, 111]
+- [1, 2, 111]
 ...
-ddd:delete(1.1)
+ddd:delete(2)
 ---
-- [1, 1.1, 111]
+- [1, 2, 111]
 ...
 s:update(2, {{'=', 2, ffi.cast('double', 255)}})
 ---
@@ -978,9 +990,9 @@ s:get(200)
 ---
 - [200, 222]
 ...
-ddd:update(ffi.cast('double', 1), {{'=', 3, 7}})
+ddd:update(22, {{'=', 3, 7}})
 ---
-- [7, 1, 7]
+- [22, 22, 7]
 ...
 ddd:delete(ffi.cast('double', 123))
 ---
@@ -990,11 +1002,12 @@ s:select()
 ---
 - - [2, 255]
   - [3, -3.0009]
-  - [7, 1, 7]
+  - [5, 9223372036854775800]
   - [8, -9223372036854775808]
   - [10, 2.2]
-  - [22, 22]
+  - [22, 22, 7]
   - [100, 100.5]
+  - [101, 100]
   - [200, 222]
 ...
 s:drop()
diff --git a/test/engine/insert.test.lua b/test/engine/insert.test.lua
index 2ffc8cd0a067c772a45c4a30e5db2ce2ddf184ae..31b6bffc66700ff7b1f48f0304cdb5590d2200d5 100644
--- a/test/engine/insert.test.lua
+++ b/test/engine/insert.test.lua
@@ -130,27 +130,27 @@ s = box.schema.space.create('s', {format = {{'i', 'integer'}, {'d', 'double'}}})
 _ = s:create_index('ii')
 
 --
--- If number of Lua type NUMBER is not integer, than it could be
--- inserted in DOUBLE field.
+-- A number of Lua type NUMBER can be inserted in DOUBLE field.
 --
 s:insert({1, 1.1})
 s:insert({2, 2.5})
 s:insert({3, -3.0009})
 
 --
--- Integers of Lua type NUMBER and CDATA of type int64 or uint64
--- cannot be inserted into this field.
+-- Integers of Lua type NUMBER and CDATA of type int64 or uint64 can
+-- also be inserted even if they can't be loselessly converted to
+-- double. They're stored in the space "as is".
 --
 s:insert({4, 1})
-s:insert({5, -9223372036854775800ULL})
+s:insert({5, 9223372036854775800ULL})
 s:insert({6, 18000000000000000000ULL})
 
 --
--- To insert an integer, we must cast it to a CDATA of type DOUBLE
--- using ffi.cast(). Non-integers can also be inserted this way.
+-- One can also cast a value to CDATA of type DOUBLE using ffi.cast().
+-- Non-integers can also be inserted this way.
 --
 s:insert({7, ffi.cast('double', 1)})
-s:insert({8, ffi.cast('double', -9223372036854775808)})
+s:insert({8, ffi.cast('double', -9223372036854775800LL)})
 s:insert({9, ffi.cast('double', tonumber('123'))})
 s:insert({10, ffi.cast('double', tonumber64('18000000000000000000'))})
 s:insert({11, ffi.cast('double', 1.1)})
@@ -161,8 +161,8 @@ s:select()
 -- The same rules apply to the key of this field:
 dd = s:create_index('dd', {unique = false, parts = {{2, 'double'}}})
 dd:select(1.1)
-dd:select(1)
-dd:select(ffi.cast('double', 1))
+dd:select(-9223372036854775800LL)
+dd:select(ffi.cast('double', -9223372036854775800LL))
 
 -- Make sure the comparisons work correctly.
 dd:select(1.1, {iterator = 'ge'})
@@ -173,6 +173,8 @@ dd:select(1.1, {iterator = 'all'})
 dd:select(1.1, {iterator = 'eq'})
 dd:select(1.1, {iterator = 'req'})
 
+s:delete(4)
+s:delete(6)
 s:delete(11)
 s:delete(12)
 
@@ -182,7 +184,7 @@ ddd = s:create_index('ddd', {parts = {{2, 'double'}}})
 s:update(1, {{'=', 2, 2}})
 s:insert({22, 22})
 s:upsert({10, 100}, {{'=', 2, 2}})
-s:upsert({100, 100}, {{'=', 2, 2}})
+s:upsert({101, 100}, {{'=', 2, 11}})
 
 ddd:update(1, {{'=', 1, 70}})
 ddd:delete(1)
@@ -194,8 +196,8 @@ s:get(100)
 s:upsert({10, 100.5}, {{'=', 2, 2.2}})
 s:get(10)
 
-ddd:update(1.1, {{'=', 3, 111}})
-ddd:delete(1.1)
+ddd:update(2, {{'=', 3, 111}})
+ddd:delete(2)
 
 s:update(2, {{'=', 2, ffi.cast('double', 255)}})
 s:replace({22, ffi.cast('double', 22)})
@@ -204,7 +206,7 @@ s:get(200)
 s:upsert({200, ffi.cast('double', 200)}, {{'=', 2, ffi.cast('double', 222)}})
 s:get(200)
 
-ddd:update(ffi.cast('double', 1), {{'=', 3, 7}})
+ddd:update(22, {{'=', 3, 7}})
 ddd:delete(ffi.cast('double', 123))
 
 s:select()
diff --git a/test/sql-tap/cast.test.lua b/test/sql-tap/cast.test.lua
index 55f2d269078a7b0181c4c7364f258deee07d2ce8..8b1f53d3d82cf69d1226613a66c8449107f2ede2 100755
--- a/test/sql-tap/cast.test.lua
+++ b/test/sql-tap/cast.test.lua
@@ -1145,12 +1145,15 @@ test:do_catchsql_test(
     })
 
 -- Make sure that search using index in field type number work right.
+-- NOTE: Both 9999999999999999 and 10000000000000001 become the same value
+-- in index comparison because of double-cast, so we use -or-equal variants
+-- of iterators. Don't expect to have precise comparisons in double indexes.
 test:do_execsql_test(
     "cast-11",
     [[
         CREATE TABLE t6(d DOUBLE PRIMARY KEY);
         INSERT INTO t6 VALUES(10000000000000000);
-        SELECT d FROM t6 WHERE d < 10000000000000001 and d > 9999999999999999;
+        SELECT d FROM t6 WHERE d <= 10000000000000001 and d >= 9999999999999999;
         DROP TABLE t6;
     ]], {
         10000000000000000
diff --git a/test/vinyl/upsert.result b/test/vinyl/upsert.result
index 2db448c56c906dd2d284221dfd67b7233263083a..a2df181e373cc26fe86a52e05f6d6dfc658069bd 100644
--- a/test/vinyl/upsert.result
+++ b/test/vinyl/upsert.result
@@ -1187,12 +1187,12 @@ box.snapshot()
 ---
 - ok
 ...
--- Can't assign integer to float field. First operation is still applied.
+-- Can assign integer to float field.
 --
-s:upsert({1, 1, 1, 2.5, decimal.new(1.1)}, {{'+', 4, 4}})
+s:upsert({1, 1, 1, 2.5, decimal.new(1.1)}, {{'=', 4, 4}})
 ---
 ...
-s:upsert({1, 1, 1, 2.5, decimal.new(1.1)}, {{'=', 4, 4}})
+s:upsert({1, 1, 1, 2.5, decimal.new(1.1)}, {{'+', 4, 4}})
 ---
 ...
 -- Can't add floating point to integer (result is floating point).
@@ -1209,7 +1209,7 @@ box.snapshot()
 ...
 s:select()
 ---
-- - [1, 1, 1, 5.1, 1.1]
+- - [1, 1, 1, 8, 1.1]
   - [2, 6, 1, 1.1, 1.1]
 ...
 -- Integer overflow check.
@@ -1234,7 +1234,7 @@ box.snapshot()
 ...
 s:select()
 ---
-- - [1, 1, 9223372036854775809, 5.1, 1.1]
+- - [1, 1, 9223372036854775809, 8, 1.1]
   - [2, 8, 1, 1.1, 1.1]
 ...
 -- Decimals do not fit into numerics and vice versa.
@@ -1257,7 +1257,7 @@ box.snapshot()
 ...
 s:select()
 ---
-- - [1, 1, 9223372036854775809, 5.1, 2.1]
+- - [1, 1, 9223372036854775809, 8, 2.1]
   - [2, 8, 1, 1.1, 1.1]
 ...
 s:drop()
diff --git a/test/vinyl/upsert.test.lua b/test/vinyl/upsert.test.lua
index 4d0e35920f26c29d2fffcc986463243fd32ae883..30bfa799ec1e729fa7d22e0cec1bb8b8b8847c45 100644
--- a/test/vinyl/upsert.test.lua
+++ b/test/vinyl/upsert.test.lua
@@ -495,10 +495,10 @@ pk = s:create_index('pk')
 s:replace{1, 1, 1, 1.1, decimal.new(1.1) }
 s:replace{2, 1, 1, 1.1, decimal.new(1.1)}
 box.snapshot()
--- Can't assign integer to float field. First operation is still applied.
+-- Can assign integer to float field.
 --
-s:upsert({1, 1, 1, 2.5, decimal.new(1.1)}, {{'+', 4, 4}})
 s:upsert({1, 1, 1, 2.5, decimal.new(1.1)}, {{'=', 4, 4}})
+s:upsert({1, 1, 1, 2.5, decimal.new(1.1)}, {{'+', 4, 4}})
 -- Can't add floating point to integer (result is floating point).
 --
 s:upsert({2, 1, 1, 2.5, decimal.new(1.1)}, {{'+', 2, 5}})