diff options
Diffstat (limited to 'ext/sqlite/libsqlite/src/build.c')
-rw-r--r-- | ext/sqlite/libsqlite/src/build.c | 323 |
1 files changed, 128 insertions, 195 deletions
diff --git a/ext/sqlite/libsqlite/src/build.c b/ext/sqlite/libsqlite/src/build.c index 9d41db21ff..4b5ed56139 100644 --- a/ext/sqlite/libsqlite/src/build.c +++ b/ext/sqlite/libsqlite/src/build.c @@ -38,7 +38,7 @@ void sqliteBeginParse(Parse *pParse, int explainFlag){ sqlite *db = pParse->db; int i; pParse->explain = explainFlag; - if((db->flags & SQLITE_Initialized)==0 && pParse->initFlag==0 ){ + if((db->flags & SQLITE_Initialized)==0 && db->init.busy==0 ){ int rc = sqliteInit(db, &pParse->zErrMsg); if( rc!=SQLITE_OK ){ pParse->rc = rc; @@ -55,17 +55,6 @@ void sqliteBeginParse(Parse *pParse, int explainFlag){ } /* -** This is a fake callback procedure used when sqlite_exec() is -** invoked with a NULL callback pointer. If we pass a NULL callback -** pointer into sqliteVdbeExec() it will return at every OP_Callback, -** which we do not want it to do. So we substitute a pointer to this -** procedure in place of the NULL. -*/ -static int fakeCallback(void *NotUsed, int n, char **az1, char **az2){ - return 0; -} - -/* ** This routine is called after a single SQL statement has been ** parsed and we want to execute the VDBE code to implement ** that statement. Prior action routines should have already @@ -76,36 +65,20 @@ static int fakeCallback(void *NotUsed, int n, char **az1, char **az2){ ** no VDBE code was generated. */ void sqliteExec(Parse *pParse){ - int rc = SQLITE_OK; sqlite *db = pParse->db; Vdbe *v = pParse->pVdbe; - int (*xCallback)(void*,int,char**,char**); + if( v==0 && (v = sqliteGetVdbe(pParse))!=0 ){ + sqliteVdbeAddOp(v, OP_Halt, 0, 0); + } if( sqlite_malloc_failed ) return; - xCallback = pParse->xCallback; - if( xCallback==0 && pParse->useCallback ) xCallback = fakeCallback; if( v && pParse->nErr==0 ){ FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0; sqliteVdbeTrace(v, trace); - sqliteVdbeMakeReady(v, pParse->nVar, xCallback, pParse->pArg, - pParse->explain); - if( pParse->useCallback ){ - if( pParse->explain ){ - rc = sqliteVdbeList(v); - db->next_cookie = db->aDb[0].schema_cookie; - }else{ - sqliteVdbeExec(v); - } - rc = sqliteVdbeFinalize(v, &pParse->zErrMsg); - if( rc ) pParse->nErr++; - pParse->pVdbe = 0; - pParse->rc = rc; - if( rc ) pParse->nErr++; - }else{ - pParse->rc = pParse->nErr ? SQLITE_ERROR : SQLITE_DONE; - } + sqliteVdbeMakeReady(v, pParse->nVar, pParse->explain); + pParse->rc = pParse->nErr ? SQLITE_ERROR : SQLITE_DONE; pParse->colNamesSet = 0; - }else if( pParse->useCallback==0 ){ + }else if( pParse->rc==SQLITE_OK ){ pParse->rc = SQLITE_ERROR; } pParse->nTab = 0; @@ -240,7 +213,7 @@ void sqliteUnlinkAndDeleteIndex(sqlite *db, Index *pIndex){ ** ** If iDb<=0 then reset the internal schema tables for all database ** files. If iDb>=2 then reset the internal schema for only the -** single file indicates. +** single file indicated. */ void sqliteResetInternalSchema(sqlite *db, int iDb){ HashElem *pElem; @@ -280,10 +253,18 @@ void sqliteResetInternalSchema(sqlite *db, int iDb){ ** schema hash tables and therefore do not have to make any changes ** to any of those tables. */ + for(i=0; i<db->nDb; i++){ + struct Db *pDb = &db->aDb[i]; + if( pDb->pBt==0 ){ + if( pDb->pAux && pDb->xFreeAux ) pDb->xFreeAux(pDb->pAux); + pDb->pAux = 0; + } + } for(i=j=2; i<db->nDb; i++){ - if( db->aDb[i].pBt==0 ){ - sqliteFree(db->aDb[i].zName); - db->aDb[i].zName = 0; + struct Db *pDb = &db->aDb[i]; + if( pDb->pBt==0 ){ + sqliteFree(pDb->zName); + pDb->zName = 0; continue; } if( j<i ){ @@ -456,7 +437,7 @@ void sqliteStartTable( pParse->sFirstToken = *pStart; zName = sqliteTableNameFromToken(pName); if( zName==0 ) return; - if( pParse->iDb==1 ) isTemp = 1; + if( db->init.iDb==1 ) isTemp = 1; #ifndef SQLITE_OMIT_AUTHORIZATION assert( (isTemp & 1)==isTemp ); { @@ -493,17 +474,16 @@ void sqliteStartTable( if( isTemp && db->aDb[1].pBt==0 && !pParse->explain ){ int rc = sqliteBtreeFactory(db, 0, 0, MAX_PAGES, &db->aDb[1].pBt); if( rc!=SQLITE_OK ){ - sqliteSetString(&pParse->zErrMsg, "unable to open a temporary database " - "file for storing temporary tables", (char*)0); + sqliteErrorMsg(pParse, "unable to open a temporary database " + "file for storing temporary tables"); pParse->nErr++; return; } if( db->flags & SQLITE_InTrans ){ rc = sqliteBtreeBeginTrans(db->aDb[1].pBt); if( rc!=SQLITE_OK ){ - sqliteSetNString(&pParse->zErrMsg, "unable to get a write lock on " - "the temporary database file", 0); - pParse->nErr++; + sqliteErrorMsg(pParse, "unable to get a write lock on " + "the temporary database file"); return; } } @@ -517,20 +497,16 @@ void sqliteStartTable( ** an existing temporary table, that is not an error. */ pTable = sqliteFindTable(db, zName, 0); - iDb = isTemp ? 1 : pParse->iDb; - if( pTable!=0 && (pTable->iDb==iDb || !pParse->initFlag) ){ - sqliteSetNString(&pParse->zErrMsg, "table ", 0, pName->z, pName->n, - " already exists", 0, 0); + iDb = isTemp ? 1 : db->init.iDb; + if( pTable!=0 && (pTable->iDb==iDb || !db->init.busy) ){ + sqliteErrorMsg(pParse, "table %T already exists", pName); sqliteFree(zName); - pParse->nErr++; return; } if( (pIdx = sqliteFindIndex(db, zName, 0))!=0 && - (pIdx->iDb==0 || !pParse->initFlag) ){ - sqliteSetString(&pParse->zErrMsg, "there is already an index named ", - zName, (char*)0); + (pIdx->iDb==0 || !db->init.busy) ){ + sqliteErrorMsg(pParse, "there is already an index named %s", zName); sqliteFree(zName); - pParse->nErr++; return; } pTable = sqliteMalloc( sizeof(Table) ); @@ -555,7 +531,7 @@ void sqliteStartTable( ** indices. Hence, the record number for the table must be allocated ** now. */ - if( !pParse->initFlag && (v = sqliteGetVdbe(pParse))!=0 ){ + if( !db->init.busy && (v = sqliteGetVdbe(pParse))!=0 ){ sqliteBeginWriteOperation(pParse, 0, isTemp); if( !isTemp ){ sqliteVdbeAddOp(v, OP_Integer, db->file_format, 0); @@ -588,8 +564,7 @@ void sqliteAddColumn(Parse *pParse, Token *pName){ sqliteDequote(z); for(i=0; i<p->nCol; i++){ if( sqliteStrICmp(z, p->aCol[i].zName)==0 ){ - sqliteSetString(&pParse->zErrMsg, "duplicate column name: ", z, (char*)0); - pParse->nErr++; + sqliteErrorMsg(pParse, "duplicate column name: %s", z); sqliteFree(z); return; } @@ -708,9 +683,8 @@ void sqliteAddPrimaryKey(Parse *pParse, IdList *pList, int onError){ int iCol = -1, i; if( pTab==0 ) goto primary_key_exit; if( pTab->hasPrimKey ){ - sqliteSetString(&pParse->zErrMsg, "table \"", pTab->zName, - "\" has more than one primary key", (char*)0); - pParse->nErr++; + sqliteErrorMsg(pParse, + "table \"%s\" has more than one primary key", pTab->zName); goto primary_key_exit; } pTab->hasPrimKey = 1; @@ -753,34 +727,16 @@ primary_key_exit: */ int sqliteCollateType(const char *zType, int nType){ int i; - for(i=0; i<nType-1; i++){ - switch( zType[i] ){ - case 'b': - case 'B': { - if( i<nType-3 && sqliteStrNICmp(&zType[i],"blob",4)==0 ){ - return SQLITE_SO_TEXT; - } - break; - } - case 'c': - case 'C': { - if( i<nType-3 && (sqliteStrNICmp(&zType[i],"char",4)==0 || - sqliteStrNICmp(&zType[i],"clob",4)==0) - ){ - return SQLITE_SO_TEXT; - } - break; - } - case 'x': - case 'X': { - if( i>=2 && sqliteStrNICmp(&zType[i-2],"text",4)==0 ){ - return SQLITE_SO_TEXT; - } - break; - } - default: { - break; - } + for(i=0; i<nType-3; i++){ + int c = *(zType++) | 0x60; + if( (c=='b' || c=='c') && sqliteStrNICmp(zType, "lob", 3)==0 ){ + return SQLITE_SO_TEXT; + } + if( c=='c' && sqliteStrNICmp(zType, "har", 3)==0 ){ + return SQLITE_SO_TEXT; + } + if( c=='t' && sqliteStrNICmp(zType, "ext", 3)==0 ){ + return SQLITE_SO_TEXT; } } return SQLITE_SO_NUM; @@ -819,7 +775,9 @@ void sqliteAddCollateType(Parse *pParse, int collType){ */ void sqliteChangeCookie(sqlite *db, Vdbe *v){ if( db->next_cookie==db->aDb[0].schema_cookie ){ - db->next_cookie = db->aDb[0].schema_cookie + sqliteRandomByte() + 1; + unsigned char r; + sqliteRandomness(1, &r); + db->next_cookie = db->aDb[0].schema_cookie + r + 1; db->flags |= SQLITE_InternChanges; sqliteVdbeAddOp(v, OP_Integer, db->next_cookie, 0); sqliteVdbeAddOp(v, OP_SetCookie, 0, 0); @@ -910,8 +868,8 @@ static char *createTableStmt(Table *p){ ** 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 this is a temporary table or initFlag==1. When initFlag==1, +** An entry for the table is made in the master table on disk, unless +** this is a temporary table or db->init.busy==1. When db->init.busy==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 @@ -944,14 +902,14 @@ void sqliteEndTable(Parse *pParse, Token *pEnd, Select *pSelect){ sqliteDeleteTable(0, pSelTab); } - /* If the initFlag is 1 it means we are reading the SQL off the + /* If the db->init.busy is 1 it means we are reading the SQL off the ** "sqlite_master" or "sqlite_temp_master" table on the disk. ** So do not write to the disk again. Extract the root page number - ** for the table from the pParse->newTnum field. (The page number + ** for the table from the db->init.newTnum field. (The page number ** should have been put there by the sqliteOpenCb routine.) */ - if( pParse->initFlag ){ - p->tnum = pParse->newTnum; + if( db->init.busy ){ + p->tnum = db->init.newTnum; } /* If not initializing, then create a record for the new table @@ -961,7 +919,7 @@ void sqliteEndTable(Parse *pParse, Token *pEnd, Select *pSelect){ ** If this is a TEMPORARY table, write the entry into the auxiliary ** file instead of into the main database file. */ - if( !pParse->initFlag ){ + if( !db->init.busy ){ int n; Vdbe *v; @@ -969,24 +927,16 @@ void sqliteEndTable(Parse *pParse, Token *pEnd, Select *pSelect){ if( v==0 ) return; if( p->pSelect==0 ){ /* A regular table */ - sqliteVdbeAddOp(v, OP_CreateTable, 0, p->iDb); - sqliteVdbeChangeP3(v, -1, (char *)&p->tnum, P3_POINTER); + sqliteVdbeOp3(v, OP_CreateTable, 0, p->iDb, (char*)&p->tnum, P3_POINTER); }else{ /* A view */ sqliteVdbeAddOp(v, OP_Integer, 0, 0); } p->tnum = 0; sqliteVdbeAddOp(v, OP_Pull, 1, 0); - sqliteVdbeAddOp(v, OP_String, 0, 0); - if( p->pSelect==0 ){ - sqliteVdbeChangeP3(v, -1, "table", P3_STATIC); - }else{ - sqliteVdbeChangeP3(v, -1, "view", P3_STATIC); - } - sqliteVdbeAddOp(v, OP_String, 0, 0); - sqliteVdbeChangeP3(v, -1, p->zName, P3_STATIC); - sqliteVdbeAddOp(v, OP_String, 0, 0); - sqliteVdbeChangeP3(v, -1, p->zName, P3_STATIC); + sqliteVdbeOp3(v, OP_String, 0, 0, p->pSelect==0?"table":"view", P3_STATIC); + sqliteVdbeOp3(v, OP_String, 0, 0, p->zName, 0); + sqliteVdbeOp3(v, OP_String, 0, 0, p->zName, 0); sqliteVdbeAddOp(v, OP_Dup, 4, 0); sqliteVdbeAddOp(v, OP_String, 0, 0); if( pSelect ){ @@ -1072,7 +1022,7 @@ void sqliteCreateView( */ p->pSelect = sqliteSelectDup(pSelect); sqliteSelectDelete(pSelect); - if( !pParse->initFlag ){ + if( !pParse->db->init.busy ){ sqliteViewGetColumnNames(pParse, p); } @@ -1084,7 +1034,7 @@ void sqliteCreateView( sEnd.z += sEnd.n; } sEnd.n = 0; - n = (char *) sEnd.z - (char *) pBegin->z; + n = sEnd.z - pBegin->z; z = pBegin->z; while( n>0 && (z[n-1]==';' || isspace(z[n-1])) ){ n--; } sEnd.z = &z[n-1]; @@ -1098,7 +1048,7 @@ void sqliteCreateView( /* ** The Table structure pTable is really a VIEW. Fill in the names of ** the columns of the view in the pTable structure. Return the number -** of errors. If an error is seen leave an error message in pPare->zErrMsg. +** of errors. If an error is seen leave an error message in pParse->zErrMsg. */ int sqliteViewGetColumnNames(Parse *pParse, Table *pTable){ ExprList *pEList; @@ -1124,9 +1074,7 @@ int sqliteViewGetColumnNames(Parse *pParse, Table *pTable){ ** should always fail. But we will leave it in place just to be safe. */ if( pTable->nCol<0 ){ - sqliteSetString(&pParse->zErrMsg, "view ", pTable->zName, - " is circularly defined", (char*)0); - pParse->nErr++; + sqliteErrorMsg(pParse, "view %s is circularly defined", pTable->zName); return 1; } @@ -1176,12 +1124,12 @@ int sqliteViewGetColumnNames(Parse *pParse, Table *pTable){ */ static void sqliteViewResetColumnNames(Table *pTable){ int i; - if( pTable==0 || pTable->pSelect==0 ) return; - if( pTable->nCol==0 ) return; - for(i=0; i<pTable->nCol; i++){ - sqliteFree(pTable->aCol[i].zName); - sqliteFree(pTable->aCol[i].zDflt); - sqliteFree(pTable->aCol[i].zType); + Column *pCol; + assert( pTable!=0 && pTable->pSelect!=0 ); + for(i=0, pCol=pTable->aCol; i<pTable->nCol; i++, pCol++){ + sqliteFree(pCol->zName); + sqliteFree(pCol->zDflt); + sqliteFree(pCol->zType); } sqliteFree(pTable->aCol); pTable->aCol = 0; @@ -1215,9 +1163,7 @@ Table *sqliteTableFromToken(Parse *pParse, Token *pTok){ pTab = sqliteFindTable(pParse->db, zName, 0); sqliteFree(zName); if( pTab==0 ){ - sqliteSetNString(&pParse->zErrMsg, "no such table: ", 0, - pTok->z, pTok->n, 0); - pParse->nErr++; + sqliteErrorMsg(pParse, "no such table: %T", pTok); } return pTab; } @@ -1268,21 +1214,16 @@ void sqliteDropTable(Parse *pParse, Token *pName, int isView){ } #endif if( pTable->readOnly ){ - sqliteSetString(&pParse->zErrMsg, "table ", pTable->zName, - " may not be dropped", (char*)0); + sqliteErrorMsg(pParse, "table %s may not be dropped", pTable->zName); pParse->nErr++; return; } if( isView && pTable->pSelect==0 ){ - sqliteSetString(&pParse->zErrMsg, "use DROP TABLE to delete table ", - pTable->zName, (char*)0); - pParse->nErr++; + sqliteErrorMsg(pParse, "use DROP TABLE to delete table %s", pTable->zName); return; } if( !isView && pTable->pSelect ){ - sqliteSetString(&pParse->zErrMsg, "use DROP VIEW to delete view ", - pTable->zName, (char*)0); - pParse->nErr++; + sqliteErrorMsg(pParse, "use DROP VIEW to delete view %s", pTable->zName); return; } @@ -1291,7 +1232,7 @@ void sqliteDropTable(Parse *pParse, Token *pName, int isView){ */ v = sqliteGetVdbe(pParse); if( v ){ - static VdbeOp dropTable[] = { + static VdbeOpList dropTable[] = { { OP_Rewind, 0, ADDR(8), 0}, { OP_String, 0, 0, 0}, /* 1 */ { OP_MemStore, 1, 1, 0}, @@ -1425,19 +1366,16 @@ void sqliteCreateForeignKey( int iCol = p->nCol-1; if( iCol<0 ) goto fk_end; if( pToCol && pToCol->nId!=1 ){ - sqliteSetNString(&pParse->zErrMsg, "foreign key on ", -1, - p->aCol[iCol].zName, -1, - " should reference only one column of table ", -1, - pTo->z, pTo->n, 0); - pParse->nErr++; + sqliteErrorMsg(pParse, "foreign key on %s" + " should reference only one column of table %T", + p->aCol[iCol].zName, pTo); goto fk_end; } nCol = 1; }else if( pToCol && pToCol->nId!=pFromCol->nId ){ - sqliteSetString(&pParse->zErrMsg, + sqliteErrorMsg(pParse, "number of columns in foreign key does not match the number of " - "columns in the referenced table", (char*)0); - pParse->nErr++; + "columns in the referenced table"); goto fk_end; }else{ nCol = pFromCol->nId; @@ -1473,9 +1411,9 @@ void sqliteCreateForeignKey( } } if( j>=p->nCol ){ - sqliteSetString(&pParse->zErrMsg, "unknown column \"", - pFromCol->a[i].zName, "\" in foreign key definition", (char*)0); - pParse->nErr++; + sqliteErrorMsg(pParse, + "unknown column \"%s\" in foreign key definition", + pFromCol->a[i].zName); goto fk_end; } } @@ -1550,8 +1488,8 @@ void sqliteCreateIndex( sqlite *db = pParse->db; if( pParse->nErr || sqlite_malloc_failed ) goto exit_create_index; - if( pParse->initFlag - && sqliteFixInit(&sFix, pParse, pParse->iDb, "index", pName) + if( db->init.busy + && sqliteFixInit(&sFix, pParse, db->init.iDb, "index", pName) && sqliteFixSrcList(&sFix, pTable) ){ goto exit_create_index; @@ -1570,20 +1508,15 @@ void sqliteCreateIndex( } if( pTab==0 || pParse->nErr ) goto exit_create_index; if( pTab->readOnly ){ - sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, - " may not be indexed", (char*)0); - pParse->nErr++; + sqliteErrorMsg(pParse, "table %s may not be indexed", pTab->zName); goto exit_create_index; } - if( pTab->iDb>=2 && pParse->initFlag==0 ){ - sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, - " may not have indices added", (char*)0); - pParse->nErr++; + if( pTab->iDb>=2 && db->init.busy==0 ){ + sqliteErrorMsg(pParse, "table %s may not have indices added", pTab->zName); goto exit_create_index; } if( pTab->pSelect ){ - sqliteSetString(&pParse->zErrMsg, "views may not be indexed", (char*)0); - pParse->nErr++; + sqliteErrorMsg(pParse, "views may not be indexed"); goto exit_create_index; } isTemp = pTab->iDb==1; @@ -1601,21 +1534,17 @@ void sqliteCreateIndex( ** dealing with a primary key or UNIQUE constraint. We have to invent our ** own name. */ - if( pName && !pParse->initFlag ){ + if( pName && !db->init.busy ){ Index *pISameName; /* Another index with the same name */ Table *pTSameName; /* A table with same name as the index */ zName = sqliteStrNDup(pName->z, pName->n); if( zName==0 ) goto exit_create_index; if( (pISameName = sqliteFindIndex(db, zName, 0))!=0 ){ - sqliteSetString(&pParse->zErrMsg, "index ", zName, - " already exists", (char*)0); - pParse->nErr++; + sqliteErrorMsg(pParse, "index %s already exists", zName); goto exit_create_index; } if( (pTSameName = sqliteFindTable(db, zName, 0))!=0 ){ - sqliteSetString(&pParse->zErrMsg, "there is already a table named ", - zName, (char*)0); - pParse->nErr++; + sqliteErrorMsg(pParse, "there is already a table named %s", zName); goto exit_create_index; } }else if( pName==0 ){ @@ -1637,7 +1566,7 @@ void sqliteCreateIndex( { const char *zDb = db->aDb[pTab->iDb].zName; - assert( pTab->iDb==pParse->iDb || isTemp ); + assert( pTab->iDb==db->init.iDb || isTemp ); if( sqliteAuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){ goto exit_create_index; } @@ -1673,7 +1602,7 @@ void sqliteCreateIndex( pIndex->nColumn = pList->nId; pIndex->onError = onError; pIndex->autoIndex = pName==0; - pIndex->iDb = isTemp ? 1 : pParse->iDb; + pIndex->iDb = isTemp ? 1 : db->init.iDb; /* Scan the names of the columns of the table to be indexed and ** load the column indices into the Index structure. Report an error @@ -1684,9 +1613,8 @@ void sqliteCreateIndex( if( sqliteStrICmp(pList->a[i].zName, pTab->aCol[j].zName)==0 ) break; } if( j>=pTab->nCol ){ - sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, - " has no column named ", pList->a[i].zName, (char*)0); - pParse->nErr++; + sqliteErrorMsg(pParse, "table %s has no column named %s", + pTab->zName, pList->a[i].zName); sqliteFree(pIndex); goto exit_create_index; } @@ -1726,20 +1654,20 @@ void sqliteCreateIndex( pOther->pNext = pIndex; } - /* If the initFlag is 1 it means we are reading the SQL off the + /* If the db->init.busy is 1 it means we are reading the SQL off the ** "sqlite_master" table on the disk. So do not write to the disk - ** again. Extract the table number from the pParse->newTnum field. + ** again. Extract the table number from the db->init.newTnum field. */ - if( pParse->initFlag && pTable!=0 ){ - pIndex->tnum = pParse->newTnum; + if( db->init.busy && pTable!=0 ){ + pIndex->tnum = db->init.newTnum; } - /* If the initFlag is 0 then create the index on disk. This + /* If the db->init.busy is 0 then create the index on disk. This ** involves writing the index into the master table and filling in the ** index with the current table contents. ** - ** The initFlag is 0 when the user first enters a CREATE INDEX - ** command. The initFlag is 1 when a database is opened and + ** The db->init.busy is 0 when the user first enters a CREATE INDEX + ** command. db->init.busy is 1 when a database is opened and ** CREATE INDEX statements are read out of the master table. In ** the latter case the index already exists on disk, which is why ** we don't want to recreate it. @@ -1749,7 +1677,7 @@ void sqliteCreateIndex( ** has just been created, it contains no data and the index initialization ** step can be skipped. */ - else if( pParse->initFlag==0 ){ + else if( db->init.busy==0 ){ int n; Vdbe *v; int lbl1, lbl2; @@ -1763,19 +1691,17 @@ void sqliteCreateIndex( sqliteOpenMasterTable(v, isTemp); } sqliteVdbeAddOp(v, OP_NewRecno, 0, 0); - sqliteVdbeAddOp(v, OP_String, 0, 0); - sqliteVdbeChangeP3(v, -1, "index", P3_STATIC); - sqliteVdbeAddOp(v, OP_String, 0, 0); - sqliteVdbeChangeP3(v, -1, pIndex->zName, P3_STATIC); - sqliteVdbeAddOp(v, OP_String, 0, 0); - sqliteVdbeChangeP3(v, -1, pTab->zName, P3_STATIC); - addr = sqliteVdbeAddOp(v, OP_CreateIndex, 0, isTemp); - sqliteVdbeChangeP3(v, addr, (char*)&pIndex->tnum, P3_POINTER); + sqliteVdbeOp3(v, OP_String, 0, 0, "index", P3_STATIC); + sqliteVdbeOp3(v, OP_String, 0, 0, pIndex->zName, 0); + sqliteVdbeOp3(v, OP_String, 0, 0, pTab->zName, 0); + sqliteVdbeOp3(v, OP_CreateIndex, 0, isTemp,(char*)&pIndex->tnum,P3_POINTER); pIndex->tnum = 0; if( pTable ){ - sqliteVdbeAddOp(v, OP_Dup, 0, 0); - sqliteVdbeAddOp(v, OP_Integer, isTemp, 0); - sqliteVdbeAddOp(v, OP_OpenWrite, 1, 0); + sqliteVdbeCode(v, + OP_Dup, 0, 0, + OP_Integer, isTemp, 0, + OP_OpenWrite, 1, 0, + 0); } addr = sqliteVdbeAddOp(v, OP_String, 0, 0); if( pStart && pEnd ){ @@ -1786,8 +1712,7 @@ void sqliteCreateIndex( sqliteVdbeAddOp(v, OP_PutIntKey, 0, 0); if( pTable ){ sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0); - sqliteVdbeAddOp(v, OP_OpenRead, 2, pTab->tnum); - sqliteVdbeChangeP3(v, -1, pTab->zName, P3_STATIC); + sqliteVdbeOp3(v, OP_OpenRead, 2, pTab->tnum, pTab->zName, 0); lbl2 = sqliteVdbeMakeLabel(v); sqliteVdbeAddOp(v, OP_Rewind, 2, lbl2); lbl1 = sqliteVdbeAddOp(v, OP_Recno, 2, 0); @@ -1801,8 +1726,8 @@ void sqliteCreateIndex( } sqliteVdbeAddOp(v, OP_MakeIdxKey, pIndex->nColumn, 0); if( db->file_format>=4 ) sqliteAddIdxKeyType(v, pIndex); - sqliteVdbeAddOp(v, OP_IdxPut, 1, pIndex->onError!=OE_None); - sqliteVdbeChangeP3(v, -1, "indexed columns are not unique", P3_STATIC); + sqliteVdbeOp3(v, OP_IdxPut, 1, pIndex->onError!=OE_None, + "indexed columns are not unique", P3_STATIC); sqliteVdbeAddOp(v, OP_Next, 2, lbl1); sqliteVdbeResolveLabel(v, lbl2); sqliteVdbeAddOp(v, OP_Close, 2, 0); @@ -1870,7 +1795,7 @@ void sqliteDropIndex(Parse *pParse, SrcList *pName){ /* Generate code to remove the index and from the master table */ v = sqliteGetVdbe(pParse); if( v ){ - static VdbeOp dropIndex[] = { + static VdbeOpList dropIndex[] = { { OP_Rewind, 0, ADDR(9), 0}, { OP_String, 0, 0, 0}, /* 1 */ { OP_MemStore, 1, 1, 0}, @@ -2102,8 +2027,10 @@ void sqliteBeginTransaction(Parse *pParse, int onError){ return; } sqliteBeginWriteOperation(pParse, 0, 0); - db->flags |= SQLITE_InTrans; - db->onError = onError; + if( !pParse->explain ){ + db->flags |= SQLITE_InTrans; + db->onError = onError; + } } /* @@ -2119,9 +2046,13 @@ void sqliteCommitTransaction(Parse *pParse){ sqliteErrorMsg(pParse, "cannot commit - no transaction is active"); return; } - db->flags &= ~SQLITE_InTrans; + if( !pParse->explain ){ + db->flags &= ~SQLITE_InTrans; + } sqliteEndWriteOperation(pParse); - db->onError = OE_Default; + if( !pParse->explain ){ + db->onError = OE_Default; + } } /* @@ -2142,8 +2073,10 @@ void sqliteRollbackTransaction(Parse *pParse){ if( v ){ sqliteVdbeAddOp(v, OP_Rollback, 0, 0); } - db->flags &= ~SQLITE_InTrans; - db->onError = OE_Default; + if( !pParse->explain ){ + db->flags &= ~SQLITE_InTrans; + db->onError = OE_Default; + } } /* |