Tarantool development patches archive
 help / color / mirror / Atom feed
From: Kirill Shcherbatov <kshcherbatov@tarantool.org>
To: tarantool-patches@freelists.org
Cc: vdavydov.dev@gmail.com, Kirill Shcherbatov <kshcherbatov@tarantool.org>
Subject: [PATCH v5 04/12] box: introduce tuple_format_add_key_part
Date: Mon, 29 Oct 2018 09:56:36 +0300	[thread overview]
Message-ID: <117feb46f029d4ba5d142fc614e063e2796a4f38.1540795996.git.kshcherbatov@tarantool.org> (raw)
In-Reply-To: <cover.1540795996.git.kshcherbatov@tarantool.org>
In-Reply-To: <cover.1540795996.git.kshcherbatov@tarantool.org>

Introduced a new tuple_format_add_key_part that makes format
initialization for specified key_part and configuration.
This decrease tuple_format_create routine complexity and would
be used to initialize structures in format for JSON path.

Need for #1012
---
 src/box/tuple_format.c | 153 ++++++++++++++++++++++++++-----------------------
 1 file changed, 82 insertions(+), 71 deletions(-)

diff --git a/src/box/tuple_format.c b/src/box/tuple_format.c
index 6f76158..088579c 100644
--- a/src/box/tuple_format.c
+++ b/src/box/tuple_format.c
@@ -43,6 +43,84 @@ static const struct tuple_field tuple_field_default = {
 	ON_CONFLICT_ACTION_DEFAULT, NULL, COLL_NONE,
 };
 
