From: dan Date: Thu, 18 Feb 2010 08:19:19 +0000 (+0000) Subject: Allow statements like "REPLACE INTO tbl(rowid) VALUES(...)" to run without a statemen... X-Git-Tag: version-3.7.2~601 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=da730f6eb4e1df1b844b8c0cb0b68f3389a37960;p=thirdparty%2Fsqlite.git Allow statements like "REPLACE INTO tbl(rowid) VALUES(...)" to run without a statement journal as long as there are no triggers, foreign keys or indexes. FossilOrigin-Name: 0e4225804010cb0e3f254e2dbffc4fe0e7d982ce --- diff --git a/manifest b/manifest index 98c2c6cdc7..6ed19049b8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Consistent\suse\sof\s#ifdef\sfor\sSQLITE_HAS_CODEC\sto\savoid\sconfusion. -D 2010-02-17T17:48:47 +C Allow\sstatements\slike\s"REPLACE\sINTO\stbl(rowid)\sVALUES(...)"\sto\srun\swithout\sa\sstatement\sjournal\sas\slong\sas\sthere\sare\sno\striggers,\sforeign\skeys\sor\sindexes. +D 2010-02-18T08:19:20 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in c5827ead754ab32b9585487177c93bb00b9497b3 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -125,7 +125,7 @@ F src/global.c 75946a4a2ab41c6ae58f10ca0ed31b3449694b26 F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 11eeb4f2e5d57b7c106f0c28eea8d0dd896dfd70 +F src/insert.c 76d6b44a9f9050134fd81205f4b792cbdac7c925 F src/journal.c b0ea6b70b532961118ab70301c00a33089f9315c F src/legacy.c 16f385490f377c2c80a6c7357391d499087defed F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e @@ -406,7 +406,7 @@ F test/fts3malloc.test 059592c4f37ccd30138bbf8e3e5b7982cb5c8f2e F test/fts3near.test 2e318ee434d32babd27c167142e2b94ddbab4844 F test/fts3query.test 154fe4b015fd61af523ee083570a134f508f5be7 F test/fts3rnd.test 2f5761db9dd92f6fe09d08976ac658ef521846ed -F test/fts3snippet.test 5745ce7270fb754b4f998c6bc33bf843791f6e36 +F test/fts3snippet.test 9f9a4a7e396c5d8ce2898be65ebabc429555430f F test/fts4aa.test 9a9bc506487399c17284fa82a72f16d5ced2910c F test/func.test 6c5ce11e3a0021ca3c0649234e2d4454c89110ca F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f @@ -584,6 +584,7 @@ F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b F test/sqllimits1.test e90a0ed94452076f6a10209d378e06b5f75ef0a0 +F test/stmt.test 877d41d41bfbbf27365b4e498c4b5b4b4d61818d F test/subquery.test b524f57c9574b2c0347045b4510ef795d4686796 F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a @@ -788,7 +789,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P d76ad8b3c494ffb4e670da0e92a1f8dbf7f48daf -R a0fcf012eeeaa6a43756a232ecac05ef -U shaneh -Z 6db38cc05906d785948a9a447f1df2f3 +P 34a3413a5318050254b246ad859c91c134516a32 +R 9abb5e0ed22f7d06fb4491d50076ada9 +U dan +Z a6ef964fdd6cde6844284b1aa32499cc diff --git a/manifest.uuid b/manifest.uuid index 5568ba96f1..e82bce46c1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -34a3413a5318050254b246ad859c91c134516a32 \ No newline at end of file +0e4225804010cb0e3f254e2dbffc4fe0e7d982ce \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 9bd9085343..5379762069 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1261,19 +1261,33 @@ void sqlite3GenerateConstraintChecks( ** the triggers and remove both the table and index b-tree entries. ** ** Otherwise, if there are no triggers or the recursive-triggers - ** flag is not set, call GenerateRowIndexDelete(). This removes - ** the index b-tree entries only. The table b-tree entry will be - ** replaced by the new entry when it is inserted. */ + ** flag is not set, but the table has one or more indexes, call + ** GenerateRowIndexDelete(). This removes the index b-tree entries + ** only. The table b-tree entry will be replaced by the new entry + ** when it is inserted. + ** + ** If either GenerateRowDelete() or GenerateRowIndexDelete() is called, + ** also invoke MultiWrite() to indicate that this VDBE may require + ** statement rollback (if the statement is aborted after the delete + ** takes place). Earlier versions called sqlite3MultiWrite() regardless, + ** but being more selective here allows statements like: + ** + ** REPLACE INTO t(rowid) VALUES($newrowid) + ** + ** to run without a statement journal if there are no indexes on the + ** table. + */ Trigger *pTrigger = 0; if( pParse->db->flags&SQLITE_RecTriggers ){ pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); } - sqlite3MultiWrite(pParse); if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){ + sqlite3MultiWrite(pParse); sqlite3GenerateRowDelete( pParse, pTab, baseCur, regRowid, 0, pTrigger, OE_Replace ); - }else{ + }else if( pTab->pIndex ){ + sqlite3MultiWrite(pParse); sqlite3GenerateRowIndexDelete(pParse, pTab, baseCur, 0); } seenReplace = 1; diff --git a/test/fts3snippet.test b/test/fts3snippet.test index 614691a8b1..e7adaee046 100644 --- a/test/fts3snippet.test +++ b/test/fts3snippet.test @@ -342,7 +342,7 @@ foreach {DO_MALLOC_TEST enc} { } execsql COMMIT } {} - do_snippet_test $T.7.2 {one two} -1 3 {*}$testresults + eval [list do_snippet_test $T.7.2 {one two} -1 3] $testresults ########################################################################## # Test the matchinfo function. diff --git a/test/stmt.test b/test/stmt.test new file mode 100644 index 0000000000..56faa896d6 --- /dev/null +++ b/test/stmt.test @@ -0,0 +1,80 @@ +# 2010 February 18 +# +# 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. +# +#*********************************************************************** +# +# The tests in this file check that SQLite uses (or does not use) a +# statement journal for various SQL statements. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_test stmt-1.1 { + execsql { CREATE TABLE t1(a integer primary key, b INTEGER NOT NULL) } +} {} + +# The following tests verify the method used for the tests in this file - +# that if a statement journal is required by a statement it is opened and +# remains open until the current transaction is committed or rolled back. +# +do_test stmt-1.2 { + set sqlite_open_file_count +} {1} +do_test stmt-1.3 { + execsql { + BEGIN; + INSERT INTO t1 VALUES(1, 1); + } + set sqlite_open_file_count +} {2} +do_test stmt-1.4 { + execsql { + INSERT INTO t1 SELECT a+1, b+1 FROM t1; + } + set sqlite_open_file_count +} {3} +do_test stmt-1.5 { + execsql COMMIT + set sqlite_open_file_count +} {1} +do_test stmt-1.6 { + execsql { + BEGIN; + INSERT INTO t1 SELECT a+2, b+2 FROM t1; + } + set sqlite_open_file_count +} {3} +do_test stmt-1.7 { + execsql COMMIT + set sqlite_open_file_count +} {1} + + +proc filecount {testname sql expected} { + uplevel [list do_test $testname [subst -nocommand { + execsql BEGIN + execsql { $sql } + set ret [set sqlite_open_file_count] + execsql ROLLBACK + set ret + }] $expected] +} + +filecount stmt-2.1 { INSERT INTO t1 VALUES(5, 5) } 2 +filecount stmt-2.2 { REPLACE INTO t1 VALUES(5, 5) } 2 +filecount stmt-2.3 { INSERT INTO t1 SELECT 5, 5 } 3 + +do_test stmt-2.4 { + execsql { CREATE INDEX i1 ON t1(b) } +} {} +filecount stmt-2.5 { REPLACE INTO t1 VALUES(5, 5) } 3 + +finish_test +