diff options
Diffstat (limited to 'src/build.c')
-rw-r--r-- | src/build.c | 295 |
1 files changed, 205 insertions, 90 deletions
diff --git a/src/build.c b/src/build.c index e8d213b43..ef59bb03c 100644 --- a/src/build.c +++ b/src/build.c @@ -25,7 +25,7 @@ ** ROLLBACK ** PRAGMA ** -** $Id: build.c,v 1.44 2001/10/06 16:33:03 drh Exp $ +** $Id: build.c,v 1.45 2001/10/08 13:22:32 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -65,7 +65,9 @@ void sqliteExec(Parse *pParse){ } /* -** Construct a new expression node and return a pointer to it. +** Construct a new expression node and return a pointer to it. Memory +** for this node is obtained from sqliteMalloc(). The calling function +** is responsible for making sure the node eventually gets freed. */ Expr *sqliteExpr(int op, Expr *pLeft, Expr *pRight, Token *pToken){ Expr *pNew; @@ -131,8 +133,8 @@ void sqliteExprDelete(Expr *p){ } /* -** Locate the in-memory structure that describes the -** format of a particular database table given the name +** Locate the in-memory structure that describes +** a particular database table given the name ** of that table. Return NULL if not found. */ Table *sqliteFindTable(sqlite *db, char *zName){ @@ -141,9 +143,9 @@ Table *sqliteFindTable(sqlite *db, char *zName){ } /* -** Locate the in-memory structure that describes the -** format of a particular index given the name -** of that index. Return NULL if not found. +** Locate the in-memory structure that describes +** a particular index given the name of that index. +** Return NULL if not found. */ Index *sqliteFindIndex(sqlite *db, char *zName){ Index *p = sqliteHashFind(&db->idxHash, zName, strlen(zName)+1); @@ -155,7 +157,7 @@ Index *sqliteFindIndex(sqlite *db, char *zName){ ** its memory structures. ** ** The index is removed from the database hash table if db!=NULL. -** But it is not unlinked from the Table that is being indexed. +** But the index is not unlinked from the Table that it indexes. ** Unlinking from the Table must be done by the calling function. */ static void sqliteDeleteIndex(sqlite *db, Index *pIndex){ @@ -167,7 +169,7 @@ static void sqliteDeleteIndex(sqlite *db, Index *pIndex){ /* ** Unlink the given index from its table, then remove -** the index from the index hash table, and free its memory +** the index from the index hash table and free its memory ** structures. */ static void sqliteUnlinkAndDeleteIndex(sqlite *db, Index *pIndex){ @@ -276,7 +278,7 @@ void sqliteCommitInternalChanges(sqlite *db){ /* ** This routine runs when one or more CREATE TABLE, CREATE INDEX, -** DROP TABLE, or DROP INDEX statements get rolled back. The +** DROP TABLE, or DROP INDEX statements gets rolled back. The ** additions or deletions of Table and Index structures in the ** internal hash tables are undone. ** @@ -334,14 +336,19 @@ char *sqliteTableNameFromToken(Token *pName){ ** the first of several action routines that get called in response ** to a CREATE TABLE statement. In particular, this routine is called ** after seeing tokens "CREATE" and "TABLE" and the table name. The -** pStart token is the CREATE and pName is the table name. +** pStart token is the CREATE and pName is the table name. The isTemp +** flag is true if the "TEMP" or "TEMPORARY" keyword occurs in between +** CREATE and TABLE. ** -** The new table is constructed in fields of the pParse structure. As -** more of the CREATE TABLE statement is parsed, additional action -** routines are called to build up more of the table. +** The new table record is initialized and put in pParse->pNewTable. +** As more of the CREATE TABLE statement is parsed, additional action +** routines will be called to add more information to this record. +** At the end of the CREATE TABLE statement, the sqliteEndTable() routine +** is called to complete the construction of the new table record. */ -void sqliteStartTable(Parse *pParse, Token *pStart, Token *pName){ +void sqliteStartTable(Parse *pParse, Token *pStart, Token *pName, int isTemp){ Table *pTable; + Index *pIdx; char *zName; sqlite *db = pParse->db; Vdbe *v; @@ -349,15 +356,54 @@ void sqliteStartTable(Parse *pParse, Token *pStart, Token *pName){ pParse->sFirstToken = *pStart; zName = sqliteTableNameFromToken(pName); if( zName==0 ) return; + + /* Before trying to create a temporary table, make sure the Btree for + ** holding temporary tables is open. + */ + if( isTemp && db->pBeTemp==0 ){ + int rc = sqliteBtreeOpen(0, 0, MAX_PAGES, &db->pBeTemp); + if( rc!=SQLITE_OK ){ + sqliteSetNString(&pParse->zErrMsg, "unable to open a temporary database " + "file for storing temporary tables", 0); + pParse->nErr++; + return; + } + if( db->flags & SQLITE_InTrans ){ + rc = sqliteBtreeBeginTrans(db->pBeTemp); + if( rc!=SQLITE_OK ){ + sqliteSetNString(&pParse->zErrMsg, "unable to get a write lock on " + "the temporary datbase file", 0); + pParse->nErr++; + return; + } + } + } + + /* Make sure the new table name does not collide with an existing + ** index or table name. Issue an error message if it does. + ** + ** If we are re-reading the sqlite_master table because of a schema + ** change and a new permanent table is found whose name collides with + ** an existing temporary table, then ignore the new permanent table. + ** We will continue parsing, but the pParse->nameClash flag will be set + ** so we will know to discard the table record once parsing has finished. + */ pTable = sqliteFindTable(db, zName); if( pTable!=0 ){ - sqliteSetNString(&pParse->zErrMsg, "table ", 0, pName->z, pName->n, - " already exists", 0, 0); - sqliteFree(zName); - pParse->nErr++; - return; + if( pTable->isTemp && pParse->initFlag ){ + pParse->nameClash = 1; + }else{ + sqliteSetNString(&pParse->zErrMsg, "table ", 0, pName->z, pName->n, + " already exists", 0, 0); + sqliteFree(zName); + pParse->nErr++; + return; + } + }else{ + pParse->nameClash = 0; } - if( sqliteFindIndex(db, zName) ){ + if( (pIdx = sqliteFindIndex(db, zName))!=0 && + (!pIdx->pTable->isTemp || !pParse->initFlag) ){ sqliteSetString(&pParse->zErrMsg, "there is already an index named ", zName, 0); sqliteFree(zName); @@ -370,6 +416,7 @@ void sqliteStartTable(Parse *pParse, Token *pStart, Token *pName){ pTable->nCol = 0; pTable->aCol = 0; pTable->pIndex = 0; + pTable->isTemp = isTemp; if( pParse->pNewTable ) sqliteDeleteTable(db, pParse->pNewTable); pParse->pNewTable = pTable; if( !pParse->initFlag && (v = sqliteGetVdbe(pParse))!=0 ){ @@ -378,7 +425,9 @@ void sqliteStartTable(Parse *pParse, Token *pStart, Token *pName){ sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0); pParse->schemaVerified = 1; } - sqliteVdbeAddOp(v, OP_OpenWrite, 0, 2, MASTER_NAME, 0); + if( !isTemp ){ + sqliteVdbeAddOp(v, OP_OpenWrite, 0, 2, MASTER_NAME, 0); + } } } @@ -418,7 +467,7 @@ void sqliteAddNotNull(Parse *pParse){ int i; if( (p = pParse->pNewTable)==0 ) return; i = p->nCol-1; - p->aCol[i].notNull = 1; + if( i>=0 ) p->aCol[i].notNull = 1; } /* @@ -437,10 +486,12 @@ void sqliteAddColumnType(Parse *pParse, Token *pFirst, Token *pLast){ char *z, **pz; if( (p = pParse->pNewTable)==0 ) return; i = p->nCol-1; + if( i<0 ) return; pz = &p->aCol[i].zType; n = pLast->n + ((int)pLast->z) - (int)pFirst->z; sqliteSetNString(pz, pFirst->z, n, 0); z = *pz; + if( z==0 ) return; for(i=j=0; z[i]; i++){ int c = z[i]; if( isspace(c) ) continue; @@ -463,6 +514,7 @@ void sqliteAddDefaultValue(Parse *pParse, Token *pVal, int minusFlag){ char **pz; if( (p = pParse->pNewTable)==0 ) return; i = p->nCol-1; + if( i<0 ) return; pz = &p->aCol[i].zDflt; if( minusFlag ){ sqliteSetNString(pz, "-", 1, pVal->z, pVal->n, 0); @@ -500,13 +552,16 @@ static void changeCookie(sqlite *db){ ** This routine is called to report the final ")" that terminates ** a CREATE TABLE statement. ** -** The table structure is added to the internal hash tables. +** The table structure that other action routines have been building +** is added to the internal hash tables, assuming no errors have +** occurred. ** ** An entry for the table is made in the master table on disk, -** unless initFlag==1. When initFlag==1, it means we are reading -** the master table because we just connected to the database, so -** the entry for this table already exists in the master table. -** We do not want to create it again. +** unless this is a temporary table or initFlag==1. When initFlag==1, +** it means we are reading the sqlite_master table because we just +** connected to the database or because the sqlite_master table has +** recently changes, so the entry for this table already exists in +** the sqlite_master table. We do not want to create it again. */ void sqliteEndTable(Parse *pParse, Token *pEnd){ Table *p; @@ -516,9 +571,10 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){ p = pParse->pNewTable; if( p==0 ) return; - /* Add the table to the in-memory representation of the database + /* Add the table to the in-memory representation of the database. */ - if( pParse->explain==0 ){ + assert( pParse->nameClash==0 || pParse->initFlag==0 ); + if( pParse->explain==0 && pParse->nameClash==0 ){ sqliteHashInsert(&db->tblHash, p->zName, strlen(p->zName)+1, p); pParse->pNewTable = 0; db->nTable++; @@ -537,6 +593,9 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){ /* If not initializing, then create a record for the new table ** in the SQLITE_MASTER table of the database. + ** + ** If this is a TEMPORARY table, then just create the table. Do not + ** make an entry in SQLITE_MASTER. */ if( !pParse->initFlag ){ int n, addr; @@ -545,20 +604,24 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){ v = sqliteGetVdbe(pParse); if( v==0 ) return; n = (int)pEnd->z - (int)pParse->sFirstToken.z + 1; - sqliteVdbeAddOp(v, OP_NewRecno, 0, 0, 0, 0); - sqliteVdbeAddOp(v, OP_String, 0, 0, "table", 0); - sqliteVdbeAddOp(v, OP_String, 0, 0, p->zName, 0); - sqliteVdbeAddOp(v, OP_String, 0, 0, p->zName, 0); + if( !p->isTemp ){ + sqliteVdbeAddOp(v, OP_NewRecno, 0, 0, 0, 0); + sqliteVdbeAddOp(v, OP_String, 0, 0, "table", 0); + sqliteVdbeAddOp(v, OP_String, 0, 0, p->zName, 0); + sqliteVdbeAddOp(v, OP_String, 0, 0, p->zName, 0); + } addr = sqliteVdbeAddOp(v, OP_CreateTable, 0, 0, 0, 0); sqliteVdbeChangeP3(v, addr, (char *)&p->tnum, -1); p->tnum = 0; - addr = sqliteVdbeAddOp(v, OP_String, 0, 0, 0, 0); - sqliteVdbeChangeP3(v, addr, pParse->sFirstToken.z, n); - sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0, 0, 0); - sqliteVdbeAddOp(v, OP_Put, 0, 0, 0, 0); - changeCookie(db); - sqliteVdbeAddOp(v, OP_SetCookie, db->next_cookie, 0, 0, 0); - sqliteVdbeAddOp(v, OP_Close, 0, 0, 0, 0); + if( !p->isTemp ){ + addr = sqliteVdbeAddOp(v, OP_String, 0, 0, 0, 0); + sqliteVdbeChangeP3(v, addr, pParse->sFirstToken.z, n); + sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0, 0, 0); + sqliteVdbeAddOp(v, OP_Put, 0, 0, 0, 0); + changeCookie(db); + sqliteVdbeAddOp(v, OP_SetCookie, db->next_cookie, 0, 0, 0); + sqliteVdbeAddOp(v, OP_Close, 0, 0, 0, 0); + } if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0); } @@ -619,8 +682,7 @@ void sqliteDropTable(Parse *pParse, Token *pName){ { OP_Ne, 0, ADDR(3), 0}, { OP_Delete, 0, 0, 0}, { OP_Goto, 0, ADDR(3), 0}, - { OP_Destroy, 0, 0, 0}, /* 9 */ - { OP_SetCookie, 0, 0, 0}, /* 10 */ + { OP_SetCookie, 0, 0, 0}, /* 9 */ { OP_Close, 0, 0, 0}, }; Index *pIdx; @@ -629,13 +691,15 @@ void sqliteDropTable(Parse *pParse, Token *pName){ sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0); pParse->schemaVerified = 1; } - base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable); - sqliteVdbeChangeP3(v, base+2, pTable->zName, 0); - sqliteVdbeChangeP1(v, base+9, pTable->tnum); - changeCookie(db); - sqliteVdbeChangeP1(v, base+10, db->next_cookie); + if( !pTable->isTemp ){ + base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable); + sqliteVdbeChangeP3(v, base+2, pTable->zName, 0); + changeCookie(db); + sqliteVdbeChangeP1(v, base+9, db->next_cookie); + } + sqliteVdbeAddOp(v, OP_Destroy, pTable->tnum, pTable->isTemp, 0, 0); for(pIdx=pTable->pIndex; pIdx; pIdx=pIdx->pNext){ - sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, 0, 0, 0); + sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, pTable->isTemp, 0, 0); } if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0); @@ -679,8 +743,9 @@ void sqliteCreateIndex( Index *pIndex; /* The index to be created */ char *zName = 0; int i, j; - Token nullId; /* Fake token for an empty ID list */ + Token nullId; /* Fake token for an empty ID list */ sqlite *db = pParse->db; + int hideName = 0; /* Do not put table name in the hash table */ if( pParse->nErr || sqlite_malloc_failed ) goto exit_create_index; @@ -702,26 +767,56 @@ void sqliteCreateIndex( goto exit_create_index; } + /* If this index is created while re-reading the schema from sqlite_master + ** but the table associated with this index is a temporary table, it can + ** only mean that the table this index is really associated with is one + ** whose name is hidden behind a temporary table with the same name. + ** Since its table has been suppressed, we need to also suppress the + ** index. + */ + if( pParse->initFlag && pTab->isTemp ){ + goto exit_create_index; + } + /* ** Find the name of the index. Make sure there is not already another - ** index or table with the same name. If pName==0 it means that we are + ** index or table with the same name. + ** + ** Exception: If we are reading the names of permanent indices from the + ** sqlite_master table (because some other process changed the schema) and + ** one of the index names collides with the name of a temporary table or + ** index, then we will continue to process this index, but we will not + ** store its name in the hash table. Set the hideName flag to accomplish + ** this. + ** + ** If pName==0 it means that we are ** dealing with a primary key or UNIQUE constraint. We have to invent our ** own name. */ if( pName ){ + Index *pISameName; /* Another index with the same name */ + Table *pTSameName; /* A table with same name as the index */ zName = sqliteTableNameFromToken(pName); if( zName==0 ) goto exit_create_index; - if( sqliteFindIndex(db, zName) ){ - sqliteSetString(&pParse->zErrMsg, "index ", zName, - " already exists", 0); - pParse->nErr++; - goto exit_create_index; + if( (pISameName = sqliteFindIndex(db, zName))!=0 ){ + if( pISameName->pTable->isTemp && pParse->initFlag ){ + hideName = 1; + }else{ + sqliteSetString(&pParse->zErrMsg, "index ", zName, + " already exists", 0); + pParse->nErr++; + goto exit_create_index; + } } - if( sqliteFindTable(db, zName) ){ - sqliteSetString(&pParse->zErrMsg, "there is already a table named ", - zName, 0); - pParse->nErr++; - goto exit_create_index; + if( (pTSameName = sqliteFindTable(db, zName))!=0 ){ + if( pTSameName->isTemp && pParse->initFlag ){ + hideName = 1; + }else{ + sqliteSetString(&pParse->zErrMsg, "there is already a table named ", + zName, 0); + pParse->nErr++; + goto exit_create_index; + } } }else{ char zBuf[30]; @@ -781,7 +876,7 @@ void sqliteCreateIndex( */ pIndex->pNext = pTab->pIndex; pTab->pIndex = pIndex; - if( !pParse->explain ){ + if( !pParse->explain && !hideName ){ sqliteHashInsert(&db->idxHash, pIndex->zName, strlen(zName)+1, pIndex); db->flags |= SQLITE_InternChanges; } @@ -815,6 +910,7 @@ void sqliteCreateIndex( int lbl1, lbl2; int i; int addr; + int isTemp = pTab->isTemp; v = sqliteGetVdbe(pParse); if( v==0 ) goto exit_create_index; @@ -824,28 +920,39 @@ void sqliteCreateIndex( sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0); pParse->schemaVerified = 1; } - sqliteVdbeAddOp(v, OP_OpenWrite, 0, 2, MASTER_NAME, 0); + if( !isTemp ){ + sqliteVdbeAddOp(v, OP_OpenWrite, 0, 2, MASTER_NAME, 0); + } } - sqliteVdbeAddOp(v, OP_NewRecno, 0, 0, 0, 0); - sqliteVdbeAddOp(v, OP_String, 0, 0, "index", 0); - sqliteVdbeAddOp(v, OP_String, 0, 0, pIndex->zName, 0); - sqliteVdbeAddOp(v, OP_String, 0, 0, pTab->zName, 0); - addr = sqliteVdbeAddOp(v, OP_CreateIndex, 0, 0, 0, 0); + if( !isTemp ){ + sqliteVdbeAddOp(v, OP_NewRecno, 0, 0, 0, 0); + sqliteVdbeAddOp(v, OP_String, 0, 0, "index", 0); + sqliteVdbeAddOp(v, OP_String, 0, 0, pIndex->zName, 0); + sqliteVdbeAddOp(v, OP_String, 0, 0, pTab->zName, 0); + } + addr = sqliteVdbeAddOp(v, OP_CreateIndex, 0, isTemp, 0, 0); sqliteVdbeChangeP3(v, addr, (char*)&pIndex->tnum, -1); pIndex->tnum = 0; if( pTable ){ - sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0); - sqliteVdbeAddOp(v, OP_OpenWrite, 1, 0, 0, 0); + if( isTemp ){ + sqliteVdbeAddOp(v, OP_OpenWrAux, 1, 0, 0, 0); + }else{ + sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0); + sqliteVdbeAddOp(v, OP_OpenWrite, 1, 0, 0, 0); + } } - addr = sqliteVdbeAddOp(v, OP_String, 0, 0, 0, 0); - if( pStart && pEnd ){ - n = (int)pEnd->z - (int)pStart->z + 1; - sqliteVdbeChangeP3(v, addr, pStart->z, n); + if( !isTemp ){ + addr = sqliteVdbeAddOp(v, OP_String, 0, 0, 0, 0); + if( pStart && pEnd ){ + n = (int)pEnd->z - (int)pStart->z + 1; + sqliteVdbeChangeP3(v, addr, pStart->z, n); + } + sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0, 0, 0); + sqliteVdbeAddOp(v, OP_Put, 0, 0, 0, 0); } - sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0, 0, 0); - sqliteVdbeAddOp(v, OP_Put, 0, 0, 0, 0); if( pTable ){ - sqliteVdbeAddOp(v, OP_Open, 2, pTab->tnum, pTab->zName, 0); + sqliteVdbeAddOp(v, isTemp ? OP_OpenAux : OP_Open, + 2, pTab->tnum, pTab->zName, 0); lbl1 = sqliteVdbeMakeLabel(v); lbl2 = sqliteVdbeMakeLabel(v); sqliteVdbeAddOp(v, OP_Rewind, 2, 0, 0, 0); @@ -859,12 +966,14 @@ void sqliteCreateIndex( sqliteVdbeAddOp(v, OP_Goto, 0, lbl1, 0, 0); sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, lbl2); sqliteVdbeAddOp(v, OP_Close, 2, 0, 0, 0); + sqliteVdbeAddOp(v, OP_Close, 1, 0, 0, 0); } - sqliteVdbeAddOp(v, OP_Close, 1, 0, 0, 0); if( pTable!=0 ){ - changeCookie(db); - sqliteVdbeAddOp(v, OP_SetCookie, db->next_cookie, 0, 0, 0); - sqliteVdbeAddOp(v, OP_Close, 0, 0, 0, 0); + if( !isTemp ){ + changeCookie(db); + sqliteVdbeAddOp(v, OP_SetCookie, db->next_cookie, 0, 0, 0); + sqliteVdbeAddOp(v, OP_Close, 0, 0, 0, 0); + } if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0); } @@ -916,17 +1025,20 @@ void sqliteDropIndex(Parse *pParse, Token *pName){ { OP_Close, 0, 0, 0}, }; int base; + Table *pTab = pIndex->pTable; if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0); pParse->schemaVerified = 1; } - base = sqliteVdbeAddOpList(v, ArraySize(dropIndex), dropIndex); - sqliteVdbeChangeP3(v, base+2, pIndex->zName, 0); - sqliteVdbeChangeP1(v, base+8, pIndex->tnum); - changeCookie(db); - sqliteVdbeChangeP1(v, base+9, db->next_cookie); + if( !pTab->isTemp ){ + base = sqliteVdbeAddOpList(v, ArraySize(dropIndex), dropIndex); + sqliteVdbeChangeP3(v, base+2, pIndex->zName, 0); + changeCookie(db); + sqliteVdbeChangeP1(v, base+9, db->next_cookie); + } + sqliteVdbeAddOp(v, OP_Destroy, pIndex->tnum, pTab->isTemp, 0, 0); if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0); } @@ -1091,6 +1203,7 @@ void sqliteCopy( } v = sqliteGetVdbe(pParse); if( v ){ + int openOp; if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0, 0, 0); @@ -1099,9 +1212,10 @@ void sqliteCopy( addr = sqliteVdbeAddOp(v, OP_FileOpen, 0, 0, 0, 0); sqliteVdbeChangeP3(v, addr, pFilename->z, pFilename->n); sqliteVdbeDequoteP3(v, addr); - sqliteVdbeAddOp(v, OP_OpenWrite, 0, pTab->tnum, pTab->zName, 0); + openOp = pTab->isTemp ? OP_OpenWrAux : OP_OpenWrite; + sqliteVdbeAddOp(v, openOp, 0, pTab->tnum, pTab->zName, 0); for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ - sqliteVdbeAddOp(v, OP_OpenWrite, i, pIdx->tnum, pIdx->zName, 0); + sqliteVdbeAddOp(v, openOp, i, pIdx->tnum, pIdx->zName, 0); } end = sqliteVdbeMakeLabel(v); addr = sqliteVdbeAddOp(v, OP_FileRead, pTab->nCol, end, 0, 0); @@ -1374,6 +1488,7 @@ void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){ }else #endif - if( zLeft ) sqliteFree(zLeft); - if( zRight ) sqliteFree(zRight); + {} + sqliteFree(zLeft); + sqliteFree(zRight); } |