From a07c5e83a2b97e387438916efc84dfd6b51b1d54 Mon Sep 17 00:00:00 2001
From: Konstantin Osipov <kostja@tarantool.org>
Date: Thu, 12 Sep 2013 13:44:43 +0400
Subject: [PATCH] Continue adding test coverage for CREATE/DROP SPACE, INDEX.

Cover basics of CREATE INDEX.
Add support for index names.
Maintain index names in Lua.
---
 src/box/alter.cc               | 21 +++++-----
 src/box/box_lua.cc             |  4 +-
 src/box/box_lua_space.cc       | 35 ++++++++++-------
 src/box/index.h                |  2 +-
 src/box/key_def.cc             | 65 ++++++++++++++++++++-----------
 src/box/key_def.h              | 19 +++++----
 src/box/lua/schema.lua         | 12 ++++--
 src/box/schema.cc              | 33 ++++++++++------
 src/box/schema.h               |  4 ++
 src/box/space.cc               |  4 +-
 src/box/tuple.cc               |  2 +-
 test/box/alter_limits.result   | 71 +++++++++++++++++++++-------------
 test/box/alter_limits.test.lua | 55 ++++++++++++++------------
 test/box/lua.result            | 16 ++++----
 test/box/lua.test.py           | 16 ++++----
 15 files changed, 216 insertions(+), 143 deletions(-)

diff --git a/src/box/alter.cc b/src/box/alter.cc
index f60fd10304..1a46a81773 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -69,8 +69,9 @@ key_def_new_from_tuple(struct tuple *tuple)
 	enum index_type type = STR2ENUM(index_type, type_str);
 	uint32_t is_unique = tuple_field_u32(tuple, INDEX_IS_UNIQUE);
 	uint32_t part_count = tuple_field_u32(tuple, INDEX_PART_COUNT);
+	const char *name = tuple_field_cstr(tuple, NAME);
 
-	struct key_def *key_def = key_def_new(index_id, type,
+	struct key_def *key_def = key_def_new(id, index_id, name, type,
 					      is_unique > 0, part_count);
 	auto scoped_guard =
 		make_scoped_guard([=] { key_def_delete(key_def); });
@@ -88,7 +89,7 @@ key_def_new_from_tuple(struct tuple *tuple)
 			STR2ENUM(field_type, field_type_str);
 		key_def_set_part(key_def, i, fieldno, field_type);
 	}
-	key_def_check(id, key_def);
+	key_def_check(key_def);
 	scoped_guard.is_active = false;
 	return key_def;
 }
@@ -562,7 +563,7 @@ ModifyIndex::commit(struct alter_space *alter)
 {
 	/* Move the old index to the new place but preserve */
 	space_swap_index(alter->old_space, alter->new_space,
-			 old_key_def->id, new_key_def->id);
+			 old_key_def->iid, new_key_def->iid);
 }
 
 ModifyIndex::~ModifyIndex()
