diff --git a/manifest b/manifest index 59832ebaa1..d3c188b5b1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sCREATE\sTABLE\sand\sCREATE\sINDEX\son\sattached\sdatabases.\s(CVS\s1483) -D 2004-05-28T11:37:27 +C Allow\sDROP\sTABLE\sand\sDROP\sINDEX\son\sattached\sdatabases.\s(CVS\s1484) +D 2004-05-28T12:11:21 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -26,7 +26,7 @@ F src/attach.c c315c58cb16fd6e913b3bfa6412aedecb4567fa5 F src/auth.c 5c2f0bea4729c98c2be3b69d6b466fc51448fe79 F src/btree.c 6db76fbf63efd6008c5e6cb038ea40f94abffcf7 F src/btree.h b65140b5ae891f30d2a39e64b9f0343225553545 -F src/build.c 7ae5b3efeb30c7bd9e74d0ef6f41c2aa43d9c586 +F src/build.c ebb6746232d4ff01555a103e69bf8740b13ca5b4 F src/date.c 0eb922af5c5f5e2455f8dc2f98023ed3e04a857e F src/delete.c 66c5ab98cbad7e6b315fc997bfe6c8080784a701 F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37 @@ -48,14 +48,14 @@ F src/os_win.c 92b51a38437b98d8aa3ac05b57c71e1d1092e5be F src/os_win.h 5d41af24caaef6c13a2d8e2399caa1c57d45c84d F src/pager.c 6ff6b906427d4824099140776cb8768f922f3dc5 F src/pager.h 78a00ac280899bcba1a89dc51585dcae6b7b3253 -F src/parse.y 1ab0393a97a17fa528b6762e14912d6ed982a28a +F src/parse.y 32d6d4b20926ef4bf2f2243e8d7009856332553c F src/pragma.c f2b05b087a5764802296a28d7abdd75728beedee F src/printf.c ef750e8e2398ca7e8b58be991075f08c6a7f0e53 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 F src/select.c 26f726b398af8708c81178acc9c68d64e78e6f5e F src/shell.c ed4d237b3e52a0a42512bfcc53530e46de20c28f F src/sqlite.h.in edc6408c7f53c2104f781a76b926036e17018ec9 -F src/sqliteInt.h a52ac00d36fd231068c92df169474c473a5b4a61 +F src/sqliteInt.h 582a4c482e4935ea99a57b6c89f4c423990e66aa F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2 F src/tclsqlite.c 877d0b96013a25b03ed6bd2d32917c42e84403bc F src/test1.c 32934478366531503d634968db414df17cb38238 @@ -79,7 +79,7 @@ F src/where.c efe5d25fe18cd7381722457898cd863e84097a0c F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242 F test/attach.test cb9b884344e6cfa5e165965d5b1adea679a24c83 F test/attach2.test 5472d442bb2ef1ee587e0ae7472bb68b52509a38 -F test/attach3.test 2cdfb3933e89a2336f68396f7505aa8dfcb88e9c +F test/attach3.test abf067bfc6a6051cc250f5c9a814cebeb23e5c54 F test/auth.test 95809b8f6a9bec18b94d28cafd03fe27d2f8a9e9 F test/bigfile.test ea904b853ce2d703b16c5ce90e2b54951bc1ae81 F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578 @@ -204,7 +204,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P 1b15b32bdbccae555243e67aa011139c50dc2fb3 -R c5dc6cd70bfe11dc9fe64e163f737f43 +P 4984a130ccf3b8e486941a5d0d0cc70a691f0dac +R f6ec791bb07b629b8edefb69fa686613 U danielk1977 -Z d391601bb46c037bdbb5671f03408a15 +Z 196ddec31e4f147783f673bcab20af4a diff --git a/manifest.uuid b/manifest.uuid index f4fb81848f..eccb5dbcfb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4984a130ccf3b8e486941a5d0d0cc70a691f0dac \ No newline at end of file +2fb3708e10a06660ad1974ef8e9742b706a0a9fc \ No newline at end of file diff --git a/src/build.c b/src/build.c index fb0aec4a56..d3b9cb709c 100644 --- a/src/build.c +++ b/src/build.c @@ -23,7 +23,7 @@ ** ROLLBACK ** PRAGMA ** -** $Id: build.c,v 1.194 2004/05/28 11:37:27 danielk1977 Exp $ +** $Id: build.c,v 1.195 2004/05/28 12:11:21 danielk1977 Exp $ */ #include "sqliteInt.h" #include @@ -1328,25 +1328,27 @@ Table *sqlite3TableFromToken(Parse *pParse, Token *pTok){ ** This routine is called to do the work of a DROP TABLE statement. ** pName is the name of the table to be dropped. */ -void sqlite3DropTable(Parse *pParse, Token *pName, int isView){ - Table *pTable; +void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){ + Table *pTab; Vdbe *v; int base; sqlite *db = pParse->db; int iDb; - if( pParse->nErr || sqlite3_malloc_failed ) return; - pTable = sqlite3TableFromToken(pParse, pName); - if( pTable==0 ) return; - iDb = pTable->iDb; + if( pParse->nErr || sqlite3_malloc_failed ) goto exit_drop_table; + assert( pName->nSrc==1 ); + pTab = sqlite3LocateTable(pParse, pName->a[0].zName, pName->a[0].zDatabase); + + if( pTab==0 ) goto exit_drop_table; + iDb = pTab->iDb; assert( iDb>=0 && iDbnDb ); #ifndef SQLITE_OMIT_AUTHORIZATION { int code; - const char *zTab = SCHEMA_TABLE(pTable->iDb); - const char *zDb = db->aDb[pTable->iDb].zName; + const char *zTab = SCHEMA_TABLE(pTab->iDb); + const char *zDb = db->aDb[pTab->iDb].zName; if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){ - return; + goto exit_drop_table; } if( isView ){ if( iDb==1 ){ @@ -1361,26 +1363,26 @@ void sqlite3DropTable(Parse *pParse, Token *pName, int isView){ code = SQLITE_DROP_TABLE; } } - if( sqlite3AuthCheck(pParse, code, pTable->zName, 0, zDb) ){ - return; + if( sqlite3AuthCheck(pParse, code, pTab->zName, 0, zDb) ){ + goto exit_drop_table; } - if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTable->zName, 0, zDb) ){ - return; + if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){ + goto exit_drop_table; } } #endif - if( pTable->readOnly ){ - sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTable->zName); + if( pTab->readOnly ){ + sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName); pParse->nErr++; - return; + goto exit_drop_table; } - if( isView && pTable->pSelect==0 ){ - sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTable->zName); - return; + if( isView && pTab->pSelect==0 ){ + sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName); + goto exit_drop_table; } - if( !isView && pTable->pSelect ){ - sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTable->zName); - return; + if( !isView && pTab->pSelect ){ + sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName); + goto exit_drop_table; } /* Generate code to remove the table from the master table @@ -1402,39 +1404,39 @@ void sqlite3DropTable(Parse *pParse, Token *pName, int isView){ }; Index *pIdx; Trigger *pTrigger; - sqlite3BeginWriteOperation(pParse, 0, pTable->iDb); + sqlite3BeginWriteOperation(pParse, 0, pTab->iDb); /* Drop all triggers associated with the table being dropped */ - pTrigger = pTable->pTrigger; + pTrigger = pTab->pTrigger; while( pTrigger ){ - assert( pTrigger->iDb==pTable->iDb || pTrigger->iDb==1 ); + assert( pTrigger->iDb==pTab->iDb || pTrigger->iDb==1 ); sqlite3DropTriggerPtr(pParse, pTrigger, 1); if( pParse->explain ){ pTrigger = pTrigger->pNext; }else{ - pTrigger = pTable->pTrigger; + pTrigger = pTab->pTrigger; } } /* Drop all SQLITE_MASTER entries that refer to the table */ - sqlite3OpenMasterTable(v, pTable->iDb); + sqlite3OpenMasterTable(v, pTab->iDb); base = sqlite3VdbeAddOpList(v, ArraySize(dropTable), dropTable); - sqlite3VdbeChangeP3(v, base+1, pTable->zName, 0); + sqlite3VdbeChangeP3(v, base+1, pTab->zName, 0); /* Drop all SQLITE_TEMP_MASTER entries that refer to the table */ - if( pTable->iDb!=1 ){ + if( pTab->iDb!=1 ){ sqlite3OpenMasterTable(v, 1); base = sqlite3VdbeAddOpList(v, ArraySize(dropTable), dropTable); - sqlite3VdbeChangeP3(v, base+1, pTable->zName, 0); + sqlite3VdbeChangeP3(v, base+1, pTab->zName, 0); } - if( pTable->iDb!=1 ){ /* Temp database has no schema cookie */ - sqlite3ChangeCookie(db, v, pTable->iDb); + if( pTab->iDb!=1 ){ /* Temp database has no schema cookie */ + sqlite3ChangeCookie(db, v, pTab->iDb); } sqlite3VdbeAddOp(v, OP_Close, 0, 0); if( !isView ){ - sqlite3VdbeAddOp(v, OP_Destroy, pTable->tnum, pTable->iDb); - for(pIdx=pTable->pIndex; pIdx; pIdx=pIdx->pNext){ + sqlite3VdbeAddOp(v, OP_Destroy, pTab->tnum, pTab->iDb); + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ sqlite3VdbeAddOp(v, OP_Destroy, pIdx->tnum, pIdx->iDb); } } @@ -1447,10 +1449,13 @@ void sqlite3DropTable(Parse *pParse, Token *pName, int isView){ ** then no changes should be made. */ if( !pParse->explain ){ - sqliteUnlinkAndDeleteTable(db, pTable); + sqliteUnlinkAndDeleteTable(db, pTab); db->flags |= SQLITE_InternChanges; } sqliteViewResetAll(db, iDb); + +exit_drop_table: + sqlite3SrcListDelete(pName); } /* @@ -1938,11 +1943,13 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName){ "or PRIMARY KEY constraint cannot be dropped", 0); goto exit_drop_index; } +/* if( pIndex->iDb>1 ){ sqlite3ErrorMsg(pParse, "cannot alter schema of attached " "databases", 0); goto exit_drop_index; } +*/ #ifndef SQLITE_OMIT_AUTHORIZATION { int code = SQLITE_DROP_INDEX; diff --git a/src/parse.y b/src/parse.y index fc14b5d605..7681ebc41d 100644 --- a/src/parse.y +++ b/src/parse.y @@ -14,7 +14,7 @@ ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** -** @(#) $Id: parse.y,v 1.120 2004/05/28 11:37:28 danielk1977 Exp $ +** @(#) $Id: parse.y,v 1.121 2004/05/28 12:11:21 danielk1977 Exp $ */ %token_prefix TK_ %token_type {Token} @@ -262,7 +262,9 @@ resolvetype(A) ::= REPLACE. { A = OE_Replace; } ////////////////////////// The DROP TABLE ///////////////////////////////////// // -cmd ::= DROP TABLE nm(X). {sqlite3DropTable(pParse,&X,0);} +cmd ::= DROP TABLE nm(X) dbnm(Y). { + sqlite3DropTable(pParse, sqlite3SrcListAppend(0,&X,&Y), 0); +} ///////////////////// The CREATE VIEW statement ///////////////////////////// // diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7f77a47bb7..37c94ec08b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.257 2004/05/28 11:37:28 danielk1977 Exp $ +** @(#) $Id: sqliteInt.h,v 1.258 2004/05/28 12:11:21 danielk1977 Exp $ */ #include "config.h" #include "sqlite.h" @@ -1211,7 +1211,7 @@ CollSeq *sqlite3ChangeCollatingFunction(sqlite*,const char*,int, void sqlite3EndTable(Parse*,Token*,Select*); void sqlite3CreateView(Parse*,Token*,Token*,Select*,int); int sqlite3ViewGetColumnNames(Parse*,Table*); -void sqlite3DropTable(Parse*, Token*, int); +void sqlite3DropTable(Parse*, SrcList*, int); void sqlite3DeleteTable(sqlite*, Table*); void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int); IdList *sqlite3IdListAppend(IdList*, Token*); diff --git a/test/attach3.test b/test/attach3.test index 06ccbffc74..897e8ea0bb 100644 --- a/test/attach3.test +++ b/test/attach3.test @@ -12,7 +12,7 @@ # focus of this script is testing the ATTACH and DETACH commands # and schema changes to attached databases. # -# $Id: attach3.test,v 1.1 2004/05/28 11:37:29 danielk1977 Exp $ +# $Id: attach3.test,v 1.2 2004/05/28 12:11:21 danielk1977 Exp $ # @@ -35,27 +35,27 @@ execsql { db2 close # Create a table in the auxilary database. -do_test attach3-1 { +do_test attach3-1.1 { execsql { ATTACH 'test2.db' AS aux; } } {} -do_test attach3-2 { +do_test attach3-1.2 { execsql { CREATE TABLE aux.t3(e, f); } } {} -do_test attach3-3 { +do_test attach3-1.3 { execsql { SELECT * FROM sqlite_master WHERE name = 't3'; } } {} -do_test attach3-4 { +do_test attach3-1.4 { execsql { SELECT * FROM aux.sqlite_master WHERE name = 't3'; } } {table t3 t3 4 {CREATE TABLE t3(e, f)}} -do_test attach3-5 { +do_test attach3-1.5 { execsql { INSERT INTO t3 VALUES(1, 2); SELECT * FROM t3; @@ -63,7 +63,7 @@ do_test attach3-5 { } {1 2} # Create an index on the auxilary database table. -do_test attach4-1 { +do_test attach4-2.1 { execsql { CREATE INDEX aux.i1 on t3(e); } @@ -71,17 +71,64 @@ do_test attach4-1 { execsql { pragma vdbe_trace = off; } -do_test attach4-2 { +do_test attach4-2.2 { execsql { SELECT * FROM sqlite_master WHERE name = 'i1'; } } {} -do_test attach4-3 { +do_test attach4-2.3 { execsql { SELECT * FROM aux.sqlite_master WHERE name = 'i1'; } } {index i1 t3 5 {CREATE INDEX i1 on t3(e)}} +# Drop the index on the aux database table. +do_test attach4-3.1 { + execsql { + DROP INDEX aux.i1; + SELECT * FROM aux.sqlite_master WHERE name = 'i1'; + } +} {} +do_test attach4-3.2 { + execsql { + CREATE INDEX aux.i1 on t3(e); + SELECT * FROM aux.sqlite_master WHERE name = 'i1'; + } +} {index i1 t3 5 {CREATE INDEX i1 on t3(e)}} +do_test attach4-3.3 { + execsql { + DROP INDEX i1; + SELECT * FROM aux.sqlite_master WHERE name = 'i1'; + } +} {} + +# Drop the tables in the auxilary database. +do_test attach4-4.1 { + execsql { + DROP TABLE aux.t1; + SELECT name FROM aux.sqlite_master; + } +} {t2 t3} +do_test attach4-4.2 { + # This will drop main.t2 + execsql { + DROP TABLE t2; + SELECT name FROM aux.sqlite_master; + } +} {t2 t3} +do_test attach4-4.3 { + execsql { + DROP TABLE t2; + SELECT name FROM aux.sqlite_master; + } +} {t3} +do_test attach4-4.4 { + execsql { + DROP TABLE aux.t3; + SELECT * FROM aux.sqlite_master; + } +} {} + finish_test