+static int
+tuple_format_add_key_part(struct tuple_format *format,
+			  const struct field_def *fields, uint32_t field_count,
+			  const struct key_part *part, bool is_sequential,
+			  int *current_slot)
+{
+	assert(part->fieldno < format->field_count);
+	struct tuple_field *field = &format->fields[part->fieldno];
+	/*
+	 * Field and part nullable actions may differ only
+	 * if one of them is DEFAULT, in which case we use
+	 * the non-default action *except* the case when
+	 * the other one is NONE, in which case we assume
+	 * DEFAULT. The latter is needed so that in case
+	 * index definition and space format have different
+	 * is_nullable flag, we will use the strictest option,
+	 * i.e. DEFAULT.
+	 */
+	if (part->fieldno >= field_count) {
+		field->nullable_action = part->nullable_action;
+	} else if (field->nullable_action == ON_CONFLICT_ACTION_DEFAULT) {
+		if (part->nullable_action != ON_CONFLICT_ACTION_NONE)
+			field->nullable_action = part->nullable_action;
+	} else if (part->nullable_action == ON_CONFLICT_ACTION_DEFAULT) {
+		if (field->nullable_action == ON_CONFLICT_ACTION_NONE)
+			field->nullable_action = part->nullable_action;
+	} else if (field->nullable_action != part->nullable_action) {
+		diag_set(ClientError, ER_ACTION_MISMATCH,
+			 part->fieldno + TUPLE_INDEX_BASE,
+			 on_conflict_action_strs[field->nullable_action],
+			 on_conflict_action_strs[part->nullable_action]);
+		return -1;
+	}
+
+	/**
+	 * Check that there are no conflicts between index part
+	 * types and space fields. If a part type is compatible
+	 * with field's one, then the part type is more strict
+	 * and the part type must be used in tuple_format.
+	 */
+	if (field_type1_contains_type2(field->type,
+					part->type)) {
+		field->type = part->type;
+	} else if (!field_type1_contains_type2(part->type,
+					       field->type)) {
+		const char *name;
+		int fieldno = part->fieldno + TUPLE_INDEX_BASE;
+		if (part->fieldno >= field_count) {
+			name = tt_sprintf("%d", fieldno);
+		} else {
+			const struct field_def *def =
+				&fields[part->fieldno];
+			name = tt_sprintf("'%s'", def->name);
+		}
+		int errcode;
+		if (!field->is_key_part)
+			errcode = ER_FORMAT_MISMATCH_INDEX_PART;
+		else
+			errcode = ER_INDEX_PART_TYPE_MISMATCH;
+		diag_set(ClientError, errcode, name,
+			 field_type_strs[field->type],
+			 field_type_strs[part->type]);
+		return -1;
+	}
+	field->is_key_part = true;
+	/*
+	 * In the tuple, store only offsets necessary to access
+	 * fields of non-sequential keys. First field is always
+	 * simply accessible, so we don't store an offset for it.
+	 */
+	if (field->offset_slot == TUPLE_OFFSET_SLOT_NIL &&
+	    is_sequential == false && part->fieldno > 0) {
+		*current_slot = *current_slot - 1;
+		field->offset_slot = *current_slot;
+	}
+	return 0;
+}
+
 /**
  * Extract all available type info from keys and field
  * definitions.
@@ -93,78 +171,11 @@ tuple_format_create(struct tuple_format *format, struct key_def * const *keys,
 		const struct key_part *parts_end = part + key_def->part_count;
 
 		for (; part < parts_end; part++) {
-			assert(part->fieldno < format->field_count);
-			struct tuple_field *field = &format->fields[part->fieldno];
-			/*
-			 * Field and part nullable actions may differ only
-			 * if one of them is DEFAULT, in which case we use
-			 * the non-default action *except* the case when
-			 * the other one is NONE, in which case we assume
-			 * DEFAULT. The latter is needed so that in case
-			 * index definition and space format have different
-			 * is_nullable flag, we will use the strictest option,
-			 * i.e. DEFAULT.
-			 */
-			if (part->fieldno >= field_count) {
-				field->nullable_action = part->nullable_action;
-			} else if (field->nullable_action == ON_CONFLICT_ACTION_DEFAULT) {
-				if (part->nullable_action != ON_CONFLICT_ACTION_NONE)
-					field->nullable_action = part->nullable_action;
-			} else if (part->nullable_action == ON_CONFLICT_ACTION_DEFAULT) {
-				if (field->nullable_action == ON_CONFLICT_ACTION_NONE)
-					field->nullable_action = part->nullable_action;
-			} else if (field->nullable_action != part->nullable_action) {
-				diag_set(ClientError, ER_ACTION_MISMATCH,
-					 part->fieldno + TUPLE_INDEX_BASE,
-					 on_conflict_action_strs[field->nullable_action],
-					 on_conflict_action_strs[part->nullable_action]);
+			if (tuple_format_add_key_part(format, fields,
+						      field_count, part,
+						      is_sequential,
+						      &current_slot) != 0)
 				return -1;
-			}
-
-			/*
-			 * Check that there are no conflicts
-			 * between index part types and space
-			 * fields. If a part type is compatible
-			 * with field's one, then the part type is
-			 * more strict and the part type must be
-			 * used in tuple_format.
-			 */
-			if (field_type1_contains_type2(field->type,
-						       part->type)) {
-				field->type = part->type;
-			} else if (! field_type1_contains_type2(part->type,
-								field->type)) {
-				const char *name;
-				int fieldno = part->fieldno + TUPLE_INDEX_BASE;
-				if (part->fieldno >= field_count) {
-					name = tt_sprintf("%d", fieldno);
-				} else {
-					const struct field_def *def =
-						&fields[part->fieldno];
-					name = tt_sprintf("'%s'", def->name);
-				}
-				int errcode;
-				if (! field->is_key_part)
-					errcode = ER_FORMAT_MISMATCH_INDEX_PART;
-				else
-					errcode = ER_INDEX_PART_TYPE_MISMATCH;
-				diag_set(ClientError, errcode, name,
-					 field_type_strs[field->type],
-					 field_type_strs[part->type]);
-				return -1;
-			}
-			field->is_key_part = true;
-			/*
-			 * In the tuple, store only offsets necessary
-			 * to access fields of non-sequential keys.
-			 * First field is always simply accessible,
-			 * so we don't store an offset for it.
-			 */
-			if (field->offset_slot == TUPLE_OFFSET_SLOT_NIL &&
-			    is_sequential == false && part->fieldno > 0) {
-
-				field->offset_slot = --current_slot;
-			}
 		}
 	}
 
