[tarantool-patches] [PATCH v4 5/7] sql: move names to server

Kirill Shcherbatov kshcherbatov at tarantool.org
Sat Apr 28 21:26:56 MSK 2018


Part of #3272.
---
 src/box/sql.c           | 38 ++++++++++++++++++++++-------
 src/box/sql.h           |  6 ++---
 src/box/sql/alter.c     | 11 +++++----
 src/box/sql/analyze.c   | 11 +++++----
 src/box/sql/build.c     | 61 ++++++++++++++++++++++++++++++-----------------
 src/box/sql/delete.c    |  6 ++---
 src/box/sql/fkey.c      | 11 +++++----
 src/box/sql/hash.c      |  5 ++--
 src/box/sql/insert.c    |  9 +++----
 src/box/sql/pragma.c    |  4 ++--
 src/box/sql/resolve.c   |  7 +++---
 src/box/sql/select.c    | 63 ++++++++++++++++++++++++-------------------------
 src/box/sql/sqliteInt.h |  1 -
 src/box/sql/treeview.c  |  2 +-
 src/box/sql/trigger.c   |  4 ++--
 src/box/sql/update.c    |  3 ++-
 src/box/sql/vdbe.c      |  2 +-
 src/box/sql/where.c     |  5 ++--
 src/box/sql/wherecode.c |  3 ++-
 src/box/sql/whereexpr.c |  2 +-
 20 files changed, 150 insertions(+), 104 deletions(-)

diff --git a/src/box/sql.c b/src/box/sql.c
index ef11eb9..47f7cb1 100644
--- a/src/box/sql.c
+++ b/src/box/sql.c
@@ -1699,12 +1699,13 @@ space_column_default_expr(uint32_t space_id, uint32_t fieldno)
 	return space->def->fields[fieldno].default_value_expr;
 }
 
-struct space_def *
-sql_ephemeral_space_def_new(Parse *parser)
+static struct space_def *
+sql_ephemeral_space_def_new(Parse *parser, const char *name)
 {
 	struct space_def *def = NULL;
 	struct region *region = &fiber()->gc;
-	size_t size = sizeof(struct space_def) + 1;
+	size_t name_len = name != NULL ? strlen(name) : 0;
+	size_t size = sizeof(struct space_def) + name_len + 1;
 	def = (struct space_def *)region_alloc(region, size);
 	if (def != NULL) {
 		memset(def, 0, size);
@@ -1718,19 +1719,40 @@ sql_ephemeral_space_def_new(Parse *parser)
 		parser->nErr++;
 		return NULL;
 	}
+	memcpy(def->name, name, name_len);
+	def->name[name_len] = '\0';
 	def->dict->refs = 1;
 	def->opts.temporary = true;
 	return def;
 }
 
+struct space_def *
+sql_ephemeral_space_def_clone(Parse *parser, struct space_def *old_def)
+{
+	struct space_def *new_def = NULL;
+	new_def = sql_ephemeral_space_def_new(parser, old_def->name);
+	if (new_def == NULL) {
+		parser->rc = SQLITE_NOMEM_BKPT;
+		parser->nErr++;
+		return NULL;
+	}
+	new_def->opts = old_def->opts;
+	new_def->opts.temporary = true;
+	new_def->id = old_def->id;
+	new_def->uid = old_def->uid;
+	memcpy(new_def->engine_name, old_def->engine_name,
+	       strlen(old_def->engine_name));
+	return new_def;
+}
+
 Table *
