tarantool
tarantool copied to clipboard
`tostring(tuple)` is super outdated
When tuple is serialized alone, it uses a very old function tuple_to_yaml which does not support any of the msgpack extensions. But when it is serialized as a part of a table, there acts some other serialization function which handles them fine. Example which uses all the extensions which we support by now (and MP_BIN`):
box.cfg{}
dt = require('datetime')
uuid = require('uuid')
dec = require('decimal')
mp = require('msgpack')
log = require('log')
tuple = {1}
table.insert(tuple, dec.new(2))
table.insert(tuple, uuid.new())
table.insert(tuple, dt.new({year = 3}))
table.insert(tuple, dt.interval.new({year = 4}))
value_as_tuple = box.execute([[SELECT CAST('5' AS VARBINARY)]]).rows[1]
value_as_tuple_mp = mp.object(value_as_tuple)
iter = value_as_tuple_mp:iterator()
iter:decode_array_header()
table.insert(tuple, iter:take())
tuple = box.tuple.new(tuple)
tarantool> log.info(tuple)
2022-05-31 01:44:12.363 [13847] main/103/interactive I> [1, null, null, null, null, !!binary NQ==]
---
...
tarantool> log.info({tuple})
2022-05-31 01:44:15.987 [13847] main/103/interactive I> [[1,"2","8a9d4179-8167-43c4-ae93-3f9c51bd2f1f","0003-01-01T00:00:00Z","+4 years","5"]]
---
...
Logs use yaml Lua module when get a table. For other types they use tostring method. As one can see, tuple alone turns all extensions into null. Tuple in a table prints its fields just fine.
I think tuple_to_yaml() should be deleted. Its only usage is in lbox_tuple_to_string(). Instead, the latter should try to reuse lua-yaml/lyaml.h API. Maybe rework it a bit if needed. When I tried to use lua_yaml_encode() straight away for tuple const char *data, I got somewhat strange result - valid yaml but looked weird.
Another issue is that tuple_to_yaml()doesn't respect serialization settings (the ones you setup via require('yaml').cfg(...).
Wasted a couple of hours because of that issue when thought my logs are corrupted due to a memory override or a similar problem.
This gets especially annoying in tests. For example, for the following assertion
t.assert_equals(box.tuple.new({require('uuid').new()}),
box.tuple.new({require('uuid').new()}))
luatest prints
expected: [null], actual: [null]