diff --git a/manifest b/manifest index ff19e66959..1e41ace4bc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sfor\sticket\s#114:\sCorrectly\shandle\sSQLITE_BUSY\sif\sit\soccurs\sduring\ndatabase\sinitialization.\s(CVS\s696) -D 2002-07-30T18:43:41 +C Fix\sfor\sticket\s#104:\sMake\striggers\son\sviews\swork\sproperly\seven\safter\sclosing\nand\sreopening\sthe\sdatabase.\s\sAlso\sfixed\san\sunrelated\sbug\sin\sthe\sversion\n2.6.0\sdatabase\sformat\supgrade\slogic.\s\sThe\supgrade\slogic\sbug\swas\sfound\swhile\ntesting\sthe\strigger\sfixes.\s(CVS\s697) +D 2002-07-31T00:32:50 F Makefile.in 6291a33b87d2a395aafd7646ee1ed562c6f2c28c F Makefile.template 4e11752e0b5c7a043ca50af4296ec562857ba495 F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0 @@ -27,8 +27,8 @@ F src/expr.c 8a6b669ba5d6cd2810e8671f918ddb0fac3dd1b1 F src/func.c e45cd908b9b723d9b91473d09e12c23f786b3fc2 F src/hash.c 6a6236b89c8c060c65dabd300a1c8ce7c10edb72 F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8 -F src/insert.c 9bc794863ea2988a7b8667ef010b3c46b26dba38 -F src/main.c 4a9b0bae947bc276093f3eb4202ad2f3904da422 +F src/insert.c 8aefc998c86a3bd53082e2f8fdd049345fcf3463 +F src/main.c 6ae1d21113b4dd4cf036f75e3c954fa43422d6df F src/md5.c 0ae1f3e2cac92d06fc6246d1b4b8f61a2fe66d3b F src/os.c edb22daad525f49681f41c76683a16c1d39755c7 F src/os.h 5b9a69875c880d1665ae040cbca1f7b9c82198ab @@ -104,6 +104,7 @@ F test/trans.test 1fd1ecdece1eca22abe631674c3bd24046df4150 F test/trigger1.test bb63749fa8a395a60541100607d86381604b7194 F test/trigger2.test f739876942a26c63d42387321a89b75ec93af48a F test/trigger3.test 7dfe798d7e72c13720394685fe353112e3f31adf +F test/trigger4.test 9a5c1406344d743020c2753ae8d6dfe6eb75f818 F test/unique.test 572aa791327c1e8d797932263e9d67f176cfdb44 F test/update.test 7ffb062d580a972e7870d0f51d5af3ab9bfeae08 F test/vacuum.test 059871b312eb910bbe49dafde1d01490cc2c6bbe @@ -142,7 +143,7 @@ F www/speed.tcl da8afcc1d3ccc5696cfb388a68982bc3d9f7f00f F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218 -P 0b0c0492cc1e55c1c4feba6e92765ea09896096c -R a473164afc293bc42dd2cac7939e21de +P 5b814b5df667ccc91d85fbb7f96e523483e9219b +R e7cab85ea2c9f7138b4a7428603a00f1 U drh -Z 4386be0810f97b9bb5d92a2b7f47c244 +Z 973c17ae849347942e20c1058f1b7159 diff --git a/manifest.uuid b/manifest.uuid index ce83386915..a1bf50e5c9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5b814b5df667ccc91d85fbb7f96e523483e9219b \ No newline at end of file +04973fc2a6a0c93877de7e564618e0e9fcffc06c \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index d2e8d71268..b5d74f14bd 100644 --- a/src/insert.c +++ b/src/insert.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: insert.c,v 1.64 2002/07/18 00:34:12 drh Exp $ +** $Id: insert.c,v 1.65 2002/07/31 00:32:50 drh Exp $ */ #include "sqliteInt.h" @@ -91,6 +91,14 @@ void sqliteInsert( if( pTab==0 ) goto insert_cleanup; + /* If pTab is really a view, make sure it has been initialized. + */ + if( pTab->pSelect ){ + if( sqliteViewGetColumnNames(pParse, pTab) ){ + goto insert_cleanup; + } + } + /* Allocate a VDBE */ v = sqliteGetVdbe(pParse); diff --git a/src/main.c b/src/main.c index d350e25be6..db697e74ac 100644 --- a/src/main.c +++ b/src/main.c @@ -14,7 +14,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.93 2002/07/30 18:43:41 drh Exp $ +** $Id: main.c,v 1.94 2002/07/31 00:32:50 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -118,6 +118,8 @@ int upgrade_3_callback(void *pInit, int argc, char **argv, char **NotUsed){ char *zErr = 0; pTab = sqliteFindTable(pData->db, argv[0]); + assert( pTab!=0 ); + assert( sqliteStrICmp(pTab->zName, argv[0])==0 ); if( pTab ){ pTrig = pTab->pTrigger; pTab->pTrigger = 0; /* Disable all triggers before rebuilding the table */ @@ -132,7 +134,17 @@ int upgrade_3_callback(void *pInit, int argc, char **argv, char **NotUsed){ sqliteSetString(pData->pzErrMsg, zErr, 0); sqlite_freemem(zErr); } - if( pTab ) pTab->pTrigger = pTrig; /* Re-enable triggers */ + + /* If an error occurred in the SQL above, then the transaction will + ** rollback which will delete the internal symbol tables. This will + ** cause the structure that pTab points to be deleted. In case that + ** happened, we need to refetch pTab. + */ + pTab = sqliteFindTable(pData->db, argv[0]); + if( pTab ){ + assert( sqliteStrICmp(pTab->zName, argv[0])==0 ); + pTab->pTrigger = pTrig; /* Re-enable triggers */ + } return rc!=SQLITE_OK; } diff --git a/test/trigger4.test b/test/trigger4.test new file mode 100644 index 0000000000..da7f4a09a6 --- /dev/null +++ b/test/trigger4.test @@ -0,0 +1,125 @@ +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file tests the triggers of views. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_test trigger4-1.1 { + execsql { + create table test1(id integer primary key,a); + create table test2(id integer,b); + create view test as + select test1.id as id,a as a,b as b + from test1 join test2 on test2.id = test1.id; + create trigger I_test instead of insert on test + begin + insert into test1 (id,a) values (NEW.id,NEW.a); + insert into test2 (id,b) values (NEW.id,NEW.b); + end; + insert into test values(1,2,3); + select * from test1; + } +} {1 2} +do_test trigger4-1.2 { + execsql { + select * from test2; + } +} {1 3} +do_test trigger4-1.3 { + db close + sqlite db test.db + execsql { + insert into test values(4,5,6); + select * from test1; + } +} {1 2 4 5} +do_test trigger4-1.4 { + execsql { + select * from test2; + } +} {1 3 4 6} + +do_test trigger4-2.1 { + execsql { + create trigger U_test instead of update on test + begin + update test1 set a=NEW.a where id=NEW.id; + update test2 set b=NEW.b where id=NEW.id; + end; + update test set a=22 where id=1; + select * from test1; + } +} {1 22 4 5} +do_test trigger4-2.2 { + execsql { + select * from test2; + } +} {1 3 4 6} +do_test trigger4-2.3 { + db close + sqlite db test.db + execsql { + update test set b=66 where id=4; + select * from test1; + } +} {1 22 4 5} +do_test trigger4-2.4 { + execsql { + select * from test2; + } +} {1 3 4 66} + +do_test trigger4-3.1 { + catchsql { + drop table test2; + insert into test values(7,8,9); + } +} {1 {no such table: test2}} +do_test trigger4-3.2 { + db close + sqlite db test.db + catchsql { + insert into test values(7,8,9); + } +} {1 {no such table: test2}} +do_test trigger4-3.3 { + catchsql { + update test set a=222 where id=1; + } +} {1 {no such table: test2}} +do_test trigger4-3.4 { + execsql { + select * from test1; + } +} {1 22 4 5} +do_test trigger4-3.5 { + execsql { + create table test2(id,b); + insert into test values(7,8,9); + select * from test1; + } +} {1 22 4 5 7 8} +do_test trigger4-3.6 { + execsql { + select * from test2; + } +} {7 9} +do_test trigger4-3.7 { + db close + sqlite db test.db + execsql { + update test set b=99 where id=7; + select * from test2; + } +} {7 99} + +finish_test