[patches] [PATCH 4/4] Allow to do not specify tail nullable index columns

Vladimir Davydov vdavydov.dev at gmail.com
Sat Feb 17 23:19:36 MSK 2018


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.

AFAIU is_optional should be updated for all indexes in alter_space_do()
or in AlterSpaceOps, not here.

> diff --git a/src/box/key_def.h b/src/box/key_def.h
> index 96f4cdbf9..a7d6eedfb 100644
> --- a/src/box/key_def.h
> +++ b/src/box/key_def.h
> @@ -72,6 +72,8 @@ struct key_part {
>  	struct coll *coll;
>  	/** True if a part can store NULLs. */
>  	bool is_nullable;
> +	/** True, if a part can absense in a tuple. */

'absence' is always a noun, never a verb.
Fix your comments please.

> +	bool is_optional;
>  };
>  
>  struct key_def;
> @@ -126,6 +128,11 @@ struct key_def {
>  	uint32_t unique_part_count;
>  	/** True, if at least one part can store NULL. */
>  	bool is_nullable;
> +	/**
> +	 * True, if some key parts can absense in a tuple. These
> +	 * fields assumed to be MP_NIL.
> +	 */
> +	bool is_optional;

You add is_optional to both key_def and key_part, but I fail to
understand why you need them. You can detect if a field is missing
in a tuple without any flags, right? So why do you need them?

> diff --git a/src/box/tuple_compare.cc b/src/box/tuple_compare.cc
> index dcfb4f636..10c00a6f4 100644
> --- a/src/box/tuple_compare.cc
> +++ b/src/box/tuple_compare.cc
> @@ -589,18 +616,12 @@ tuple_compare_with_key_slowpath(const struct tuple *tuple, const char *key,
>  	return 0;
>  }
>  
> -/**
> - * is_sequential_nullable_tuples used to determine if this
> - * function is used to compare two tuples, which keys are
> - * sequential. In such a case it is necessary to compare them
> - * using primary parts if a NULL was met.
> - */
> -template<bool is_nullable, bool is_sequential_nullable_tuples>
> +template<bool is_nullable>
>  static inline int
>  key_compare_parts(const char *key_a, const char *key_b, uint32_t part_count,
>  		  const struct key_def *key_def)

To ease review, removal of is_sequential_nullable_tuples template
parameter should be done in a separate patch.

> -static int
> -tuple_compare_sequential_nullable(const struct tuple *tuple_a,
> -				  const struct tuple *tuple_b,
> -				  const struct key_def *key_def)

Turning tuple_compare_sequential_nullable into a template parameter
should be done in a separate patch. Folding it in the patch removing
is_sequential_nullable_tuples (see above) would be OK.



More information about the Tarantool-patches mailing list