box: compare and hash msgpack value of double key field as double
1. Make double-formatted fields accept integer and float values. 2. Make indexes compare the values as double if the field key type is FIELD_TYPE_DOUBLE. 3. Make hashers cast double key field to double before hashing, so we are able to insert and select any int, uint, float or double if their value casted to double is equal (for double keys). Notes about tuple_compare.cc: Since now `mp_compare_double` casts any value placed in field to double it was renamed to `mp_compare_as_double` to not semantically conflict with existing `mp_compare_double_*` functions. Notes about tuple_hash.cc: The hashee cast result is encoded in MP_DOUBLE and hashed for backward compatibility reasons. Since now the field hashing function (tuple_hash_field) requires field type to hash the field correctly, a new parameter has been introduced. By the way added assertions to the generic `field_hash` to prevent invalid hashing for new precompiled hashers and made `key_hash_slowpath` static cause it's only used in this file. Closes #7483 Closes #5933 Unblocks tarantool/crud#298 @TarantoolBot document Title: It's not required to ffi-cast integral floating point to double anymore. The page describing tarantool data model states that: > In Lua, fields of the double type can only contain non-integer > numeric values... If the patch is merged this isn't the case anymore, so this statement and the code snippet below it should be updated. Link to the document: [Data storage](https://www.tarantool.io/en/doc/latest/concepts/data_model/value_store/#field-type-details). Affected segments: > double. The double field type exists mainly to be equivalent > to Tarantool/SQL’s DOUBLE data type. In msgpuck.h (Tarantool’s > interface to MsgPack), the storage type is MP_DOUBLE and the > size of the encoded value is always 9 bytes. In Lua, fields of > the double type can only contain non-integer numeric values and > cdata values with double floating-point numbers. Examples: 1.234, > -44, 1.447e+44. > > To avoid using the wrong kind of values inadvertently, use > ffi.cast() when searching or changing double fields. For example, > instead of space_object:insert{value} use ffi = require('ffi') > ... space_object:insert({ffi.cast('double',value)}). Example: > > ``` > s = box.schema.space.create('s', {format = {{'d', 'double'}}}) > s:create_index('ii') > s:insert({1.1}) > ffi = require('ffi') > s:insert({ffi.cast('double', 1)}) > s:insert({ffi.cast('double', tonumber('123'))}) > s:select(1.1) > s:select({ffi.cast('double', 1)}) > ```
Showing
- changelogs/unreleased/gh-7483-ignore-mpack-types.md 4 additions, 0 deletionschangelogs/unreleased/gh-7483-ignore-mpack-types.md
- src/box/field_def.c 2 additions, 1 deletionsrc/box/field_def.c
- src/box/key_def.h 2 additions, 1 deletionsrc/box/key_def.h
- src/box/tuple_bloom.c 2 additions, 0 deletionssrc/box/tuple_bloom.c
- src/box/tuple_compare.cc 23 additions, 7 deletionssrc/box/tuple_compare.cc
- src/box/tuple_hash.cc 49 additions, 6 deletionssrc/box/tuple_hash.cc
- test/engine-luatest/gh_7483_insert_int_into_double_field_test.lua 67 additions, 0 deletions...ine-luatest/gh_7483_insert_int_into_double_field_test.lua
- test/engine/insert.result 50 additions, 37 deletionstest/engine/insert.result
- test/engine/insert.test.lua 16 additions, 14 deletionstest/engine/insert.test.lua
- test/sql-tap/cast.test.lua 4 additions, 1 deletiontest/sql-tap/cast.test.lua
- test/vinyl/upsert.result 6 additions, 6 deletionstest/vinyl/upsert.result
- test/vinyl/upsert.test.lua 2 additions, 2 deletionstest/vinyl/upsert.test.lua
Loading