[tarantool-patches] [PATCH 7/7] sql: finish DD integration

Nikita Pettik korablev at tarantool.org
Fri Aug 24 01:55:53 MSK 2018


This patch finishes SQL DD integration with Tarantool core. Within it
Table hash has been removed alongside with callback routine and
OP_ParseSchema legacy opcode: we don't need anymore to update separate
SQL DD. Moreover, now we can get rid of struct Schema.

It is worth mentioning that some allocations during table and index
creations now can be moved to region, since those things are not used
after parsing and anyway destroyed.

Closes #3561
Closes #2217
---
 src/box/alter.cc             |  15 +-
 src/box/sql.c                |  36 ++--
 src/box/sql.h                |   3 +-
 src/box/sql/analyze.c        |   1 -
 src/box/sql/build.c          | 414 +++++++++----------------------------------
 src/box/sql/callback.c       |  42 -----
 src/box/sql/delete.c         |   2 +-
 src/box/sql/expr.c           |   1 -
 src/box/sql/main.c           |   1 -
 src/box/sql/pragma.c         |   5 -
 src/box/sql/prepare.c        | 117 ------------
 src/box/sql/sqliteInt.h      |  61 -------
 src/box/sql/status.c         |  16 --
 src/box/sql/trigger.c        |   5 +-
 src/box/sql/vdbe.c           |  97 ----------
 src/box/sql/vdbe.h           |   1 -
 src/box/sql/vdbeaux.c        |   6 -
 test/sql-tap/index1.test.lua |   2 +-
 18 files changed, 106 insertions(+), 719 deletions(-)

diff --git a/src/box/alter.cc b/src/box/alter.cc
index d5872961c..e49780caa 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -3400,16 +3400,14 @@ on_replace_trigger_rollback(struct trigger *trigger, void *event)
 		/* Rollback DELETE trigger. */
 		if (old_trigger == NULL)
 			return;
