]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Allow DROP TABLE and DROP INDEX on attached databases. (CVS 1484)
authordanielk1977 <danielk1977@noemail.net>
Fri, 28 May 2004 12:11:21 +0000 (12:11 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Fri, 28 May 2004 12:11:21 +0000 (12:11 +0000)
FossilOrigin-Name: 2fb3708e10a06660ad1974ef8e9742b706a0a9fc

manifest
manifest.uuid
src/build.c
src/parse.y
src/sqliteInt.h
test/attach3.test

index 59832ebaa17235fbf58a269aa36905419cd2684d..d3c188b5b18a29a728294ea53677dcb387cddfc1 100644 (file)
--- 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
index f4fb81848f2ad85198beaddb8cf0ef4d9895c29f..eccb5dbcfb6b334f81999ea57f10127cee879342 100644 (file)
@@ -1 +1 @@
-4984a130ccf3b8e486941a5d0d0cc70a691f0dac
\ No newline at end of file
+2fb3708e10a06660ad1974ef8e9742b706a0a9fc
\ No newline at end of file
index fb0aec4a5691ae75ebbac3faeae32571580a0333..d3b9cb709cd85b8a0b38169da4d58296fdacef5e 100644 (file)
@@ -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 <ctype.h>
@@ -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 && iDb<db->nDb );
 #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;
index fc14b5d605219f34cefbb2af25c618bc53752c58..7681ebc41daa0b352a43346db863e816ae7402f3 100644 (file)
@@ -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 /////////////////////////////
 //
index 7f77a47bb7f74ce2fcbf2f434db0e8145ff7ca53..37c94ec08b70f2d80b9109150bbef5ddc6b57266 100644 (file)
@@ -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*);
index 06ccbffc7405c7bc2dff4150d859f0b76d5f881b..897e8ea0bb4bc3132fc0f9e4e524549bb65d9c50 100644 (file)
@@ -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