From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id CC60521757 for ; Sat, 28 Apr 2018 14:27:09 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id w8bWiXzVLGbh for ; Sat, 28 Apr 2018 14:27:09 -0400 (EDT) Received: from smtpng3.m.smailru.net (smtpng3.m.smailru.net [94.100.177.149]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id 3BDDB1FCE1 for ; Sat, 28 Apr 2018 14:27:09 -0400 (EDT) From: Kirill Shcherbatov Subject: [tarantool-patches] [PATCH v4 5/7] sql: move names to server Date: Sat, 28 Apr 2018 21:26:56 +0300 Message-Id: In-Reply-To: References: In-Reply-To: References: Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-help: List-unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-subscribe: List-owner: List-post: List-archive: To: tarantool-patches@freelists.org Cc: v.shpilevoy@tarantool.org, Kirill Shcherbatov 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