]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Working on a bug: Dropping and recreating a table within a transaction
authordrh <drh@noemail.net>
Wed, 9 Jan 2002 03:19:59 +0000 (03:19 +0000)
committerdrh <drh@noemail.net>
Wed, 9 Jan 2002 03:19:59 +0000 (03:19 +0000)
causes an assertion failure. (CVS 342)

FossilOrigin-Name: b3656a5cfef91c89de2cbb9790087d0d53c03e6f

Makefile.in
manifest
manifest.uuid
src/build.c
src/main.c
src/sqliteInt.h
src/where.c
test/trans.test
www/changes.tcl

index acde6d3380faf33d69ba2402a8416713b4faad23..ce21097db75328010df2fb865e57f3c4595584a5 100644 (file)
@@ -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
index 0d468a765928bf6463a8ea33d581d7d19eff32a8..ae21b2f2ba58b0059eec52c211fd476cdbb529ab 100644 (file)
--- 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
index 401947eedef8794d5088a68093dd04c3faa1a9bc..abaa4645200ac31d048702c4d76e6a134f352c72 100644 (file)
@@ -1 +1 @@
-7deb62241300ff23af5a78dd855f0f69e5f16ffd
\ No newline at end of file
+b3656a5cfef91c89de2cbb9790087d0d53c03e6f
\ No newline at end of file
index 32e7e5fa42965cfc1213725fa03fc8ae064a8ba9..bb8f3053ba5b6631645c33e2164d5ff1065734e6 100644 (file)
@@ -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 <ctype.h>
@@ -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 *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.
 */
-static void sqliteUnlinkAndDeleteTable(sqlite *db, Table *pTable){
-  if( pTable->zName && db ){
-    sqliteHashInsert(&db->tblHash, pTable->zName, strlen(pTable->zName)+1, 0);
+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;
   }
 }
index 34ec6963cc67446336b9781da97faca42aa104aa..5a6118afd77896385dd2c63cc826b9881e043a40 100644 (file)
@@ -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);
index 871fbf1375f3194298641a17ac1686073833c25d..1e49e61a5febb0100bc3ed9b692bb4444d187d71 100644 (file)
@@ -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 */
 };
 
