Allow DROP TABLE and DROP INDEX on attached databases. (CVS 1484)

FossilOrigin-Name: 2fb3708e10a06660ad1974ef8e9742b706a0a9fc
This commit is contained in:
danielk1977 2004-05-28 12:11:21 +00:00
parent cbb18d2256
commit a8858103c9
6 changed files with 115 additions and 59 deletions

View File

@ -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

View File

@ -1 +1 @@
4984a130ccf3b8e486941a5d0d0cc70a691f0dac
2fb3708e10a06660ad1974ef8e9742b706a0a9fc

View 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;

View 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 /////////////////////////////
//

View 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*);

View 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