Search code examples
luanosqltarantool

How to add new field to Tarantool space


I have a following space schema in Tarantool

box.schema.space.create('customer')

format = {
    {name = 'id', type = 'string'},
    {name = 'last_name', type = 'string'},
}

box.space.customer:format(format)
box.space.customer:create_index('id', {parts = {{field = 'id', is_nullable = false}}})
box.space.customer:replace({'1', 'Ivanov'})

I want to add the new field first_name to this space. What's the way I can do that?


Solution

  • Before answering a question we should discuss a format method.

    format - it’s a space option that allows you to get value from a tuple by name. Actually tuple is a “list” of values and any field could be accessed by field number.

    What’s next? E.g. you have a simple schema.

    box.schema.space.create('customer')
    box.space.customer:format(format)
    box.space.customer:create_index('id', {parts = {{field = 'id', is_nullable = false}}})
    box.space.customer:replace({'1', 'Ivanov'})
    

    Let’s define new format that has the third field - first_name.

    new_format = {
        {name = 'id', type = 'string'},
        {name = 'last_name', type = 'string'},
        {name = 'first_name', type = 'string'},
    }
    
    box.space.customer:format(new_format) -- error: our tuple have only two fields
    
    tarantool> box.space.customer:format(new_format)
    - --
    - error: Tuple field 3 required by space format is missing
    ...
    

    There are two ways to fix it.

    1. Add new field to the end of tuple with default value.
    box.space.customer:update({'1'}, {{'=', 3, 'Ivan'}})
    box.space.customer:format(new_format) -- OK
    
    1. Define new field as nullable
    new_format = {
        {name = 'id', type = 'string'},
        {name = 'last_name', type = 'string'},
        {name = 'first_name', type = 'string', is_nullable = true},
    }
    
    box.space.customer:format(new_format) -- OK: absence of the third value is acceptable
    

    You can choose one described above variant.

    I’ve just add some notes:

    • You can’t add some value through the absence field (e.g. you have first and second values you should add the third before adding the fourth)
    tarantool> box.tuple.new({'1', 'Ivanov'}):update({{'=', 4, 'value'}})
    - --
    - error: Field 4 was not found in the tuple
    
    ...
    
    tarantool> box.tuple.new({'1', 'Ivanov'}):update({{'=', 3, box.NULL}, {'=', 4, 'value'}})
    - --
    - ['1', 'Ivanov', null, 'value']
    
    ...
    
    • Filling in the field with the default value can be quite a long operation if you have a lot of data. Please be careful when apply any migratons.

    Read more about format method in the documentation.