diff --git a/manifest b/manifest index 11ac4ac099..17047eb6cd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C It\sruns.\sSimple\stables\scan\sbe\screated.\sINSERT\sand\sSELECT\swork.\sMuch\smore\ntesting\sis\sneeded,\showever.\s(CVS\s241) -D 2001-09-13T16:18:54 +C Many\sproblems\sfixed.\sMany\sproblems\syet\sto\sgo.\s(CVS\s242) +D 2001-09-13T21:53:09 F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4 F Makefile.in 7ecb2370b5cb34d390af1fcb3118ea6d84a253ca F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958 @@ -13,10 +13,10 @@ F notes/notes2.txt 7e3fafd5e25906c1fe1e95f13b089aa398ca403e F notes/notes2b.txt 1c17a5b7f6b44a75cd3eb98ed2c24db1eefb06c3 F notes/notes3.txt 71e47be517e3d2578b3b9343a45b772d43b7ba16 F src/TODO f0ea267ab55c4d15127c1ac1667edbf781147438 -F src/btree.c 9f22b51681bcc0026ea300134e4e2f1f40fc0800 +F src/btree.c 823d765a20ef208ba9e8fc841d2c521fa91baefd F src/btree.h 2427961c702dd0755ec70f529cf3db32707d689b -F src/build.c 5839600c9fced909e9d336203b758aeaa541b3b1 -F src/delete.c 769a28cf35ab75df4b2416982d8369520b28f3c5 +F src/build.c ebc3ecd58f2c2792d23dd20c06fbd58393628ad7 +F src/delete.c 62500a09606c0f714b651756475cd42979ef08e8 F src/ex/README b745b00acce2d892f60c40111dacdfc48e0c1c7a F src/ex/db.c f1419ae6c93e40b5ac6e39fe7efd95d868e6f9d7 F src/ex/db.h 3f2933ee20c147fe494835786e4c6f3a562def4e @@ -27,14 +27,14 @@ F src/ex/pg.h 23a4ac807b0546ec2bb6239ec8bd3e06926572cd F src/ex/sizes.tcl f54bad4a2ac567624be59131a6ee42d71b41a3d7 F src/expr.c 83b6a7ed4cf502249f192b698517e9a9b8f05303 F src/insert.c 1072c0dd7782c17af735df37f447630d4d577ba1 -F src/main.c 1feb8e6681fd7bf5d8da5cbec2f6d15767c26033 +F src/main.c b72d2b03a226fdbc241afd3cf66254d504ce74b5 F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c F src/pager.c 05a2177c99a835c3efec1e4187556e2e29311d4a F src/pager.h 238aa88bafe33911bf9b0b365f35afd0a261cd46 F src/parse.y 8fc096948994a7ffbf61ba13129cc589f794a9cb F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9 -F src/random.c b36c3f57dc80c8f354e6bfbf39cf1e1de021d54a -F src/select.c 0f7e6652b5a1869f8eb39778ffece5055a909b29 +F src/random.c 55775802549c7152086bd19c3342293d31608532 +F src/select.c 1e37bea8f9d8e8fdb31ef750bb038ca6a2337447 F src/shell.c 1fcdf8c4180098bcfdee12501e01b4c8eb21d726 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e F src/sqlite.h.in 8faa2fed0513d188ced16e5f9094e57694594e70 @@ -43,23 +43,22 @@ F src/table.c adcaf074f6c1075e86359174e68701fa2acfc4d6 F src/tclsqlite.c d328970848c028e13e61e173bef79adcc379568a F src/test1.c abb3cb427e735ae87e6533f5b3b7164b7da91bc4 F src/test2.c b3177e061fabd20d48e4b1b4bca610a0d2b28670 -F src/test3.c 147b42ec368a10e9f267e7466d30c46e76d7f278 +F src/test3.c 1fc103f198cbd0447d1a12c3ce48795755ec1a53 F src/tokenize.c 0118b57702cb6550769316e8443b06760b067acf F src/update.c ea8f2c0712cd4cd19314a26ef4766866013facda F src/util.c c77668fef860cfd2e4e682ef4f3ed8f9e68c551b -F src/vdbe.c d7d30c19330b6c2452859424d7fd6d452d6dee62 -F src/vdbe.h 6ee941ecd78b7b224607517fd060d6547910dc10 +F src/vdbe.c 826fcc85277ed256d2db725cabfbefbd186b734a +F src/vdbe.h 9f32bd12c47bd2b4bdd7e93092bb796f2a3b649f F src/where.c fef978a9a2234b01e30e36833ab63e14bbc626d3 -F test/all.test 21d55a97e39e7ec5776751dc9dd8b1b51ef4a048 +F test/all.test 841d176f11fe2fb4419e5b617faedfa617f815fa F test/btree.test 5e1eeb03cda22161eec827dc5224ce6c500eaaf9 F test/btree2.test a3c9ff1e4490357dd15c9a41f8aefd02f6e32fdc F test/copy.test b77a1214bd7756f2849d5c4fa6e715c0ff0c34eb -F test/dbbe.test a022fe2d983848f786e17ef1fc6809cfd37fb02c F test/delete.test 50b9b1f06c843d591741dba7869433a105360dbf F test/expr.test 80bf8f0e9aa6b9c35bf97ce5d603a28381168d8a F test/func.test ac3def2a673d1042750ae1a4ad1768bb7c7ae90b F test/in.test ea48016c4fcc479d315932ae2b8568146686ffaf -F test/index.test 266474cd101d7ed3703a0fc0428145cedacc92e0 +F test/index.test 73f34caeab4751e48dc337e504199b934e06b12d F test/insert.test dbd3bd189edb61fddbe66c236694ef23352429f1 F test/insert2.test 732405e30331635af8d159fccabe835eea5cd0c6 F test/lock.test bca7d53de73138b1f670a2fbdb1f481ff7eaa45a @@ -70,19 +69,19 @@ F test/printf.test 4c71871e1a75a2dacb673945fc13ddb30168798f F test/quote.test 40a3164af8456933a81312803fa8cdb21b205c12 F test/rowid.test b01e6dec09780c93f55db6cfe7ad097323954f23 F test/select1.test 223507655cdb4f9901d83fa7f5c5328e022c211f -F test/select2.test 4cee2d9d4d7d4657b086569064a0c454e1795afe +F test/select2.test 3817db11ee8d547328cfb6775f6399f50e3a4aa6 F test/select3.test a9234b8424b6c6d71de534f43b91ade9be68e9cc F test/select4.test cb5374d7c87680e294ac749307459a5cc547609d F test/select5.test e2b9d51d88cbd6c307c2c05b0ef55fe7ba811ac2 F test/sort.test 838cd862642ed9a2c47e1a17b5c33da452b4552e F test/subselect.test bf8b251a92fb091973c1c469ce499dc9648a41d5 -F test/table.test 3e0d74ec03f3df167544d63f39b9b6cd6d1d1273 +F test/table.test 4d3a978ea7fb0bd88e6eec27ebd69877a529b7dd F test/tableapi.test 4778414470ba150983d03b9858334effe720c2e0 F test/tclsqlite.test d2aa55926874783b2401f0146e839f773c6796e1 -F test/tester.tcl 39a707dac2b6048d9c9e07a98d3256d50069fe47 +F test/tester.tcl 3147bb13461280dfc0afb7a74d14efcd8c0969a0 F test/trans.test 51e50e8273da6845b31a2095e9d3b221fb60d8d0 F test/update.test 72c0c93310483b86dc904a992220c5b84c7ce100 -F test/vacuum.test b95d8119a0a83dc6c4ac63888f8872f06199e065 +F test/vacuum.test 62b01e7972dd513fb9587fbc383e5f6a5ef1a3fb F test/where.test 755957829c493b1b7ad1ecb27d6c782131a6b3d5 F tool/gdbmdump.c 529e67c78d920606ba196326ea55b57b75fcc82b F tool/gdbmstat.c 56a9033531e5f5a48413f6ec436d5fb0341632c1 @@ -108,7 +107,7 @@ F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f F www/tclsqlite.tcl 06f81c401f79a04f2c5ebfb97e7c176225c0aef2 F www/vdbe.tcl 0c8aaa529dd216ccbf7daaabd80985e413d5f9ad -P 991ce8115052da9395d4bf8ff29f417e3c36dc7f -R f709a5820bca7397e17a0af30d07e86d +P 9ac8399c99cb996a382f3d49f45b6ca857adc827 +R 2372c1f59dbe1995efdd6847c777d732 U drh -Z c3ae2020eeb73a32f1d2074b9db28833 +Z 2c92ace69c7d17b3485a5d299eba152d diff --git a/manifest.uuid b/manifest.uuid index 1c42c56827..cb8a7be6f8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9ac8399c99cb996a382f3d49f45b6ca857adc827 \ No newline at end of file +62c7bd11bcf6438cdcbf66fa67a2bf4ab9d1664d \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index a67af7d4aa..0508d99710 100644 --- a/src/btree.c +++ b/src/btree.c @@ -21,7 +21,7 @@ ** http://www.hwaci.com/drh/ ** ************************************************************************* -** $Id: btree.c,v 1.23 2001/09/13 14:46:10 drh Exp $ +** $Id: btree.c,v 1.24 2001/09/13 21:53:09 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -1685,6 +1685,7 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){ int nxDiv; /* Next divider slot in pParent->apCell[] */ int rc; /* The return code */ int iCur; /* apCell[iCur] is the cell of the cursor */ + MemPage *pOldCurPage; /* The cursor originally points to this page */ int totalSize; /* Total bytes for all cells */ int subtotal; /* Subtotal of bytes in cells on one page */ int cntNew[4]; /* Index in apCell[] of cell after i-th page */ @@ -1730,6 +1731,11 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){ rc = initPage(pPage, sqlitepager_pagenumber(pPage), 0); assert( rc==SQLITE_OK ); reparentChildPages(pBt->pPager, pPage); + if( pCur && pCur->pPage==pChild ){ + sqlitepager_unref(pChild); + pCur->pPage = pPage; + sqlitepager_ref(pPage); + } freePage(pBt, pChild, pgnoChild); sqlitepager_unref(pChild); }else{ @@ -1760,8 +1766,8 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){ pChild->pParent = pPage; sqlitepager_ref(pPage); pChild->isOverfull = 1; - if( pCur ){ - sqlitepager_unref(pCur->pPage); + if( pCur && pCur->pPage==pPage ){ + sqlitepager_unref(pPage); pCur->pPage = pChild; }else{ extraUnref = pChild; @@ -1796,7 +1802,7 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){ /* ** Initialize variables so that it will be safe to jump - ** directory to balance_cleanup at any moment. + ** directly to balance_cleanup at any moment. */ nOld = nNew = 0; sqlitepager_ref(pParent); @@ -1836,15 +1842,25 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){ /* ** Set iCur to be the index in apCell[] of the cell that the cursor ** is pointing to. We will need this later on in order to keep the - ** cursor pointing at the same cell. + ** cursor pointing at the same cell. If pCur points to a page that + ** has no involvement with this rebalancing, then set iCur to a large + ** number so that the iCur==j tests always fail in the main cell + ** distribution loop below. */ if( pCur ){ - iCur = pCur->idx; - for(i=0; inCell + 1; + iCur = 0; + for(i=0; ipPage==apOld[i] ){ + iCur += pCur->idx; + break; + } + iCur += apOld[i]->nCell; + if( ipPage==pParent && pCur->idx==idxDiv[i] ){ + break; + } + iCur++; } - sqlitepager_unref(pCur->pPage); - pCur->pPage = 0; + pOldCurPage = pCur->pPage; } /* @@ -1965,8 +1981,9 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){ pParent->apCell[nxDiv]->h.leftChild = pgnoNew[nNew-1]; } if( pCur ){ - assert( pCur->pPage!=0 ); + assert( pOldCurPage!=0 ); sqlitepager_ref(pCur->pPage); + sqlitepager_unref(pOldCurPage); } /* @@ -1980,7 +1997,7 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){ /* ** balance the parent page. */ - rc = balance(pBt, pParent, 0); + rc = balance(pBt, pParent, pCur); /* ** Cleanup before returning. @@ -2022,7 +2039,7 @@ int sqliteBtreeInsert( MemPage *pPage; Btree *pBt = pCur->pBt; - if( !pCur->pBt->inTrans ){ + if( !pCur->pBt->inTrans || nKey+nData==0 ){ return SQLITE_ERROR; /* Must start a transaction first */ } rc = sqliteBtreeMoveto(pCur, pKey, nKey, &loc); @@ -2107,8 +2124,10 @@ int sqliteBtreeDelete(BtCursor *pCur){ releaseTempCursor(&leafCur); }else{ dropCell(pPage, pCur->idx, cellSize(pCell)); - if( pCur->idx>=pPage->nCell && pCur->idx>0 ){ - pCur->idx--; + if( pCur->idx>=pPage->nCell ){ + pCur->idx = pPage->nCell-1; + if( pCur->idx<0 ){ pCur->idx = 0; } + pCur->bSkipNext = 0; }else{ pCur->bSkipNext = 1; } @@ -2252,7 +2271,7 @@ int sqliteBtreeUpdateMeta(Btree *pBt, int *aMeta){ ** All of the following code is omitted unless the library is compiled with ** the -DSQLITE_TEST=1 compiler option. ******************************************************************************/ -#ifdef SQLITE_TEST +#if 1 /* ** Print a disassembly of the given page on standard output. This routine diff --git a/src/build.c b/src/build.c index 14d8793fa0..436e0d2620 100644 --- a/src/build.c +++ b/src/build.c @@ -33,7 +33,7 @@ ** COPY ** VACUUM ** -** $Id: build.c,v 1.31 2001/09/13 16:18:54 drh Exp $ +** $Id: build.c,v 1.32 2001/09/13 21:53:10 drh Exp $ */ #include "sqliteInt.h" @@ -240,6 +240,26 @@ void sqliteDeleteTable(sqlite *db, Table *pTable){ sqliteFree(pTable); } +/* +** Unlink the given table from the hash tables and the delete the +** table structure and all its indices. +*/ +static void sqliteUnlinkAndDeleteTable(sqlite *db, Table *pTable){ + if( pTable->zName && db ){ + int h = sqliteHashNoCase(pTable->zName, 0) % N_HASH; + if( db->apTblHash[h]==pTable ){ + db->apTblHash[h] = pTable->pHash; + }else{ + Table *p; + for(p=db->apTblHash[h]; p && p->pHash!=pTable; p=p->pHash){} + if( p && p->pHash==pTable ){ + p->pHash = pTable->pHash; + } + } + } + sqliteDeleteTable(db, pTable); +} + /* ** Check all Tables and Indexes in the internal hash table and commit ** any additions or deletions to those hash tables. @@ -262,7 +282,7 @@ void sqliteCommitInternalChanges(sqlite *db){ for(pTable = db->apTblHash[i]; pTable; pTable=pNext){ pNext = pTable->pHash; if( pTable->isDelete ){ - sqliteDeleteTable(db, pTable); + sqliteUnlinkAndDeleteTable(db, pTable); }else if( pTable->isCommit==0 ){ pTable->isCommit = 1; } @@ -298,7 +318,7 @@ void sqliteRollbackInternalChanges(sqlite *db){ for(pTable = db->apTblHash[i]; pTable; pTable=pNext){ pNext = pTable->pHash; if( !pTable->isCommit ){ - sqliteDeleteTable(db, pTable); + sqliteUnlinkAndDeleteTable(db, pTable); }else if( pTable->isDelete ){ pTable->isDelete = 0; } @@ -473,7 +493,7 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){ */ if( !pParse->initFlag ){ static VdbeOp addTable[] = { - { OP_Open, 0, 2, 0}, + { OP_Open, 0, 2, MASTER_NAME}, { OP_NewRecno, 0, 0, 0}, { OP_String, 0, 0, "table" }, { OP_String, 0, 0, 0}, /* 3 */ @@ -495,6 +515,15 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){ sqliteVdbeChangeP3(v, base+5, p->zName, 0); sqliteVdbeChangeP3(v, base+6, pParse->sFirstToken.z, n); sqliteVdbeAddOp(v, OP_Close, 0, 0, 0, 0); + if( p->pIndex ){ + /* If the table has a primary key, create an index in the database + ** for that key. */ + Index *pIndex = p->pIndex; + assert( pIndex->pNext==0 ); + assert( pIndex->tnum==0 ); + sqliteVdbeAddOp(v, OP_CreateIndex, 0, 0, 0, 0), + sqliteVdbeIndexRootAddr(v, &pIndex->tnum); + } if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0); } @@ -528,6 +557,7 @@ void sqliteDropTable(Parse *pParse, Token *pName){ Table *pTable; Vdbe *v; int base; + sqlite *db = pParse->db; if( pParse->nErr || sqlite_malloc_failed ) return; pTable = sqliteTableFromToken(pParse, pName); @@ -545,29 +575,29 @@ void sqliteDropTable(Parse *pParse, Token *pName){ v = sqliteGetVdbe(pParse); if( v ){ static VdbeOp dropTable[] = { - { OP_Open, 0, 2, 0}, + { OP_Open, 0, 2, MASTER_NAME}, { OP_Rewind, 0, 0, 0}, { OP_String, 0, 0, 0}, /* 2 */ - { OP_Next, 0, ADDR(10), 0}, /* 3 */ + { OP_Next, 0, ADDR(9), 0}, /* 3 */ { OP_Dup, 0, 0, 0}, { OP_Column, 0, 3, 0}, { OP_Ne, 0, ADDR(3), 0}, - { OP_Recno, 0, 0, 0}, { OP_Delete, 0, 0, 0}, { OP_Goto, 0, ADDR(3), 0}, - { OP_Destroy, 0, 0, 0}, /* 10 */ + { OP_Destroy, 0, 0, 0}, /* 9 */ { OP_Close, 0, 0, 0}, }; Index *pIdx; - if( (pParse->db->flags & SQLITE_InTrans)==0 ){ + if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); } base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable); - sqliteVdbeChangeP1(v, base+10, pTable->tnum); + sqliteVdbeChangeP3(v, base+2, pTable->zName, 0); + sqliteVdbeChangeP1(v, base+9, pTable->tnum); for(pIdx=pTable->pIndex; pIdx; pIdx=pIdx->pNext){ sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, 0, 0, 0); } - if( (pParse->db->flags & SQLITE_InTrans)==0 ){ + if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0); } } @@ -580,7 +610,7 @@ void sqliteDropTable(Parse *pParse, Token *pName){ */ if( !pParse->explain ){ pTable->isDelete = 1; - pParse->db->flags |= SQLITE_InternChanges; + db->flags |= SQLITE_InternChanges; } } @@ -720,16 +750,25 @@ void sqliteCreateIndex( ** 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. + ** + ** If pTable==0 it means this index is generated as a primary key + ** and those does not have a CREATE INDEX statement to add to the + ** master table. Also, since primary keys are created at the same + ** time as tables, the table will be empty so there is no need to + ** initialize the index. Hence, skip all the code generation if + ** pTable==0. */ - if( pParse->initFlag==0 ){ + else if( pParse->initFlag==0 && pTable!=0 ){ static VdbeOp addTable[] = { - { OP_Open, 2, 2, 0}, + { OP_Open, 2, 2, MASTER_NAME}, { OP_NewRecno, 2, 0, 0}, { OP_String, 0, 0, "index"}, { OP_String, 0, 0, 0}, /* 3 */ - { OP_CreateIndex, 0, 0, 0}, - { OP_String, 0, 0, 0}, /* 5 */ - { OP_String, 0, 0, 0}, /* 6 */ + { OP_CreateIndex, 1, 0, 0}, + { OP_Dup, 0, 0, 0}, + { OP_Open, 1, 0, 0}, /* 6 */ + { OP_String, 0, 0, 0}, /* 7 */ + { OP_String, 0, 0, 0}, /* 8 */ { OP_MakeRecord, 5, 0, 0}, { OP_Put, 2, 0, 0}, { OP_Close, 2, 0, 0}, @@ -744,17 +783,17 @@ void sqliteCreateIndex( if( pTable!=0 && (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); } - sqliteVdbeAddOp(v, OP_Open, 0, pTab->tnum, pTab->zName, 0); - sqliteVdbeAddOp(v, OP_Open, 1, pIndex->tnum, pIndex->zName, 0); if( pStart && pEnd ){ int base; n = (int)pEnd->z - (int)pStart->z + 1; base = sqliteVdbeAddOpList(v, ArraySize(addTable), addTable); sqliteVdbeChangeP3(v, base+3, pIndex->zName, 0); sqliteVdbeIndexRootAddr(v, &pIndex->tnum); - sqliteVdbeChangeP3(v, base+5, pTab->zName, 0); - sqliteVdbeChangeP3(v, base+6, pStart->z, n); + sqliteVdbeChangeP3(v, base+6, pIndex->zName, 0); + sqliteVdbeChangeP3(v, base+7, pTab->zName, 0); + sqliteVdbeChangeP3(v, base+8, pStart->z, n); } + sqliteVdbeAddOp(v, OP_Open, 0, pTab->tnum, pTab->zName, 0); lbl1 = sqliteVdbeMakeLabel(v); lbl2 = sqliteVdbeMakeLabel(v); sqliteVdbeAddOp(v, OP_Rewind, 0, 0, 0, 0); @@ -812,16 +851,15 @@ void sqliteDropIndex(Parse *pParse, Token *pName){ v = sqliteGetVdbe(pParse); if( v ){ static VdbeOp dropIndex[] = { - { OP_Open, 0, 2, 0}, + { OP_Open, 0, 2, MASTER_NAME}, { OP_Rewind, 0, 0, 0}, { OP_String, 0, 0, 0}, /* 2 */ - { OP_Next, 0, ADDR(9), 0}, /* 3 */ + { OP_Next, 0, ADDR(8), 0}, /* 3 */ { OP_Dup, 0, 0, 0}, { OP_Column, 0, 1, 0}, { OP_Ne, 0, ADDR(3), 0}, - { OP_Recno, 0, 0, 0}, { OP_Delete, 0, 0, 0}, - { OP_Destroy, 0, 0, 0}, /* 9 */ + { OP_Destroy, 0, 0, 0}, /* 8 */ { OP_Close, 0, 0, 0}, }; int base; @@ -830,7 +868,7 @@ void sqliteDropIndex(Parse *pParse, Token *pName){ sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0); } base = sqliteVdbeAddOpList(v, ArraySize(dropIndex), dropIndex); - sqliteVdbeChangeP1(v, base+9, pIndex->tnum); + sqliteVdbeChangeP1(v, base+8, pIndex->tnum); if( (db->flags & SQLITE_InTrans)==0 ){ sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0); } diff --git a/src/delete.c b/src/delete.c index ab5e7f2da1..523bc2ec04 100644 --- a/src/delete.c +++ b/src/delete.c @@ -24,7 +24,7 @@ ** This file contains C code routines that are called by the parser ** to handle DELETE FROM statements. ** -** $Id: delete.c,v 1.11 2001/09/13 14:46:10 drh Exp $ +** $Id: delete.c,v 1.12 2001/09/13 21:53:10 drh Exp $ */ #include "sqliteInt.h" @@ -96,12 +96,12 @@ void sqliteDeleteFrom( /* Special case: A DELETE without a WHERE clause deletes everything. - ** It is easier just to deleted the database files directly. + ** It is easier just to clear all information the database tables directly. */ if( pWhere==0 ){ - sqliteVdbeAddOp(v, OP_Destroy, pTab->tnum, 0, 0, 0); + sqliteVdbeAddOp(v, OP_Clear, pTab->tnum, 0, 0, 0); for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, 0, 0, 0); + sqliteVdbeAddOp(v, OP_Clear, pIdx->tnum, 0, 0, 0); } } @@ -135,12 +135,11 @@ void sqliteDeleteFrom( } end = sqliteVdbeMakeLabel(v); addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end, 0, 0); + sqliteVdbeAddOp(v, OP_MoveTo, base, 0, 0, 0); if( pTab->pIndex ){ - sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0); - sqliteVdbeAddOp(v, OP_MoveTo, base, 0, 0, 0); for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ int j; - sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0); + sqliteVdbeAddOp(v, OP_Recno, base, 0, 0, 0); for(j=0; jnColumn; j++){ sqliteVdbeAddOp(v, OP_Column, base, pIdx->aiColumn[j], 0, 0); } diff --git a/src/main.c b/src/main.c index 8704149c99..7583542de7 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.33 2001/09/13 16:18:54 drh Exp $ +** $Id: main.c,v 1.34 2001/09/13 21:53:10 drh Exp $ */ #include "sqliteInt.h" #if defined(HAVE_USLEEP) && HAVE_USLEEP @@ -253,6 +253,7 @@ sqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){ } } sqliteFree(db); + sqliteStrRealloc(pzErrMsg); return 0; } @@ -265,6 +266,7 @@ sqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){ goto no_mem_on_open; }else if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ sqlite_close(db); + sqliteStrRealloc(pzErrMsg); return 0; }else /* if( pzErrMsg ) */{ sqliteFree(*pzErrMsg); diff --git a/src/random.c b/src/random.c index 413b5d9c42..86cb91d205 100644 --- a/src/random.c +++ b/src/random.c @@ -27,7 +27,7 @@ ** Random numbers are used by some of the database backends in order ** to generate random integer keys for tables or random filenames. ** -** $Id: random.c,v 1.2 2001/01/31 13:28:09 drh Exp $ +** $Id: random.c,v 1.3 2001/09/13 21:53:10 drh Exp $ */ #include "sqliteInt.h" #include @@ -87,7 +87,7 @@ int sqliteRandomByte(void){ prng_state.s[prng_state.i] = prng_state.s[prng_state.j]; prng_state.s[prng_state.j] = t; t = prng_state.s[prng_state.i] + prng_state.s[prng_state.j]; - return t & 0xff; + return prng_state.s[t & 0xff]; } /* diff --git a/src/select.c b/src/select.c index e0e38a1e36..a937d93cdb 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.34 2001/09/13 16:18:54 drh Exp $ +** $Id: select.c,v 1.35 2001/09/13 21:53:10 drh Exp $ */ #include "sqliteInt.h" @@ -182,6 +182,7 @@ static int selectInnerLoop( */ if( eDest==SRT_Except ){ sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0, 0, 0); + sqliteVdbeAddOp(v, OP_MoveTo, iParm, 0, 0, 0); sqliteVdbeAddOp(v, OP_Delete, iParm, 0, 0, 0); }else diff --git a/src/test3.c b/src/test3.c index 289c45e52c..42f44b3574 100644 --- a/src/test3.c +++ b/src/test3.c @@ -25,7 +25,7 @@ ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** -** $Id: test3.c,v 1.9 2001/08/20 00:33:58 drh Exp $ +** $Id: test3.c,v 1.10 2001/09/13 21:53:10 drh Exp $ */ #include "sqliteInt.h" #include "pager.h" @@ -715,9 +715,11 @@ static int btree_key( sqliteBtreeKeySize(pCur, &n); zBuf = malloc( n+1 ); rc = sqliteBtreeKey(pCur, 0, n, zBuf); - if( rc ){ + if( rc!=n ){ + char zMsg[100]; free(zBuf); - Tcl_AppendResult(interp, errorName(rc), 0); + sprintf(zMsg, "truncated key: got %d of %d bytes", rc, n); + Tcl_AppendResult(interp, zMsg, 0); return TCL_ERROR; } zBuf[n] = 0; @@ -751,9 +753,11 @@ static int btree_data( sqliteBtreeDataSize(pCur, &n); zBuf = malloc( n+1 ); rc = sqliteBtreeData(pCur, 0, n, zBuf); - if( rc ){ + if( rc!=n ){ + char zMsg[100]; free(zBuf); - Tcl_AppendResult(interp, errorName(rc), 0); + sprintf(zMsg, "truncated data: got %d of %d bytes", rc, n); + Tcl_AppendResult(interp, zMsg, 0); return TCL_ERROR; } zBuf[n] = 0; diff --git a/src/vdbe.c b/src/vdbe.c index 1133c18863..8962fd2b3d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -41,10 +41,11 @@ ** But other routines are also provided to help in building up ** a program instruction by instruction. ** -** $Id: vdbe.c,v 1.63 2001/09/13 16:18:54 drh Exp $ +** $Id: vdbe.c,v 1.64 2001/09/13 21:53:10 drh Exp $ */ #include "sqliteInt.h" #include +#include /* ** SQL is translated into a sequence of instructions to be @@ -875,26 +876,26 @@ static char *zOpName[] = { 0, "NewRecno", "Put", "Distinct", "Found", "NotFound", "Delete", "Column", "KeyAsData", "Recno", "FullKey", "Rewind", "Next", - "Destroy", "CreateIndex", "CreateTable", "Reorganize", - "BeginIdx", "NextIdx", "PutIdx", "DeleteIdx", - "MemLoad", "MemStore", "ListOpen", "ListWrite", - "ListRewind", "ListRead", "ListClose", "SortOpen", - "SortPut", "SortMakeRec", "SortMakeKey", "Sort", - "SortNext", "SortKey", "SortCallback", "SortClose", - "FileOpen", "FileRead", "FileColumn", "FileClose", - "AggReset", "AggFocus", "AggIncr", "AggNext", - "AggSet", "AggGet", "SetInsert", "SetFound", - "SetNotFound", "SetClear", "MakeRecord", "MakeKey", - "MakeIdxKey", "Goto", "If", "Halt", - "ColumnCount", "ColumnName", "Callback", "Integer", - "String", "Null", "Pop", "Dup", - "Pull", "Add", "AddImm", "Subtract", - "Multiply", "Divide", "Min", "Max", - "Like", "Glob", "Eq", "Ne", - "Lt", "Le", "Gt", "Ge", - "IsNull", "NotNull", "Negative", "And", - "Or", "Not", "Concat", "Noop", - "Strlen", "Substr", + "Destroy", "Clear", "CreateIndex", "CreateTable", + "Reorganize", "BeginIdx", "NextIdx", "PutIdx", + "DeleteIdx", "MemLoad", "MemStore", "ListOpen", + "ListWrite", "ListRewind", "ListRead", "ListClose", + "SortOpen", "SortPut", "SortMakeRec", "SortMakeKey", + "Sort", "SortNext", "SortKey", "SortCallback", + "SortClose", "FileOpen", "FileRead", "FileColumn", + "FileClose", "AggReset", "AggFocus", "AggIncr", + "AggNext", "AggSet", "AggGet", "SetInsert", + "SetFound", "SetNotFound", "SetClear", "MakeRecord", + "MakeKey", "MakeIdxKey", "Goto", "If", + "Halt", "ColumnCount", "ColumnName", "Callback", + "Integer", "String", "Null", "Pop", + "Dup", "Pull", "Add", "AddImm", + "Subtract", "Multiply", "Divide", "Min", + "Max", "Like", "Glob", "Eq", + "Ne", "Lt", "Le", "Gt", + "Ge", "IsNull", "NotNull", "Negative", + "And", "Or", "Not", "Concat", + "Noop", "Strlen", "Substr", }; /* @@ -1979,6 +1980,8 @@ case OP_Rollback: { ** of P1. The P1 values need not be contiguous but all P1 values ** should be small integers. It is an error for P1 to be negative. ** +** If P2==0 then take the root page number from the top of the stack. +** ** The P3 value is the name of the table or index being opened. ** The P3 value is not actually used by this opcode and may be ** omitted. But the code generator usually inserts the index or @@ -1987,6 +1990,19 @@ case OP_Rollback: { case OP_Open: { int busy = 0; int i = pOp->p1; + int tos = p->tos; + int p2 = pOp->p2; + if( p2<=0 ){ + if( tos<0 ) goto not_enough_stack; + Integerify(p, tos); + p2 = p->aStack[tos].i; + POPSTACK; + if( p2<2 ){ + sqliteSetString(pzErrMsg, "root page number less than 2", 0); + rc = SQLITE_INTERNAL; + goto cleanup; + } + } VERIFY( if( i<0 ) goto bad_instruction; ) if( i>=p->nCursor ){ int j; @@ -1999,7 +2015,7 @@ case OP_Open: { } memset(&p->aCsr[i], 0, sizeof(Cursor)); do{ - rc = sqliteBtreeCursor(pBt, pOp->p2, &p->aCsr[i].pCursor); + rc = sqliteBtreeCursor(pBt, p2, &p->aCsr[i].pCursor); switch( rc ){ case SQLITE_BUSY: { if( xBusy==0 || (*xBusy)(pBusyArg, pOp->p3, ++busy)==0 ){ @@ -2240,29 +2256,18 @@ case OP_Put: { /* Opcode: Delete P1 * * ** -** The top of the stack is a key. Remove this key and its data -** from database file P1. Then pop the stack to discard the key. +** Delete the record at which the P1 cursor is currently pointing. +** +** The cursor will be left pointing at either the next or the previous +** record in the table. If it is left pointing at the next record, then +** the next OP_Next will be a no-op. Hence it is OK to delete a record +** from within an OP_Next loop. */ case OP_Delete: { - int tos = p->tos; int i = pOp->p1; - int res; - VERIFY( if( tos<0 ) goto not_enough_stack; ) if( VERIFY( i>=0 && inCursor && ) p->aCsr[i].pCursor!=0 ){ - char *zKey; - int nKey; - if( aStack[tos].flags & STK_Int ){ - nKey = sizeof(int); - zKey = (char*)&aStack[tos].i; - }else{ - if( Stringify(p, tos) ) goto no_mem; - nKey = aStack[tos].n; - zKey = zStack[tos]; - } - rc = sqliteBtreeMoveto(p->aCsr[i].pCursor, zKey, nKey, &res); rc = sqliteBtreeDelete(p->aCsr[i].pCursor); } - POPSTACK; break; } @@ -2303,11 +2308,11 @@ case OP_Column: { static const int mxHdr = sizeof(aHdr)/sizeof(aHdr[0]); int i = pOp->p1; int p2 = pOp->p2; - int tos = ++p->tos; + int tos = p->tos+1; BtCursor *pCrsr; char *z; - VERIFY( if( NeedStack(p, tos) ) goto no_mem; ) + VERIFY( if( NeedStack(p, tos+1) ) goto no_mem; ) if( VERIFY( i>=0 && inCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){ int (*xSize)(BtCursor*, int*); int (*xRead)(BtCursor*, int, int, char*); @@ -2371,6 +2376,7 @@ case OP_Column: { zStack[tos] = z; aStack[tos].n = amt; } + p->tos = tos; } break; } @@ -2530,8 +2536,13 @@ case OP_NextIdx: { zStack[tos] = 0; if( VERIFY( i>=0 && inCursor && ) (pCrsr = &p->aCsr[i])->pCursor!=0 ){ pCur = pCrsr->pCursor; - rx = sqliteBtreeNext(pCur, &res); - if( rx!=SQLITE_OK ) goto abort_due_to_error; + if( pCrsr->atFirst ){ + pCrsr->atFirst = 0; + res = 0; + }else{ + rx = sqliteBtreeNext(pCur, &res); + if( rx!=SQLITE_OK ) goto abort_due_to_error; + } sqliteBtreeKeySize(pCur, &size); if( res>0 || size!=pCrsr->nKey+sizeof(int) || sqliteBtreeKey(pCur, 0, pCrsr->nKey, pCrsr->zBuf)!=pCrsr->nKey || @@ -2599,6 +2610,17 @@ case OP_Destroy: { break; } +/* Opcode: Clear P1 * * +** +** Delete all contents of the database table or index whose root page +** in the database file is given by P1. But, unlike OP_Destroy, do not +** remove the table or index from the database file. +*/ +case OP_Clear: { + sqliteBtreeClearTable(pBt, pOp->p1); + break; +} + /* Opcode: CreateTable * * * ** ** Allocate a new table in the main database file. Push the page number @@ -2634,6 +2656,8 @@ case OP_CreateTable: { ** Allocate a new Index in the main database file. Push the page number ** for the root page of the new table onto the stack. ** +** If P1>=0 then open a cursor named P1 on the newly created index. +** ** The root page number is also written to a memory location which has ** be set up by the parser. The difference between CreateTable and ** CreateIndex is that each writes its root page number into a different @@ -3684,7 +3708,7 @@ default: { cleanup: Cleanup(p); - if( p->pTableRoot || p->pIndexRoot ){ + if( (p->pTableRoot || p->pIndexRoot) && rc==SQLITE_OK ){ rc = SQLITE_INTERNAL; sqliteSetString(pzErrMsg, "table or index root page not set", 0); } diff --git a/src/vdbe.h b/src/vdbe.h index 59f8340226..cbf7e08c97 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -27,7 +27,7 @@ ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** -** $Id: vdbe.h,v 1.20 2001/09/13 14:46:11 drh Exp $ +** $Id: vdbe.h,v 1.21 2001/09/13 21:53:10 drh Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ @@ -94,98 +94,99 @@ typedef struct VdbeOp VdbeOp; #define OP_Next 20 #define OP_Destroy 21 -#define OP_CreateIndex 22 -#define OP_CreateTable 23 -#define OP_Reorganize 24 +#define OP_Clear 22 +#define OP_CreateIndex 23 +#define OP_CreateTable 24 +#define OP_Reorganize 25 -#define OP_BeginIdx 25 -#define OP_NextIdx 26 -#define OP_PutIdx 27 -#define OP_DeleteIdx 28 +#define OP_BeginIdx 26 +#define OP_NextIdx 27 +#define OP_PutIdx 28 +#define OP_DeleteIdx 29 -#define OP_MemLoad 29 -#define OP_MemStore 30 +#define OP_MemLoad 30 +#define OP_MemStore 31 -#define OP_ListOpen 31 -#define OP_ListWrite 32 -#define OP_ListRewind 33 -#define OP_ListRead 34 -#define OP_ListClose 35 +#define OP_ListOpen 32 +#define OP_ListWrite 33 +#define OP_ListRewind 34 +#define OP_ListRead 35 +#define OP_ListClose 36 -#define OP_SortOpen 36 -#define OP_SortPut 37 -#define OP_SortMakeRec 38 -#define OP_SortMakeKey 39 -#define OP_Sort 40 -#define OP_SortNext 41 -#define OP_SortKey 42 -#define OP_SortCallback 43 -#define OP_SortClose 44 +#define OP_SortOpen 37 +#define OP_SortPut 38 +#define OP_SortMakeRec 39 +#define OP_SortMakeKey 40 +#define OP_Sort 41 +#define OP_SortNext 42 +#define OP_SortKey 43 +#define OP_SortCallback 44 +#define OP_SortClose 45 -#define OP_FileOpen 45 -#define OP_FileRead 46 -#define OP_FileColumn 47 -#define OP_FileClose 48 +#define OP_FileOpen 46 +#define OP_FileRead 47 +#define OP_FileColumn 48 +#define OP_FileClose 49 -#define OP_AggReset 49 -#define OP_AggFocus 50 -#define OP_AggIncr 51 -#define OP_AggNext 52 -#define OP_AggSet 53 -#define OP_AggGet 54 +#define OP_AggReset 50 +#define OP_AggFocus 51 +#define OP_AggIncr 52 +#define OP_AggNext 53 +#define OP_AggSet 54 +#define OP_AggGet 55 -#define OP_SetInsert 55 -#define OP_SetFound 56 -#define OP_SetNotFound 57 -#define OP_SetClear 58 +#define OP_SetInsert 56 +#define OP_SetFound 57 +#define OP_SetNotFound 58 +#define OP_SetClear 59 -#define OP_MakeRecord 59 -#define OP_MakeKey 60 -#define OP_MakeIdxKey 61 +#define OP_MakeRecord 60 +#define OP_MakeKey 61 +#define OP_MakeIdxKey 62 -#define OP_Goto 62 -#define OP_If 63 -#define OP_Halt 64 +#define OP_Goto 63 +#define OP_If 64 +#define OP_Halt 65 -#define OP_ColumnCount 65 -#define OP_ColumnName 66 -#define OP_Callback 67 +#define OP_ColumnCount 66 +#define OP_ColumnName 67 +#define OP_Callback 68 -#define OP_Integer 68 -#define OP_String 69 -#define OP_Null 70 -#define OP_Pop 71 -#define OP_Dup 72 -#define OP_Pull 73 +#define OP_Integer 69 +#define OP_String 70 +#define OP_Null 71 +#define OP_Pop 72 +#define OP_Dup 73 +#define OP_Pull 74 -#define OP_Add 74 -#define OP_AddImm 75 -#define OP_Subtract 76 -#define OP_Multiply 77 -#define OP_Divide 78 -#define OP_Min 79 -#define OP_Max 80 -#define OP_Like 81 -#define OP_Glob 82 -#define OP_Eq 83 -#define OP_Ne 84 -#define OP_Lt 85 -#define OP_Le 86 -#define OP_Gt 87 -#define OP_Ge 88 -#define OP_IsNull 89 -#define OP_NotNull 90 -#define OP_Negative 91 -#define OP_And 92 -#define OP_Or 93 -#define OP_Not 94 -#define OP_Concat 95 -#define OP_Noop 96 +#define OP_Add 75 +#define OP_AddImm 76 +#define OP_Subtract 77 +#define OP_Multiply 78 +#define OP_Divide 79 +#define OP_Min 80 +#define OP_Max 81 +#define OP_Like 82 +#define OP_Glob 83 +#define OP_Eq 84 +#define OP_Ne 85 +#define OP_Lt 86 +#define OP_Le 87 +#define OP_Gt 88 +#define OP_Ge 89 +#define OP_IsNull 90 +#define OP_NotNull 91 +#define OP_Negative 92 +#define OP_And 93 +#define OP_Or 94 +#define OP_Not 95 +#define OP_Concat 96 +#define OP_Noop 97 -#define OP_Strlen 97 -#define OP_Substr 98 +#define OP_Strlen 98 +#define OP_Substr 99 -#define OP_MAX 98 +#define OP_MAX 99 /* ** Prototypes for the VDBE interface. See comments on the implementation diff --git a/test/all.test b/test/all.test index b052599acb..a1fb54caf9 100644 --- a/test/all.test +++ b/test/all.test @@ -22,7 +22,7 @@ #*********************************************************************** # This file runs all tests. # -# $Id: all.test,v 1.7 2001/04/12 23:21:59 drh Exp $ +# $Id: all.test,v 1.8 2001/09/13 21:53:10 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -35,12 +35,6 @@ if {[file exists ./sqlite_test_count]} { set COUNT 3 } -if {[file exists ./sqlite_test_prefixes]} { - set PREFIXES [exec cat ./sqlite_test_prefixes] -} else { - set PREFIXES {memory: gdbm:} -} - # LeakList will hold a list of the number of unfreed mallocs after # each round of the test. This number should be constant. If it # grows, it may mean there is a memory leak in the library. @@ -49,13 +43,10 @@ set LeakList {} for {set Counter 0} {$Counter<$COUNT} {incr Counter} { - foreach p $PREFIXES { - set dbprefix $p - foreach testfile [lsort -dictionary [glob $testdir/*.test]] { - if {[file tail $testfile]=="all.test"} continue - if {[file tail $testfile]=="malloc.test"} continue - source $testfile - } + foreach testfile [lsort -dictionary [glob $testdir/*.test]] { + if {[file tail $testfile]=="all.test"} continue + if {[file tail $testfile]=="malloc.test"} continue + source $testfile } if {[info exists Leak]} { lappend LeakList $Leak @@ -81,10 +72,7 @@ if {$LeakList!=""} { } if {[file readable $testdir/malloc.test]} { - foreach p $PREFIXES { - set dbprefix $p - source $testdir/malloc.test - } + source $testdir/malloc.test } really_finish_test diff --git a/test/dbbe.test b/test/dbbe.test deleted file mode 100644 index c9cd2148c3..0000000000 --- a/test/dbbe.test +++ /dev/null @@ -1,140 +0,0 @@ -# Copyright (c) 1999, 2000 D. Richard Hipp -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public -# License along with this library; if not, write to the -# Free Software Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. -# -# Author contact information: -# drh@hwaci.com -# http://www.hwaci.com/drh/ -# -#*********************************************************************** -# This file implements regression tests for SQLite library. The -# focus of this file is exercising the code in dbbe.c. -# -# $Id: dbbe.test,v 1.7 2001/04/03 16:53:22 drh Exp $ - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# Try to open a database that does not exist. -# -do_test dbbe-1.1 { - catch {db close} - forcedelete testdb - set v [catch {sqlite db testdb 0444} msg] - lappend v $msg -} {1 {can't find directory "testdb"}} -do_test dbbe-1.2 { - catch {db close} - forcedelete testdb - set v [catch {sqlite db testdb/dummy 0666} msg] - lappend v $msg -} {1 {can't find or create directory "testdb/dummy"}} - -# Try to open a database for writing in a directory that -# doesn't exist but for which the parent directory does -# exist. This should work! -# -do_test dbbe-1.3 { - catch {db close} - forcedelete testdb - set v [catch {sqlite db testdb 0666} msg] - lappend v $msg -} {0 {}} - -# Try to open a file instead of a directory. -# -do_test dbbe-1.4 { - catch {db close} - forcedelete testdb - set fd [open testdb w] - puts $fd hi! - close $fd - set v [catch {sqlite db testdb 0666} msg] - lappend v $msg -} {1 {not a directory: "testdb"}} - -if {$::tcl_platform(platform)!="windows"} { - -# Access permission denied on the directory. -# -do_test dbbe-1.5 { - catch {db close} - forcedelete testdb - file mkdir testdb - file attributes testdb -permissions 0 - set v [catch {sqlite db testdb 0666} msg] - lappend v $msg -} {1 {access permission denied}} - -# Access permission denied on the master file -# -do_test dbbe-1.6 { - catch {db close} - forcedelete testdb - sqlite db testdb 0666 - execsql {CREATE TABLE t1(x int)} - db close - file attributes testdb/sqlite_master.tbl -permission 0444 - set v [catch {sqlite db testdb 0666} msg] - lappend v $msg -} {1 {access permission denied for testdb/sqlite_master.tbl}} -do_test dbbe-1.6b { - catch {db close} - forcedelete testdb - sqlite db testdb 0666 - execsql {CREATE TABLE t1(x int)} - db close - file attributes testdb/sqlite_master.tbl -permission 0444 - set v [catch {sqlite db testdb 0444} msg] - lappend v $msg -} {0 {}} - -} ;# End of if( platform!=windows ) - -# Make sure a table can be accessed by either uppercase or lowercase -# names -# -do_test dbbe-2.1 { - catch {db close} - forcedelete testdb - sqlite db testdb 0666 - execsql { - CREATE TABLE t1(x int); - INSERT INTO t1 VALUES(1); - } - db close - sqlite db testdb 0444 - set r [execsql {SELECT * FROM T1}] - db close - sqlite db testdb 0666 - lappend r [execsql {SELECT * FROM t1}] -} {1 1} - -# Try to change a table after opening the database readonly -# -do_test dbbe-3.1 { - catch {db close} - forcedelete testdb - sqlite db testdb 0666 - execsql {CREATE TABLE t1(x int)} - db close - sqlite db testdb 0444 - set v [catch {execsql {INSERT INTO t1 VALUES(1)}} msg] - lappend v $msg -} {1 {table t1 is readonly}} - - -finish_test diff --git a/test/index.test b/test/index.test index 79d54a8c43..2d6dc47002 100644 --- a/test/index.test +++ b/test/index.test @@ -23,7 +23,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the CREATE INDEX statement. # -# $Id: index.test,v 1.10 2001/08/19 18:19:46 drh Exp $ +# $Id: index.test,v 1.11 2001/09/13 21:53:10 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -39,17 +39,15 @@ do_test index-1.1b { execsql {SELECT name, sql, tbl_name, type FROM sqlite_master WHERE name='index1'} } {index1 {CREATE INDEX index1 ON test1(f1)} test1 index} -skipif memory: do_test index-1.1c { db close - sqlite db testdb + sqlite db test.db execsql {SELECT name, sql, tbl_name, type FROM sqlite_master WHERE name='index1'} } {index1 {CREATE INDEX index1 ON test1(f1)} test1 index} -skipif memory: do_test index-1.1d { db close - sqlite db testdb + sqlite db test.db execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name} } {index1 test1} @@ -101,18 +99,6 @@ do_test index-3.1 { ORDER BY name} } $r -# Add a single entry to the table. Verify that files are created -# for every index. -# -set r {} -for {set i 1} {$i<100} {incr i} { - lappend r testdb/index$i.tbl -} -skipif memory: -do_test index-3.2 { - execsql {INSERT INTO test1 VALUES(1,2,3,4,5)} - lsort -dictionary [glob testdb/index*.tbl] -} $r # Verify that all the indices go away when we drop the table. # @@ -122,9 +108,6 @@ do_test index-3.3 { WHERE type='index' AND tbl_name='test1' ORDER BY name} } {} -do_test index-3.4 { - lsort -dictionary [glob -nocomplain testdb/index*.tbl] -} {} # Create a table and insert values into that table. Then create # an index on that table. Verify that we can select values @@ -228,10 +211,6 @@ do_test index-7.1 { } execsql {SELECT count(*) FROM test1} } {19} -skipif memory: -do_test index-7.1b { - lsort -dictionary [glob testdb/test1*.tbl] -} {testdb/test1.tbl testdb/test1__primary_key.tbl} do_test index-7.2 { execsql {SELECT f1 FROM test1 WHERE f2=65536} } {16} diff --git a/test/select2.test b/test/select2.test index ef1ffb204a..d89c827879 100644 --- a/test/select2.test +++ b/test/select2.test @@ -23,7 +23,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the SELECT statement. # -# $Id: select2.test,v 1.11 2001/08/19 18:19:46 drh Exp $ +# $Id: select2.test,v 1.12 2001/09/13 21:53:10 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -112,7 +112,6 @@ do_test select2-3.2e { # omit the time-dependent tests # -testif gdbm: do_probtest select2-3.2f { set t1 [lindex [time {execsql {SELECT f1 FROM tbl2 WHERE 1000=f2}} 1] 0] set t2 [lindex [time {execsql {SELECT f1 FROM tbl2 WHERE f2=1000}} 1] 0] diff --git a/test/table.test b/test/table.test index 6c103b1ea3..6438438ab2 100644 --- a/test/table.test +++ b/test/table.test @@ -23,7 +23,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the CREATE TABLE statement. # -# $Id: table.test,v 1.9 2001/04/12 23:21:59 drh Exp $ +# $Id: table.test,v 1.10 2001/09/13 21:53:10 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -45,15 +45,6 @@ do_test table-1.1 { two text )}} -# Verify that both table files exists in the database directory -# -do_test table-1.2 { - execsql {INSERT INTO test1 VALUES('hi', 'y''all')} -} {} -testif gdbm: -do_test table-1.2b { - lsort [glob -nocomplain testdb/*.tbl] -} {testdb/sqlite_master.tbl testdb/test1.tbl} # Verify the other fields of the sqlite_master file. # @@ -64,7 +55,6 @@ do_test table-1.3 { # Close and reopen the database. Verify that everything is # still the same. # -skipif memory: do_test table-1.4 { db close sqlite db testdb @@ -80,7 +70,6 @@ do_test table-1.5 { # Verify that the file associated with the database is gone. # -testif gdbm: do_test table-1.5 { lsort [glob -nocomplain testdb/*.tbl] } {testdb/sqlite_master.tbl} @@ -88,7 +77,6 @@ do_test table-1.5 { # Close and reopen the database. Verify that the table is # still gone. # -skipif memory: do_test table-1.6 { db close sqlite db testdb @@ -127,7 +115,6 @@ do_test table-2.1b { set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg] lappend v $msg } {1 {table sqlite_master already exists}} -skipif memory: do_test table-2.1c { db close sqlite db testdb @@ -145,7 +132,6 @@ do_test table-2.2a { set v [catch {execsql {CREATE TABLE test3(two text)}} msg] lappend v $msg } {1 {there is already an index named test3}} -skipif memory: do_test table-2.2b { db close sqlite db testdb @@ -206,7 +192,6 @@ do_test table-3.4 { set v [catch {execsql {CREATE TABLE bIg(xyz foo)}} msg] lappend v $msg } {1 {table bIg already exists}} -skipif memory: do_test table-3.5 { db close sqlite db testdb @@ -235,7 +220,6 @@ do_test table-4.1 { } execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name} } $r -skipif memory: do_test table-4.1b { db close sqlite db testdb @@ -297,7 +281,6 @@ do_test table-5.4 { # Create a table with a goofy name # -testif gdbm: do_test table-6.1 { execsql {CREATE TABLE 'Spaces In This Name!'(x int)} execsql {INSERT INTO 'spaces in this name!' VALUES(1)} diff --git a/test/tester.tcl b/test/tester.tcl index 120ce86e95..6d2bd2f227 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -23,7 +23,7 @@ # This file implements some common TCL routines used for regression # testing the SQLite library # -# $Id: tester.tcl,v 1.15 2001/04/11 14:28:43 drh Exp $ +# $Id: tester.tcl,v 1.16 2001/09/13 21:53:10 drh Exp $ # Make sure tclsqlite was compiled correctly. Abort now with an # error message if not. @@ -54,28 +54,9 @@ if {[sqlite -tcl-uses-utf]} { # Create a test database # -if {![info exists dbprefix]} { - if {[info exists env(SQLITE_PREFIX)]} { - set dbprefix $env(SQLITE_PREFIX): - } else { - set dbprefix "gdbm:" - } -} -switch $dbprefix { - gdbm: { - foreach f [glob -nocomplain testdb/*] { - catch {file delete -force $f} - } - if {[catch {file delete -force testdb}]} { - exec rm -rf testdb - } - file mkdir testdb - } - memory: { - # do nothing - } -} -sqlite db ${dbprefix}testdb +file delete -force ./test.db +file delete -force ./test.db-journal +sqlite db ./test.db # Abort early if this script has been run before. # @@ -109,14 +90,16 @@ proc do_test {name cmd expected} { } if {!$go} return incr nTest - puts -nonewline $::dbprefix$name... + puts -nonewline $name... flush stdout if {[catch {uplevel #0 "$cmd;\n"} result]} { puts "\nError: $result" incr nErr + if {$nErr>10} {puts "*** Giving up..."; exit 1} } elseif {[string compare $result $expected]} { puts "\nExpected: \[$expected\]\n Got: \[$result\]" incr nErr + if {$nErr>10} {puts "*** Giving up..."; exit 1} } else { puts " Ok" } @@ -144,7 +127,7 @@ proc do_probtest {name cmd expected} { } if {!$go} return incr nTest - puts -nonewline $::dbprefix$name... + puts -nonewline $name... flush stdout if {[catch {uplevel #0 "$cmd;\n"} result]} { puts "\nError: $result" @@ -160,29 +143,6 @@ proc do_probtest {name cmd expected} { } } -# Skip a test based on the dbprefix -# -proc skipif {args} { - foreach a $args { - if {$::dbprefix==$a} { - set ::skip_test 1 - return - } - } -} - -# Run the next test only if the dbprefix is among the listed arguments -# -proc testif {args} { - foreach a $args { - if {$::dbprefix==$a} { - set ::skip_test 0 - return - } - } - set ::skip_test 1 -} - # The procedure uses the special "sqlite_malloc_stat" command # (which is only available if SQLite is compiled with -DMEMORY_DEBUG=1) # to see how many malloc()s have not been free()ed. The number diff --git a/test/vacuum.test b/test/vacuum.test index 157bf17020..45e51480bc 100644 --- a/test/vacuum.test +++ b/test/vacuum.test @@ -23,7 +23,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the VACUUM statement. # -# $Id: vacuum.test,v 1.3 2001/03/20 12:55:14 drh Exp $ +# $Id: vacuum.test,v 1.4 2001/09/13 21:53:10 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -53,7 +53,6 @@ execsql {INSERT INTO test1 VALUES(2)} execsql {INSERT INTO test1 VALUES(3)} execsql {INSERT INTO test2 VALUES(4)} -testif gdbm: do_test vacuum-1.3 { set b1 [file mtime testdb/test1.tbl] set b2 [file mtime testdb/test2.tbl] @@ -66,7 +65,6 @@ do_test vacuum-1.3 { expr {$a1>$b1 && $a2==$b2 && $a3==$b3} } {1} if {$::tcl_platform(platform)!="windows"} { -testif gdbm: do_test vacuum-1.4 { set b1 [file mtime testdb/test1.tbl] set b2 [file mtime testdb/test2.tbl]