cartridge-java icon indicating copy to clipboard operation
cartridge-java copied to clipboard

Writing byte[] values into varbinary fields fails

Open akudiyar opened this issue 3 years ago • 3 comments

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

akudiyar avatar Oct 24 '21 15:10 akudiyar

Possible solution: implement encoding procedure as suggested in https://github.com/tarantool/tarantool/issues/1629#issuecomment-705097392

akudiyar avatar Oct 24 '21 15:10 akudiyar

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.

ArtDu avatar May 24 '22 21:05 ArtDu

Related (in context of crud): https://github.com/tarantool/crud/issues/298

Totktonada avatar Jun 06 '22 14:06 Totktonada