Allow DROP TABLE and DROP INDEX on attached databases. (CVS 1484)
FossilOrigin-Name: 2fb3708e10a06660ad1974ef8e9742b706a0a9fc
This commit is contained in:
parent
cbb18d2256
commit
a8858103c9
18
manifest
18
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
|
||||
|
@ -1 +1 @@
|
||||
4984a130ccf3b8e486941a5d0d0cc70a691f0dac
|
||||
2fb3708e10a06660ad1974ef8e9742b706a0a9fc
|
79
src/build.c
79
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 <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;
|
||||
|
@ -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 /////////////////////////////
|
||||
//
|
||||
|
@ -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*);
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user