-- 
2.7.4

  parent reply	other threads:[~2018-10-29  6:56 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-29  6:56 [PATCH v5 00/12] box: indexes by JSON path Kirill Shcherbatov
2018-10-29  6:56 ` [PATCH v5 01/12] box: refactor key_def_find routine Kirill Shcherbatov
2018-11-19 17:48   ` Vladimir Davydov
2018-10-29  6:56 ` [PATCH v5 10/12] box: tune tuple_field_raw_by_path for indexed data Kirill Shcherbatov
2018-10-29  6:56 ` [PATCH v5 11/12] box: introduce offset slot cache in key_part Kirill Shcherbatov
2018-11-01 13:32   ` [tarantool-patches] " Konstantin Osipov
2018-11-06 12:15     ` [tarantool-patches] " Kirill Shcherbatov
2018-10-29  6:56 ` [PATCH v5 12/12] box: specify indexes in user-friendly form Kirill Shcherbatov
2018-11-01 13:34   ` [tarantool-patches] " Konstantin Osipov
2018-11-01 14:18   ` Konstantin Osipov
2018-11-06 12:15     ` [tarantool-patches] " Kirill Shcherbatov
2018-10-29  6:56 ` [PATCH v5 02/12] box: introduce key_def_parts_are_sequential Kirill Shcherbatov
2018-11-01 14:23   ` [tarantool-patches] " Konstantin Osipov
2018-11-06 12:14     ` [tarantool-patches] " Kirill Shcherbatov
2018-11-19 17:48   ` Vladimir Davydov
2018-10-29  6:56 ` [PATCH v5 03/12] box: introduce tuple_field_go_to_path Kirill Shcherbatov
2018-11-19 17:48   ` Vladimir Davydov
2018-10-29  6:56 ` Kirill Shcherbatov [this message]
2018-11-01 14:38   ` [tarantool-patches] [PATCH v5 04/12] box: introduce tuple_format_add_key_part Konstantin Osipov
2018-11-06 12:15     ` [tarantool-patches] " Kirill Shcherbatov
2018-11-19 17:50   ` Vladimir Davydov
2018-10-29  6:56 ` [PATCH v5 05/12] lib: implement JSON tree class for json library Kirill Shcherbatov
2018-11-01 15:08   ` [tarantool-patches] " Konstantin Osipov
2018-11-06 12:15     ` [tarantool-patches] " Kirill Shcherbatov
2018-11-19 17:53       ` Vladimir Davydov
2018-11-20 16:43   ` Vladimir Davydov
2018-11-21 10:37     ` [tarantool-patches] " Kirill Shcherbatov
2018-11-26 10:50     ` Kirill Shcherbatov
2018-10-29  6:56 ` [PATCH v5 06/12] box: manage format fields with JSON tree class Kirill Shcherbatov
2018-10-29  6:56 ` [PATCH v5 07/12] lib: introduce json_path_normalize routine Kirill Shcherbatov
2018-11-01 15:22   ` [tarantool-patches] " Konstantin Osipov
2018-11-01 15:27     ` [tarantool-patches] " Kirill Shcherbatov
2018-11-20 15:13       ` Vladimir Davydov
2018-11-26 10:50         ` Kirill Shcherbatov
2018-11-20 15:14   ` Vladimir Davydov
2018-10-29  6:56 ` [PATCH v5 08/12] box: introduce JSON indexes Kirill Shcherbatov
2018-11-20 16:52   ` Vladimir Davydov
2018-11-26 10:50     ` [tarantool-patches] " Kirill Shcherbatov
2018-10-29  6:56 ` [tarantool-patches] [PATCH v5 09/12] box: introduce has_json_paths flag in templates Kirill Shcherbatov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=117feb46f029d4ba5d142fc614e063e2796a4f38.1540795996.git.kshcherbatov@tarantool.org \
    --to=kshcherbatov@tarantool.org \
    --cc=tarantool-patches@freelists.org \
    --cc=vdavydov.dev@gmail.com \
    --subject='Re: [PATCH v5 04/12] box: introduce tuple_format_add_key_part' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox