diff --git a/src/lua/utils.c b/src/lua/utils.c index d5122ee2c137470be2429b23ea574186a0fbcc50..208b64eb115f3e2ca5dee3b0199f3664e0f147f2 100644 --- a/src/lua/utils.c +++ b/src/lua/utils.c @@ -667,7 +667,7 @@ luaL_tofield(struct lua_State *L, struct luaL_serializer *cfg, int index, } else if (num >= 0 && num < exp2(64)) { field->type = MP_UINT; field->ival = (uint64_t) num; - } else if (num > -exp2(63) && num < exp2(63)) { + } else if (num >= -exp2(63) && num < exp2(63)) { field->type = MP_INT; field->ival = (int64_t) num; } else { diff --git a/test/app-tap/lua/serializer_test.lua b/test/app-tap/lua/serializer_test.lua index 1609f768f19989b1b45f6c68cc39728d1870111d..03855975681390d1346c1e56e4e6d458c4f971fc 100644 --- a/test/app-tap/lua/serializer_test.lua +++ b/test/app-tap/lua/serializer_test.lua @@ -101,7 +101,7 @@ local function test_unsigned(test, s) end local function test_signed(test, s) - test:plan(52) + test:plan(53) rt(test, s, -1, 'number') rt(test, s, -1LL, 'number') @@ -143,6 +143,10 @@ local function test_signed(test, s) rt(test, s, ffi.new('short', -128), 'number') rt(test, s, ffi.new('int', -128), 'number') + + -- gh-4672: Make sure that -2^63 encoded as INTEGER. + test:ok(s.encode(-9223372036854775808LL) == s.encode(-2^63), + '-2^63 encoded as INTEGER') end local function test_double(test, s) diff --git a/test/box/gh-4672-min-integer-value-in-serializer.result b/test/box/gh-4672-min-integer-value-in-serializer.result new file mode 100644 index 0000000000000000000000000000000000000000..f4d7adb4d33b15f018545ab0c96b4bbbbfd950a9 --- /dev/null +++ b/test/box/gh-4672-min-integer-value-in-serializer.result @@ -0,0 +1,97 @@ +-- test-run result file version 2 +remote = require('net.box') + | --- + | ... +env = require('test_run') + | --- + | ... +test_run = env.new() + | --- + | ... + +-- +-- gh-4672: Due to an error in the serializer, -2^63 was +-- serialized as double, although in accordance with the rules of +-- serialization it should be serialized as an integer. +-- +format={{name='u', type='unsigned'}, {name='i', type='integer'}} + | --- + | ... +s = box.schema.space.create('serializer_test_space', {format=format}) + | --- + | ... +_ = s:create_index('ii') + | --- + | ... + +s:insert({1, -2^63}) + | --- + | - [1, -9223372036854775808] + | ... +s:insert({2, -9223372036854775808LL}) + | --- + | - [2, -9223372036854775808] + | ... +s:insert({3, 0}) + | --- + | - [3, 0] + | ... +s:update(3, {{'=', 'i', -2^63}}) + | --- + | - [3, -9223372036854775808] + | ... +s:insert({4, 0}) + | --- + | - [4, 0] + | ... +s:update(4, {{'=', 'i', -9223372036854775808LL}}) + | --- + | - [4, -9223372036854775808] + | ... + +box.schema.user.grant('guest', 'read, write', 'space', 'serializer_test_space') + | --- + | ... + +cn = remote.connect(box.cfg.listen) + | --- + | ... +s = cn.space.serializer_test_space + | --- + | ... + +s:insert({11, -2^63}) + | --- + | - [11, -9223372036854775808] + | ... +s:insert({12, -9223372036854775808LL}) + | --- + | - [12, -9223372036854775808] + | ... +s:insert({13, 0}) + | --- + | - [13, 0] + | ... +s:update(13, {{'=', 'i', -2^63}}) + | --- + | - [13, -9223372036854775808] + | ... +s:insert({14, 0}) + | --- + | - [14, 0] + | ... +s:update(14, {{'=', 'i', -9223372036854775808LL}}) + | --- + | - [14, -9223372036854775808] + | ... + +cn:close() + | --- + | ... +box.schema.user.revoke('guest', 'read, write', 'space', 'serializer_test_space') + | --- + | ... + +box.space.serializer_test_space:drop() + | --- + | ... diff --git a/test/box/gh-4672-min-integer-value-in-serializer.test.lua b/test/box/gh-4672-min-integer-value-in-serializer.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..f718a56147395d9b80385a9c37a7638e75a798f1 --- /dev/null +++ b/test/box/gh-4672-min-integer-value-in-serializer.test.lua @@ -0,0 +1,36 @@ +remote = require('net.box') +env = require('test_run') +test_run = env.new() + +-- +-- gh-4672: Due to an error in the serializer, -2^63 was +-- serialized as double, although in accordance with the rules of +-- serialization it should be serialized as an integer. +-- +format={{name='u', type='unsigned'}, {name='i', type='integer'}} +s = box.schema.space.create('serializer_test_space', {format=format}) +_ = s:create_index('ii') + +s:insert({1, -2^63}) +s:insert({2, -9223372036854775808LL}) +s:insert({3, 0}) +s:update(3, {{'=', 'i', -2^63}}) +s:insert({4, 0}) +s:update(4, {{'=', 'i', -9223372036854775808LL}}) + +box.schema.user.grant('guest', 'read, write', 'space', 'serializer_test_space') + +cn = remote.connect(box.cfg.listen) +s = cn.space.serializer_test_space + +s:insert({11, -2^63}) +s:insert({12, -9223372036854775808LL}) +s:insert({13, 0}) +s:update(13, {{'=', 'i', -2^63}}) +s:insert({14, 0}) +s:update(14, {{'=', 'i', -9223372036854775808LL}}) + +cn:close() +box.schema.user.revoke('guest', 'read, write', 'space', 'serializer_test_space') + +box.space.serializer_test_space:drop()