tarantool / go-tarantool

Tarantool 1.10+ client for Go language
https://pkg.go.dev/github.com/tarantool/go-tarantool/v2
BSD 2-Clause "Simplified" License
180 stars 57 forks source link

Cant GetTyped if one of tarantool response keys is non-string typed #368

Closed KaymeKaydex closed 7 months ago

KaymeKaydex commented 8 months ago

msgpack: invalid code=1 decoding string/bytes length

https://github.com/vmihailenco/msgpack/blob/19c91dfdfa062658c39d9321be26163fc5833bd1/decode_string.go#L31

KaymeKaydex commented 8 months ago
Снимок экрана 2024-01-02 в 22 05 34

but data non-empty

oleg-jukovec commented 8 months ago

Please give an example of the code in which you decode the response with GetTyped() and the response decoded as {}interface with Get().

Ideally I would like to see a minimal reproducer.

Now it’s not entirely clear to me what’s not working for you.

oleg-jukovec commented 8 months ago

I got it. You need to write a custom decoder for this cases, as example:

type testReproducer368 struct {
    Value int
    Foo   string
}

func (t *testReproducer368) DecodeMsgpack(d *msgpack.Decoder) error {
    var (
        err error
        l   int
    )
    if l, err = d.DecodeMapLen(); err != nil {
        return err
    }
    for i := 0; i < l; i++ {
        key, err := d.DecodeInterface()
        if err != nil {
            return err
        }
        value, err := d.DecodeInterface()
        if err != nil {
            return err
        }
        switch key {
        case int8(34):
            t.Value = int(value.(int8))
        case "foo":
            t.Foo = value.(string)
        }
    }
    return nil
}

func TestReproducer368(t *testing.T) {
    conn := test_helpers.ConnectWithValidation(t, dialer, opts)
    defer conn.Close()

    test := []testReproducer368{}
    err := conn.Do(NewEvalRequest("return {[34] = 2, foo = 'bar'}")).GetTyped(&test)
    require.NoError(t, err)
    require.Equal(t, []testReproducer368{testReproducer368{2, "bar"}}, test)
}

You could see examples of the custom decoders in the connector code or in the msgpack library. See: https://github.com/vmihailenco/msgpack/issues/314

oleg-jukovec commented 7 months ago

The reason in the msgpack library implementation, we can't fix it on our side.