From ca4987e76c38a8d5367195de32061192caa720de Mon Sep 17 00:00:00 2001
From: Konstantin Osipov <kostja@tarantool.org>
Date: Fri, 5 Jul 2013 19:02:20 +0400
Subject: [PATCH] Make space->max_fieldno actually mean what the name says.

---
 src/box/box.cc     |  2 +-
 src/box/key_def.cc |  7 +++----
 src/box/key_def.h  |  4 ++--
 src/box/space.cc   | 10 +++++-----
 4 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/src/box/box.cc b/src/box/box.cc
index 1be2126ec7..386a12e54f 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -124,7 +124,7 @@ recover_snap_row(const void *data)
 	struct space *space = space_find(row->space);
 	Index *index = space_index(space, 0);
 	/* Check to see if the tuple has a sufficient number of fields. */
-	if (unlikely(row->tuple_size < space->max_fieldno)) {
+	if (unlikely(row->tuple_size < space->max_fieldno + 1)) {
 		tnt_raise(IllegalParams,
 			  "tuple must have all indexed fields");
 	}
diff --git a/src/box/key_def.cc b/src/box/key_def.cc
index f668fb23dc..29c51c5944 100644
--- a/src/box/key_def.cc
+++ b/src/box/key_def.cc
@@ -63,13 +63,12 @@ key_def_create(struct key_def *def, struct tarantool_cfg_space_index *cfg_index)
 	def->parts = (struct key_part *) malloc(sizeof(struct key_part) *
 						def->part_count);
 
+	uint32_t cmp_order_size = (def->max_fieldno + 1) * sizeof(uint32_t);
 	/* init compare order array */
-	def->max_fieldno++;
-	def->cmp_order = (uint32_t *) malloc(def->max_fieldno * sizeof(uint32_t));
+	def->cmp_order = (uint32_t *) malloc(cmp_order_size);
 
-	for (uint32_t fieldno = 0; fieldno < def->max_fieldno; fieldno++) {
+	for (uint32_t fieldno = 0; fieldno <= def->max_fieldno; fieldno++)
 		def->cmp_order[fieldno] = UINT32_MAX;
-	}
 
 	/* fill fields and compare order */
 	for (uint32_t k = 0; cfg_index->key_field[k] != NULL; ++k) {
diff --git a/src/box/key_def.h b/src/box/key_def.h
index 3ba9954108..8cc2340827 100644
--- a/src/box/key_def.h
+++ b/src/box/key_def.h
@@ -77,8 +77,8 @@ struct key_def {
 	/* The size of the 'parts' array. */
 	uint32_t part_count;
 	/*
-	 * The size of 'cmp_order' array (= max fieldno in 'parts'
-	 * array).
+	 * Max fieldno in 'parts' array. Defines the size of
+	 * cmp_order array (which is max_fieldno + 1).
 	 */
 	uint32_t max_fieldno;
 	bool is_unique;
diff --git a/src/box/space.cc b/src/box/space.cc
index 9ed0524f04..0df76ddf98 100644
--- a/src/box/space.cc
+++ b/src/box/space.cc
@@ -206,7 +206,7 @@ void
 space_validate_tuple(struct space *sp, struct tuple *new_tuple)
 {
 	/* Check to see if the tuple has a sufficient number of fields. */
-	if (new_tuple->field_count < sp->max_fieldno)
+	if (new_tuple->field_count < sp->max_fieldno + 1)
 		tnt_raise(IllegalParams,
 			  "tuple must have all indexed fields");
 
@@ -221,8 +221,6 @@ space_validate_tuple(struct space *sp, struct tuple *new_tuple)
 	uint32_t len;
 	uint32_t fieldno = 0;
 	while ((field = tuple_next(&it, &len))) {
-		if (fieldno == sp->max_fieldno)
-			break;
 		/*
 		 * Check fixed size fields (NUM and NUM64) and
 		 * skip undefined size fields (STRING and UNKNOWN).
@@ -236,6 +234,8 @@ space_validate_tuple(struct space *sp, struct tuple *new_tuple)
 				tnt_raise(ClientError, ER_KEY_FIELD_TYPE,
 					  "NUM64");
 		}
+		if (fieldno == sp->max_fieldno)
+			break;
 		fieldno++;
 	}
 }
@@ -276,14 +276,14 @@ space_init_field_types(struct space *space)
 	/* alloc & init field type info */
 	space->max_fieldno = max_fieldno;
 	space->field_types = (enum field_type *)
-			     calloc(max_fieldno, sizeof(enum field_type));
+			     calloc(max_fieldno + 1, sizeof(enum field_type));
 
 	/* extract field type info */
 	for (i = 0; i < key_count; i++) {
 		struct key_def *def = &key_defs[i];
 		for (uint32_t pi = 0; pi < def->part_count; pi++) {
 			struct key_part *part = &def->parts[pi];
-			assert(part->fieldno < max_fieldno);
+			assert(part->fieldno <= max_fieldno);
 			space->field_types[part->fieldno] = part->type;
 		}
 	}
-- 
GitLab