[patches] [PATCH 4/4] Allow to do not specify tail nullable index columns
Vladimir Davydov
vdavydov.dev at gmail.com
Sun Feb 18 13:15:08 MSK 2018
On Sat, Feb 17, 2018 at 11:38:57PM +0300, v.shpilevoy at tarantool.org wrote:
>
>
> С уважением, Владислав Шпилевой.
>
> > 17 февр. 2018 г., в 23:19, Vladimir Davydov <vdavydov.dev at gmail.com> написал(а):
> >
> >> On Tue, Feb 13, 2018 at 06:28:38PM +0300, Vladislav Shpilevoy wrote:
> >> diff --git a/src/box/alter.cc b/src/box/alter.cc
> >> index c48e89f9e..cb3b8353d 100644
> >> --- a/src/box/alter.cc
> >> +++ b/src/box/alter.cc
> >> @@ -323,7 +323,39 @@ index_def_new_from_tuple(struct tuple *tuple, struct space *space)
> >> space->def->field_count) != 0)
> >> diag_raise();
> >> }
> >> - key_def = key_def_new_with_parts(part_def, part_count);
> >> + struct space_def *sd = space->def;
> >> + int unchanged_index_count = 0;
> >> + struct key_def **keys = NULL;
> >> + /*
> >> + * To detect which key parts are optional, min_field_count
> >> + * is required. But min_field_count from the old space
> >> + * format can not be used. For example, consider the case,
> >> + * when a space has no format, has a primary index on the
> >> + * first field and has a single secondary index on a
> >> + * non-nullable second field. Min field count here is 2.
> >> + * Now alter the secondary index to make its part be
> >> + * nullable. The 'space' variable here is the old space,
> >> + * where min_field_count is still 2, but actually it is
> >> + * already 1. Actual min_field_count must be calculated
> >> + * using old unchanged indexes, NEW definition of an
> >> + * updated index and a space format, defined by a user.
> >> + */
> >> + for (uint32_t i = 0; i < space->index_count; ++i) {
> >> + if (space->index[i]->def->iid != index_id)
> >> + ++unchanged_index_count;
> >> + }
> >> + if (unchanged_index_count > 0) {
> >> + size_t bsize = unchanged_index_count * sizeof(keys[0]);
> >> + keys = (struct key_def **) region_alloc_xc(&fiber()->gc, bsize);
> >> + for (uint32_t i = 0, j = 0; i < space->index_count; ++i) {
> >> + if (space->index[i]->def->iid != index_id)
> >> + keys[j++] = space->index[i]->def->key_def;
> >> + }
> >> + }
> >> + uint32_t min_field_count =
> >> + tuple_format_min_field_count(keys, unchanged_index_count,
> >> + sd->fields, sd->field_count);
> >> + key_def = key_def_new_with_parts(part_def, part_count, min_field_count);
> >
> > What will happen if there are two indexes over the same field, nullable
> > and not nullable, and the one which is not nullable is set to be
> > nullable? I don't see where you update is_optional then.
>
> Is_optional in such a case is set due to decreased min_field_count.
Well, I tried to check this, but got a crash:
vlad at esperanza test$ cat test.lua
box.cfg{log_level = 2}
s = box.schema.space.create('test')
s:create_index('pk')
i1 = s:create_index('i1', {parts = {2, 'unsigned', 3, 'unsigned'}})
i2 = s:create_index('i2', {parts = {3, 'unsigned', 2, 'unsigned'}})
i1:alter{parts = {{2, 'unsigned'}, {3, 'unsigned', is_nullable = true}}}
i2:alter{parts = {{3, 'unsigned', is_nullable = true}, {2, 'unsigned'}}}
s:insert{1, 1}
vlad at esperanza test$ tarantool test.lua
tarantool: /home/vlad/src/tarantool/src/box/tuple_format.c:94: tuple_format_create: Assertion `part->fieldno + 1 <= format->min_field_count || part->is_optional' failed.
Aborted
>
> >
> > AFAIU is_optional should be updated for all indexes in alter_space_do()
> > or in AlterSpaceOps, not here.
>
> I disagree.
More information about the Tarantool-patches
mailing list