diff --git a/Makefile.in b/Makefile.in index acde6d3380..ce21097db7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -303,12 +303,16 @@ doc: $(DOC) install: sqlite libsqlite.la sqlite.h $(LIBTOOL) $(INSTALL) libsqlite.la $(prefix)/lib $(LIBTOOL) $(INSTALL) sqlite $(prefix)/bin - $(INSTALL) sqlite.h $(prefix)/include + $(INSTALL) -m 0644 sqlite.h $(prefix)/include clean: rm -f *.lo *.la *.o sqlite libsqlite.la sqlite.h - rm -rf .libs .deps + rm -rf .libs .deps rm -f lemon lempar.c parse.* sqlite*.tar.gz rm -f $(PUBLISH) rm -f *.da *.bb *.bbg gmon.out rm -f testfixture test.db + rm -rf doc + +distclean: clean + rm -f config.log config.status diff --git a/manifest b/manifest index 0d468a7659..ae21b2f2ba 100644 --- a/manifest +++ b/manifest @@ -1,6 +1,6 @@ -C Added\sa\smanpage\sfrom\sA.\sRottmann.\s(CVS\s341) -D 2002-01-07T19:58:44 -F Makefile.in 4b445b9a47f454ecd05220d803ee1b48a81f45ac +C Working\son\sa\sbug:\sDropping\sand\srecreating\sa\stable\swithin\sa\stransaction\ncauses\san\sassertion\sfailure.\s(CVS\s342) +D 2002-01-09T03:19:59 +F Makefile.in 9fa4277413bf1d9cf91365f07d4108d7d87ed2af F Makefile.template c88ffcb9c339e718f434d0c7f045bcd7eea125af F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0 F VERSION 6565c509ed61af074681258bd346dca53ad38128 @@ -21,13 +21,13 @@ F sqlite.1 2e2bb0529ef468ade9e4322bd609d0695fb9ded9 F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6 F src/btree.c c796e387da340cb628dc1e41f684fc20253f561e F src/btree.h 9ead7f54c270d8a554e59352ca7318fdaf411390 -F src/build.c 6c01002e98204ad2b993d0d043ee56c8c7dc8692 +F src/build.c 66195e45353b1c56ee12ba74a5743cb7a487f65e F src/delete.c f7690efc09ad6a2f1f3f0490e1b0cbb676bb95cf F src/expr.c 8169261ac56e96c860407a8773ca10b779e32328 F src/hash.c 838a6f2af547dfdc5ff2b438e8f981ea4b74f224 F src/hash.h a5f5b3ce2d086a172c5879b0b06a27a82eac9fac F src/insert.c 813c37719866c583e6ca7660f94f10230f4e385d -F src/main.c 567e472a1ca22f7d9970b1f96b9be91d45ccd7e2 +F src/main.c 46c752711300f1994be4162aaa59cbfb9db0c11e F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c F src/os.c 07882cde5c61f26751b8ee76fd84726c1f7e453c F src/os.h 00a18e0ae1139a64f1d3ead465ae2b9ff43f3db2 @@ -40,7 +40,7 @@ F src/select.c bddd8b5d07ffdae0d798c10b20dc7167469a3904 F src/shell.c f8008f0607f9523ca0f9562b8975c1bcc427d2b3 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e F src/sqlite.h.in a4c11d38d62b1bfbd50a5804edee8ca54c1adc9b -F src/sqliteInt.h 5b613b2c30965051135641e98e41b066cc0f8245 +F src/sqliteInt.h 7a7c5213a422e29883dcfe4c07d1f1def24f03fd F src/table.c c89698bd5bb4b8d14722d6ee7e9be014c383d24a F src/tclsqlite.c b82e4faeae89fdb7304b3c970979ade299336a1f F src/test1.c 41eabe255970ef947263b94145c9b2766bab8675 @@ -51,7 +51,7 @@ F src/update.c f9f48e78c13c79e32a55840414bea84479f9848d F src/util.c 8e9ca72d8288cae39c57c6f397abd14a56b14a38 F src/vdbe.c b27b256a5930da1e8fc347a272357be72de0f853 F src/vdbe.h e5cc6fb13d1905a4339db4d6dba4ab393c0765fa -F src/where.c ed7343344a30d62eb91464f1580490b80a6275ac +F src/where.c a9b286ac7323e7ebed5d3d217b3963acf1e6a355 F test/all.test 2a51e5395ac7c2c539689b123b9782a05e3837fe F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578 F test/btree.test 6ab4dc5f595905a276ef588fad3c9236dc07a47b @@ -89,7 +89,7 @@ F test/tableapi.test 51d0c209aa6b1158cb952ec917c656d4ce66e9e4 F test/tclsqlite.test feca0f2b23ba51d202d67d71e10ba7a8a1621f82 F test/temptable.test 37acd9e39781c2ff7cff2ba741b6b27ce020a44a F test/tester.tcl 96db1b49157388edb57e11bf33285e3811a897e4 -F test/trans.test 855337b8a178c73c433fcf8ee88e4b2f5efff0d9 +F test/trans.test 5f8543d3df10600b36732ebed5b46030073913a1 F test/unique.test 07776624b82221a80c8b4138ce0dd8b0853bb3ea F test/update.test 3cf1ca0565f678063c2dfa9a7948d2d66ae1a778 F test/vacuum.test 8acf8669f3b627e54149b25165b034aa06c2432e @@ -105,7 +105,7 @@ F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4 F www/arch.tcl 72a0c80e9054cc7025a50928d28d9c75c02c2b8b F www/c_interface.tcl 9123810452845783fac8e3184929463d9e70d609 -F www/changes.tcl 9bb023d26ece0f6083816beb29ff03d17eeb7977 +F www/changes.tcl 9419dcf548bcdd46e85ec07b72447c8b53d495c9 F www/crosscompile.tcl 3622ebbe518927a3854a12de51344673eb2dd060 F www/download.tcl 1ea61f9d89a2a5a9b2cee36b0d5cf97321bdefe0 F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c @@ -119,7 +119,7 @@ F www/speed.tcl 83457b2bf6bb430900bd48ca3dd98264d9a916a5 F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279 F www/tclsqlite.tcl 880ef67cb4f2797b95bf1368fc4e0d8ca0fda956 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 -P 7910bc7885ddbd90400c3c50014bba499e34d53d -R 4c30dbc37ad8cfa8a80bc76fe7f8ae94 +P 7deb62241300ff23af5a78dd855f0f69e5f16ffd +R 4f050fe6f09f01448c2bd7cd3c521994 U drh -Z 041af271d808d5bcd7b358a0634b5942 +Z 333823479478d2952c0013142638bffb diff --git a/manifest.uuid b/manifest.uuid index 401947eede..abaa464520 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7deb62241300ff23af5a78dd855f0f69e5f16ffd \ No newline at end of file +b3656a5cfef91c89de2cbb9790087d0d53c03e6f \ No newline at end of file diff --git a/src/build.c b/src/build.c index 32e7e5fa42..bb8f3053ba 100644 --- a/src/build.c +++ b/src/build.c @@ -25,7 +25,7 @@ ** ROLLBACK ** PRAGMA ** -** $Id: build.c,v 1.61 2001/12/22 14:49:25 drh Exp $ +** $Id: build.c,v 1.62 2002/01/09 03:20:00 drh Exp $ */ #include "sqliteInt.h" #include @@ -146,7 +146,7 @@ void sqliteExprDelete(Expr *p){ */ Table *sqliteFindTable(sqlite *db, char *zName){ Table *p = sqliteHashFind(&db->tblHash, zName, strlen(zName)+1); - return (p==0 || p->isDelete) ? 0 : p; + return p; } /* @@ -156,22 +156,25 @@ Table *sqliteFindTable(sqlite *db, char *zName){ */ Index *sqliteFindIndex(sqlite *db, char *zName){ Index *p = sqliteHashFind(&db->idxHash, zName, strlen(zName)+1); - return (p==0 || p->isDelete) ? 0 : p; + return p; } /* ** Remove the given index from the index hash table, and free ** its memory structures. ** -** The index is removed from the database hash table if db!=NULL. +** The index is removed from the database hash tables if db!=NULL. ** 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){ - if( pIndex->zName && db ){ - sqliteHashInsert(&db->idxHash, pIndex->zName, strlen(pIndex->zName)+1, 0); +static void sqliteDeleteIndex(sqlite *db, Index *p){ + if( p->zName && db ){ + Index *pOld; + pOld = sqliteHashInsert(&db->idxHash, p->zName, strlen(p->zName)+1, 0); + assert( pOld==0 || pOld==p ); + sqliteHashInsert(&db->idxDrop, p, 0, 0); } - sqliteFree(pIndex); + sqliteFree(p); } /* @@ -192,6 +195,27 @@ void sqliteUnlinkAndDeleteIndex(sqlite *db, Index *pIndex){ sqliteDeleteIndex(db, pIndex); } +/* +** Move the given index to the pending DROP INDEX queue if it has +** been committed. If this index was never committed, then just +** delete it. +** +** Indices on the pending drop queue are deleted when a COMMIT is +** executed. If a ROLLBACK occurs, the indices are moved back into +** the main index hash table. +*/ +void sqlitePendingDropIndex(sqlite *db, Index *p){ + if( !p->isCommit ){ + sqliteUnlinkAndDeleteIndex(db, p); + }else{ + Index *pOld; + pOld = sqliteHashInsert(&db->idxHash, p->zName, strlen(p->zName)+1, 0); + assert( pOld==p ); + sqliteHashInsert(&db->idxDrop, p, 0, p); + p->isDropped = 1; + } +} + /* ** Remove the memory data structures associated with the given ** Table. No changes are made to disk by this routine. @@ -225,13 +249,42 @@ void sqliteDeleteTable(sqlite *db, Table *pTable){ /* ** Unlink the given table from the hash tables and the delete the -** table structure and all its indices. +** table structure with all its indices. */ -static void sqliteUnlinkAndDeleteTable(sqlite *db, Table *pTable){ - if( pTable->zName && db ){ - sqliteHashInsert(&db->tblHash, pTable->zName, strlen(pTable->zName)+1, 0); +static void sqliteUnlinkAndDeleteTable(sqlite *db, Table *p){ + if( p->zName && db ){ + Table *pOld; + pOld = sqliteHashInsert(&db->tblHash, p->zName, strlen(p->zName)+1, 0); + assert( pOld==0 || pOld==p ); + sqliteHashInsert(&db->tblDrop, p, 0, 0); + } + sqliteDeleteTable(db, p); +} + +/* +** Move the given table to the pending DROP TABLE queue if it has +** been committed. If this table was never committed, then just +** delete it. Do the same for all its indices. +** +** Table on the drop queue are not actually deleted until a COMMIT +** statement is executed. If a ROLLBACK occurs instead of a COMMIT, +** then the tables on the drop queue are moved back into the main +** hash table. +*/ +void sqlitePendingDropTable(sqlite *db, Table *pTbl){ + if( !pTbl->isCommit ){ + sqliteUnlinkAndDeleteTable(db, pTbl); + }else{ + Table *pOld; + Index *pIndex, *pNext; + pOld = sqliteHashInsert(&db->tblHash, pTbl->zName, strlen(pTbl->zName)+1,0); + assert( pOld==pTbl ); + sqliteHashInsert(&db->tblDrop, pTbl, 0, pTbl); + for(pIndex = pTbl->pIndex; pIndex; pIndex=pNext){ + pNext = pIndex->pNext; + sqlitePendingDropIndex(db, pIndex); + } } - sqliteDeleteTable(db, pTable); } /* @@ -241,45 +294,34 @@ static void sqliteUnlinkAndDeleteTable(sqlite *db, Table *pTable){ ** When executing CREATE TABLE and CREATE INDEX statements, the Table ** and Index structures are created and added to the hash tables, but ** the "isCommit" field is not set. This routine sets those fields. -** When executing DROP TABLE and DROP INDEX, the "isDelete" fields of -** Table and Index structures is set but the structures are not unlinked -** from the hash tables nor deallocated. This routine handles that -** deallocation. +** When executing DROP TABLE and DROP INDEX, the table or index structures +** are moved out of tblHash and idxHash into tblDrop and idxDrop. This +** routine deletes the structure in tblDrop and idxDrop. ** ** See also: sqliteRollbackInternalChanges() */ void sqliteCommitInternalChanges(sqlite *db){ - Hash toDelete; HashElem *pElem; if( (db->flags & SQLITE_InternChanges)==0 ) return; - sqliteHashInit(&toDelete, SQLITE_HASH_POINTER, 0); db->schema_cookie = db->next_cookie; for(pElem=sqliteHashFirst(&db->tblHash); pElem; pElem=sqliteHashNext(pElem)){ Table *pTable = sqliteHashData(pElem); - if( pTable->isDelete ){ - sqliteHashInsert(&toDelete, pTable, 0, pTable); - }else{ - pTable->isCommit = 1; - } + pTable->isCommit = 1; } - for(pElem=sqliteHashFirst(&toDelete); pElem; pElem=sqliteHashNext(pElem)){ + for(pElem=sqliteHashFirst(&db->tblDrop); pElem; pElem=sqliteHashNext(pElem)){ Table *pTable = sqliteHashData(pElem); - sqliteUnlinkAndDeleteTable(db, pTable); + sqliteDeleteTable(db, pTable); } - sqliteHashClear(&toDelete); + sqliteHashClear(&db->tblDrop); for(pElem=sqliteHashFirst(&db->idxHash); pElem; pElem=sqliteHashNext(pElem)){ Index *pIndex = sqliteHashData(pElem); - if( pIndex->isDelete ){ - sqliteHashInsert(&toDelete, pIndex, 0, pIndex); - }else{ - pIndex->isCommit = 1; - } + pIndex->isCommit = 1; } - for(pElem=sqliteHashFirst(&toDelete); pElem; pElem=sqliteHashNext(pElem)){ + while( (pElem=sqliteHashFirst(&db->idxDrop))!=0 ){ Index *pIndex = sqliteHashData(pElem); sqliteUnlinkAndDeleteIndex(db, pIndex); } - sqliteHashClear(&toDelete); + sqliteHashClear(&db->idxDrop); db->flags &= ~SQLITE_InternChanges; } @@ -301,8 +343,6 @@ void sqliteRollbackInternalChanges(sqlite *db){ Table *pTable = sqliteHashData(pElem); if( !pTable->isCommit ){ sqliteHashInsert(&toDelete, pTable, 0, pTable); - }else{ - pTable->isDelete = 0; } } for(pElem=sqliteHashFirst(&toDelete); pElem; pElem=sqliteHashNext(pElem)){ @@ -310,12 +350,17 @@ void sqliteRollbackInternalChanges(sqlite *db){ sqliteUnlinkAndDeleteTable(db, pTable); } sqliteHashClear(&toDelete); + for(pElem=sqliteHashFirst(&db->tblDrop); pElem; pElem=sqliteHashNext(pElem)){ + Table *pOld, *p = sqliteHashData(pElem); + assert( p->isCommit ); + pOld = sqliteHashInsert(&db->tblHash, p->zName, strlen(p->zName)+1, p); + assert( pOld==0 || pOld==p ); + } + sqliteHashClear(&db->tblDrop); for(pElem=sqliteHashFirst(&db->idxHash); pElem; pElem=sqliteHashNext(pElem)){ Index *pIndex = sqliteHashData(pElem); if( !pIndex->isCommit ){ sqliteHashInsert(&toDelete, pIndex, 0, pIndex); - }else{ - pIndex->isDelete = 0; } } for(pElem=sqliteHashFirst(&toDelete); pElem; pElem=sqliteHashNext(pElem)){ @@ -323,6 +368,14 @@ void sqliteRollbackInternalChanges(sqlite *db){ sqliteUnlinkAndDeleteIndex(db, pIndex); } sqliteHashClear(&toDelete); + for(pElem=sqliteHashFirst(&db->idxDrop); pElem; pElem=sqliteHashNext(pElem)){ + Index *pOld, *p = sqliteHashData(pElem); + assert( p->isCommit ); + p->isDropped = 0; + pOld = sqliteHashInsert(&db->idxHash, p->zName, strlen(p->zName)+1, p); + assert( pOld==0 || pOld==p ); + } + sqliteHashClear(&db->idxDrop); db->flags &= ~SQLITE_InternChanges; } @@ -640,7 +693,7 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){ Table *pOld; pOld = sqliteHashInsert(&db->tblHash, p->zName, strlen(p->zName)+1, p); if( pOld ){ - assert( p==pOld ); /* Malloc must have failed */ + assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ return; } pParse->pNewTable = 0; @@ -776,14 +829,16 @@ void sqliteDropTable(Parse *pParse, Token *pName){ } } - /* Mark the in-memory Table structure as being deleted. The actually - ** deletion occurs inside of sqliteCommitInternalChanges(). + /* Move the table (and all its indices) to the pending DROP queue. + ** Or, if the table was never committed, just delete it. If the table + ** has been committed and is placed on the pending DROP queue, then the + ** delete will occur when sqliteCommitInternalChanges() executes. ** ** Exception: if the SQL statement began with the EXPLAIN keyword, ** then no changes should be made. */ if( !pParse->explain ){ - pTable->isDelete = 1; + sqlitePendingDropTable(db, pTable); db->flags |= SQLITE_InternChanges; } } @@ -1066,7 +1121,8 @@ exit_create_index: } /* -** This routine will drop an existing named index. +** This routine will drop an existing named index. This routine +** implements the DROP INDEX statement. */ void sqliteDropIndex(Parse *pParse, Token *pName){ Index *pIndex; @@ -1123,11 +1179,14 @@ void sqliteDropIndex(Parse *pParse, Token *pName){ } } - /* Mark the internal Index structure for deletion by the - ** sqliteCommitInternalChanges routine. + /* Move the index onto the pending DROP queue. Or, if the index was + ** never committed, just delete it. Indices on the pending DROP queue + ** get deleted by sqliteCommitInternalChanges() when the user executes + ** a COMMIT. Or if a rollback occurs, the elements of the DROP queue + ** are moved back into the main hash table. */ if( !pParse->explain ){ - pIndex->isDelete = 1; + sqlitePendingDropIndex(db, pIndex); db->flags |= SQLITE_InternChanges; } } diff --git a/src/main.c b/src/main.c index 34ec6963cc..5a6118afd7 100644 --- a/src/main.c +++ b/src/main.c @@ -14,7 +14,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.53 2002/01/06 17:07:40 drh Exp $ +** $Id: main.c,v 1.54 2002/01/09 03:20:00 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -268,6 +268,8 @@ sqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){ if( db==0 ) goto no_mem_on_open; sqliteHashInit(&db->tblHash, SQLITE_HASH_STRING, 0); sqliteHashInit(&db->idxHash, SQLITE_HASH_STRING, 0); + sqliteHashInit(&db->tblDrop, SQLITE_HASH_POINTER, 0); + sqliteHashInit(&db->idxDrop, SQLITE_HASH_POINTER, 0); db->nextRowid = sqliteRandomInteger(); /* Open the backend database driver */ @@ -318,6 +320,8 @@ no_mem_on_open: static void clearHashTable(sqlite *db, int preserveTemps){ HashElem *pElem; Hash temp1; + assert( sqliteHashFirst(&db->tblDrop)==0 ); /* There can not be uncommitted */ + assert( sqliteHashFirst(&db->idxDrop)==0 ); /* DROP TABLEs or DROP INDEXs */ temp1 = db->tblHash; sqliteHashInit(&db->tblHash, SQLITE_HASH_STRING, 0); sqliteHashClear(&db->idxHash); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 871fbf1375..1e49e61a5f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.75 2002/01/06 17:07:40 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.76 2002/01/09 03:20:00 drh Exp $ */ #include "sqlite.h" #include "hash.h" @@ -179,6 +179,8 @@ struct sqlite { int (*xBusyCallback)(void *,const char*,int); /* The busy callback */ Hash tblHash; /* All tables indexed by name */ Hash idxHash; /* All (named) indices indexed by name */ + Hash tblDrop; /* Uncommitted DROP TABLEs */ + Hash idxDrop; /* Uncommitted DROP INDEXs */ int nextRowid; /* Next generated rowID */ }; @@ -228,7 +230,6 @@ struct Table { int tnum; /* Page containing root for this table */ u8 readOnly; /* True if this table should not be written by the user */ u8 isCommit; /* True if creation of this table has been committed */ - u8 isDelete; /* True if this table is being deleted */ u8 isTemp; /* True if stored in db->pBeTemp instead of db->pBe */ u8 hasPrimKey; /* True if there exists a primary key */ }; @@ -260,7 +261,7 @@ struct Index { int tnum; /* Page containing root of this index in database file */ u8 isUnique; /* True if keys must all be unique */ u8 isCommit; /* True if creation of this index has been committed */ - u8 isDelete; /* True if deletion of this index has not been comitted */ + u8 isDropped; /* True if a DROP INDEX has executed on this index */ Index *pNext; /* The next index associated with the same table */ }; diff --git a/src/where.c b/src/where.c index 33a5b174b6..526f2aeed2 100644 --- a/src/where.c +++ b/src/where.c @@ -13,7 +13,7 @@ ** the WHERE clause of SQL statements. Also found here are subroutines ** to generate VDBE code to evaluate expressions. ** -** $Id: where.c,v 1.31 2002/01/06 17:07:41 drh Exp $ +** $Id: where.c,v 1.32 2002/01/09 03:20:00 drh Exp $ */ #include "sqliteInt.h" @@ -302,6 +302,7 @@ WhereInfo *sqliteWhereBegin( int gtMask = 0; /* Index columns covered by an x>... constraing */ int nEq, m, score; + if( pIdx->isDropped ) continue; /* Ignore dropped indices */ if( pIdx->nColumn>32 ) continue; /* Ignore indices too many columns */ for(j=0; j

" } -chng {2002 Jan 4 (2.2.1)} { +chng {2002 Jan 8 (2.2.1)} {
  • Bug fix: An attempt to delete a single row of a table with a WHERE clause of "ROWID=x" when no such rowid exists was causing an error.
  • Bug fix: Passing in a NULL as the 3rd parameter to sqlite_open() would sometimes cause a coredump.
  • +
  • Bug fix: DROP TABLE followed by a CREATE TABLE with the same name all + within a single transaction was causing a coredump.
  • +
  • Makefile updates from A. Rottmann
  • } chng {2001 Dec 22 (2.2.0)} {