index 33a5b174b6662ef6d25a7ab9d5da1939891d6f59..526f2aeed223bcd15dddfabd27570b07712fceb9 100644 (file)
@@ -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<nExpr; j++){
         if( aExpr[j].idxLeft==idx 
index 1c33e6dcd0af3893b2e10760f6aaeec908425c5b..ae0a4808f73442ead024872565f5297a105e00b0 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this script is database locks.
 #
-# $Id: trans.test,v 1.7 2001/09/24 03:12:41 drh Exp $
+# $Id: trans.test,v 1.8 2002/01/09 03:20:00 drh Exp $
 
 
 set testdir [file dirname $argv0]
@@ -406,4 +406,129 @@ do_test trans-5.23 {
   }
 } {1 2 3}
 
+# Try to DROP and CREATE tables and indices with the same name
+# within a transaction.  Make sure ROLLBACK works.
+#
+do_test trans-6.1 {
+  execsql2 {
+    INSERT INTO t1 VALUES(1,2,3);
+    BEGIN TRANSACTION;
+    DROP TABLE t1;
+    CREATE TABLE t1(p,q,r);
+    ROLLBACK;
+    SELECT * FROM t1;
+  }
+} {a 1 b 2 c 3}
+do_test trans-6.2 {
+  execsql2 {
+    INSERT INTO t1 VALUES(1,2,3);
+    BEGIN TRANSACTION;
+    DROP TABLE t1;
+    CREATE TABLE t1(p,q,r);
+    COMMIT;
+    SELECT * FROM t1;
+  }
+} {}
+do_test trans-6.3 {
+  execsql2 {
+    INSERT INTO t1 VALUES(1,2,3);
+    SELECT * FROM t1;
+  }
+} {p 1 q 2 r 3}
+do_test trans-6.4 {
+  execsql2 {
+    BEGIN TRANSACTION;
+    DROP TABLE t1;
+    CREATE TABLE t1(a,b,c);
+    INSERT INTO t1 VALUES(4,5,6);
+    SELECT * FROM t1;
+    DROP TABLE t1;
+  }
+} {a 4 b 5 c 6}
+do_test trans-6.5 {
+  execsql2 {
+    ROLLBACK;
+    SELECT * FROM t1;
+  }
+} {p 1 q 2 r 3}
+do_test trans-6.6 {
+  execsql2 {
+    BEGIN TRANSACTION;
+    DROP TABLE t1;
+    CREATE TABLE t1(a,b,c);
+    INSERT INTO t1 VALUES(4,5,6);
+    SELECT * FROM t1;
+    DROP TABLE t1;
+  }
+} {a 4 b 5 c 6}
+do_test trans-6.7 {
+  catchsql {
+    COMMIT;
+    SELECT * FROM t1;
+  }
+} {1 {no such table: t1}}
+
+do_test trans-6.8 {
+  execsql {
+    CREATE TABLE t1(a integer primary key,b,c);
+    INSERT INTO t1 VALUES(1,-2,-3);
+    INSERT INTO t1 VALUES(4,-5,-6);
+    SELECT * FROM t1;
+  }
+} {1 -2 -3 4 -5 -6}
+do_test trans-6.9 {
+  execsql {
+    CREATE INDEX i1 ON t1(b);
+    SELECT * FROM t1 WHERE b<1;
+  }
+} {4 -5 -6 1 -2 -3}
+do_test trans-6.10 {
+  execsql {
+    BEGIN TRANSACTION;
+    DROP INDEX i1;
+    SELECT * FROM t1 WHERE b<1;
+    ROLLBACK;
+  }
+} {1 -2 -3 4 -5 -6}
+do_test trans-6.11 {
+  execsql {
+    SELECT * FROM t1 WHERE b<1;
+  }
+} {4 -5 -6 1 -2 -3}
+do_test trans-6.12 {
+  execsql {
+    BEGIN TRANSACTION;
+    DROP TABLE t1;
+    ROLLBACK;
+    SELECT * FROM t1 WHERE b<1;
+  }
+} {4 -5 -6 1 -2 -3}
+
+do_test trans-6.13 {
+  execsql {
+    BEGIN TRANSACTION;
+    DROP INDEX i1;
+    CREATE INDEX i1 ON t1(c);
+    SELECT * FROM t1 WHERE b<1;
+  }
+} {1 -2 -3 4 -5 -6}
+do_test trans-6.14 {
+  execsql {
+    SELECT * FROM t1 WHERE c<1;
+  }
+} {4 -5 -6 1 -2 -3}
+do_test trans-6.15 {
+  execsql {
+    ROLLBACK;
+    SELECT * FROM t1 WHERE b<1;
+  }
+} {4 -5 -6 1 -2 -3}
+do_test trans-6.16 {
+  execsql {
+    SELECT * FROM t1 WHERE c<1;
+  }
+} {1 -2 -3 4 -5 -6}
+
+
+
 finish_test
index 0d1e97e5429922eec28a78f3283b26d4099c8658..abfe67690be6c495c7dadb5b6acbee0addf3c473 100644 (file)
@@ -17,11 +17,14 @@ proc chng {date desc} {
   puts "<DD><P><UL>$desc</UL></P></DD>"
 }
 
-chng {2002 Jan 4 (2.2.1)} {
+chng {2002 Jan 8 (2.2.1)} {
 <li>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.</li>
 <li>Bug fix: Passing in a NULL as the 3rd parameter to <b>sqlite_open()</b>
     would sometimes cause a coredump.</li>
+<li>Bug fix: DROP TABLE followed by a CREATE TABLE with the same name all
+    within a single transaction was causing a coredump.</li>
+<li>Makefile updates from A. Rottmann</li>
 }
 
 chng {2001 Dec 22 (2.2.0)} {