diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/build.c | 45 | ||||
-rw-r--r-- | src/main.c | 101 | ||||
-rw-r--r-- | src/select.c | 4 | ||||
-rw-r--r-- | src/sqliteInt.h | 3 | ||||
-rw-r--r-- | src/vdbe.c | 9 | ||||
-rw-r--r-- | src/where.c | 3 |
6 files changed, 104 insertions, 61 deletions
diff --git a/src/build.c b/src/build.c index 2d452d8ce..14d8793fa 100644 --- a/src/build.c +++ b/src/build.c @@ -33,7 +33,7 @@ ** COPY ** VACUUM ** -** $Id: build.c,v 1.30 2001/09/13 14:46:10 drh Exp $ +** $Id: build.c,v 1.31 2001/09/13 16:18:54 drh Exp $ */ #include "sqliteInt.h" @@ -461,6 +461,14 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){ db->flags |= SQLITE_InternChanges; } + /* If the initFlag 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. + */ + if( pParse->initFlag ){ + p->tnum = pParse->newTnum; + } + /* If not initializing, then create the table on disk. */ if( !pParse->initFlag ){ @@ -472,7 +480,7 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){ { OP_CreateTable, 0, 0, 0}, { OP_String, 0, 0, 0}, /* 5 */ { OP_String, 0, 0, 0}, /* 6 */ - { OP_MakeRecord, 4, 0, 0}, + { OP_MakeRecord, 5, 0, 0}, { OP_Put, 0, 0, 0}, }; int n, base; @@ -538,15 +546,16 @@ void sqliteDropTable(Parse *pParse, Token *pName){ if( v ){ static VdbeOp dropTable[] = { { OP_Open, 0, 2, 0}, - { OP_String, 0, 0, 0}, /* 1 */ - { OP_Next, 0, ADDR(9), 0}, /* 2 */ + { OP_Rewind, 0, 0, 0}, + { OP_String, 0, 0, 0}, /* 2 */ + { OP_Next, 0, ADDR(10), 0}, /* 3 */ { OP_Dup, 0, 0, 0}, { OP_Column, 0, 3, 0}, - { OP_Ne, 0, ADDR(2), 0}, + { OP_Ne, 0, ADDR(3), 0}, { OP_Recno, 0, 0, 0}, { OP_Delete, 0, 0, 0}, - { OP_Goto, 0, ADDR(2), 0}, - { OP_Destroy, 0, 0, 0}, /* 9 */ + { OP_Goto, 0, ADDR(3), 0}, + { OP_Destroy, 0, 0, 0}, /* 10 */ { OP_Close, 0, 0, 0}, }; Index *pIdx; @@ -554,7 +563,7 @@ void sqliteDropTable(Parse *pParse, Token *pName){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); } base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable); - sqliteVdbeChangeP1(v, base+9, pTable->tnum); + sqliteVdbeChangeP1(v, base+10, pTable->tnum); for(pIdx=pTable->pIndex; pIdx; pIdx=pIdx->pNext){ sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, 0, 0, 0); } @@ -694,6 +703,14 @@ void sqliteCreateIndex( db->flags |= SQLITE_InternChanges; } + /* If the initFlag 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. + */ + if( pParse->initFlag ){ + pIndex->tnum = pParse->newTnum; + } + /* If the initFlag 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. @@ -740,6 +757,7 @@ void sqliteCreateIndex( } lbl1 = sqliteVdbeMakeLabel(v); lbl2 = sqliteVdbeMakeLabel(v); + sqliteVdbeAddOp(v, OP_Rewind, 0, 0, 0, 0); sqliteVdbeAddOp(v, OP_Next, 0, lbl2, 0, lbl1); sqliteVdbeAddOp(v, OP_Recno, 0, 0, 0, 0); for(i=0; i<pIndex->nColumn; i++){ @@ -795,14 +813,15 @@ void sqliteDropIndex(Parse *pParse, Token *pName){ if( v ){ static VdbeOp dropIndex[] = { { OP_Open, 0, 2, 0}, - { OP_String, 0, 0, 0}, /* 1 */ - { OP_Next, 0, ADDR(8), 0}, /* 2 */ + { OP_Rewind, 0, 0, 0}, + { OP_String, 0, 0, 0}, /* 2 */ + { OP_Next, 0, ADDR(9), 0}, /* 3 */ { OP_Dup, 0, 0, 0}, { OP_Column, 0, 1, 0}, - { OP_Ne, 0, ADDR(2), 0}, + { OP_Ne, 0, ADDR(3), 0}, { OP_Recno, 0, 0, 0}, { OP_Delete, 0, 0, 0}, - { OP_Destroy, 0, 0, 0}, /* 8 */ + { OP_Destroy, 0, 0, 0}, /* 9 */ { OP_Close, 0, 0, 0}, }; int base; @@ -811,7 +830,7 @@ void sqliteDropIndex(Parse *pParse, Token *pName){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); } base = sqliteVdbeAddOpList(v, ArraySize(dropIndex), dropIndex); - sqliteVdbeChangeP1(v, base+8, pIndex->tnum); + sqliteVdbeChangeP1(v, base+9, pIndex->tnum); if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0); } diff --git a/src/main.c b/src/main.c index 2301915f4..8704149c9 100644 --- a/src/main.c +++ b/src/main.c @@ -26,7 +26,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.32 2001/09/13 15:21:32 drh Exp $ +** $Id: main.c,v 1.33 2001/09/13 16:18:54 drh Exp $ */ #include "sqliteInt.h" #if defined(HAVE_USLEEP) && HAVE_USLEEP @@ -35,32 +35,40 @@ /* ** This is the callback routine for the code that initializes the -** database. Each callback contains text of a CREATE TABLE or -** CREATE INDEX statement that must be parsed to yield the internal -** structures that describe the tables. +** database. Each callback contains the following information: +** +** argv[0] = "meta" or "table" or "index" +** argv[1] = table or index name +** argv[2] = root page number for table or index +** argv[3] = SQL create statement for the table or index ** -** This callback is also called with argc==2 when there is meta -** information in the sqlite_master file. The meta information is -** contained in argv[1]. Typical meta information is the file format -** version. */ static int sqliteOpenCb(void *pDb, int argc, char **argv, char **azColName){ sqlite *db = (sqlite*)pDb; Parse sParse; - int nErr; + int nErr = 0; - if( argc==2 ){ - if( sscanf(argv[1],"file format %d",&db->file_format)==1 ){ - return 0; + assert( argc==4 ); + switch( argv[0][0] ){ + case 'm': { /* Meta information */ + sscanf(argv[1],"file format %d",&db->file_format); + break; + } + case 'i': + case 't': { /* CREATE TABLE and CREATE INDEX statements */ + memset(&sParse, 0, sizeof(sParse)); + sParse.db = db; + sParse.initFlag = 1; + sParse.newTnum = atoi(argv[2]); + nErr = sqliteRunParser(&sParse, argv[3], 0); + break; + } + default: { + /* This can not happen! */ + nErr = 1; + assert( nErr==0 ); } - /* Unknown meta information. Ignore it. */ - return 0; } - if( argc!=1 ) return 0; - memset(&sParse, 0, sizeof(sParse)); - sParse.db = db; - sParse.initFlag = 1; - nErr = sqliteRunParser(&sParse, argv[0], 0); return nErr; } @@ -129,31 +137,40 @@ static int sqliteInit(sqlite *db, char **pzErrMsg){ */ static VdbeOp initProg[] = { { OP_Open, 0, 2, 0}, - { OP_Next, 0, 9, 0}, /* 1 */ + { OP_Rewind, 0, 0, 0}, + { OP_Next, 0, 12, 0}, /* 2 */ { OP_Column, 0, 0, 0}, { OP_String, 0, 0, "meta"}, - { OP_Ne, 0, 1, 0}, + { OP_Ne, 0, 2, 0}, { OP_Column, 0, 0, 0}, + { OP_Column, 0, 1, 0}, + { OP_Column, 0, 2, 0}, { OP_Column, 0, 4, 0}, - { OP_Callback, 2, 0, 0}, - { OP_Goto, 0, 1, 0}, - { OP_Rewind, 0, 0, 0}, /* 9 */ - { OP_Next, 0, 17, 0}, /* 10 */ + { OP_Callback, 4, 0, 0}, + { OP_Goto, 0, 2, 0}, + { OP_Rewind, 0, 0, 0}, /* 12 */ + { OP_Next, 0, 23, 0}, /* 13 */ { OP_Column, 0, 0, 0}, { OP_String, 0, 0, "table"}, - { OP_Ne, 0, 10, 0}, + { OP_Ne, 0, 13, 0}, + { OP_Column, 0, 0, 0}, + { OP_Column, 0, 1, 0}, + { OP_Column, 0, 2, 0}, { OP_Column, 0, 4, 0}, - { OP_Callback, 1, 0, 0}, - { OP_Goto, 0, 10, 0}, - { OP_Rewind, 0, 0, 0}, /* 17 */ - { OP_Next, 0, 25, 0}, /* 18 */ + { OP_Callback, 4, 0, 0}, + { OP_Goto, 0, 13, 0}, + { OP_Rewind, 0, 0, 0}, /* 23 */ + { OP_Next, 0, 34, 0}, /* 24 */ { OP_Column, 0, 0, 0}, { OP_String, 0, 0, "index"}, - { OP_Ne, 0, 18, 0}, + { OP_Ne, 0, 24, 0}, + { OP_Column, 0, 0, 0}, + { OP_Column, 0, 1, 0}, + { OP_Column, 0, 2, 0}, { OP_Column, 0, 4, 0}, - { OP_Callback, 1, 0, 0}, - { OP_Goto, 0, 18, 0}, - { OP_Close, 2, 0, 0}, /* 25 */ + { OP_Callback, 4, 0, 0}, + { OP_Goto, 0, 24, 0}, + { OP_Close, 0, 0, 0}, /* 34 */ { OP_Halt, 0, 0, 0}, }; @@ -169,20 +186,22 @@ static int sqliteInit(sqlite *db, char **pzErrMsg){ rc = sqliteVdbeExec(vdbe, sqliteOpenCb, db, pzErrMsg, db->pBusyArg, db->xBusyCallback); sqliteVdbeDelete(vdbe); - if( rc==SQLITE_OK && db->file_format<2 && db->nTable>0 ){ - sqliteSetString(pzErrMsg, "obsolete file format", 0); + if( rc==SQLITE_OK && db->file_format>1 && db->nTable>0 ){ + sqliteSetString(pzErrMsg, "unsupported file format", 0); rc = SQLITE_ERROR; } if( rc==SQLITE_OK ){ Table *pTab; - char *azArg[2]; - azArg[0] = master_schema; - azArg[1] = 0; - sqliteOpenCb(db, 1, azArg, 0); + char *azArg[5]; + azArg[0] = "table"; + azArg[1] = MASTER_NAME; + azArg[2] = "2"; + azArg[3] = master_schema; + azArg[4] = 0; + sqliteOpenCb(db, 4, azArg, 0); pTab = sqliteFindTable(db, MASTER_NAME); if( pTab ){ pTab->readOnly = 1; - pTab->tnum = 2; } db->flags |= SQLITE_Initialized; sqliteCommitInternalChanges(db); diff --git a/src/select.c b/src/select.c index ea29e1251..e0e38a1e3 100644 --- a/src/select.c +++ b/src/select.c @@ -24,7 +24,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements. ** -** $Id: select.c,v 1.33 2001/09/13 14:46:10 drh Exp $ +** $Id: select.c,v 1.34 2001/09/13 16:18:54 drh Exp $ */ #include "sqliteInt.h" @@ -549,6 +549,7 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){ if( p->pOrderBy ){ sqliteVdbeAddOp(v, OP_SortOpen, 0, 0, 0, 0); } + sqliteVdbeAddOp(v, OP_Rewind, unionTab, 0, 0, 0); iBreak = sqliteVdbeMakeLabel(v); iCont = sqliteVdbeAddOp(v, OP_Next, unionTab, iBreak, 0, 0); rc = selectInnerLoop(pParse, 0, unionTab, p->pEList->nExpr, @@ -601,6 +602,7 @@ static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){ if( p->pOrderBy ){ sqliteVdbeAddOp(v, OP_SortOpen, 0, 0, 0, 0); } + sqliteVdbeAddOp(v, OP_Rewind, tab1, 0, 0, 0); iBreak = sqliteVdbeMakeLabel(v); iCont = sqliteVdbeAddOp(v, OP_Next, tab1, iBreak, 0, 0); sqliteVdbeAddOp(v, OP_FullKey, tab1, 0, 0, 0); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index bc4a1125b..71d1e0294 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -23,7 +23,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.44 2001/09/13 14:46:10 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.45 2001/09/13 16:18:54 drh Exp $ */ #include "sqlite.h" #include "vdbe.h" @@ -359,6 +359,7 @@ struct Parse { int colNamesSet; /* TRUE after OP_ColumnCount has been issued to pVdbe */ int explain; /* True if the EXPLAIN flag is found on the query */ int initFlag; /* True if reparsing CREATE TABLEs */ + int newTnum; /* Table number to use when reparsing CREATE TABLEs */ int nErr; /* Number of errors seen */ int nTab; /* Number of previously allocated cursors */ int nMem; /* Number of memory cells used so far */ diff --git a/src/vdbe.c b/src/vdbe.c index ba47f1b36..1133c1886 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -41,7 +41,7 @@ ** But other routines are also provided to help in building up ** a program instruction by instruction. ** -** $Id: vdbe.c,v 1.62 2001/09/13 15:21:32 drh Exp $ +** $Id: vdbe.c,v 1.63 2001/09/13 16:18:54 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -1798,11 +1798,11 @@ case OP_MakeRecord: { j = 0; addr = sizeof(int)*nField; for(i=p->tos-nField+1; i<=p->tos; i++){ + memcpy(&zNewRecord[j], (char*)&addr, sizeof(int)); + j += sizeof(int); if( (aStack[i].flags & STK_Null)==0 ){ addr += aStack[i].n; } - memcpy(&zNewRecord[j], (char*)&addr, sizeof(int)); - j += sizeof(int); } for(i=p->tos-nField+1; i<=p->tos; i++){ if( (aStack[i].flags & STK_Null)==0 ){ @@ -2300,7 +2300,7 @@ case OP_KeyAsData: { case OP_Column: { int amt, offset, nCol, payloadSize; int aHdr[10]; - const int mxHdr = sizeof(aHdr)/sizeof(aHdr[0]); + static const int mxHdr = sizeof(aHdr)/sizeof(aHdr[0]); int i = pOp->p1; int p2 = pOp->p2; int tos = ++p->tos; @@ -2338,6 +2338,7 @@ case OP_Column: { if( p2+1<mxHdr ){ (*xRead)(pCrsr, 0, sizeof(aHdr[0])*(p2+2), (char*)aHdr); nCol = aHdr[0]; + nCol /= sizeof(int); offset = aHdr[p2]; if( p2 == nCol-1 ){ amt = payloadSize - offset; diff --git a/src/where.c b/src/where.c index 33cb3897d..91ffa143e 100644 --- a/src/where.c +++ b/src/where.c @@ -25,7 +25,7 @@ ** the WHERE clause of SQL statements. Also found here are subroutines ** to generate VDBE code to evaluate expressions. ** -** $Id: where.c,v 1.17 2001/09/13 14:46:11 drh Exp $ +** $Id: where.c,v 1.18 2001/09/13 16:18:55 drh Exp $ */ #include "sqliteInt.h" @@ -358,6 +358,7 @@ WhereInfo *sqliteWhereBegin( /* Case 2: There was no usable index. We must do a complete ** scan of the table. */ + sqliteVdbeAddOp(v, OP_Rewind, base+idx, 0, 0, 0); cont = sqliteVdbeMakeLabel(v); sqliteVdbeAddOp(v, OP_Next, base+idx, brk, 0, cont); haveKey = 0; |