@@ -661,7 +662,7 @@ AddIndex::prepare(struct alter_space *alter)
 void
 AddIndex::alter_def(struct alter_space *alter)
 {
-	rlist_add_entry(&alter->key_list, new_key_def, link);
+	rlist_add_tail_entry(&alter->key_list, new_key_def, link);
 }
 
 /**
@@ -716,7 +717,7 @@ AddIndex::alter(struct alter_space *alter)
 	 * Possible both during and after recovery.
 	 */
 	if (alter->new_space->engine.state == READY_NO_KEYS) {
-		if (new_key_def->id == 0) {
+		if (new_key_def->iid == 0) {
 			/*
 			 * Adding a primary key: bring the space
 			 * up to speed with the current recovery
@@ -745,10 +746,10 @@ AddIndex::alter(struct alter_space *alter)
 		return;
 	}
 	Index *pk = index_find(alter->old_space, 0);
-	Index *new_index = index_find(alter->new_space, new_key_def->id);
+	Index *new_index = index_find(alter->new_space, new_key_def->iid);
 	/* READY_PRIMARY_KEY is a state that only occurs during WAL recovery. */
 	if (alter->new_space->engine.state == READY_PRIMARY_KEY) {
-		if (new_key_def->id == 0) {
+		if (new_key_def->iid == 0) {
 			/*
 			 * Bulk rebuild of the new primary key
 			 * from old primary key - it is safe to do
@@ -994,10 +995,10 @@ on_replace_dd_index(struct trigger * /* trigger */, void *event)
 	struct tuple *old_tuple = txn->old_tuple;
 	struct tuple *new_tuple = txn->new_tuple;
 	uint32_t id = tuple_field_u32(old_tuple ? old_tuple : new_tuple, ID);
-	uint32_t index_id = tuple_field_u32(old_tuple ? old_tuple : new_tuple,
-					    INDEX_ID);
+	uint32_t iid = tuple_field_u32(old_tuple ? old_tuple : new_tuple,
+				       INDEX_ID);
 	struct space *old_space = space_find(id);
-	Index *old_index = space_index(old_space, index_id);
+	Index *old_index = space_index(old_space, iid);
 	struct alter_space *alter = alter_space_new();
 	auto scoped_guard =
 		make_scoped_guard([=] { alter_space_delete(alter); });
diff --git a/src/box/box_lua.cc b/src/box/box_lua.cc
index 7d43c1c283..01959b2f5a 100644
--- a/src/box/box_lua.cc
+++ b/src/box/box_lua.cc
@@ -688,7 +688,7 @@ lua_checkindex(struct lua_State *L, int i)
 }
 
 static int
-lbox_index_new(struct lua_State *L)
+lbox_index_bind(struct lua_State *L)
 {
 	uint32_t id = (uint32_t) luaL_checkint(L, 1); /* get space id */
 	uint32_t iid = (uint32_t) luaL_checkint(L, 2); /* get index id in */
@@ -976,7 +976,7 @@ static const struct luaL_reg lbox_index_meta[] = {
 };
 
 static const struct luaL_reg indexlib [] = {
-	{"new", lbox_index_new},
+	{"bind", lbox_index_bind},
 	{NULL, NULL}
 };
 
diff --git a/src/box/box_lua_space.cc b/src/box/box_lua_space.cc
index a3ea0ebe44..edc3c5aa28 100644
--- a/src/box/box_lua_space.cc
+++ b/src/box/box_lua_space.cc
@@ -93,16 +93,23 @@ lbox_fillspace(struct lua_State *L, struct space *space, int i)
 		if (index == NULL)
 			continue;
 		struct key_def *key_def = index->key_def;
-		lua_pushnumber(L, key_def->id);
+		lua_pushnumber(L, key_def->iid);
 		lua_newtable(L);		/* space.index[i] */
 
-		lua_pushstring(L, "unique");
 		lua_pushboolean(L, key_def->is_unique);
-		lua_settable(L, -3);
+		lua_setfield(L, -2, "unique");
 
-		lua_pushstring(L, "type");
 		lua_pushstring(L, index_type_strs[key_def->type]);
-		lua_settable(L, -3);
+		lua_setfield(L, -2, "type");
+
+		lua_pushnumber(L, key_def->iid);
+		lua_setfield(L, -2, "id");
+
+		lua_pushnumber(L, key_def->space_id);
+		lua_setfield(L, -2, "n");
+
+		lua_pushstring(L, key_def->name);
+		lua_setfield(L, -2, "name");
 
 		lua_pushstring(L, "key_field");
 		lua_newtable(L);
@@ -111,21 +118,21 @@ lbox_fillspace(struct lua_State *L, struct space *space, int i)
 			lua_pushnumber(L, j);
 			lua_newtable(L);
 
-			lua_pushstring(L, "type");
 			lua_pushstring(L,
 			       field_type_strs[key_def->parts[j].type]);
-			lua_settable(L, -3);
+			lua_setfield(L, -2, "type");
 
-			lua_pushstring(L, "fieldno");
 			lua_pushnumber(L, key_def->parts[j].fieldno);
-			lua_settable(L, -3);
+			lua_setfield(L, -2, "fieldno");
 
-			lua_settable(L, -3);
+			lua_settable(L, -3); /* index[i].key_field[j] */
 		}
 
-		lua_settable(L, -3);	/* index[i].key_field */
+		lua_settable(L, -3); /* space.index[i].key_field */
 
-		lua_settable(L, -3);	/* space.index[i] */
+		lua_settable(L, -3); /* space.index[i] */
+		lua_rawgeti(L, -1, key_def->iid);
+		lua_setfield(L, -2, key_def->name);
 	}
 
 	lua_pop(L, 1); /* pop the index field */
@@ -175,9 +182,7 @@ box_lua_space_new(struct lua_State *L, struct space *space)
 		lua_settable(L, -4);
 	}
 	lbox_fillspace(L, space, lua_gettop(L));
-	lua_pushstring(L, space_name(space));
-	lua_insert(L, -2);
-	lua_rawset(L, -3);
+	lua_setfield(L, -2, space_name(space));
 
 	lua_pop(L, 2); /* box, space */
 }
diff --git a/src/box/index.h b/src/box/index.h
index a90b5c71c5..860fb0e014 100644
--- a/src/box/index.h
+++ b/src/box/index.h
@@ -232,7 +232,7 @@ replace_check_dup(struct tuple *old_tuple, struct tuple *dup_tuple,
 static inline uint32_t
 index_id(const Index *index)
 {
-	return index->key_def->id;
+	return index->key_def->iid;
 }
 
 /** True if this index is a primary key. */
diff --git a/src/box/key_def.cc b/src/box/key_def.cc
index 0fb0320ded..07d4b24826 100644
--- a/src/box/key_def.cc
+++ b/src/box/key_def.cc
@@ -28,23 +28,33 @@
  */
 #include "key_def.h"
 #include <stdlib.h>
+#include <stdio.h>
 #include "exception.h"
 
 const char *field_type_strs[] = {"UNKNOWN", "NUM", "NUM64", "STR", "\0"};
 STRS(index_type, ENUM_INDEX_TYPE);
 
 struct key_def *
-key_def_new(uint32_t id, enum index_type type, bool is_unique,
-	    uint32_t part_count)
+key_def_new(uint32_t space_id, uint32_t iid, const char *name,
+	    enum index_type type, bool is_unique, uint32_t part_count)
 {
 	uint32_t parts_size = sizeof(struct key_part) * part_count;
 	size_t sz = parts_size + sizeof(struct key_def);
 	struct key_def *def = (struct key_def *) malloc(sz);
-	if (def == NULL)
+	if (def == NULL) {
 		tnt_raise(LoggedError, ER_MEMORY_ISSUE,
 			  sz, "struct key_def", "malloc");
+	}
+	int n = snprintf(def->name, sizeof(def->name) - 1, "%s", name);
+	if (n >= sizeof(def->name)) {
+		free(def);
+		tnt_raise(LoggedError, ER_MODIFY_INDEX,
+			  (unsigned) iid, (unsigned) space_id,
+			  "index name is too long");
+	}
 	def->type = type;
-	def->id = id;
+	def->space_id = space_id;
+	def->iid = iid;
 	def->is_unique = is_unique;
 	def->part_count = part_count;
 
@@ -79,8 +89,10 @@ key_part_cmp(const struct key_part *parts1, uint32_t part_count1,
 int
 key_def_cmp(const struct key_def *key1, const struct key_def *key2)
 {
-	if (key1->id != key2->id)
-		return key1->id < key2->id ? -1 : 1;
+	if (key1->iid != key2->iid)
+		return key1->iid < key2->iid ? -1 : 1;
+	if (strcmp(key1->name, key2->name))
+		return strcmp(key1->name, key2->name);
 	if (key1->type != key2->type)
 		return (int) key1->type < (int) key2->type ? -1 : 1;
 	if (key1->is_unique != key2->is_unique)
@@ -91,11 +103,11 @@ key_def_cmp(const struct key_def *key1, const struct key_def *key2)
 }
 
 void
-key_list_del_key(struct rlist *key_list, uint32_t id)
+key_list_del_key(struct rlist *key_list, uint32_t iid)
 {
 	struct key_def *key;
 	rlist_foreach_entry(key, key_list, link) {
-		if (key->id == id) {
+		if (key->iid == iid) {
 			rlist_del_entry(key, link);
 			return;
 		}
@@ -104,32 +116,37 @@ key_list_del_key(struct rlist *key_list, uint32_t id)
 }
 
 void
-key_def_check(uint32_t id, struct key_def *key_def)
+key_def_check(struct key_def *key_def)
 {
-	if (key_def->id >= BOX_INDEX_MAX) {
+	if (key_def->iid >= BOX_INDEX_MAX) {
 		tnt_raise(ClientError, ER_MODIFY_INDEX,
-			  (unsigned) key_def->id, (unsigned) id,
+			  (unsigned) key_def->iid,
+			  (unsigned) key_def->space_id,
 			  "index id too big");
 	}
 	if (key_def->part_count == 0) {
 		tnt_raise(ClientError, ER_MODIFY_INDEX,
-			  (unsigned) key_def->id, (unsigned) id,
+			  (unsigned) key_def->iid,
+			  (unsigned) key_def->space_id,
 			  "part count must be positive");
 	}
 	if (key_def->part_count > BOX_INDEX_PART_MAX) {
 		tnt_raise(ClientError, ER_MODIFY_INDEX,
-			  (unsigned) key_def->id, (unsigned) id,
+			  (unsigned) key_def->iid,
+			  (unsigned) key_def->space_id,
 			  "too many key parts");
 	}
 	for (uint32_t i = 0; i < key_def->part_count; i++) {
 		if (key_def->parts[i].type == field_type_MAX) {
 			tnt_raise(ClientError, ER_MODIFY_INDEX,
-				  (unsigned) key_def->id, (unsigned) id,
+				  (unsigned) key_def->iid,
+				  (unsigned) key_def->space_id,
 				  "unknown field type");
 		}
 		if (key_def->parts[i].fieldno > BOX_INDEX_FIELD_MAX) {
 			tnt_raise(ClientError, ER_MODIFY_INDEX,
-				  (unsigned) key_def->id, (unsigned) id,
+				  (unsigned) key_def->iid,
+				  (unsigned) key_def->space_id,
 				  "field no is too big");
 		}
 		for (uint32_t j = 0; j < i; j++) {
@@ -140,8 +157,8 @@ key_def_check(uint32_t id, struct key_def *key_def)
 			if (key_def->parts[i].fieldno ==
 			    key_def->parts[j].fieldno) {
 				tnt_raise(ClientError, ER_MODIFY_INDEX,
-					  (unsigned) key_def->id,
-					  (unsigned) id,
+					  (unsigned) key_def->iid,
+					  (unsigned) key_def->space_id,
 					  "same key part is indexed twice");
 			}
 		}
@@ -150,7 +167,8 @@ key_def_check(uint32_t id, struct key_def *key_def)
 	case HASH:
 		if (! key_def->is_unique) {
 			tnt_raise(ClientError, ER_MODIFY_INDEX,
-				  (unsigned) key_def->id, (unsigned) id,
+				  (unsigned) key_def->iid,
+				  (unsigned) key_def->space_id,
 				  "HASH index must be unique");
 		}
 		break;
@@ -160,18 +178,21 @@ key_def_check(uint32_t id, struct key_def *key_def)
 	case BITSET:
 		if (key_def->part_count != 1) {
 			tnt_raise(ClientError, ER_MODIFY_INDEX,
-				  (unsigned) key_def->id, (unsigned) id,
-				    "BITSET index key can not be multipart");
+				  (unsigned) key_def->iid,
+				  (unsigned) key_def->space_id,
+				  "BITSET index key can not be multipart");
 		}
 		if (key_def->is_unique) {
 			tnt_raise(ClientError, ER_MODIFY_INDEX,
-				  (unsigned) key_def->id, (unsigned) id,
+				  (unsigned) key_def->iid,
+				  (unsigned) key_def->space_id,
 				  "BITSET can not be unique");
 		}
 		break;
 	default:
 		tnt_raise(ClientError, ER_INDEX_TYPE,
-			  (unsigned) key_def->id, (unsigned) id);
+			  (unsigned) key_def->iid,
+			  (unsigned) key_def->space_id);
 		break;
 	}
 }
diff --git a/src/box/key_def.h b/src/box/key_def.h
index 10daefc582..56bfc26dff 100644
--- a/src/box/key_def.h
+++ b/src/box/key_def.h
@@ -82,7 +82,11 @@ struct key_def {
 	/* A link in key list. */
 	struct rlist link;
 	/** Ordinal index number in the index array. */
-	uint32_t id;
+	uint32_t iid;
+	/* Space id. */
+	uint32_t space_id;
+	/** Index name. */
+	char name[BOX_NAME_MAX + 1];
 	/** The size of the 'parts' array. */
 	uint32_t part_count;
 	/** Index type. */
@@ -95,13 +99,14 @@ struct key_def {
 
 /** Initialize a pre-allocated key_def. */
 struct key_def *
-key_def_new(uint32_t id, enum index_type type,
-	    bool is_unique, uint32_t part_count);
+key_def_new(uint32_t space_id, uint32_t iid, const char *name,
+	    enum index_type type, bool is_unique, uint32_t part_count);
 
 static inline struct key_def *
 key_def_dup(struct key_def *def)
 {
-	struct key_def *dup = key_def_new(def->id, def->type, def->is_unique,
+	struct key_def *dup = key_def_new(def->space_id, def->iid, def->name,
+					  def->type, def->is_unique,
 					  def->part_count);
 	if (dup) {
 		memcpy(dup->parts, def->parts,
@@ -146,8 +151,8 @@ key_part_cmp(const struct key_part *parts1, uint32_t part_count1,
 
 /**
  * One key definition is greater than the other if it's id is
- * greater, it's index type is greater (HASH < TREE < BITSET)
- * or its key part array is greater.
+ * greater, it's name is greater,  it's index type is greater
+ * (HASH < TREE < BITSET) or its key part array is greater.
  */
 int
 key_def_cmp(const struct key_def *key1, const struct key_def *key2);
@@ -175,7 +180,7 @@ key_list_del_key(struct rlist *key_list, uint32_t id);
  * @param type_str  type name (to produce a nice error)
  */
 void
-key_def_check(uint32_t id, struct key_def *key_def);
+key_def_check(struct key_def *key_def);
 
 /** Space metadata. */
 struct space_def {
diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index 04bdcf82dd..af74cdf358 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -91,6 +91,10 @@ box.schema.index.drop = function(space_id, index_id)
     local _index = box.space[box.schema.INDEX_ID]
     _index:delete(space_id, index_id)
 end
+box.schema.index.rename = function(space_id, index_id, name)
+    local _index = box.space[box.schema.INDEX_ID]
+    _index:update({space_id, index_id}, "=p", 3, name)
+end
 
 function box.schema.space.bless(space)
     local index_mt = {}
@@ -219,10 +223,10 @@ function box.schema.space.bless(space)
     setmetatable(space, space_mt)
     if type(space.index) == 'table' and space.enabled then
         for j, index in pairs(space.index) do
-            rawset(index, 'idx', box.index.new(space.n, j))
-            rawset(index, 'id', j)
-            rawset(index, 'n', space.n)
-            setmetatable(index, index_mt)
+            if type(j) == 'number' then
+                rawset(index, 'idx', box.index.bind(space.n, j))
+                setmetatable(index, index_mt)
+            end
         end
     end
 end
diff --git a/src/box/schema.cc b/src/box/schema.cc
index 967d48d088..065f28ec10 100644
--- a/src/box/schema.cc
+++ b/src/box/schema.cc
@@ -72,6 +72,13 @@ space_by_id(uint32_t id)
 	return (struct space *) mh_i32ptr_node(spaces, space)->val;
 }
 
+extern "C" const char *
+space_name_by_id(uint32_t id)
+{
+	struct space *space = space_by_id(id);
+	return space ? space_name(space) : "";
+}
+
 /**
  * Visit all spaces and apply 'func'.
  */
@@ -210,25 +217,30 @@ schema_init()
 	 * (and re-created) first.
 	 */
 	/* _schema - key/value space with schema description */
-	struct space_def space_def = { SC_SCHEMA_ID, 0, "_schema" };
-	struct key_def *key_def = key_def_new(0 /* id */,
+	struct space_def def = { SC_SCHEMA_ID, 0, "_schema" };
+	struct key_def *key_def = key_def_new(def.id,
+					      0 /* index id */,
+					      "primary", /* name */
 					      TREE /* index type */,
 					      true /* unique */,
 					      1 /* part count */);
 	key_def_set_part(key_def, 0 /* part no */, 0 /* field no */, STRING);
-	(void) sc_space_new(&space_def, key_def, NULL);
+	(void) sc_space_new(&def, key_def, NULL);
 
 	/* _space - home for all spaces. */
-	space_def.id = SC_SPACE_ID;
-	snprintf(space_def.name, sizeof(space_def.name), "_space");
+	key_def->space_id = def.id = SC_SPACE_ID;
+	snprintf(def.name, sizeof(def.name), "_space");
 	key_def_set_part(key_def, 0 /* part no */, 0 /* field no */, NUM);
 
-	(void) sc_space_new(&space_def, key_def,
-			    &alter_space_on_replace_space);
+	(void) sc_space_new(&def, key_def, &alter_space_on_replace_space);
 	key_def_delete(key_def);
 
 	/* _index - definition of indexes in all spaces */
-	key_def = key_def_new(0 /* id */,
+	def.id = SC_INDEX_ID;
+	snprintf(def.name, sizeof(def.name), "_index");
+	key_def = key_def_new(def.id,
+			      0 /* index id */,
+			      "primary",
 			      TREE /* index type */,
 			      true /* unique */,
 			      2 /* part count */);
@@ -236,10 +248,7 @@ schema_init()
 	key_def_set_part(key_def, 0 /* part no */, 0 /* field no */, NUM);
 	/* index no */
 	key_def_set_part(key_def, 1 /* part no */, 1 /* field no */, NUM);
-	space_def.id = SC_INDEX_ID;
-	snprintf(space_def.name, sizeof(space_def.name), "_index");
-	(void) sc_space_new(&space_def, key_def,
-			    &alter_space_on_replace_index);
+	(void) sc_space_new(&def, key_def, &alter_space_on_replace_index);
 	key_def_delete(key_def);
 }
 
diff --git a/src/box/schema.h b/src/box/schema.h
index a97076ce07..76873bb949 100644
--- a/src/box/schema.h
+++ b/src/box/schema.h
@@ -60,6 +60,10 @@ space_foreach(void (*func)(struct space *sp, void *udata), void *udata);
 extern "C" struct space *
 space_by_id(uint32_t id);
 
+/** No-throw conversion of space id to space name */
+extern "C" const char *
+space_name_by_id(uint32_t id);
+
 static inline struct space *
 space_find(uint32_t id)
 {
diff --git a/src/box/space.cc b/src/box/space.cc
index 2b08ad6036..849053f1ff 100644
--- a/src/box/space.cc
+++ b/src/box/space.cc
@@ -52,7 +52,7 @@ space_new(struct space_def *def, struct rlist *key_list)
 	struct key_def *key_def;
 	rlist_foreach_entry(key_def, key_list, link) {
 		index_count++;
-		index_id_max = MAX(index_id_max, key_def->id);
+		index_id_max = MAX(index_id_max, key_def->iid);
 	}
 	size_t sz = sizeof(struct space) +
 		(index_count + index_id_max + 1) * sizeof(Index *);
@@ -76,7 +76,7 @@ space_new(struct space_def *def, struct rlist *key_list)
 	space->index_id_max = index_id_max;
 	/* fill space indexes */
 	rlist_foreach_entry(key_def, key_list, link) {
-		space->index_map[key_def->id] = Index::factory(key_def);
+		space->index_map[key_def->iid] = Index::factory(key_def);
 	}
 	space_fill_index_map(space);
 	space->engine = engine_no_keys;
diff --git a/src/box/tuple.cc b/src/box/tuple.cc
index 33375d7cc8..a6b56b16ae 100644
--- a/src/box/tuple.cc
+++ b/src/box/tuple.cc
@@ -63,7 +63,7 @@ field_type_create(enum field_type *types, uint32_t field_count,
 			if (*ptype != UNKNOWN && *ptype != part->type) {
 				tnt_raise(ClientError,
 					  ER_FIELD_TYPE_MISMATCH,
-					  key_def->id, part - key_def->parts,
+					  key_def->iid, part - key_def->parts,
 					  field_type_strs[part->type],
 					  field_type_strs[*ptype]);
 			}
diff --git a/test/box/alter_limits.result b/test/box/alter_limits.result
index 6acadfc4c9..0d95815285 100644
--- a/test/box/alter_limits.result
+++ b/test/box/alter_limits.result
@@ -133,7 +133,7 @@ s:select(0)
 ...
 s:select_range(0, 0, 0)
 ---
-- error: '[string "-- schema.lua (internal file)..."]:170: attempt to index a nil
+- error: '[string "-- schema.lua (internal file)..."]:174: attempt to index a nil
     value'
 ...
 s:delete(0)
@@ -477,36 +477,53 @@ s:create_index('t1', 'hash', {parts = parts});
 s:drop()
 ---
 ...
--- add index:
--- ---------
---     - a test case for contraints in tuple_format_new
---     - index rebuild:
---        - a duplicate in the new index
---        - no field for the new index
---        - wrong field type in the new index
---     - alter algorithm correctly detects
---        test that during the rebuild there is a duplicate
---     according to the new index
---     - index rebuild -> no field in the index (validate tuple
---     during build)
+-- check costraints in tuple_format_new()
+s = box.schema.create_space('test')
+---
+...
+s:create_index('t1', 'hash', { parts = { 0, 'num' }})
+---
+...
+-- field type contradicts field type of another index
+s:create_index('t2', 'hash', { parts = { 0, 'str' }})
+---
+- error: Ambiguous field type in index 1, key part 0. Requested type is STR but the
+    field has previously been defined as NUM
+...
+-- ok
+s:create_index('t2', 'hash', { parts = { 1, 'str' }})
+---
+...
+-- don't allow drop of the primary key in presence of other keys
+s.index[0]:drop()
+---
+- error: Can't drop primary key in space 512 while secondary keys exist
+...
+-- cleanup
+s:drop()
+---
+...
+-- index name, name manipulation
+-- box.schema.create_space(string.rep('t', box.schema.NAME_MAX)..'_')
+-- s = box.schema.create_space(string.rep('t', box.schema.NAME_MAX - 1)..'_')
+-- s.name
+-- s:drop()
+-- s = box.schema.create_space(string.rep('t', box.schema.NAME_MAX - 2)..'_')
+-- modify index
+-- ------------
 --     - alter unique -> non unique
 --     - alter index type
+--     - add identical index - verify there is no rebuild
 --     - index access by name
 --     - alter add key part
---     - arbitrary index
---     - test that during commit phase
---       -> inject error at commit, inject error at rollback
---     - add check that doesn't allow drop of a primary
---       key in presence of other keys, or moves the space
---       to disabled state otherwise.
+--     - rename index 
 --
---     - add identical index - verify there is no rebuild
---     - rename index (all non-essential propeties)
---       -> duplicate key
---     - inject fiber sleep during commit, so that some stuff is added
---     (test crap which happens while there is a record to the wal
---     - test ambiguous field type when adding an index (ER_FIELD_TYPE_MISMATCH)
---     - test addition of a new index on data which it can't handle
+-- build index
+-- -----------
+--     - index rebuild:
+--        - a duplicate in the new index
+--        - no field for the new index
+--        - wrong field type in the new index
 --
 -- space cache
 -- -----------
@@ -521,6 +538,8 @@ s:drop()
 --
 -- -- inject error at various stages of commit and see that
 -- the alter has no effects
+--     - test that during commit phase
+--       -> inject error at commit, inject error at rollback
 --
 -- usability
 -- ---------
diff --git a/test/box/alter_limits.test.lua b/test/box/alter_limits.test.lua
index 582c3ba0b2..d57cfff7a5 100644
--- a/test/box/alter_limits.test.lua
+++ b/test/box/alter_limits.test.lua
@@ -179,36 +179,39 @@ s:create_index('t1', 'hash', {parts = parts});
 #s.index[0].key_field
 -- cleanup
 s:drop()
--- add index:
--- ---------
---     - a test case for contraints in tuple_format_new
---     - index rebuild:
---        - a duplicate in the new index
---        - no field for the new index
---        - wrong field type in the new index
---     - alter algorithm correctly detects
---        test that during the rebuild there is a duplicate
---     according to the new index
---     - index rebuild -> no field in the index (validate tuple
---     during build)
+-- check costraints in tuple_format_new()
+s = box.schema.create_space('test')
+s:create_index('t1', 'hash', { parts = { 0, 'num' }})
+-- field type contradicts field type of another index
+s:create_index('t2', 'hash', { parts = { 0, 'str' }})
+-- ok
+s:create_index('t2', 'hash', { parts = { 1, 'str' }})
+-- don't allow drop of the primary key in presence of other keys
+s.index[0]:drop()
+-- cleanup
+s:drop()
+-- index name, name manipulation
+
+-- box.schema.create_space(string.rep('t', box.schema.NAME_MAX)..'_')
+-- s = box.schema.create_space(string.rep('t', box.schema.NAME_MAX - 1)..'_')
+-- s.name
+-- s:drop()
+-- s = box.schema.create_space(string.rep('t', box.schema.NAME_MAX - 2)..'_')
+-- modify index
+-- ------------
 --     - alter unique -> non unique
 --     - alter index type
+--     - add identical index - verify there is no rebuild
 --     - index access by name
 --     - alter add key part
---     - arbitrary index
---     - test that during commit phase
---       -> inject error at commit, inject error at rollback
---     - add check that doesn't allow drop of a primary
---       key in presence of other keys, or moves the space
---       to disabled state otherwise.
+--     - rename index 
 --
---     - add identical index - verify there is no rebuild
---     - rename index (all non-essential propeties)
---       -> duplicate key
---     - inject fiber sleep during commit, so that some stuff is added
---     (test crap which happens while there is a record to the wal
---     - test ambiguous field type when adding an index (ER_FIELD_TYPE_MISMATCH)
---     - test addition of a new index on data which it can't handle
+-- build index
+-- -----------
+--     - index rebuild:
+--        - a duplicate in the new index
+--        - no field for the new index
+--        - wrong field type in the new index
 --
 -- space cache
 -- -----------
@@ -223,6 +226,8 @@ s:drop()
 --
 -- -- inject error at various stages of commit and see that
 -- the alter has no effects
+--     - test that during commit phase
+--       -> inject error at commit, inject error at rollback
 --
 -- usability
 -- ---------
diff --git a/test/box/lua.result b/test/box/lua.result
index 18a1b86761..fc98c621d4 100644
--- a/test/box/lua.result
+++ b/test/box/lua.result
@@ -531,23 +531,23 @@ box.cfg.nosuchoption = 1
 box.space[300] = 1
 ---
 ...
-box.index.new('abc', 'cde')
+box.index.bind('abc', 'cde')
 ---
 - error: 'bad argument #1 to ''?'' (number expected, got string)'
 ...
-box.index.new(1, 2)
+box.index.bind(1, 2)
 ---
 - error: Space 1 does not exist
 ...
-box.index.new(0, 1)
+box.index.bind(0, 1)
 ---
 - error: 'No index #1 is defined in space 0'
 ...
-box.index.new(0, 0)
+box.index.bind(0, 0)
 ---
 -index 0
 ...
-#box.index.new(0,0)
+#box.index.bind(0,0)
 ---
 - 0
 ...
@@ -563,7 +563,7 @@ box.insert(0, 'abcd')
 ---
 - [1684234849]
 ...
-#box.index.new(0,0)
+#box.index.bind(0,0)
 ---
 - 2
 ...
@@ -575,7 +575,7 @@ box.delete(0, 'test')
 ---
 - [1953719668]
 ...
-#box.index.new(0,0)
+#box.index.bind(0,0)
 ---
 - 1
 ...
@@ -587,7 +587,7 @@ box.delete(0, 'abcd')
 ---
 - 0
 ...
-#box.index.new(0,0)
+#box.index.bind(0,0)
 ---
 - 0
 ...
diff --git a/test/box/lua.test.py b/test/box/lua.test.py
index 858d8cff2b..57c9ec6cfc 100644
--- a/test/box/lua.test.py
+++ b/test/box/lua.test.py
@@ -146,21 +146,21 @@ admin("t")
 admin("box.cfg.nosuchoption = 1")
 admin("box.space[300] = 1")
 
-admin("box.index.new('abc', 'cde')")
-admin("box.index.new(1, 2)")
-admin("box.index.new(0, 1)")
-admin("box.index.new(0, 0)")
-admin("#box.index.new(0,0)")
+admin("box.index.bind('abc', 'cde')")
+admin("box.index.bind(1, 2)")
+admin("box.index.bind(0, 1)")
+admin("box.index.bind(0, 0)")
+admin("#box.index.bind(0,0)")
 admin("#box.space[0].index[0].idx")
 admin("box.insert(0, 'test')")
 admin("box.insert(0, 'abcd')")
-admin("#box.index.new(0,0)")
+admin("#box.index.bind(0,0)")
 admin("#box.space[0].index[0].idx")
 admin("box.delete(0, 'test')")
-admin("#box.index.new(0,0)")
+admin("#box.index.bind(0,0)")
 admin("box.delete(0, 'abcd')")
 admin("#box.space[0].index[0].idx")
-admin("#box.index.new(0,0)")
+admin("#box.index.bind(0,0)")
 admin("box.space[0]:insert('test', 'hello world')")
 admin("box.space[0]:update('test', '=p', 1, 'bye, world')")
 admin("box.space[0]:delete('test')")
-- 
GitLab