cartridge-java
cartridge-java copied to clipboard
Writing byte[] values into varbinary fields fails
Having the following space structure:
local test_space_with_byte_array = box.schema.space.create(
'test_space_with_byte_array', { if_not_exists = true })
test_space_with_byte_array:format({
{ name = 'id', type = 'unsigned' },
{ name = 'bucket_id', type = 'unsigned' },
{ name = 'value', type = 'varbinary' },
});
and trying to write a byte value into it:
client.space(SPACE)
.insert(tupleFactory.create(1, null, new byte[]{1, 2, 3, 4})).get();
it fails with the following error:
java.util.concurrent.ExecutionException: io.tarantool.driver.exceptions.TarantoolInternalException: InnerErrorMessage:
str: Insert: Failed to insert: Call: Failed for d1bf9bff-b57d-4f8b-804c-8f34e24fdb14: Function returned an error: {"code":32,"base_type":"ClientError","type":"ClientError","message":"Tuple field 3 (value) type does not match one required by operation: expected varbinary, got string","trace":[{"file":"[C]","line":4294967295}]}
stack traceback:
/app/.rocks/share/tarantool/crud/common/call.lua:163: in function 'rw_single'
/app/.rocks/share/tarantool/crud/insert.lua:71: in function </app/.rocks/share/tarantool/crud/insert.lua:52>
[C]: at 0x004fdd50
line: 76
class_name: Insert
err: /app/.rocks/share/tarantool/crud/insert.lua
Expected behavior: byte arrays are correctly encoded and saved into varbinary
fields.
Related to https://github.com/tarantool/tarantool/issues/1629
Possible solution: implement encoding procedure as suggested in https://github.com/tarantool/tarantool/issues/1629#issuecomment-705097392
space operations (IPROTO_SELECT, IPROTO_INSERT and etc.)
We have correctly varbinary work with space iproto methods without touching the lua world(i.e. not IPROTO_EVAL/CALL) (you can see the correct work here https://github.com/tarantool/cartridge-java/pull/228).
lua world operations (IPROTO_CALL, IPROTO_EVAL)
In the lua world, we accept a string because there is no easy way to pass MP_BIN to lua without ffi
https://github.com/tarantool/tarantool/issues/1629 . That is the reason why crud functions don't work correctly.
Possible solution: implement encoding procedure as suggested in tarantool/tarantool#1629 (comment)
We can implement this only in lua code, we just accept MP_BIN as lua string from IPROTO(java connector). Without any handlers on the lua side, we can't pass true MP_BIN in space.
proposal
In my opinion there is only one w/a how to use Java byte array, and that is using string field in Tarantool space and StringToByteArrayConverter in cartridge-java.
Related (in context of crud): https://github.com/tarantool/crud/issues/298