-sql_ephemeral_table_new(Parse *parser)
+sql_ephemeral_table_new(Parse *parser, const char *name)
 {
 	sqlite3 *db = parser->db;
 	struct space_def *def = NULL;
 	Table *table = sqlite3DbMallocZero(db, sizeof(Table));
 	if (table != NULL)
-		def = sql_ephemeral_space_def_new(parser);
+		def = sql_ephemeral_space_def_new(parser, name);
 	if (def == NULL) {
 		sqlite3DbFree(db, table);
 		return NULL;
@@ -1744,13 +1766,13 @@ int
 sql_table_def_rebuild(struct sqlite3 *db, struct Table *pTable)
 {
 	assert(pTable->def->opts.temporary == true);
-
 	/* All allocations are on region. */
 	struct space_def *old_def = pTable->def;
 	struct space_def *new_def = NULL;
 	new_def = space_def_new(old_def->id, old_def->uid,
-				old_def->field_count, old_def->name,
-				strlen(old_def->name), old_def->engine_name,
+				old_def->field_count,
+				pTable->def->name, strlen(pTable->def->name),
+				old_def->engine_name,
 				strlen(old_def->engine_name), &old_def->opts,
 				old_def->fields, old_def->field_count);
 	if (new_def == NULL) {
diff --git a/src/box/sql.h b/src/box/sql.h
index 410653b..d7cfd70 100644
--- a/src/box/sql.h
+++ b/src/box/sql.h
@@ -152,16 +152,16 @@ sql_expr_free(struct sqlite3 *db, struct Expr *expr, bool extern_alloc);
  * @retval not NULL on success.
  */
 struct Table *
-sql_ephemeral_table_new(struct Parse *parser);
+sql_ephemeral_table_new(struct Parse *parser, const char *name);
 
 /**
- * Create and initialize a new ephemeric space_def object.
+ * Create and initialize a new ephemeric space_def object copy.
  * @param pParse SQL Parser object.
  * @retval NULL on memory allocation error, Parser state changed.
  * @retval not NULL on success.
  */
 struct space_def *
-sql_ephemeral_space_def_new(struct Parse *parser);
+sql_ephemeral_space_def_clone(struct Parse *parser, struct space_def *old_def);
 
 /**
  * Rebuild struct def in Table with memory allocated on a single
diff --git a/src/box/sql/alter.c b/src/box/sql/alter.c
index f830a15..33a4f4d 100644
--- a/src/box/sql/alter.c
+++ b/src/box/sql/alter.c
@@ -109,7 +109,7 @@ sqlite3AlterRenameTable(Parse * pParse,	/* Parser context. */
 #ifndef SQLITE_OMIT_VIEW
 	if (space_is_view(pTab)) {
 		sqlite3ErrorMsg(pParse, "view %s may not be altered",
-				pTab->zName);
+				pTab->def->name);
 		goto exit_rename_table;
 	}
 #endif
@@ -163,7 +163,7 @@ sqlite3AlterFinishAddColumn(Parse * pParse, Token * pColDef)
 	pNew = pParse->pNewTable;
 	assert(pNew);
 
-	zTab = &pNew->zName[16];	/* Skip the "sqlite_altertab_" prefix on the name */
+	zTab = &pNew->def->name[16];	/* Skip the "sqlite_altertab_" prefix on the name */
 	pCol = &pNew->aCol[pNew->def->field_count - 1];
 	assert(pNew->def != NULL);
 	pDflt = space_column_default_expr(SQLITE_PAGENO_TO_SPACEID(pNew->tnum),
@@ -235,7 +235,7 @@ sqlite3AlterFinishAddColumn(Parse * pParse, Token * pColDef)
 	(void)pColDef;
 
 	/* Reload the schema of the modified table. */
-	reloadTableSchema(pParse, pTab, pTab->zName);
+	reloadTableSchema(pParse, pTab, pTab->def->name);
 }
 
 /*
@@ -305,8 +305,9 @@ sqlite3AlterBeginAddColumn(Parse * pParse, SrcList * pSrc)
 	       && nAlloc - pNew->def->field_count < 8);
 	pNew->aCol =
 	    (Column *) sqlite3DbMallocZero(db, sizeof(Column) * nAlloc);
-	pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName);
-	if (!pNew->aCol || !pNew->zName) {
+	/* FIXME: pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName); */
+	/* FIXME: if (!pNew->aCol || !pNew->zName) { */
+	if (!pNew->aCol) {
 		assert(db->mallocFailed);
 		goto exit_begin_add_column;
 	}
diff --git a/src/box/sql/analyze.c b/src/box/sql/analyze.c
index a0ad511..dc5b4e9 100644
--- a/src/box/sql/analyze.c
+++ b/src/box/sql/analyze.c
@@ -828,7 +828,7 @@ analyzeOneTable(Parse * pParse,	/* Parser context */
 		return;
 	}
 	assert(pTab->tnum != 0);
-	if (sqlite3_strlike("\\_%", pTab->zName, '\\') == 0) {
+	if (sqlite3_strlike("\\_%", pTab->def->name, '\\') == 0) {
 		/* Do not gather statistics on system tables */
 		return;
 	}
@@ -842,7 +842,7 @@ analyzeOneTable(Parse * pParse,	/* Parser context */
 	iIdxCur = iTab++;
 	pParse->nTab = MAX(pParse->nTab, iTab);
 	sqlite3OpenTable(pParse, iTabCur, pTab, OP_OpenRead);
-	sqlite3VdbeLoadString(v, regTabname, pTab->zName);
+	sqlite3VdbeLoadString(v, regTabname, pTab->def->name);
 
 	for (pIdx = pTab->pIndex; pIdx; pIdx = pIdx->pNext) {
 		int addrRewind;	/* Address of "OP_Rewind iIdxCur" */
@@ -857,7 +857,7 @@ analyzeOneTable(Parse * pParse,	/* Parser context */
 		 * instead more familiar table name.
 		 */
 		if (IsPrimaryKeyIndex(pIdx)) {
-			zIdxName = pTab->zName;
+			zIdxName = pTab->def->name;
 		} else {
 			zIdxName = pIdx->zName;
 		}
@@ -865,7 +865,8 @@ analyzeOneTable(Parse * pParse,	/* Parser context */
 
 		/* Populate the register containing the index name. */
 		sqlite3VdbeLoadString(v, regIdxname, zIdxName);
-		VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName));
+		VdbeComment((v, "Analysis for %s.%s",
+			pTab->def->name, zIdxName));
 
 		/*
 		 * Pseudo-code for loop that calls stat_push():
@@ -1146,7 +1147,7 @@ analyzeTable(Parse * pParse, Table * pTab, Index * pOnlyIdx)
 	if (pOnlyIdx) {
 		openStatTable(pParse, iStatCur, pOnlyIdx->zName, "idx");
 	} else {
-		openStatTable(pParse, iStatCur, pTab->zName, "tbl");
+		openStatTable(pParse, iStatCur, pTab->def->name, "tbl");
 	}
 	analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur, pParse->nMem + 1,
 			pParse->nTab);
diff --git a/src/box/sql/build.c b/src/box/sql/build.c
index e9c0686..4e0ae87 100644
--- a/src/box/sql/build.c
+++ b/src/box/sql/build.c
@@ -382,7 +382,6 @@ deleteTable(sqlite3 * db, Table * pTable)
 	 */
 	sqlite3HashClear(&pTable->idxHash);
 	sqlite3DeleteColumnNames(db, pTable);
-	sqlite3DbFree(db, pTable->zName);
 	sqlite3DbFree(db, pTable->zColAff);
 	sqlite3SelectDelete(db, pTable->pSelect);
 	sqlite3ExprListDelete(db, pTable->pCheck);
@@ -495,10 +494,9 @@ static Table *
 sql_table_new(Parse *parser, char *name)
 {
 	sqlite3 *db = parser->db;
-	struct Table *table = sql_ephemeral_table_new(parser);
+	struct Table *table = sql_ephemeral_table_new(parser, name);
 	if (table == NULL)
 		return NULL;
-	table->zName = name;
 	table->iPKey = -1;
 	table->iAutoIncPKey = -1;
 	table->pSchema = db->pSchema;
@@ -662,7 +660,8 @@ sqlite3AddColumn(Parse * pParse, Token * pName, Token * pType)
 	assert(p->def->opts.temporary == true);
 #if SQLITE_MAX_COLUMN
 	if ((int)p->def->field_count + 1 > db->aLimit[SQLITE_LIMIT_COLUMN]) {
-		sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName);
+		sqlite3ErrorMsg(pParse, "too many columns on %s", 
+				p->def->name);
 		return;
 	}
 #endif
@@ -921,7 +920,7 @@ sqlite3AddPrimaryKey(Parse * pParse,	/* Parsing context */
 	if (pTab->tabFlags & TF_HasPrimaryKey) {
 		sqlite3ErrorMsg(pParse,
 				"table \"%s\" has more than one primary key",
-				pTab->zName);
+				pTab->def->name);
 		goto primary_key_exit;
 	}
 	pTab->tabFlags |= TF_HasPrimaryKey;
@@ -1288,7 +1287,7 @@ createTableStmt(sqlite3 * db, Table * p)
 	n = 0;
 	for (i = 0; i < (int)p->def->field_count; i++)
 		n += identLength(p->def->fields[i].name) + 5;
-	n += identLength(p->zName);
+	n += identLength(p->def->name);
 	if (n < 50) {
 		zSep = "";
 		zSep2 = ",";
@@ -1306,7 +1305,7 @@ createTableStmt(sqlite3 * db, Table * p)
 	}
 	sqlite3_snprintf(n, zStmt, "CREATE TABLE ");
 	k = sqlite3Strlen30(zStmt);
-	identPut(zStmt, &k, p->zName);
+	identPut(zStmt, &k, (char *)p->def->name);
 	zStmt[k++] = '(';
 	for (pCol = p->aCol, i = 0; i < (int)p->def->field_count; i++, pCol++) {
 		static const char *const azType[] = {
@@ -1642,7 +1641,7 @@ createSpace(Parse * pParse, int iSpaceId, char *zStmt)
 	sqlite3VdbeAddOp2(v, OP_Integer, effective_user()->uid,
 			  iFirstCol + 1 /* owner */ );
 	sqlite3VdbeAddOp4(v, OP_String8, 0, iFirstCol + 2 /* name */ , 0,
-			  sqlite3DbStrDup(pParse->db, p->zName), P4_DYNAMIC);
+			  sqlite3DbStrDup(pParse->db, p->def->name), P4_DYNAMIC);
 	sqlite3VdbeAddOp4(v, OP_String8, 0, iFirstCol + 3 /* engine */ , 0,
 			  "memtx", P4_STATIC);
 	sqlite3VdbeAddOp2(v, OP_Integer, p->def->field_count,
@@ -1710,7 +1709,8 @@ parseTableSchemaRecord(Parse * pParse, int iSpaceId, char *zStmt)
 
 	sqlite3VdbeAddOp4(v,
 			  OP_String8, 0, iTop, 0,
-			  sqlite3DbStrDup(pParse->db, p->zName), P4_DYNAMIC);
+			  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);
@@ -1848,7 +1848,7 @@ sqlite3EndTable(Parse * pParse,	/* Parse context */
 		if ((p->tabFlags & TF_HasPrimaryKey) == 0) {
 			sqlite3ErrorMsg(pParse,
 					"PRIMARY KEY missing on table %s",
-					p->zName);
+					p->def->name);
 			return;
 		} else {
 			convertToWithoutRowidTable(pParse, p);
@@ -1950,7 +1950,7 @@ sqlite3EndTable(Parse * pParse,	/* Parse context */
 
 			reg_seq_record = emitNewSysSequenceRecord(pParse,
 								  reg_seq_id,
-								  p->zName);
+								  	p->def->name);
 			sqlite3VdbeAddOp2(v, OP_SInsert, BOX_SEQUENCE_ID,
 					  reg_seq_record);
 			/* Do an insertion into _space_sequence. */
@@ -1970,8 +1970,8 @@ sqlite3EndTable(Parse * pParse,	/* Parse context */
 	if (db->init.busy) {
 		Table *pOld;
 		Schema *pSchema = p->pSchema;
-		assert(p->def->opts.temporary == false);
-		pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, p);
+		pOld = sqlite3HashInsert(&pSchema->tblHash,
+					 p->def->name, p);
 		if (pOld) {
 			assert(p == pOld);	/* Malloc must have failed inside HashInsert() */
 			sqlite3OomFault(db);
@@ -2106,7 +2106,7 @@ sqlite3ViewGetColumnNames(Parse * pParse, Table * pTable)
 	 */
 	if ((int)pTable->def->field_count < 0) {
 		sqlite3ErrorMsg(pParse, "view %s is circularly defined",
-				pTable->zName);
+				pTable->def->name);
 		return 1;
 	}
 	assert((int)pTable->def->field_count >= 0);
@@ -2135,6 +2135,11 @@ sqlite3ViewGetColumnNames(Parse * pParse, Table * pTable)
 			 * a VIEW it holds the list of column names.
 			 */
 			sqlite3ColumnsFromExprList(pParse, pTable->pCheck, pTable);
+			struct space_def *old_def = pTable->def;
+			old_def->opts.temporary = true; /* delete it manually */
+			if (sql_table_def_rebuild(db, pTable) != 0)
+				nErr++;
+			space_def_delete(old_def);
 			if (db->mallocFailed == 0 && pParse->nErr == 0
 			    && (int)pTable->def->field_count == pSel->pEList->nExpr) {
 				sqlite3SelectAddColumnTypeAndCollation(pParse,
@@ -2142,18 +2147,30 @@ sqlite3ViewGetColumnNames(Parse * pParse, Table * pTable)
 								       pSel);
 			}
 		} else if (pSelTab) {
-			assert(pTable->def->opts.temporary == false);
 			/* CREATE VIEW name AS...  without an argument list.  Construct
 			 * the column names from the SELECT statement that defines the view.
 			 */
 			assert(pTable->aCol == 0);
 			assert((int)pTable->def->field_count == -1);
-			struct space_def *def = pSelTab->def;
-			pSelTab->def = pTable->def;
-			pSelTab->def->field_count = 0;
-			pTable->def = def;
+			assert(pSelTab->def->opts.temporary);
+
+			struct space_def *old_def = pTable->def;
+			struct space_def *new_def =
+				sql_ephemeral_space_def_clone(pParse, old_def);
+			if (new_def == NULL) {
+				nErr++;
+			} else {
+				new_def->fields = pSelTab->def->fields;
+				new_def->field_count = pSelTab->def->field_count;
+				pTable->def = new_def;
+				if (sql_table_def_rebuild(db, pTable) != 0)
+					nErr++;
+			}
 			pTable->aCol = pSelTab->aCol;
 			pSelTab->aCol = 0;
+			pSelTab->def = old_def;
+			pSelTab->def->fields = NULL;
+			pSelTab->def->field_count = 0;
 		} else {
 			pTable->def->field_count = 0;
 			nErr++;
@@ -2939,7 +2956,7 @@ sqlite3CreateIndex(Parse * pParse,	/* All information about this parse */
 			if (!ifNotExist) {
 				sqlite3ErrorMsg(pParse,
 						"index %s.%s already exists",
-						pTab->zName, zName);
+						pTab->def->name, zName);
 			} else {
 				assert(!db->init.busy);
 			}
@@ -2952,7 +2969,7 @@ sqlite3CreateIndex(Parse * pParse,	/* All information about this parse */
 		     pLoop = pLoop->pNext, n++) {
 		}
 		zName =
-		    sqlite3MPrintf(db, "sqlite_autoindex_%s_%d", pTab->zName,
+		    sqlite3MPrintf(db, "sqlite_autoindex_%s_%d", pTab->def->name,
 				   n);
 		if (zName == 0) {
 			goto exit_create_index;
@@ -4022,7 +4039,7 @@ sqlite3UniqueConstraint(Parse * pParse,	/* Parsing context */
 			zCol = pTab->def->fields[pIdx->aiColumn[j]].name;
 			if (j)
 				sqlite3StrAccumAppend(&errMsg, ", ", 2);
-			sqlite3XPrintf(&errMsg, "%s.%s", pTab->zName, zCol);
+			sqlite3XPrintf(&errMsg, "%s.%s", pTab->def->name, zCol);
 		}
 	}
 	zErr = sqlite3StrAccumFinish(&errMsg);
diff --git a/src/box/sql/delete.c b/src/box/sql/delete.c
index 65d20fa..c6ecba6 100644
--- a/src/box/sql/delete.c
+++ b/src/box/sql/delete.c
@@ -82,13 +82,13 @@ sqlite3IsReadOnly(Parse * pParse, Table * pTab, int viewOk)
 	 */
 	if ((pTab->tabFlags & TF_Readonly) != 0 && pParse->nested == 0) {
 		sqlite3ErrorMsg(pParse, "table %s may not be modified",
-				pTab->zName);
+				pTab->def->name);
 		return 1;
 	}
 #ifndef SQLITE_OMIT_VIEW
 	if (!viewOk && space_is_view(pTab)) {
 		sqlite3ErrorMsg(pParse, "cannot modify %s because it is a view",
-				pTab->zName);
+				pTab->def->name);
 		return 1;
 	}
 #endif
@@ -115,7 +115,7 @@ sqlite3MaterializeView(Parse * pParse,	/* Parsing context */
 	pFrom = sqlite3SrcListAppend(db, 0, 0);
 	if (pFrom) {
 		assert(pFrom->nSrc == 1);
-		pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
+		pFrom->a[0].zName = sqlite3DbStrDup(db, pView->def->name);
 		assert(pFrom->a[0].pOn == 0);
 		assert(pFrom->a[0].pUsing == 0);
 	}
diff --git a/src/box/sql/fkey.c b/src/box/sql/fkey.c
index 8c015c9..16f72d8 100644
--- a/src/box/sql/fkey.c
+++ b/src/box/sql/fkey.c
@@ -332,7 +332,7 @@ sqlite3FkLocateIndex(Parse * pParse,	/* Parse context to store any error in */
 		if (!pParse->disableTriggers) {
 			sqlite3ErrorMsg(pParse,
 					"foreign key mismatch - \"%w\" referencing \"%w\"",
-					pFKey->pFrom->zName, pFKey->zTo);
+					pFKey->pFrom->def->name, pFKey->zTo);
 		}
 		sqlite3DbFree(pParse->db, aiCol);
 		return 1;
@@ -721,7 +721,8 @@ fkScanChildren(Parse * pParse,	/* Parse context */
 FKey *
 sqlite3FkReferences(Table * pTab)
 {
-	return (FKey *) sqlite3HashFind(&pTab->pSchema->fkeyHash, pTab->zName);
+	return (FKey *) sqlite3HashFind(&pTab->pSchema->fkeyHash,
+					pTab->def->name);
 }
 
 /*
@@ -951,7 +952,7 @@ sqlite3FkCheck(Parse * pParse,	/* Parse context */
 		int bIgnore = 0;
 
 		if (aChange
-		    && sqlite3_stricmp(pTab->zName, pFKey->zTo) != 0
+		    && sqlite3_stricmp(pTab->def->name, pFKey->zTo) != 0
 		    && fkChildIsModified(pFKey, aChange) == 0) {
 			continue;
 		}
@@ -1076,7 +1077,7 @@ sqlite3FkCheck(Parse * pParse,	/* Parse context */
 		if (pSrc) {
 			struct SrcList_item *pItem = pSrc->a;
 			pItem->pTab = pFKey->pFrom;
-			pItem->zName = pFKey->pFrom->zName;
+			pItem->zName = pFKey->pFrom->def->name;
 			pItem->pTab->nTabRef++;
 			pItem->iCursor = pParse->nTab++;
 
@@ -1375,7 +1376,7 @@ fkActionTrigger(Parse * pParse,	/* Parse context */
 		}
 		sqlite3DbFree(db, aiCol);
 
-		zFrom = pFKey->pFrom->zName;
+		zFrom = pFKey->pFrom->def->name;
 		nFrom = sqlite3Strlen30(zFrom);
 
 		if (action == OE_Restrict) {
diff --git a/src/box/sql/hash.c b/src/box/sql/hash.c
index cedcb7d..79f0840 100644
--- a/src/box/sql/hash.c
+++ b/src/box/sql/hash.c
@@ -69,6 +69,7 @@ sqlite3HashClear(Hash * pH)
 	while (elem) {
 		HashElem *next_elem = elem->next;
 		sqlite3_free(elem);
+		free((void *)elem->pKey);
 		elem = next_elem;
 	}
 	pH->count = 0;
@@ -292,7 +293,7 @@ sqlite3HashInsert(Hash * pH, const char *pKey, void *data)
 			removeElementGivenHash(pH, elem, h);
 		} else {
 			elem->data = data;
-			elem->pKey = pKey;
+			elem->pKey = strdup(pKey);
 		}
 		return old_data;
 	}
@@ -301,7 +302,7 @@ sqlite3HashInsert(Hash * pH, const char *pKey, void *data)
 	new_elem = (HashElem *) sqlite3Malloc(sizeof(HashElem));
 	if (new_elem == 0)
 		return data;
-	new_elem->pKey = pKey;
+	new_elem->pKey = strdup(pKey);
 	new_elem->data = data;
 	pH->count++;
 	if (pH->count >= 10 && pH->count > 2 * pH->htsize) {
diff --git a/src/box/sql/insert.c b/src/box/sql/insert.c
index 06635ee..bde0cc1 100644
--- a/src/box/sql/insert.c
+++ b/src/box/sql/insert.c
@@ -56,7 +56,7 @@ sqlite3OpenTable(Parse * pParse,	/* Generate code into this VDBE */
 	assert(pPk->tnum == pTab->tnum);
 	emit_open_cursor(pParse, iCur, pPk->tnum);
 	sqlite3VdbeSetP4KeyInfo(pParse, pPk);
-	VdbeComment((v, "%s", pTab->zName));
+	VdbeComment((v, "%s", pTab->def->name));
 }
 
 /*
@@ -1145,7 +1145,8 @@ sqlite3GenerateConstraintChecks(Parse * pParse,		/* The parser context */
 		case ON_CONFLICT_ACTION_ROLLBACK:
 		case ON_CONFLICT_ACTION_FAIL: {
 				char *zMsg =
-				    sqlite3MPrintf(db, "%s.%s", pTab->zName,
+				    sqlite3MPrintf(db, "%s.%s", 
+						   pTab->def->name,
 						   pTab->def->fields[i].name);
 				sqlite3VdbeAddOp3(v, OP_HaltIfNull,
 						  SQLITE_CONSTRAINT_NOTNULL,
@@ -1200,7 +1201,7 @@ sqlite3GenerateConstraintChecks(Parse * pParse,		/* The parser context */
 			} else {
 				char *zName = pCheck->a[i].zName;
 				if (zName == 0)
-					zName = pTab->zName;
+					zName = pTab->def->name;
 				if (onError == ON_CONFLICT_ACTION_REPLACE)
 					onError = ON_CONFLICT_ACTION_ABORT;
 				sqlite3HaltConstraint(pParse,
@@ -1404,7 +1405,7 @@ sqlite3GenerateConstraintChecks(Parse * pParse,		/* The parser context */
 					x = pPk->aiColumn[i];
 					sqlite3VdbeAddOp3(v, OP_Column,
 							  iThisCur, x, regR + i);
-					VdbeComment((v, "%s.%s", pTab->zName,
+					VdbeComment((v, "%s.%s", pTab->def->name,
 						pTab->def->fields[
 							pPk->aiColumn[i]].name));
 				}
diff --git a/src/box/sql/pragma.c b/src/box/sql/pragma.c
index 0cf103c..463bb7e 100644
--- a/src/box/sql/pragma.c
+++ b/src/box/sql/pragma.c
@@ -405,7 +405,7 @@ sqlite3Pragma(Parse * pParse, Token * pId,	/* First part of [schema.]id field */
 			     i = sqliteHashNext(i)) {
 				Table *pTab = sqliteHashData(i);
 				sqlite3VdbeMultiLoad(v, 1, "ssii",
-						     pTab->zName,
+						     pTab->def->name,
 						     0,
 						     pTab->szTabRow,
 						     pTab->nRowLogEst);
@@ -623,7 +623,7 @@ sqlite3Pragma(Parse * pParse, Token * pId,	/* First part of [schema.]id field */
 						pTab->def->field_count + regRow;
 				sqlite3OpenTable(pParse, 0, pTab, OP_OpenRead);
 				sqlite3VdbeLoadString(v, regResult,
-						      pTab->zName);
+						      pTab->def->name);
 				for (i = 1, pFK = pTab->pFKey; pFK;
 				     i++, pFK = pFK->pNextFrom) {
 					pParent =
diff --git a/src/box/sql/resolve.c b/src/box/sql/resolve.c
index 109c410..5d85ef7 100644
--- a/src/box/sql/resolve.c
+++ b/src/box/sql/resolve.c
@@ -239,7 +239,8 @@ lookupName(Parse * pParse,	/* The parsing context */
 			for (i = 0, pItem = pSrcList->a; i < pSrcList->nSrc;
 			     i++, pItem++) {
 				pTab = pItem->pTab;
-				assert(pTab != 0 && pTab->zName != 0);
+				assert(pTab != 0 && 
+					pTab->def->name != NULL);
 				assert(pTab->def->field_count > 0);
 				if (pItem->pSelect
 				    && (pItem->pSelect->
@@ -263,7 +264,7 @@ lookupName(Parse * pParse,	/* The parsing context */
 				if (zTab) {
 					const char *zTabName =
 					    pItem->zAlias ? pItem->
-					    zAlias : pTab->zName;
+					    zAlias : pTab->def->name;
 					assert(zTabName != 0);
 					if (strcmp(zTabName, zTab) != 0) {
 						continue;
@@ -1604,7 +1605,7 @@ sqlite3ResolveSelfReference(Parse * pParse,	/* Parsing context */
 	memset(&sNC, 0, sizeof(sNC));
 	memset(&sSrc, 0, sizeof(sSrc));
 	sSrc.nSrc = 1;
-	sSrc.a[0].zName = pTab->zName;
+	sSrc.a[0].zName = pTab->def->name;
 	sSrc.a[0].pTab = pTab;
 	sSrc.a[0].iCursor = -1;
 	sNC.pParse = pParse;
diff --git a/src/box/sql/select.c b/src/box/sql/select.c
index fa1de9b..199caf0 100644
--- a/src/box/sql/select.c
+++ b/src/box/sql/select.c
@@ -1765,7 +1765,8 @@ generateColumnNames(Parse * pParse,	/* Parser context */
 			} else if (fullNames) {
 				char *zName = 0;
 				zName =
-				    sqlite3MPrintf(db, "%s.%s", pTab->zName,
+				    sqlite3MPrintf(db, "%s.%s", 
+						   pTab->def->name,
 						   zCol);
 				sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName,
 						      SQLITE_DYNAMIC);
@@ -1825,14 +1826,6 @@ sqlite3ColumnsFromExprList(Parse * pParse,	/* Parsing context */
 
 	struct region *region = &fiber()->gc;
 	assert(pTable->def->fields == NULL);
-	if (pTable->def->opts.temporary == false) {
-		/* CREATE VIEW name AS...  without an argument list.  Construct
-		 * the column names from the SELECT statement that defines the view.
-		 */
-		pTable->def->field_count = 0;
-		space_def_delete(pTable->def);
-		pTable->def = sql_ephemeral_space_def_new(pParse);
-	}
 	pTable->def->fields =
 		region_alloc(region, nCol*sizeof(pTable->def->fields[0]));
 	memset(pTable->def->fields, 0, nCol*sizeof(pTable->def->fields[0]));
@@ -1904,11 +1897,8 @@ sqlite3ColumnsFromExprList(Parse * pParse,	/* Parsing context */
 	}
 	sqlite3HashClear(&ht);
 	int rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_OK;
-	if (sql_table_def_rebuild(db, pTable) != 0)
-		rc = SQLITE_NOMEM_BKPT;
 	if (rc != SQLITE_OK) {
 		sqlite3DbFree(db, aCol);
-		sqlite3DbFree(db, pTable->def->fields);
 		pTable->def->fields = NULL;
 		pTable->def->field_count = 0;
 		pTable->aCol = 0;
@@ -1972,6 +1962,7 @@ sqlite3SelectAddColumnTypeAndCollation(Parse * pParse,		/* Parsing contexts */
 /*
  * Given a SELECT statement, generate a Table structure that describes
  * the result set of that SELECT.
+ * Return table with def is allocated on region.
  */
 Table *
 sqlite3ResultSetOfSelect(Parse * pParse, Select * pSelect)
@@ -1990,7 +1981,7 @@ sqlite3ResultSetOfSelect(Parse * pParse, Select * pSelect)
 	while (pSelect->pPrior)
 		pSelect = pSelect->pPrior;
 	user_session->sql_flags = savedFlags;
-	pTab = sql_ephemeral_table_new(pParse);
+	pTab = sql_ephemeral_table_new(pParse, NULL);
 	if (pTab == NULL)
 		return 0;
 	/* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside
@@ -1998,7 +1989,6 @@ sqlite3ResultSetOfSelect(Parse * pParse, Select * pSelect)
 	 */
 	assert(db->lookaside.bDisable);
 	pTab->nTabRef = 1;
-	pTab->zName = 0;
 	pTab->nRowLogEst = 200;
 	assert(200 == sqlite3LogEst(1048576));
 	sqlite3ColumnsFromExprList(pParse, pSelect->pEList, pTab);
@@ -4522,11 +4512,11 @@ withExpand(Walker * pWalker, struct SrcList_item *pFrom)
 			return SQLITE_ERROR;
 
 		assert(pFrom->pTab == 0);
-		pFrom->pTab = pTab = sql_ephemeral_table_new(pParse);
+		pFrom->pTab = pTab =
+			sql_ephemeral_table_new(pParse, pCte->zName);
 		if (pTab == NULL)
 			return WRC_Abort;
 		pTab->nTabRef = 1;
-		pTab->zName = sqlite3DbStrDup(db, pCte->zName);
 		pTab->iPKey = -1;
 		pTab->nRowLogEst = 200;
 		assert(200 == sqlite3LogEst(1048576));
@@ -4691,12 +4681,14 @@ selectExpander(Walker * pWalker, Select * p)
 	for (i = 0, pFrom = pTabList->a; i < pTabList->nSrc; i++, pFrom++) {
 		Table *pTab;
 		assert(pFrom->fg.isRecursive == 0 || pFrom->pTab != 0);
-		if (pFrom->fg.isRecursive)
+		if (pFrom->fg.isRecursive) {
 			continue;
+		}
 		assert(pFrom->pTab == 0);
 #ifndef SQLITE_OMIT_CTE
-		if (withExpand(pWalker, pFrom))
+		if (withExpand(pWalker, pFrom)) {
 			return WRC_Abort;
+		}
 		if (pFrom->pTab) {
 		} else
 #endif
@@ -4707,17 +4699,24 @@ selectExpander(Walker * pWalker, Select * p)
 			assert(pFrom->pTab == 0);
 			if (sqlite3WalkSelect(pWalker, pSel))
 				return WRC_Abort;
+			char *name = "sqlite_sq_DEADBEAFDEADBEAF";
 			pFrom->pTab = pTab =
-				sql_ephemeral_table_new(pParse);
+				sql_ephemeral_table_new(pParse, name);
 			if (pTab == NULL)
 				return WRC_Abort;
+			/* rewrite old name with correct pointer */
+			name = sqlite3MPrintf(db, "sqlite_sq_%p", (void *)pTab);
+			sprintf(pTab->def->name, "%s", name);
+			sqlite3DbFree(db, name);
+
 			pTab->nTabRef = 1;
-			pTab->zName =
-			    sqlite3MPrintf(db, "sqlite_sq_%p", (void *)pTab);
 			while (pSel->pPrior) {
 				pSel = pSel->pPrior;
 			}
 			sqlite3ColumnsFromExprList(pParse, pSel->pEList, pTab);
+			if (sql_table_def_rebuild(db, pTab) != 0)
+				return WRC_Abort;
+
 			pTab->iPKey = -1;
 			pTab->nRowLogEst = 200;
 			assert(200 == sqlite3LogEst(1048576));
@@ -4727,12 +4726,13 @@ selectExpander(Walker * pWalker, Select * p)
 			assert(pFrom->pTab == 0);
 			pFrom->pTab = pTab =
 			    sqlite3LocateTable(pParse, 0, pFrom->zName);
-			if (pTab == NULL)
+			if (pTab == NULL) {
 				return WRC_Abort;
+			}
 			if (pTab->nTabRef >= 0xffff) {
 				sqlite3ErrorMsg(pParse,
 						"too many references to \"%s\": max 65535",
-						pTab->zName);
+						pTab->def->name);
 				pFrom->pTab = 0;
 				return WRC_Abort;
 			}
@@ -4749,7 +4749,7 @@ selectExpander(Walker * pWalker, Select * p)
 				pFrom->pSelect =
 				    sqlite3SelectDup(db, pTab->pSelect, 0);
 				sqlite3SelectSetName(pFrom->pSelect,
-						     pTab->zName);
+						     pTab->def->name);
 				nCol = pTab->def->field_count;
 				pTab->def->field_count = -1;
 				sqlite3WalkSelect(pWalker, pFrom->pSelect);
@@ -4842,7 +4842,7 @@ selectExpander(Walker * pWalker, Select * p)
 					Select *pSub = pFrom->pSelect;
 					char *zTabName = pFrom->zAlias;
 					if (zTabName == 0) {
-						zTabName = pTab->zName;
+						zTabName = pTab->def->name;
 					}
 					if (db->mallocFailed)
 						break;
@@ -5288,7 +5288,7 @@ explainSimpleCount(Parse * pParse,	/* Parse context */
 	if (pParse->explain == 2) {
 		int bCover = (pIdx != 0 && !IsPrimaryKeyIndex(pIdx));
 		char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s%s%s",
-					    pTab->zName,
+					    pTab->def->name,
 					    bCover ? " USING COVERING INDEX " :
 					    "",
 					    bCover ? pIdx->zName : "");
@@ -5390,14 +5390,13 @@ sqlite3Select(Parse * pParse,		/* The parser context */
 		Table *pTab = pItem->pTab;
 		if (pSub == 0)
 			continue;
-
 		/* Catch mismatch in the declared columns of a view and the number of
 		 * columns in the SELECT on the RHS
 		 */
 		if ((int)pTab->def->field_count != pSub->pEList->nExpr) {
 			sqlite3ErrorMsg(pParse,
 					"expected %d columns for '%s' but got %d",
-					pTab->def->field_count, pTab->zName,
+					pTab->def->field_count, pTab->def->name,
 					pSub->pEList->nExpr);
 			goto select_end;
 		}
@@ -5515,7 +5514,7 @@ sqlite3Select(Parse * pParse,		/* The parser context */
 			pItem->regReturn = ++pParse->nMem;
 			sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn,
 					  0, addrTop);
-			VdbeComment((v, "%s", pItem->pTab->zName));
+			VdbeComment((v, "%s", pItem->pTab->def->name));
 			pItem->addrFillSub = addrTop;
 			sqlite3SelectDestInit(&dest, SRT_Coroutine,
 					      pItem->regReturn);
@@ -5550,10 +5549,10 @@ sqlite3Select(Parse * pParse,		/* The parser context */
 				onceAddr = sqlite3VdbeAddOp0(v, OP_Once);
 				VdbeCoverage(v);
 				VdbeComment((v, "materialize \"%s\"",
-					     pItem->pTab->zName));
+					     pItem->pTab->def->name));
 			} else {
 				VdbeNoopComment((v, "materialize \"%s\"",
-						 pItem->pTab->zName));
+						 pItem->pTab->def->name));
 			}
 			sqlite3SelectDestInit(&dest, SRT_EphemTab,
 					      pItem->iCursor);
@@ -5564,7 +5563,7 @@ sqlite3Select(Parse * pParse,		/* The parser context */
 				sqlite3VdbeJumpHere(v, onceAddr);
 			retAddr =
 			    sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
-			VdbeComment((v, "end %s", pItem->pTab->zName));
+			VdbeComment((v, "end %s", pItem->pTab->def->name));
 			sqlite3VdbeChangeP1(v, topAddr, retAddr);
 			sqlite3ClearTempRegCache(pParse);
 		}
diff --git a/src/box/sql/sqliteInt.h b/src/box/sql/sqliteInt.h
index a045286..6eddbec 100644
--- a/src/box/sql/sqliteInt.h
+++ b/src/box/sql/sqliteInt.h
@@ -1927,7 +1927,6 @@ struct Column {
  * by an instance of the following structure.
  */
 struct Table {
-	char *zName;		/* Name of the table or view */
 	Column *aCol;		/* Information about each column */
 	Index *pIndex;		/* List of SQL indexes on this table. */
 	Select *pSelect;	/* NULL for tables.  Points to definition if a view. */
diff --git a/src/box/sql/treeview.c b/src/box/sql/treeview.c
index 1ff949c..f9077c1 100644
--- a/src/box/sql/treeview.c
+++ b/src/box/sql/treeview.c
@@ -224,7 +224,7 @@ sqlite3TreeViewSelect(TreeView * pView, const Select * p, u8 moreToFollow)
 				}
 				if (pItem->pTab) {
 					sqlite3XPrintf(&x, " tabname=%Q",
-						       pItem->pTab->zName);
+						       pItem->pTab->def->name);
 				}
 				if (pItem->zAlias) {
 					sqlite3XPrintf(&x, " (AS %s)",
diff --git a/src/box/sql/trigger.c b/src/box/sql/trigger.c
index 9b03be1..ae992eb 100644
--- a/src/box/sql/trigger.c
+++ b/src/box/sql/trigger.c
@@ -134,7 +134,7 @@ sqlite3BeginTrigger(Parse * pParse,	/* The parse context of the CREATE TRIGGER s
 	}
 
 	/* Do not create a trigger on a system table */
-	if (sqlite3StrNICmp(pTab->zName, "sqlite_", 7) == 0) {
+	if (sqlite3StrNICmp(pTab->def->name, "sqlite_", 7) == 0) {
 		sqlite3ErrorMsg(pParse,
 				"cannot create trigger on system table");
 		goto trigger_cleanup;
@@ -885,7 +885,7 @@ codeRowTrigger(Parse * pParse,	/* Current parse context */
 			     (pTrigger->op == TK_UPDATE ? "UPDATE" : ""),
 			     (pTrigger->op == TK_INSERT ? "INSERT" : ""),
 			     (pTrigger->op == TK_DELETE ? "DELETE" : ""),
-			     pTab->zName));
+			     pTab->def->name));
 #ifndef SQLITE_OMIT_TRACE
 		sqlite3VdbeChangeP4(v, -1,
 				    sqlite3MPrintf(db, "-- TRIGGER %s",
diff --git a/src/box/sql/update.c b/src/box/sql/update.c
index 464feee..ad00537 100644
--- a/src/box/sql/update.c
+++ b/src/box/sql/update.c
@@ -75,7 +75,8 @@ sqlite3ColumnDefault(Vdbe * v, Table * pTab, int i, int iReg)
 	if (!pTab->pSelect) {
 		sqlite3_value *pValue = 0;
 		Column *pCol = &pTab->aCol[i];
-		VdbeComment((v, "%s.%s", pTab->zName, pTab->def->fields[i].name));
+		VdbeComment((v, "%s.%s", pTab->def->name,
+			pTab->def->fields[i].name));
 		assert(i < (int)pTab->def->field_count);
 
 		Expr *expr = NULL;
diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 013460f..dc779b4 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -4799,7 +4799,7 @@ case OP_RenameTable: {
 		sqlite3HashInsert(&db->pSchema->fkeyHash, zNewTableName, pFKey);
 	}
 
-	sqlite3UnlinkAndDeleteTable(db, pTab->zName);
+	sqlite3UnlinkAndDeleteTable(db, pTab->def->name);
 
 	initData.db = db;
 	initData.pzErrMsg = &p->zErrMsg;
diff --git a/src/box/sql/where.c b/src/box/sql/where.c
index fc0f84c..88f4c28 100644
--- a/src/box/sql/where.c
+++ b/src/box/sql/where.c
@@ -1639,7 +1639,8 @@ whereLoopPrint(WhereLoop * p, WhereClause * pWC)
 	sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
 			   p->iTab, nb, p->maskSelf, nb, p->prereq & mAll);
 	sqlite3DebugPrintf(" %12s",
-			   pItem->zAlias ? pItem->zAlias : pTab->zName);
+			   pItem->zAlias ? pItem->zAlias : 
+			   pTab->def->name);
 #endif
 	const char *zName;
 	if (p->pIndex && (zName = p->pIndex->zName) != 0) {
@@ -4749,7 +4750,7 @@ sqlite3WhereEnd(WhereInfo * pWInfo)
 		}
 		VdbeModuleComment((v, "End WHERE-loop%d: %s", i,
 				   pWInfo->pTabList->a[pLevel->iFrom].pTab->
-				   zName));
+				   def->name));
 	}
 
 	/* The "break" point is here, just past the end of the outer loop.
diff --git a/src/box/sql/wherecode.c b/src/box/sql/wherecode.c
index 233fde0..3da7cdb 100644
--- a/src/box/sql/wherecode.c
+++ b/src/box/sql/wherecode.c
@@ -1158,7 +1158,8 @@ sqlite3WhereCodeOneLoopStart(WhereInfo * pWInfo,	/* Complete information about t
 				  pTabItem->addrFillSub);
 		pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk);
 		VdbeCoverage(v);
-		VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName));
+		VdbeComment((v, "next row of \"%s\"", 
+			    pTabItem->pTab->def->name));
 		pLevel->op = OP_Goto;
 	} else if (pLoop->wsFlags & WHERE_INDEXED) {
 		/* Case 4: A scan using an index.
diff --git a/src/box/sql/whereexpr.c b/src/box/sql/whereexpr.c
index 1b0d961..e602111 100644
--- a/src/box/sql/whereexpr.c
+++ b/src/box/sql/whereexpr.c
@@ -1508,7 +1508,7 @@ sqlite3WhereTabFuncArgs(Parse * pParse,	/* Parsing context */
 		if (k >= (int)pTab->def->field_count) {
 			sqlite3ErrorMsg(pParse,
 					"too many arguments on %s() - max %d",
-					pTab->zName, j);
+					pTab->def->name, j);
 			return;
 		}
 		pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
-- 
2.7.4






More information about the Tarantool-patches mailing list