diff --git a/manifest b/manifest index 57dca557ce..df046678e8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"ALTER\sTABLE\sxxx\sRENAME\sTO\syyy"\scommand.\s(CVS\s2092) -D 2004-11-12T13:42:31 +C Add\sauthorization\scallbacks\sto\sALTER\sTABLE.\s(CVS\s2093) +D 2004-11-12T15:53:37 F Makefile.in c4d2416860f472a1e3393714d0372074197565df F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457 F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1 @@ -31,7 +31,7 @@ F src/attach.c e49d09dad9f5f9fb10b4b0c1be5a70ae4c45e689 F src/auth.c 3b81f2a42f48a62c2c9c9b0eda31a157c681edea F src/btree.c 9fd74df65bad768a441afefc3b73174d45b85d5b F src/btree.h 861e40b759a195ba63819740e484390012cf81ab -F src/build.c cbd985e9d0168204fcca3e1123f0b7f621f402e6 +F src/build.c 45ba40523aa4f9130c5a5af8b7db5d0d878443a3 F src/date.c 4fd4e90b3880dacd67305e96330940dc243ffc10 F src/delete.c f0af21a1ede15524a5edd59fe10ef486283a1ee9 F src/expr.c 4ee3e47358c92a919062255b14057a7a8f641e01 @@ -60,11 +60,11 @@ F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 F src/select.c 156990c636102bb6b8de85e7ff3396a62568476b F src/shell.c 55adda3cf3c1cc2f6c1919aac17b2318f9c2a96f -F src/sqlite.h.in 4f97b5907acfd2a5068cb0cec9d5178816734db7 +F src/sqlite.h.in a44eac0716bf4751447160d5c8ed049ece66d45a F src/sqliteInt.h 8569ce94e891a854de71d7bd628da1d25ee6dfe4 F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9 -F src/tclsqlite.c 0302e3f42f015d132d1291f3388c06e86c24a008 -F src/test1.c e80e070fe794cdc204ec144ce03bd7b27dab4946 +F src/tclsqlite.c 7f1a1a678140e6901c8954590ca2aabe50b48f71 +F src/test1.c f4dca9e072971dd0207a2d09913da48dac7f7871 F src/test2.c b11fa244fff02190707dd0879987c37c75e61fc8 F src/test3.c 6f1ec93e13632a004b527049535079eda84c459d F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df @@ -83,11 +83,11 @@ F src/vdbeaux.c c6da55e0096e141211f918837eca98e0be6400b4 F src/vdbemem.c ef9ac7d32acfe4bce5c5b408b1294c8d9e0cdb56 F src/where.c 6e637a6b3e61fe3104adc4e5caa4738bf6570daa F test/all.test 929bfa932b55e75c96fe2203f7650ba451c1862c -F test/alter.test faf3440c4170033f5ea38d1343a0d82f4f3f7017 +F test/alter.test ea6b104fa83da6970b1ce61885827817bdaced3a F test/attach.test e305dd59a375e37c658c6d401f19f8a95880bf9a F test/attach2.test 399128a7b3b209a339a8dbf53ca2ed42eb982d1a F test/attach3.test 8a0309e284cf9aa1d7d6cc444989031881f7a21c -F test/auth.test 1cc252d9e7b3bdc1314199cbf3a0d3c5ed026c21 +F test/auth.test cf13e449cb253f75d6584b376202c94bbdd53ec9 F test/autovacuum.test e52b8fab3b82f6b51b7fde5b7140827ce8e86b1c F test/autovacuum_crash.test 2dca85cbcc497098e45e8847c86407eb3554f3d4 F test/bigfile.test d3744a8821ce9abb8697f2826a3e3d22b719e89f @@ -256,7 +256,7 @@ F www/tclsqlite.tcl 560ecd6a916b320e59f2917317398f3d59b7cc25 F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618 F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0 F www/whentouse.tcl fdacb0ba2d39831e8a6240d05a490026ad4c4e4c -P 8fde833c812b91c5a574208a70b5f92b9d4b0a87 -R 8245e15b31d6598597e65a4dce12b056 +P a1b2cc63e604785bd51e358ff72c485d858752e3 +R ef4bbd1e2466e0b000964937492388e1 U danielk1977 -Z 014cc6af755028b6df88d60e431d5a3f +Z f041132b38a543a682f3a1cb1fe1f777 diff --git a/manifest.uuid b/manifest.uuid index 09fe0612a5..4fa45a39fc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a1b2cc63e604785bd51e358ff72c485d858752e3 \ No newline at end of file +c4115aa3a1b010704af76c5ae9f6dcbfa4038df8 \ No newline at end of file diff --git a/src/build.c b/src/build.c index ab3877dab9..54568b7200 100644 --- a/src/build.c +++ b/src/build.c @@ -22,7 +22,7 @@ ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.277 2004/11/12 13:42:31 danielk1977 Exp $ +** $Id: build.c,v 1.278 2004/11/12 15:53:37 danielk1977 Exp $ */ #include "sqliteInt.h" #include @@ -2931,10 +2931,11 @@ void sqlite3AlterRenameTable( Token *pName /* The new table name. */ ){ int iDb; /* Database that contains the table */ + char *zDb; /* Name of database iDb */ Table *pTab; /* Table being renamed */ - sqlite3 *db = pParse->db; /* Database connection */ char *zName = 0; /* NULL-terminated version of pName */ char *zWhere = 0; /* Where clause of schema elements to reparse */ + sqlite3 *db = pParse->db; /* Database connection */ Vdbe *v; assert( pSrc->nSrc==1 ); @@ -2942,6 +2943,7 @@ void sqlite3AlterRenameTable( pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase); if( !pTab ) return; iDb = pTab->iDb; + zDb = db->aDb[iDb].zName; /* Get a NULL terminated version of the new table name. */ zName = sqlite3NameFromToken(pName); @@ -2950,20 +2952,30 @@ void sqlite3AlterRenameTable( /* Check that a table or index named 'zName' does not already exist ** in database iDb. If so, this is an error. */ - if( sqlite3FindTable(db, zName, db->aDb[iDb].zName) || - sqlite3FindIndex(db, zName, db->aDb[iDb].zName) ){ + if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){ sqlite3ErrorMsg(pParse, "there is already another table or index with this name: %s", zName); sqliteFree(zName); return; } +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Invoke the authorization callback. */ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ + sqliteFree(zName); + return; + } +#endif + /* Begin a transaction and code the VerifyCookie for database iDb. ** Then modify the schema cookie (since the ALTER TABLE modifies the ** schema). */ v = sqlite3GetVdbe(pParse); - if( v==0 ) return; + if( v==0 ){ + sqliteFree(zName); + return; + } sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3ChangeCookie(db, v, iDb); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index c39dcdf5a8..398995421d 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -12,7 +12,7 @@ ** This header file defines the interface that the SQLite library ** presents to client programs. ** -** @(#) $Id: sqlite.h.in,v 1.121 2004/10/06 15:52:01 drh Exp $ +** @(#) $Id: sqlite.h.in,v 1.122 2004/11/12 15:53:37 danielk1977 Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ @@ -428,6 +428,7 @@ int sqlite3_set_authorizer( #define SQLITE_UPDATE 23 /* Table Name Column Name */ #define SQLITE_ATTACH 24 /* Filename NULL */ #define SQLITE_DETACH 25 /* Database Name NULL */ +#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ /* diff --git a/src/tclsqlite.c b/src/tclsqlite.c index a599994258..fa82058d01 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -11,7 +11,7 @@ ************************************************************************* ** A TCL Interface to SQLite ** -** $Id: tclsqlite.c,v 1.106 2004/09/13 13:16:32 drh Exp $ +** $Id: tclsqlite.c,v 1.107 2004/11/12 15:53:37 danielk1977 Exp $ */ #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ @@ -287,6 +287,7 @@ static int auth_callback( case SQLITE_UPDATE : zCode="SQLITE_UPDATE"; break; case SQLITE_ATTACH : zCode="SQLITE_ATTACH"; break; case SQLITE_DETACH : zCode="SQLITE_DETACH"; break; + case SQLITE_ALTER_TABLE : zCode="SQLITE_ALTER_TABLE"; break; default : zCode="????"; break; } Tcl_DStringInit(&str); diff --git a/src/test1.c b/src/test1.c index 82888220a7..49c58a7a51 100644 --- a/src/test1.c +++ b/src/test1.c @@ -13,7 +13,7 @@ ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** -** $Id: test1.c,v 1.109 2004/11/10 15:27:38 danielk1977 Exp $ +** $Id: test1.c,v 1.110 2004/11/12 15:53:37 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -2563,7 +2563,11 @@ static void set_options(Tcl_Interp *interp){ #else Tcl_SetVar2(interp, "sqlite_options", "reindex", "1", TCL_GLOBAL_ONLY); #endif - +#ifdef SQLITE_OMIT_ALTERTABLE + Tcl_SetVar2(interp, "sqlite_options", "altertable", "0", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "altertable", "1", TCL_GLOBAL_ONLY); +#endif #ifdef SQLITE_OMIT_AUTOVACUUM Tcl_SetVar2(interp, "sqlite_options", "autovacuum", "0", TCL_GLOBAL_ONLY); #else diff --git a/test/alter.test b/test/alter.test index 52e7146605..a107bd038b 100644 --- a/test/alter.test +++ b/test/alter.test @@ -8,12 +8,17 @@ # This file implements regression tests for SQLite library. The # focus of this script is testing the ALTER TABLE statement. # -# $Id: alter.test,v 1.1 2004/11/12 13:42:32 danielk1977 Exp $ +# $Id: alter.test,v 1.2 2004/11/12 15:53:37 danielk1977 Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl +# If SQLITE_OMIT_ALTERTABLE is defined, omit this file. +ifcapable !altertable { + finish_test + return +} # Create some tables to rename. Be sure to include some TEMP tables # and some tables with odd names. @@ -144,6 +149,52 @@ do_test alter-1.7 { index {sqlite_autoindex__2} \ ] +# Check that ALTER TABLE works on attached databases. +# +do_test alter-1.8.1 { + file delete -force test2.db + file delete -force test2.db-journal + execsql { + ATTACH 'test2.db' AS aux; + } +} {} +do_test alter-1.8.2 { + execsql { + CREATE TABLE t4(a PRIMARY KEY, b, c); + CREATE TABLE aux.t4(a PRIMARY KEY, b, c); + CREATE INDEX i4 ON t4(b); + CREATE INDEX aux.i4 ON aux.t4(b); + } +} {} +do_test alter-1.8.3 { + execsql { + INSERT INTO t4 VALUES('main', 'main', 'main'); + INSERT INTO aux.t4 VALUES('aux', 'aux', 'aux'); + SELECT * FROM t4 WHERE a = 'main'; + } +} {main main main} +do_test alter-1.8.4 { + execsql { + ALTER TABLE t4 RENAME TO t5; + SELECT * FROM t4 WHERE a = 'aux'; + } +} {aux aux aux} +do_test alter-1.8.5 { + execsql { + SELECT * FROM t5; + } +} {main main main} +do_test alter-1.8.6 { + execsql { + SELECT * FROM t5 WHERE b = 'main'; + } +} {main main main} +do_test alter-1.8.7 { + execsql { + ALTER TABLE aux.t4 RENAME TO t5; + SELECT * FROM aux.t5 WHERE b = 'aux'; + } +} {aux aux aux} # Test error messages # @@ -166,6 +217,5 @@ do_test alter-2.3 { } } {1 {there is already another table or index with this name: i3}} - finish_test diff --git a/test/auth.test b/test/auth.test index 573e8abe65..c89b85c28a 100644 --- a/test/auth.test +++ b/test/auth.test @@ -12,7 +12,7 @@ # focus of this script is testing the ATTACH and DETACH commands # and related functionality. # -# $Id: auth.test,v 1.19 2004/09/30 13:43:14 drh Exp $ +# $Id: auth.test,v 1.20 2004/11/12 15:53:37 danielk1977 Exp $ # set testdir [file dirname $argv0] @@ -1665,6 +1665,123 @@ do_test auth-1.262 { } {test1} db authorizer {} execsql {DETACH DATABASE test1} +db authorizer ::auth + +# Authorization for ALTER TABLE +# +do_test auth-1.263 { + proc auth {code arg1 arg2 arg3 arg4} { + if {$code=="SQLITE_ALTER_TABLE"} { + set ::authargs [list $arg1 $arg2 $arg3 $arg4] + return SQLITE_OK + } + return SQLITE_OK + } + catchsql { + ALTER TABLE t1 RENAME TO t1x + } +} {0 {}} +do_test auth-1.264 { + execsql {SELECT name FROM sqlite_temp_master WHERE type='table'} +} {t1x} +do_test auth-1.265 { + set authargs +} {temp t1 {} {}} +do_test auth-1.266 { + proc auth {code arg1 arg2 arg3 arg4} { + if {$code=="SQLITE_ALTER_TABLE"} { + set ::authargs [list $arg1 $arg2 $arg3 $arg4] + return SQLITE_IGNORE + } + return SQLITE_OK + } + catchsql { + ALTER TABLE t1x RENAME TO t1 + } +} {0 {}} +do_test auth-1.267 { + execsql {SELECT name FROM sqlite_temp_master WHERE type='table'} +} {t1x} +do_test auth-1.268 { + set authargs +} {temp t1x {} {}} +do_test auth-1.269 { + proc auth {code arg1 arg2 arg3 arg4} { + if {$code=="SQLITE_ALTER_TABLE"} { + set ::authargs [list $arg1 $arg2 $arg3 $arg4] + return SQLITE_DENY + } + return SQLITE_OK + } + catchsql { + ALTER TABLE t1x RENAME TO t1 + } +} {1 {not authorized}} +do_test auth-1.270 { + execsql {SELECT name FROM sqlite_temp_master WHERE type='table'} +} {t1x} +do_test auth-1.271 { + set authargs +} {temp t1x {} {}} +db authorizer {} +catchsql {ALTER TABLE t1x RENAME TO t1} +db authorizer ::auth +do_test auth-1.272 { + proc auth {code arg1 arg2 arg3 arg4} { + if {$code=="SQLITE_ALTER_TABLE"} { + set ::authargs [list $arg1 $arg2 $arg3 $arg4] + return SQLITE_OK + } + return SQLITE_OK + } + catchsql { + ALTER TABLE t2 RENAME TO t2x + } +} {0 {}} +do_test auth-1.273 { + execsql {SELECT name FROM sqlite_master WHERE type='table'} +} {t2x} +do_test auth-1.274 { + set authargs +} {main t2 {} {}} +do_test auth-1.275 { + proc auth {code arg1 arg2 arg3 arg4} { + if {$code=="SQLITE_ALTER_TABLE"} { + set ::authargs [list $arg1 $arg2 $arg3 $arg4] + return SQLITE_IGNORE + } + return SQLITE_OK + } + catchsql { + ALTER TABLE t2x RENAME TO t2 + } +} {0 {}} +do_test auth-1.276 { + execsql {SELECT name FROM sqlite_master WHERE type='table'} +} {t2x} +do_test auth-1.277 { + set authargs +} {main t2x {} {}} +do_test auth-1.278 { + proc auth {code arg1 arg2 arg3 arg4} { + if {$code=="SQLITE_ALTER_TABLE"} { + set ::authargs [list $arg1 $arg2 $arg3 $arg4] + return SQLITE_DENY + } + return SQLITE_OK + } + catchsql { + ALTER TABLE t2x RENAME TO t2 + } +} {1 {not authorized}} +do_test auth-1.279 { + execsql {SELECT name FROM sqlite_master WHERE type='table'} +} {t2x} +do_test auth-1.280 { + set authargs +} {main t2x {} {}} +db authorizer {} +catchsql {ALTER TABLE t2x RENAME TO t2} do_test auth-2.1 {