-		if (sql_trigger_replace(sql_get(),
-					sql_trigger_name(old_trigger),
+		if (sql_trigger_replace(sql_trigger_name(old_trigger),
 					sql_trigger_space_id(old_trigger),
 					old_trigger, &new_trigger) != 0)
 			panic("Out of memory on insertion into trigger hash");
 		assert(new_trigger == NULL);
 	}  else if (stmt->new_tuple != NULL && stmt->old_tuple == NULL) {
 		/* Rollback INSERT trigger. */
-		int rc = sql_trigger_replace(sql_get(),
-					     sql_trigger_name(old_trigger),
+		int rc = sql_trigger_replace(sql_trigger_name(old_trigger),
 					     sql_trigger_space_id(old_trigger),
 					     NULL, &new_trigger);
 		(void)rc;
@@ -3418,8 +3416,7 @@ on_replace_trigger_rollback(struct trigger *trigger, void *event)
 		sql_trigger_delete(sql_get(), new_trigger);
 	} else {
 		/* Rollback REPLACE trigger. */
-		if (sql_trigger_replace(sql_get(),
-					sql_trigger_name(old_trigger),
+		if (sql_trigger_replace(sql_trigger_name(old_trigger),
 					sql_trigger_space_id(old_trigger),
 					old_trigger, &new_trigger) != 0)
 			panic("Out of memory on insertion into trigger hash");
@@ -3472,8 +3469,8 @@ on_replace_dd_trigger(struct trigger * /* trigger */, void *event)
 		trigger_name[trigger_name_len] = 0;
 
 		struct sql_trigger *old_trigger;
-		int rc = sql_trigger_replace(sql_get(), trigger_name, space_id,
-					     NULL, &old_trigger);
+		int rc = sql_trigger_replace(trigger_name, space_id, NULL,
+					     &old_trigger);
 		(void)rc;
 		assert(rc == 0);
 
@@ -3520,7 +3517,7 @@ on_replace_dd_trigger(struct trigger * /* trigger */, void *event)
 		}
 
 		struct sql_trigger *old_trigger;
-		if (sql_trigger_replace(sql_get(), trigger_name,
+		if (sql_trigger_replace(trigger_name,
 					sql_trigger_space_id(new_trigger),
 					new_trigger, &old_trigger) != 0)
 			diag_raise();
diff --git a/src/box/sql.c b/src/box/sql.c
index bec74bf29..10b1e6418 100644
--- a/src/box/sql.c
+++ b/src/box/sql.c
@@ -76,36 +76,32 @@ sql_init()
 		panic("failed to initialize SQL subsystem");
 
 	assert(db != NULL);
-	/*
-	 * Initialize pSchema to use SQL parser on initialization:
-	 * e.g. Trigger objects (compiled from SQL on tuple
-	 * insertion in _trigger) need to refer it.
-	 */
-	db->pSchema = sqlite3SchemaCreate(db);
-	if (db->pSchema == NULL) {
-		sqlite3_close(db);
-		panic("failed to initialize SQL Schema subsystem");
-	}
 }
 
 void
 sql_load_schema()
 {
-	assert(db->pSchema != NULL);
-	int rc;
 	struct session *user_session = current_session();
 	int commit_internal = !(user_session->sql_flags
 				& SQLITE_InternChanges);
 
 	assert(db->init.busy == 0);
+	/*
+	 * This function is called before version upgrade.
+	 * Old versions (< 2.0) lack system spaces containing
+	 * statistics (_sql_stat1 and _sql_stat4). Thus, we can
+	 * skip statistics loading.
+	 */
+	struct space *stat = space_by_id(BOX_SQL_STAT1_ID);
+	assert(stat != NULL);
+	if (stat->def->field_count == 0)
+		return;
 	db->init.busy = 1;
-	rc = sqlite3InitDatabase(db);
-	if (rc != SQLITE_OK) {
-		sqlite3SchemaClear(db);
+	sql_analysis_load(db);
+	if (db->errCode != SQLITE_OK)
 		panic("failed to initialize SQL subsystem");
-	}
 	db->init.busy = 0;
-	if (rc == SQLITE_OK && commit_internal)
+	if (commit_internal)
 		sqlite3CommitInternalChanges();
 }
 
@@ -1492,14 +1488,16 @@ sql_ephemeral_table_new(Parse *parser, const char *name)
 		sqlite3DbFree(db, table);
 		return NULL;
 	}
-	table->space = (struct space *) calloc(1, sizeof(struct space));
+	table->space = (struct space *) region_alloc(&parser->region,
+						     sizeof(struct space));
 	if (table->space == NULL) {
-		diag_set(OutOfMemory, sizeof(struct space), "calloc", "space");
+		diag_set(OutOfMemory, sizeof(struct space), "region", "space");
 		parser->rc = SQL_TARANTOOL_ERROR;
 		parser->nErr++;
 		sqlite3DbFree(db, table);
 		return NULL;
 	}
+	memset(table->space, 0, sizeof(struct space));
 
 	table->def = def;
 	return table;
diff --git a/src/box/sql.h b/src/box/sql.h
index 5350d390c..ec6d9d3cc 100644
--- a/src/box/sql.h
+++ b/src/box/sql.h
@@ -124,7 +124,6 @@ space_trigger_list(uint32_t space_id);
 
 /**
  * Perform replace trigger in SQL internals with new AST object.
- * @param db SQL handle.
  * @param name a name of the trigger.
  * @param space_id of the space to insert trigger.
  * @param trigger AST object to insert.
@@ -134,7 +133,7 @@ space_trigger_list(uint32_t space_id);
  * @retval -1 on error.
  */
 int
-sql_trigger_replace(struct sqlite3 *db, const char *name, uint32_t space_id,
+sql_trigger_replace(const char *name, uint32_t space_id,
 		    struct sql_trigger *trigger,
 		    struct sql_trigger **old_trigger);
 
diff --git a/src/box/sql/analyze.c b/src/box/sql/analyze.c
index e835a8697..21d02ab8c 100644
--- a/src/box/sql/analyze.c
+++ b/src/box/sql/analyze.c
@@ -1155,7 +1155,6 @@ void
 sqlite3Analyze(Parse * pParse, Token * pName)
 {
 	sqlite3 *db = pParse->db;
-	assert(db->pSchema != NULL);
 	if (pName == NULL) {
 		/* Form 1:  Analyze everything */
 		sql_analyze_database(pParse);
diff --git a/src/box/sql/build.c b/src/box/sql/build.c
index 840604aa3..0d83587df 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -114,98 +114,25 @@ sql_finish_coding(struct Parse *parse_context)
 		parse_context->rc = SQLITE_ERROR;
 	}
 }
-
-/*
- * Locate the in-memory structure that describes a particular database
- * table given the name of that table. Return NULL if not found.
- * Also leave an error message in pParse->zErrMsg.
+/**
+ * Find index by its name.
+ *
+ * @param space Space index belongs to.
+ * @param name Name of index to be found.
+ *
+ * @retval NULL in case index doesn't exist.
  */
-Table *
-sqlite3LocateTable(Parse * pParse,	/* context in which to report errors */
-		   u32 flags,	/* LOCATE_VIEW or LOCATE_NOERR */
-		   const char *zName	/* Name of the table we are looking for */
-    )
-{
-	Table *p;
-
-	assert(pParse->db->pSchema != NULL);
-
-	p = sqlite3HashFind(&pParse->db->pSchema->tblHash, zName);
-	if (p == NULL) {
-		const char *zMsg =
-		    flags & LOCATE_VIEW ? "no such view" : "no such table";
-		if ((flags & LOCATE_NOERR) == 0)
-			sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
-	}
-
-	return p;
-}
-
-struct index *
-sqlite3LocateIndex(sqlite3 * db, const char *zName, const char *zTable)
+static struct index *
+sql_space_index_by_name(struct space *space, const char *name)
 {
-	assert(zName);
-	assert(zTable);
-
-	Table *pTab = sqlite3HashFind(&db->pSchema->tblHash, zTable);
-
-	if (pTab == NULL)
+	if (space == NULL)
 		return NULL;
-	for (uint32_t i = 0; i < pTab->space->index_count; ++i) {
-		struct index *idx = pTab->space->index[i];
-		if (strcmp(zName, idx->def->name) == 0)
-			return idx;
-	}
-	return NULL;
-}
-
-void
-sql_space_index_delete(struct space *space, uint32_t iid)
-{
-	assert(space != NULL);
 	for (uint32_t i = 0; i < space->index_count; ++i) {
 		struct index *idx = space->index[i];
-		/*
-		 * Allocate new chunk with size reduced by 1 slot.
-		 * Copy all indexes to that chunk except for one
-		 * to be deleted.
-		 */
-		if (idx->def->iid == iid) {
-			free(idx->def);
-			free(idx);
-			size_t idx_sz = sizeof(struct index *);
-			uint32_t idx_count = --space->index_count;
-			struct index **new_idexes =
-				(struct index **) malloc(idx_sz * idx_count);
-			if (new_idexes == NULL) {
-				diag_set(OutOfMemory, idx_sz * idx_count,
-					 "malloc", "new_indexes");
-				return;
-			}
-			memcpy(new_idexes, space->index, i * idx_sz);
-			memcpy(new_idexes + i, space->index + i + 1,
-			       idx_sz * (idx_count - i));
-			free(space->index);
-			space->index = new_idexes;
-			break;
-		}
-	}
-	struct session *user_session = current_session();
-	user_session->sql_flags |= SQLITE_InternChanges;
-}
-
-/*
- * Erase all schema information from all attached databases (including
- * "main" and "temp") for a single database connection.
- */
-void
-sqlite3ResetAllSchemasOfConnection(sqlite3 * db)
-{
-	struct session *user_session = current_session();
-	if (db->pSchema) {
-		sqlite3SchemaClear(db);
+		if (strcmp(name, idx->def->name) == 0)
+			return idx;
 	}
-	user_session->sql_flags &= ~SQLITE_InternChanges;
+	return NULL;
 }
 
 /*
@@ -248,7 +175,7 @@ sql_space_column_is_in_pk(struct space *space, uint32_t column)
 static void
 table_delete(struct sqlite3 *db, struct Table *tab)
 {
-	if (tab->space->def != NULL)
+	if (!tab->def->opts.is_temporary)
 		goto skip_index_delete;
 	/* Delete all indices associated with this table. */
 	for (uint32_t i = 0; i < tab->space->index_count; ++i) {
@@ -259,16 +186,12 @@ table_delete(struct sqlite3 *db, struct Table *tab)
 		 */
 		struct index *idx = tab->space->index[i];
 		free(idx->def);
-		free(idx);
 	}
-	free(tab->space);
 	free(tab->space->index);
 skip_index_delete:
 	assert(tab->def != NULL);
 	/* Do not delete table->def allocated on region. */
-	if (!tab->def->opts.is_temporary)
-		space_def_delete(tab->def);
-	else
+	if (tab->def->opts.is_temporary)
 		sql_expr_list_delete(db, tab->def->opts.checks);
 	sqlite3DbFree(db, tab);
 }
@@ -284,22 +207,6 @@ sqlite3DeleteTable(sqlite3 * db, Table * pTable)
 	table_delete(db, pTable);
 }
 
-/*
- * Unlink the given table from the hash tables and the delete the
- * table structure with all its indices and foreign keys.
- */
-void
-sqlite3UnlinkAndDeleteTable(sqlite3 * db, const char *zTabName)
-{
-	Table *p;
-
-	assert(db != 0);
-	assert(zTabName);
-	testcase(zTabName[0] == 0);	/* Zero-length table names are allowed */
-	p = sqlite3HashInsert(&db->pSchema->tblHash, zTabName, 0);
-	sqlite3DeleteTable(db, p);
-}
-
 /*
  * Given a token, return a string that consists of the text of that
  * token.  Space to hold the returned string
@@ -418,12 +325,10 @@ sqlite3StartTable(Parse *pParse, Token *pName, int noErr)
 	if (sqlite3CheckIdentifierName(pParse, zName) != SQLITE_OK)
 		goto cleanup;
 
-	assert(db->pSchema != NULL);
-	pTable = sqlite3HashFind(&db->pSchema->tblHash, zName);
-	if (pTable != NULL) {
+	uint32_t space_id = box_space_id_by_name(zName, strlen(zName));
+	if (space_id != BOX_ID_NIL) {
 		if (!noErr) {
-			sqlite3ErrorMsg(pParse,
-					"table %s already exists",
+			sqlite3ErrorMsg(pParse, "table %s already exists",
 					zName);
 		} else {
 			assert(!db->init.busy || CORRUPT_DB);
@@ -1194,54 +1099,6 @@ vdbe_emit_create_index(struct Parse *parse, struct space_def *def,
 		sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE);
 }
 
-/**
- * Generate code to initialize register range with arguments for
- * ParseSchema2. Consumes zSql. Returns the first register used.
- *
- * @param parse Current parsing context.
- * @param idx_name Name of index to be created.
- * @param space_id Space id (or register containing it)
- *                 which index belongs to.
- * @param iIndexId Id of index (or register containing it)
- *                 to be created.
- * @param sql_stmt String containing 'CREATE INDEX ...' statement.
- *                 NULL for UNIQUE and PK constraints.
- */
-static int
-vdbe_emit_index_schema_record(struct Parse *parse, const char *idx_name,
-			      int space_id, int iid, const char *sql_stmt)
-{
-	struct Vdbe *v = sqlite3GetVdbe(parse);
-	int entry_reg = parse->nMem + 1;
-	parse->nMem += 4;
-
-	sqlite3VdbeAddOp4(v, OP_String8, 0, entry_reg, 0,
-			  sqlite3DbStrDup(parse->db, idx_name), P4_DYNAMIC);
-	if (parse->pNewTable) {
-		/*
-		 * A new table is being created, hence space_id
-		 * is a register, but index id is literal.
-		 */
-		sqlite3VdbeAddOp2(v, OP_SCopy, space_id, entry_reg + 1);
-		sqlite3VdbeAddOp2(v, OP_Integer, iid, entry_reg + 2);
-	} else {
-		/*
-		 * An existing table is being modified; space id
-		 * is literal, but index id is a register.
-		 */
-		sqlite3VdbeAddOp2(v, OP_Integer, space_id, entry_reg + 1);
-		sqlite3VdbeAddOp2(v, OP_SCopy, iid, entry_reg + 2);
-	}
-	int p4_type = P4_DYNAMIC;
-	if (sql_stmt == NULL) {
-		sql_stmt = "";
-		p4_type = P4_STATIC;
-	}
-	sqlite3VdbeAddOp4(v, OP_String8, 0, entry_reg + 3, 0, sql_stmt,
-			  p4_type);
-	return entry_reg;
-}
-
 /*
  * Generate code to create a new space.
  * iSpaceId is a register storing the id of the space.
@@ -1296,35 +1153,6 @@ createSpace(Parse * pParse, int iSpaceId, char *zStmt)
 	sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE);
 }
 
-/*
- * Generate code to emit and parse table schema record.
- * iSpaceId is a register storing the id of the space.
- * Consumes zStmt.
- */
-static void
-parseTableSchemaRecord(Parse * pParse, int iSpaceId, char *zStmt)
-{
-	Table *p = pParse->pNewTable;
-	Vdbe *v = sqlite3GetVdbe(pParse);
-	int iTop = pParse->nMem + 1;
-	pParse->nMem += 4;
-
-	sqlite3VdbeAddOp4(v, OP_String8, 0, iTop, 0,
-			  sqlite3DbStrDup(pParse->db, p->def->name), P4_DYNAMIC);
-	sqlite3VdbeAddOp2(v, OP_SCopy, iSpaceId, iTop + 1);
-	sqlite3VdbeAddOp2(v, OP_Integer, 0, iTop + 2);
-	sqlite3VdbeAddOp4(v, OP_String8, 0, iTop + 3, 0, zStmt, P4_DYNAMIC);
-
-	if (!p->def->opts.is_view)
-		for (uint32_t i = 1; i < p->space->index_count; ++i) {
-			const char *idx_name = p->space->index[i]->def->name;
-			vdbe_emit_index_schema_record(pParse, idx_name,
-						      iSpaceId, i, NULL);
-	}
-
-	sqlite3VdbeAddParseSchema2Op(v, iTop, pParse->nMem - iTop + 1);
-}
-
 int
 emitNewSysSequenceRecord(Parse *pParse, int reg_seq_id, const char *seq_name)
 {
@@ -1556,19 +1384,7 @@ sqlite3EndTable(Parse * pParse,	/* Parse context */
 	if (p == 0)
 		return;
 
-	assert(!db->init.busy || !pSelect);
-
-	/* If db->init.busy == 1, then we're called from
-	 * OP_ParseSchema2 and is about to update in-memory
-	 * schema.
-	 */
-	if (db->init.busy) {
-		p->def->id = db->init.space_id;
-		if (!p->def->opts.is_view) {
-			for (uint32_t i = 0; i < p->space->index_count; ++i)
-				p->space->index[i]->def->space_id = p->def->id;
-		}
-	}
+	assert(!db->init.busy);
 
 	if (!p->def->opts.is_view) {
 		if (sql_table_primary_key(p) == NULL) {
@@ -1592,34 +1408,6 @@ sqlite3EndTable(Parse * pParse,	/* Parse context */
 			field->is_nullable = true;
 		}
 	}
-
-	if (db->init.busy) {
-		/*
-		 * As rebuild creates a new ExpList tree and
-		 * old_def is allocated on region release old
-		 * tree manually. This procedure is necessary
-		 * only at second stage of table creation, i.e.
-		 * before adding to table hash.
-		 */
-		struct ExprList *old_checks = p->def->opts.checks;
-		if (sql_table_def_rebuild(db, p) != 0)
-			goto cleanup;
-		sql_expr_list_delete(db, old_checks);
-		/*
-		 * Add the table to the in-memory representation
-		 * of the database.
-		 */
-		struct Table *pOld = sqlite3HashInsert(&db->pSchema->tblHash,
-						       p->def->name, p);
-		if (pOld != NULL) {
-			assert(p == pOld);
-			sqlite3OomFault(db);
-			goto cleanup;
-		}
-		pParse->pNewTable = NULL;
-		current_session()->sql_flags |= SQLITE_InternChanges;
-		goto finish;
-	}
 	/*
 	 * If not initializing, then create new Tarantool space.
 	 */
@@ -1675,14 +1463,6 @@ sqlite3EndTable(Parse * pParse,	/* Parse context */
 		sqlite3VdbeAddOp2(v, OP_SInsert, BOX_SPACE_SEQUENCE_ID,
 				  reg_space_seq_record);
 	}
-
-	/*
-	 * Reparse everything to update our internal data
-	 * structures.
-	 */
-	parseTableSchemaRecord(pParse, reg_space_id, stmt);
-	/* 'stmt' is kept inside the call. */
-
 	/* Code creation of FK constraints, if any. */
 	struct fkey_parse *fk_parse;
 	rlist_foreach_entry(fk_parse, &pParse->new_fkey, link) {
@@ -1718,14 +1498,6 @@ sqlite3EndTable(Parse * pParse,	/* Parse context */
 		fk->child_id = reg_space_id;
 		vdbe_emit_fkey_create(pParse, fk);
 	}
-
-finish:
-	/*
-	 * Checks are useless for now as all operations process
-	 * with the server checks instance. Remove to do not
-	 * consume extra memory, don't require make a copy on
-	 * space_def_dup and to improve debuggability.
-	 */
 cleanup:
 	sql_expr_list_delete(db, p->def->opts.checks);
 	p->def->opts.checks = NULL;
@@ -2035,8 +1807,6 @@ sql_code_drop_table(struct Parse *parse_context, struct space *space,
 	sqlite3VdbeAddOp2(v, OP_SDelete, BOX_SPACE_ID, idx_rec_reg);
 	sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE);
 	VdbeComment((v, "Delete entry from _space"));
-	/* Remove the table entry from SQLite's internal schema. */
-	sqlite3VdbeAddOp4(v, OP_DropTable, 0, 0, 0, space->def->name, 0);
 }
 
 /**
@@ -2398,9 +2168,9 @@ sql_drop_foreign_key(struct Parse *parse_context, struct SrcList *table,
 
 /*
  * Generate code to determine next free Iid in the space identified by
- * the iSpaceId. Return register number holding the result.
+ * the iSpaceId.
  */
-static int
+static void
 getNewIid(Parse * pParse, int iSpaceId, int iCursor)
 {
 	Vdbe *v = sqlite3GetVdbe(pParse);
@@ -2434,7 +2204,6 @@ getNewIid(Parse * pParse, int iSpaceId, int iCursor)
 	sqlite3VdbeJumpHere(v, iGotoInst);
 	sqlite3VdbeAddOp3(v, OP_Column, iCursor, 1, iRes);
 	sqlite3VdbeAddOp2(v, OP_AddImm, iRes, 1);
-	return iRes;
 }
 
 /**
@@ -2445,24 +2214,24 @@ getNewIid(Parse * pParse, int iSpaceId, int iCursor)
  * @param tab Table to which belongs given index.
  */
 static void
-table_add_index(struct Table *tab, struct index *index)
+table_add_index(struct space *space, struct index *index)
 {
-	uint32_t idx_count = tab->space->index_count;
+	uint32_t idx_count = space->index_count;
 	size_t indexes_sz = sizeof(struct index *) * (idx_count + 1);
-	struct index **idx = (struct index **) realloc(tab->space->index,
+	struct index **idx = (struct index **) realloc(space->index,
 						       indexes_sz);
 	if (idx == NULL) {
 		diag_set(OutOfMemory, indexes_sz, "malloc", "idx");
 		return;
 	}
-	tab->space->index = idx;
+	space->index = idx;
 	/* Make sure that PK always comes as first member. */
 	if (index->def->iid == 0 && idx_count != 0) {
-		struct index *tmp = tab->space->index[0];
-		tab->space->index[0] = index;
+		struct index *tmp = space->index[0];
+		space->index[0] = index;
 		index = tmp;
 	}
-	tab->space->index[tab->space->index_count++] = index;
+	space->index[space->index_count++] = index;
 }
 
 /**
@@ -2487,11 +2256,10 @@ table_add_index(struct Table *tab, struct index *index)
  */
 static int
 index_fill_def(struct Parse *parse, struct index *index,
-	       struct Table *table, uint32_t iid, const char *name,
+	       struct space_def *space_def, uint32_t iid, const char *name,
 	       uint32_t name_len, struct ExprList *expr_list,
 	       enum sql_index_type idx_type, char *sql_stmt)
 {
-	struct space_def *space_def = table->def;
 	struct index_opts opts;
 	index_opts_create(&opts);
 	opts.is_unique = idx_type != SQL_INDEX_TYPE_NON_UNIQUE;
@@ -2502,10 +2270,13 @@ index_fill_def(struct Parse *parse, struct index *index,
 	struct key_def *key_def = key_def_new(expr_list->nExpr);
 	if (key_def == NULL)
 		goto tnt_error;
-
+	struct Table tmp_tab;
+	tmp_tab.def = space_def;
+	tmp_tab.nTabRef = 2;
 	for (int i = 0; i < expr_list->nExpr; i++) {
 		struct Expr *expr = expr_list->a[i].pExpr;
-		sql_resolve_self_reference(parse, table, NC_IdxExpr, expr, 0);
+		sql_resolve_self_reference(parse, &tmp_tab, NC_IdxExpr,
+					   expr, 0);
 		if (parse->nErr > 0)
 			goto cleanup;
 
@@ -2584,7 +2355,7 @@ sql_create_index(struct Parse *parse, struct Token *token,
 	/* Name of the index. */
 	char *name = NULL;
 	struct sqlite3 *db = parse->db;
-	struct session *user_session = current_session();
+	assert(!db->init.busy);
 
 	if (db->mallocFailed || parse->nErr > 0)
 		goto exit_create_index;
@@ -2595,27 +2366,38 @@ sql_create_index(struct Parse *parse, struct Token *token,
 			goto exit_create_index;
 		sqlite3VdbeCountChanges(v);
 	}
-	assert(db->pSchema != NULL);
 
 	/*
 	 * Find the table that is to be indexed.
 	 * Return early if not found.
 	 */
-	struct Table *table = NULL;
+	struct space *space = NULL;
+	struct space_def *def = NULL;
 	if (tbl_name != NULL) {
 		assert(token != NULL && token->z != NULL);
-		table = sqlite3LocateTable(parse, 0, tbl_name->a[0].zName);
-		assert(db->mallocFailed == 0 || table == NULL);
+		const char *name = tbl_name->a[0].zName;
+		uint32_t space_id = box_space_id_by_name(name, strlen(name));
+		if (space_id == BOX_ID_NIL) {
+			if (! if_not_exist) {
+				diag_set(ClientError, ER_NO_SUCH_SPACE, name);
+				parse->rc = SQL_TARANTOOL_ERROR;
+				parse->nErr++;
+			}
+			goto exit_create_index;
+		}
+		space = space_by_id(space_id);
+		assert(space != NULL);
+		def = space->def;
 	} else {
+		if (parse->pNewTable == NULL)
+			goto exit_create_index;
 		assert(token == NULL);
 		assert(start == NULL);
-		table = parse->pNewTable;
+		space = parse->pNewTable->space;
+		def = parse->pNewTable->def;
 	}
 
-	if (table == NULL)
-		goto exit_create_index;
-
-	if (table->def->opts.is_view) {
+	if (def->opts.is_view) {
 		sqlite3ErrorMsg(parse, "views can not be indexed");
 		goto exit_create_index;
 	}
@@ -2644,11 +2426,11 @@ sql_create_index(struct Parse *parse, struct Token *token,
 		name = sqlite3NameFromToken(db, token);
 		if (name == NULL)
 			goto exit_create_index;
-		if (sqlite3LocateIndex(db, name, table->def->name) != NULL) {
+		if (sql_space_index_by_name(space, name) != NULL) {
 			if (!if_not_exist) {
 				sqlite3ErrorMsg(parse,
 						"index %s.%s already exists",
-						table->def->name, name);
+						def->name, name);
 			}
 			goto exit_create_index;
 		}
@@ -2677,11 +2459,11 @@ sql_create_index(struct Parse *parse, struct Token *token,
 			prefix = constraint_name == NULL ?
 				"pk_unnamed_%s_%d" : "pk_%s_%d";
 		}
-		uint32_t idx_count = table->space->index_count;
+		uint32_t idx_count = space->index_count;
 		if (constraint_name == NULL ||
 		    strcmp(constraint_name, "") == 0) {
-			name = sqlite3MPrintf(db, prefix,
-					      table->def->name, idx_count + 1);
+			name = sqlite3MPrintf(db, prefix, def->name,
+					      idx_count + 1);
 		} else {
 			name = sqlite3MPrintf(db, prefix,
 					      constraint_name, idx_count + 1);
@@ -2692,12 +2474,8 @@ sql_create_index(struct Parse *parse, struct Token *token,
 	if (name == NULL || sqlite3CheckIdentifierName(parse, name) != 0)
 		goto exit_create_index;
 
-	bool is_system_space = BOX_SYSTEM_ID_MIN < table->def->id &&
-			       table->def->id < BOX_SYSTEM_ID_MAX;
-	if (is_system_space && (idx_type == SQL_INDEX_TYPE_NON_UNIQUE ||
-				idx_type == SQL_INDEX_TYPE_UNIQUE)) {
-		diag_set(ClientError, ER_MODIFY_INDEX, name,
-			 table->def->name,
+	if (tbl_name != NULL && space_is_system(space)) {
+		diag_set(ClientError, ER_MODIFY_INDEX, name, def->name,
 			 "can't create index on system space");
 		parse->nErr++;
 		parse->rc = SQL_TARANTOOL_ERROR;
@@ -2712,9 +2490,8 @@ sql_create_index(struct Parse *parse, struct Token *token,
 	 */
 	if (col_list == NULL) {
 		struct Token prev_col;
-		uint32_t last_field = table->def->field_count - 1;
-		sqlite3TokenInit(&prev_col,
-				 table->def->fields[last_field].name);
+		uint32_t last_field = def->field_count - 1;
+		sqlite3TokenInit(&prev_col, def->fields[last_field].name);
 		col_list = sql_expr_list_append(parse->db, NULL,
 						sqlite3ExprAlloc(db, TK_ID,
 								 &prev_col, 0));
@@ -2726,13 +2503,14 @@ sql_create_index(struct Parse *parse, struct Token *token,
 		sqlite3ExprListCheckLength(parse, col_list, "index");
 	}
 
-	index = (struct index *) calloc(1, sizeof(*index));
+	index = (struct index *) region_alloc(&parse->region, sizeof(*index));
 	if (index == NULL) {
-		diag_set(OutOfMemory, sizeof(*index), "calloc", "index");
+		diag_set(OutOfMemory, sizeof(*index), "region", "index");
 		parse->rc = SQL_TARANTOOL_ERROR;
 		parse->nErr++;
 		goto exit_create_index;
 	}
+	memset(index, 0, sizeof(*index));
 
 	/*
 	 * TODO: Issue a warning if two or more columns of the
@@ -2741,7 +2519,7 @@ sql_create_index(struct Parse *parse, struct Token *token,
 	 * as part of the index key.
 	 */
 	char *sql_stmt = NULL;
-	if (!db->init.busy && tbl_name != NULL) {
+	if (tbl_name != NULL) {
 		int n = (int) (parse->sLastToken.z - token->z) +
 			parse->sLastToken.n;
 		if (token->z[n - 1] == ';')
@@ -2758,7 +2536,7 @@ sql_create_index(struct Parse *parse, struct Token *token,
 	 * still must have iid == 0.
 	 */
 	uint32_t iid = idx_type != SQL_INDEX_TYPE_CONSTRAINT_PK;
-	if (index_fill_def(parse, index, table, iid, name, strlen(name),
+	if (index_fill_def(parse, index, def, iid, name, strlen(name),
 			   col_list, idx_type, sql_stmt) != 0)
 		goto exit_create_index;
 	/*
@@ -2782,7 +2560,7 @@ sql_create_index(struct Parse *parse, struct Token *token,
 	}
 	index->def->key_def->part_count = new_part_count;
 
-	if (!index_def_is_valid(index->def, table->def->name))
+	if (!index_def_is_valid(index->def, def->name))
 		goto exit_create_index;
 
 	/*
@@ -2814,9 +2592,9 @@ sql_create_index(struct Parse *parse, struct Token *token,
 	 * constraint, but has different onError (behavior on
 	 * constraint violation), then an error is raised.
 	 */
-	if (table == parse->pNewTable) {
-		for (uint32_t i = 0; i < table->space->index_count; ++i) {
-			struct index *existing_idx = table->space->index[i];
+	if (parse->pNewTable != NULL) {
+		for (uint32_t i = 0; i < space->index_count; ++i) {
+			struct index *existing_idx = space->index[i];
 			struct key_def *key_def = index->def->key_def;
 			struct key_def *exst_key_def =
 				existing_idx->def->key_def;
@@ -2852,17 +2630,6 @@ sql_create_index(struct Parse *parse, struct Token *token,
 				goto exit_create_index;
 		}
 	}
-	/*
-	 * Link the new Index structure to its table and to the
-	 * other in-memory database structures. If index created
-	 * within CREATE TABLE statement, its iid is assigned
-	 * in sql_init_callback().
-	 */
-	assert(parse->nErr == 0);
-	if (db->init.busy && tbl_name != NULL) {
-		user_session->sql_flags |= SQLITE_InternChanges;
-		index->def->iid = db->init.index_id;
-	}
 
 	/*
 	 * If this is the initial CREATE INDEX statement (or
@@ -2881,7 +2648,6 @@ sql_create_index(struct Parse *parse, struct Token *token,
 	else if (tbl_name != NULL) {
 		Vdbe *vdbe;
 		int cursor = parse->nTab++;
-		int space_id, index_id, first_schema_col;
 
 		vdbe = sqlite3GetVdbe(parse);
 		if (vdbe == 0)
@@ -2894,36 +2660,23 @@ sql_create_index(struct Parse *parse, struct Token *token,
 		sqlite3VdbeChangeP5(vdbe, OPFLAG_SEEKEQ);
 
 		assert(start != NULL);
-		space_id = table->def->id;
-		index_id = getNewIid(parse, space_id, cursor);
+		getNewIid(parse, def->id, cursor);
 		sqlite3VdbeAddOp1(vdbe, OP_Close, cursor);
-		struct index *pk = sql_table_primary_key(table);
-		vdbe_emit_create_index(parse, table->def, index->def, pk->def,
-				       space_id);
-		/* Consumes sql_stmt. */
-		first_schema_col =
-			vdbe_emit_index_schema_record(parse, index->def->name,
-						      space_id, index_id,
-						      sql_stmt);
-
-		/*
-		 * Reparse the schema. Code an OP_Expire
-		 * to invalidate all pre-compiled statements.
-		 */
-		sqlite3VdbeAddParseSchema2Op(vdbe, first_schema_col, 4);
+		struct index *pk = space_index(space, 0);
+		vdbe_emit_create_index(parse, def, index->def, pk->def,
+				       def->id);
 		sqlite3VdbeAddOp0(vdbe, OP_Expire);
 	}
 
-	if (!db->init.busy && tbl_name != NULL)
+	if (tbl_name != NULL)
 		goto exit_create_index;
-	table_add_index(table, index);
+	table_add_index(space, index);
 	index = NULL;
 
 	/* Clean up before exiting. */
  exit_create_index:
 	if (index != NULL)
 		free(index->def);
-	free(index);
 	sql_expr_list_delete(db, col_list);
 	sqlite3SrcListDelete(db, tbl_name);
 	sqlite3DbFree(db, name);
@@ -2992,15 +2745,6 @@ sql_drop_index(struct Parse *parse_context, struct SrcList *index_name_list,
 	sqlite3VdbeAddOp3(v, OP_MakeRecord, space_id_reg, 2, record_reg);
 	sqlite3VdbeAddOp2(v, OP_SDelete, BOX_INDEX_ID, record_reg);
 	sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE);
-	/*
-	 * Still need to cleanup internal SQL structures.
-	 * Should be removed when SQL and Tarantool
-	 * data-dictionaries will be completely merged.
-	 */
-	struct Table *tab = sqlite3HashFind(&db->pSchema->tblHash, table_name);
-	sqlite3VdbeAddOp3(v, OP_DropIndex, index->def->iid, 0, 0);
-	sqlite3VdbeAppendP4(v, tab->space, P4_SPACEPTR);
-
  exit_drop_index:
 	sqlite3SrcListDelete(db, index_name_list);
 	sqlite3DbFree(db, (void *) table_name);
diff --git a/src/box/sql/callback.c b/src/box/sql/callback.c
index d1a48597c..3cf3a835d 100644
--- a/src/box/sql/callback.c
+++ b/src/box/sql/callback.c
@@ -268,45 +268,3 @@ sqlite3FindFunction(sqlite3 * db,	/* An open database */
 	}
 	return 0;
 }
-
-/*
- * Free all resources held by the schema structure. The void* argument points
- * at a Schema struct. This function does not call sqlite3DbFree(db, ) on the
- * pointer itself, it just cleans up subsidiary resources (i.e. the contents
- * of the schema hash tables).
- *
- * The Schema.cache_size variable is not cleared.
- */
-void
-sqlite3SchemaClear(sqlite3 * db)
-{
-	assert(db->pSchema != NULL);
-
-	Hash temp1;
-	HashElem *pElem;
-	Schema *pSchema = db->pSchema;
-
-	temp1 = pSchema->tblHash;
-	sqlite3HashInit(&pSchema->tblHash);
-	for (pElem = sqliteHashFirst(&temp1); pElem;
-	     pElem = sqliteHashNext(pElem)) {
-		Table *pTab = sqliteHashData(pElem);
-		sqlite3DeleteTable(0, pTab);
-	}
-	sqlite3HashClear(&temp1);
-
-	db->pSchema = NULL;
-}
-
-/* Create a brand new schema. */
-Schema *
-sqlite3SchemaCreate(sqlite3 * db)
-{
-	struct Schema *p =
-		(struct Schema *) sqlite3DbMallocZero(0, sizeof(Schema));
-	if (p == NULL)
-		sqlite3OomFault(db);
-	else
-		sqlite3HashInit(&p->tblHash);
-	return p;
-}
diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c
index a457a71d1..16679ea99 100644
--- a/src/box/sql/delete.c
+++ b/src/box/sql/delete.c
@@ -56,7 +56,7 @@ sql_lookup_table(struct Parse *parse, struct SrcList_item *tbl_name)
 	struct Table *table = sqlite3DbMallocZero(parse->db, sizeof(*table));
 	if (table == NULL)
 		return NULL;
-	table->def = space_def_dup(space->def);
+	table->def = space->def;
 	table->space = space;
 	table->nTabRef = 1;
 	tbl_name->pTab = table;
diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index 7b6300c75..f560ada09 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -1515,7 +1515,6 @@ sqlite3SrcListDup(sqlite3 * db, SrcList * p, int flags)
 		struct SrcList_item *pNewItem = &pNew->a[i];
 		struct SrcList_item *pOldItem = &p->a[i];
 		Table *pTab;
-		pNewItem->pSchema = pOldItem->pSchema;
 		pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
 		pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
 		pNewItem->fg = pOldItem->fg;
diff --git a/src/box/sql/main.c b/src/box/sql/main.c
index 69b2fec80..996f13c25 100644
--- a/src/box/sql/main.c
+++ b/src/box/sql/main.c
@@ -1859,7 +1859,6 @@ sql_init_db(sqlite3 **out_db)
 	db->szMmap = sqlite3GlobalConfig.szMmap;
 	db->nMaxSorterMmap = 0x7FFFFFFF;
 
-	db->pSchema = NULL;
 	db->magic = SQLITE_MAGIC_OPEN;
 	if (db->mallocFailed) {
 		goto opendb_out;
diff --git a/src/box/sql/pragma.c b/src/box/sql/pragma.c
index 063836989..b594c8521 100644
--- a/src/box/sql/pragma.c
+++ b/src/box/sql/pragma.c
@@ -474,11 +474,6 @@ sqlite3Pragma(Parse * pParse, Token * pId,	/* First part of [schema.]id field */
 		sqlite3ErrorMsg(pParse, "no such pragma: %s", zLeft);
 		goto pragma_out;
 	}
-
-	/* Make sure the database schema is loaded if the pragma requires that */
-	if ((pPragma->mPragFlg & PragFlg_NeedSchema) != 0) {
-		assert(db->pSchema != NULL);
-	}
 	/* Register the result column names for pragmas that return results */
 	if ((pPragma->mPragFlg & PragFlg_NoColumns) == 0
 	    && ((pPragma->mPragFlg & PragFlg_NoColumns1) == 0 || zRight == 0)
diff --git a/src/box/sql/prepare.c b/src/box/sql/prepare.c
index a59e70dd0..34484a0e3 100644
--- a/src/box/sql/prepare.c
+++ b/src/box/sql/prepare.c
@@ -39,123 +39,6 @@
 #include "box/space.h"
 #include "box/session.h"
 
-/*
- * Fill the InitData structure with an error message that indicates
- * that the database is corrupt.
- */
-static void
-corruptSchema(struct init_data *data,	/* Initialization context */
-	      const char *zObj,	/* Object being parsed at the point of error */
-	      const char *zExtra	/* Error information */
-    )
-{
-	sqlite3 *db = data->db;
-	if (!db->mallocFailed) {
-		char *z;
-		if (zObj == 0)
-			zObj = "?";
-		z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj);
-		if (zExtra)
-			z = sqlite3MPrintf(db, "%z - %s", z, zExtra);
-		sqlite3DbFree(db, *data->pzErrMsg);
-		*data->pzErrMsg = z;
-	}
-	data->rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_CORRUPT_BKPT;
-}
-
-/* Necessary for appropriate value return in InitCallback.
- * Otherwise it will return uint32_t instead of 64 bit pointer.
- */
-struct space *space_by_id(uint32_t id);
-
-int
-sql_init_callback(struct init_data *init, const char *name,
-		  uint32_t space_id, uint32_t index_id, const char *sql)
-{
-	sqlite3 *db = init->db;
-	if (db->mallocFailed) {
-		corruptSchema(init, name, 0);
-		return 1;
-	}
-
-	assert(space_id > 0);
-	if ((strlen(sql) > 7) &&
-	    sqlite3_strnicmp(sql, "create ", 7) == 0) {
-		/* Call the parser to process a CREATE TABLE, INDEX or VIEW.
-		 * But because db->init.busy is set to 1, no VDBE code is generated
-		 * or executed.  All the parser does is build the internal data
-		 * structures that describe the table, index, or view.
-		 */
-		int rc;
-		sqlite3_stmt *pStmt;
-		TESTONLY(int rcp);	/* Return code from sqlite3_prepare() */
-
-		assert(db->init.busy);
-		db->init.space_id = space_id;
-		db->init.index_id = index_id;
-		db->init.orphanTrigger = 0;
-		TESTONLY(rcp =) sqlite3_prepare(db, sql,
-						strlen(sql) + 1, &pStmt, 0);
-		rc = db->errCode;
-		assert((rc & 0xFF) == (rcp & 0xFF));
-		if (SQLITE_OK != rc) {
-			init->rc = rc;
-			if (rc == SQLITE_NOMEM)
-				sqlite3OomFault(db);
-			else if (rc != SQLITE_INTERRUPT &&
-				 (rc & 0xFF) != SQLITE_LOCKED)
-				corruptSchema(init, name, sqlite3_errmsg(db));
-		}
-		sqlite3_finalize(pStmt);
-	} else if (name == NULL || (sql != NULL && sql[0] != 0)) {
-		corruptSchema(init, name, 0);
-	} else {
-		/* If the SQL column is blank it means this is an index that
-		 * was created to be the PRIMARY KEY or to fulfill a UNIQUE
-		 * constraint for a CREATE TABLE.  The index should have already
-		 * been created when we processed the CREATE TABLE.  All we have
-		 * to do here is record the root page number for that index.
-		 */
-		struct space *space = space_by_id(space_id);
-		const char *zSpace = space_name(space);
-		struct index *idx = sqlite3LocateIndex(db, name, zSpace);
-		assert(idx != NULL);
-		idx->def->iid = index_id;
-	}
-	return 0;
-}
-
-/*
- * Attempt to read the database schema and initialize internal
- * data structures for a single database file.
- * Return one of the SQLITE_ error codes to indicate or failure.
- */
-extern int
-sqlite3InitDatabase(sqlite3 * db)
-{
-	int rc;
-	struct init_data init;
-
-	assert(db->pSchema != NULL);
-
-	memset(&init, 0, sizeof(init));
-	init.db = db;
-	/* Read the schema information out of the schema tables
-	 */
-	assert(db->init.busy);
-	{
-		rc = init.rc;
-		if (rc == SQLITE_OK)
-			sql_analysis_load(db);
-	}
-	if (db->mallocFailed) {
-		rc = SQLITE_NOMEM_BKPT;
-		sqlite3ResetAllSchemasOfConnection(db);
-	}
-	return rc;
-}
-
-
 /*
  * Compile the UTF-8 encoded SQL statement zSql into a statement handle.
  */
diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h
index 08893c473..f6b930266 100644
--- a/src/box/sql/sqliteInt.h
+++ b/src/box/sql/sqliteInt.h
@@ -1428,7 +1428,6 @@ void *sqlite3_wsd_find(void *K, int L);
 typedef struct AggInfo AggInfo;
 typedef struct Bitvec Bitvec;
 typedef struct Column Column;
-typedef struct Schema Schema;
 typedef struct Expr Expr;
 typedef struct ExprList ExprList;
 typedef struct ExprSpan ExprSpan;
@@ -1476,13 +1475,6 @@ typedef int VList;
 #include "vdbe.h"
 #include "os.h"
 
-/*
- * An instance of the following structure stores a database schema.
- */
-struct Schema {
-	Hash tblHash;		/* All tables indexed by name */
-};
-
 /*
  * The number of different kinds of things that can be limited
  * using the sqlite3_limit() interface.
@@ -1543,7 +1535,6 @@ struct sqlite3 {
 	sqlite3_vfs *pVfs;	/* OS Interface */
 	struct Vdbe *pVdbe;	/* List of active virtual machines */
 	struct coll *pDfltColl;	/* The default collating sequence (BINARY) */
-	struct Schema *pSchema; /* Schema of the database */
 	i64 szMmap;		/* Default mmap_size setting */
 	int errCode;		/* Most recent error code (SQLITE_*) */
 	int errMask;		/* & result codes with this before returning */
@@ -2355,7 +2346,6 @@ struct SrcList {
 	int nSrc;		/* Number of tables or subqueries in the FROM clause */
 	u32 nAlloc;		/* Number of entries allocated in a[] below */
 	struct SrcList_item {
-		Schema *pSchema;	/* Schema to which this item is fixed */
 		char *zName;	/* Name of the table */
 		char *zAlias;	/* The "B" part of a "A AS B" phrase.  zName is the "A" */
 		Table *pTab;	/* An SQL table corresponding to zName */
@@ -2982,19 +2972,6 @@ struct StrAccum {
 
 #define isMalloced(X)  (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0)
 
-/**
- * A pointer to this structure is used to communicate information
- * from sqlite3Init and OP_ParseSchema into the sql_init_callback.
- */
-struct init_data {
-	/** The database being initialized. */
-	sqlite3 *db;
-	/** Error message stored here. */
-	char **pzErrMsg;
-	/** Result code stored here. */
-	int rc;
-};
-
 /*
  * Structure containing global configuration data for the SQLite library.
  *
@@ -3334,28 +3311,9 @@ u32 sqlite3ExprListFlags(const ExprList *);
 int sqlite3Init(sqlite3 *);
 
 void sqlite3Pragma(Parse *, Token *, Token *, Token *, int);
-void sqlite3ResetAllSchemasOfConnection(sqlite3 *);
 void sqlite3CommitInternalChanges();
 void sqlite3DeleteColumnNames(sqlite3 *, Table *);
 
-/**
- * This is the callback routine for the code that initializes the
- * database.  See sqlite3Init() below for additional information.
- * This routine is also called from the OP_ParseSchema2 opcode of
- * the VDBE.
- *
- * @param init Initialization context.
- * @param name Name of thing being created.
- * @param space_id Space identifier.
- * @param index_id Index identifier.
- * @param sql Text of SQL query.
- *
- * @retval 0 on success, 1 otherwise.
- */
-int
-sql_init_callback(struct init_data *init, const char *name,
-		  uint32_t space_id, uint32_t index_id, const char *sql);
-
 /**
  * Return true if given column is part of primary key.
  * If field number is less than 63, corresponding bit
@@ -3697,23 +3655,6 @@ void sqlite3ExprIfFalse(Parse *, Expr *, int, int);
 void sqlite3ExprIfFalseDup(Parse *, Expr *, int, int);
 #define LOCATE_VIEW    0x01
 #define LOCATE_NOERR   0x02
-Table *sqlite3LocateTable(Parse *, u32 flags, const char *);
-
-struct index *
-sqlite3LocateIndex(sqlite3 *, const char *, const char *);
-void sqlite3UnlinkAndDeleteTable(sqlite3 *, const char *);
-
-/**
- * Release memory for index with given iid and
- * reallocate memory for an array of indexes.
- * FIXME: should be removed after finishing merging SQLite DD
- * with server one.
- *
- * @param space Space which index belongs to.
- * @param iid Id of index to be deleted.
- */
-void
-sql_space_index_delete(struct space *space, uint32_t iid);
 
 char *sqlite3NameFromToken(sqlite3 *, Token *);
 int sqlite3ExprCompare(Expr *, Expr *, int);
@@ -4561,8 +4502,6 @@ sql_analysis_load(struct sqlite3 *db);
 
 void sqlite3RegisterLikeFunctions(sqlite3 *, int);
 int sqlite3IsLikeFunction(sqlite3 *, Expr *, int *, char *);
-void sqlite3SchemaClear(sqlite3 *);
-Schema *sqlite3SchemaCreate(sqlite3 *);
 int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
 		      void (*)(sqlite3_context *, int, sqlite3_value **),
 		      void (*)(sqlite3_context *, int, sqlite3_value **),
diff --git a/src/box/sql/status.c b/src/box/sql/status.c
index 209ed8571..f1501e57a 100644
--- a/src/box/sql/status.c
+++ b/src/box/sql/status.c
@@ -240,22 +240,6 @@ sqlite3_db_status(sqlite3 * db,	/* The database connection whose status is desir
 	case SQLITE_DBSTATUS_SCHEMA_USED:{
 			int nByte = 0;	/* Used to accumulate return value */
 
-			db->pnBytesFreed = &nByte;
-			Schema *pSchema = db->pSchema;
-			if (ALWAYS(pSchema != 0)) {
-				HashElem *p;
-				nByte += ROUND8(sizeof(HashElem)) *
-					 pSchema->tblHash.count;
-
-				for (p = sqliteHashFirst(&pSchema->tblHash); p;
-				     p = sqliteHashNext(p)) {
-					sqlite3DeleteTable(db,
-							   (Table *)
-							   sqliteHashData(p));
-				}
-			}
-			db->pnBytesFreed = 0;
-
 			*pHighwater = 0;
 			*pCurrent = nByte;
 			break;
diff --git a/src/box/sql/trigger.c b/src/box/sql/trigger.c
index b6b727fdd..4fbb855c4 100644
--- a/src/box/sql/trigger.c
+++ b/src/box/sql/trigger.c
@@ -422,7 +422,6 @@ vdbe_code_drop_trigger(struct Parse *parser, const char *trigger_name,
 		       bool account_changes)
 {
 	sqlite3 *db = parser->db;
-	assert(db->pSchema != NULL);
 	struct Vdbe *v = sqlite3GetVdbe(parser);
 	if (v == NULL)
 		return;
@@ -449,7 +448,6 @@ sql_drop_trigger(struct Parse *parser, struct SrcList *name, bool no_err)
 	sqlite3 *db = parser->db;
 	if (db->mallocFailed)
 		goto drop_trigger_cleanup;
-	assert(db->pSchema != NULL);
 
 	struct Vdbe *v = sqlite3GetVdbe(parser);
 	if (v != NULL)
@@ -477,11 +475,10 @@ sql_drop_trigger(struct Parse *parser, struct SrcList *name, bool no_err)
 }
 
 int
-sql_trigger_replace(struct sqlite3 *db, const char *name, uint32_t space_id,
+sql_trigger_replace(const char *name, uint32_t space_id,
 		    struct sql_trigger *trigger,
 		    struct sql_trigger **old_trigger)
 {
-	assert(db->pSchema != NULL);
 	assert(trigger == NULL || strcmp(name, trigger->zName) == 0);
 
 	struct space *space = space_cache_find(space_id);
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index ad251ca99..8973d68d8 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -584,7 +584,6 @@ int sqlite3VdbeExec(Vdbe *p)
 #endif
 	int rc = SQLITE_OK;        /* Value to return */
 	sqlite3 *db = p->db;       /* The database */
-	u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
 	int iCompare = 0;          /* Result of last comparison */
 	unsigned nVmStep = 0;      /* Number of virtual machine steps */
 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
@@ -4533,55 +4532,6 @@ case OP_ResetSorter: {
 	break;
 }
 
-/* Opcode: ParseSchema2 P1 P2 * * *
- * Synopsis: rows=r[P1 at P2]
- *
- * For each 4-tuple from r[P1 at P2] range convert to following
- * format and update the schema with the resulting entry:
- *  <name, pageno (which is hash(spaceId, indexId)), sql>
- */
-case OP_ParseSchema2: {
-	struct init_data init;
-	Mem *pRec, *pRecEnd;
-	assert(db->pSchema != NULL);
-
-	init.db = db;
-	init.pzErrMsg = &p->zErrMsg;
-
-	assert(db->init.busy==0);
-	db->init.busy = 1;
-	init.rc = SQLITE_OK;
-	assert(!db->mallocFailed);
-
-	pRec = &aMem[pOp->p1];
-	pRecEnd = pRec + pOp->p2;
-
-	/*
-	 * A register range contains
-	 *   name1, spaceId1, indexId1, sql1,
-	 *   ...
-	 *   nameN, spaceIdN, indexIdN, sqlN.
-	 *
-	 * Uppdate the schema.
-	 */
-	for(; pRecEnd - pRec >= 4 && init.rc == SQLITE_OK; pRec += 4) {
-		sql_init_callback(&init, pRec[0].z, pRec[1].u.i, pRec[2].u.i,
-				  pRec[3].z);
-	}
-
-	rc = init.rc;
-	db->init.busy = 0;
-
-	if (rc) {
-		sqlite3ResetAllSchemasOfConnection(db);
-		if (rc==SQLITE_NOMEM) {
-			goto no_mem;
-		}
-		goto abort_due_to_error;
-	}
-	break;
-}
-
 /* Opcode: RenameTable P1 * * P4 *
  * Synopsis: P1 = space_id, P4 = name
  *
@@ -4599,7 +4549,6 @@ case OP_RenameTable: {
 	struct space *space;
 	const char *zOldTableName;
 	const char *zNewTableName;
-	struct init_data init;
 	char *zSqlStmt;
 
 	space_id = pOp->p1;
@@ -4614,22 +4563,6 @@ case OP_RenameTable: {
 					 sqlite3Strlen30(zOldTableName));
 	rc = sql_rename_table(space_id, zNewTableName, &zSqlStmt);
 	if (rc) goto abort_due_to_error;
-
-	sqlite3UnlinkAndDeleteTable(db, space->def->name);
-
-	init.db = db;
-	init.pzErrMsg = &p->zErrMsg;
-	assert(db->init.busy == 0);
-	db->init.busy = 1;
-	init.rc = SQLITE_OK;
-	sql_init_callback(&init, zNewTableName, space_id, 0, zSqlStmt);
-	db->init.busy = 0;
-	rc = init.rc;
-	if (rc) {
-		sqlite3CommitInternalChanges();
-		goto abort_due_to_error;
-	}
-
 	/*
 	 * Rebuild 'CREATE TRIGGER' expressions of all triggers
 	 * created on this table. Sure, this action is not atomic
@@ -4674,33 +4607,6 @@ case OP_LoadAnalysis: {
 	break;
 }
 
-/* Opcode: DropTable P1 * * P4 *
- *
- * Remove the internal (in-memory) data structures that describe
- * the table named P4 in database P1.  This is called after a table
- * is dropped from disk (using the Destroy opcode) in order to keep
- * the internal representation of the
- * schema consistent with what is on disk.
- */
-case OP_DropTable: {
-	sqlite3UnlinkAndDeleteTable(db, pOp->p4.z);
-	break;
-}
-
-/* Opcode: DropIndex P1 * *  P4
- *
- * @P1 Contains index id of index to be removed.
- * @P4 Space of removed index.
- *
- * Remove the internal (in-memory) data structures that describe
- * the index named P4 for table.
- * This is called after an index is dropped from Tarantool DD.
- */
-case OP_DropIndex: {
-	sql_space_index_delete(pOp->p4.space, pOp->p1);
-	break;
-}
-
 /* Opcode: Program P1 P2 P3 P4 P5
  *
  * Execute the trigger program passed as P4 (type P4_SUBPROGRAM).
@@ -5319,9 +5225,6 @@ abort_due_to_error:
 	sqlite3VdbeHalt(p);
 	if (rc==SQLITE_IOERR_NOMEM) sqlite3OomFault(db);
 	rc = SQLITE_ERROR;
-	if (resetSchemaOnFault>0) {
-		sqlite3SchemaClear(db);
-	}
 
 	/* This is the only way out of this procedure. */
 vdbe_return:
diff --git a/src/box/sql/vdbe.h b/src/box/sql/vdbe.h
index 6ee83a5de..2d75605bb 100644
--- a/src/box/sql/vdbe.h
+++ b/src/box/sql/vdbe.h
@@ -213,7 +213,6 @@ void sqlite3VdbeVerifyNoResultRow(Vdbe * p);
 #else
 #define sqlite3VdbeVerifyNoResultRow(A)
 #endif
-void sqlite3VdbeAddParseSchema2Op(Vdbe * p, int, int);
 void sqlite3VdbeChangeOpcode(Vdbe *, u32 addr, u8);
 void sqlite3VdbeChangeP1(Vdbe *, u32 addr, int P1);
 void sqlite3VdbeChangeP2(Vdbe *, u32 addr, int P2);
diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
index 12c2edffe..cb906d385 100644
--- a/src/box/sql/vdbeaux.c
+++ b/src/box/sql/vdbeaux.c
@@ -404,12 +404,6 @@ sqlite3VdbeAddOp4Dup8(Vdbe * p,	/* Add the opcode to this VM */
 	return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type);
 }
 
-void
-sqlite3VdbeAddParseSchema2Op(Vdbe * p, int iRec, int n)
-{
-	sqlite3VdbeAddOp3(p, OP_ParseSchema2, iRec, n, 0);
-}
-
 /*
  * Add an opcode that includes the p4 value as an integer.
  */
diff --git a/test/sql-tap/index1.test.lua b/test/sql-tap/index1.test.lua
index fdce2683c..5d060fcdf 100755
--- a/test/sql-tap/index1.test.lua
+++ b/test/sql-tap/index1.test.lua
@@ -83,7 +83,7 @@ test:do_catchsql_test(
         CREATE INDEX index1 ON test1(f1)
     ]], {
         -- <index-2.1>
-        1, "no such table: TEST1"
+        1, "Space 'TEST1' does not exist"
         -- </index-2.1>
     })
 
-- 
2.15.1







More information about the Tarantool-patches mailing list