-C Fix\sa\sbug\sin\sthe\sTCL\scode\sfor\ssqlite3_analyzer.\s(CVS\s4590)
-D 2007-12-04T13:41:51
+C Make\ssure\sstatement\sjournals\sare\sinitiated\swhen\sdoing\sDROP\soperations\n(since\sthe\sDROP\smight\sfail\safter\ssqlite_master\schanges).\s\sAlso\smake\nsure\sstatement\sjournals\sare\sinitiated\sif\sthere\sare\spending\sSELECT\nstatements.\s\sTicket\s#2820.\s(CVS\s4591)
+D 2007-12-04T16:54:53
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/btree.c c5844bb4bbe997a7c8400a714fcf304d91855383
F src/btree.h d0736ebca4b6eafbdd823c46a8de574cea078211
F src/btreeInt.h 4330c19b8314545fdb209cc77e2a57f6a5290e9c
-F src/build.c 04e0783a105d4d65c1850815adfdfe7403dcb592
+F src/build.c 580561a0d9e070ff2741f3b115cae51c1ef08260
F src/callback.c 77b302b0d41468dcda78c70e706e5b84577f0fa0
F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
F src/date.c 49c5a6d2de6c12000905b4d36868b07d3011bbf6
F src/utf.c ef4b7d83bae533b76c3e1bf635b113fdad86a736
F src/util.c 05f31144bbd3f1a24f4139ae029c42545cb72624
F src/vacuum.c a5e51c77370c1a6445e86d42abfc43867cdd482d
-F src/vdbe.c 9859467b3762a1c05f956b5f556fb922e139ff9f
+F src/vdbe.c a99beac1162fa490c4b75ac36ed97146ab181837
F src/vdbe.h 79e09ff13b85457abe437d9814454534ebbc1fe3
F src/vdbeInt.h 630145b9bfaa19190ab491f52658a7db550f2247
F src/vdbeapi.c dd2c43317294e0a013e9f634ee4209a3ea459b43
-F src/vdbeaux.c 285f113364134f7c1571456723dcb84be89e6c3f
+F src/vdbeaux.c 5bc14ff3da6c6b3b7f643cbc3d50a344e9b599f8
F src/vdbeblob.c 82f51cdf9b0c0af729732fde48c824e498c0a1ca
F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
F src/vdbemem.c 123994fcd344993d2fb050a83b91b341bbbd08b4
F test/tkt2686.test 8815c3eeae7c8363bd7c2889349ec39e8bc8000d
F test/tkt2767.test 6b02308d553d194f329a469bf5c157fe724738d4
F test/tkt2817.test 709a2201a5590bf56cb97f6fb168a62282203fd1
+F test/tkt2820.test 017fdee33aaef7abc092beab6088816f1942304b
F test/trace.test 75ffc1b992c780d054748a656e3e7fd674f18567
F test/trans.test b73289992b46d38d9479ecc4fdc03d8edb2413dc
F test/trigger1.test 7c13f39ca36f529bf856e05c7d004fc0531d48b4
F test/vtab4.test a9d7104d41a787754a734740d7aa61c807a69f87
F test/vtab5.test 26bc7a0a52c5c2bcfa849ba327f8a0d4abccdb23
F test/vtab6.test ec0036f29f8a803da9935206f2d9d1b6a8026392
-F test/vtab7.test 9249e8e31f4f1a44f07984b402d12ce3e63be4f3
+F test/vtab7.test a8c3c3cb3eb60be364991bd714e4927e26c4cd85
F test/vtab8.test e19fa4a538fcd1bb66c22825fa8f71618fb13583
F test/vtab9.test ea58d2b95d61955f87226381716b2d0b1d4e4f9b
F test/vtabA.test 9cb6b1afead6fdd91bbdf1ca65c44ccfd9b10936
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 78f359dffa6f4af4d5b7e4523f451e0e405350c0
-R cfc28c51a4620cec082dc386c8465836
+P 7c2cf4542852a81daf29a930ab103c52bb678326
+R c111fb18ebb6378f510e950ea7f7ef09
U drh
-Z c95254d1012df22f0a03f3a42376bc6c
+Z 60a6d3adb97dfb253eaa60aa3a1f2c5c
-7c2cf4542852a81daf29a930ab103c52bb678326
\ No newline at end of file
+bf34284ff0c60ae6e735e09bb29cd48b158e8dce
\ No newline at end of file
** COMMIT
** ROLLBACK
**
-** $Id: build.c,v 1.449 2007/12/02 11:46:35 danielk1977 Exp $
+** $Id: build.c,v 1.450 2007/12/04 16:54:53 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
if( v ){
Trigger *pTrigger;
Db *pDb = &db->aDb[iDb];
- sqlite3BeginWriteOperation(pParse, 0, iDb);
+ sqlite3BeginWriteOperation(pParse, 1, iDb);
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pTab) ){
/* Generate code to remove the index and from the master table */
v = sqlite3GetVdbe(pParse);
if( v ){
+ sqlite3BeginWriteOperation(pParse, 1, iDb);
sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE name=%Q",
db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
-** $Id: vdbe.c,v 1.655 2007/11/29 17:05:18 danielk1977 Exp $
+** $Id: vdbe.c,v 1.656 2007/12/04 16:54:53 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
case OP_Statement: { /* no-push */
int i = pOp->p1;
Btree *pBt;
- if( i>=0 && i<db->nDb && (pBt = db->aDb[i].pBt)!=0 && !(db->autoCommit) ){
+ if( i>=0 && i<db->nDb && (pBt = db->aDb[i].pBt)!=0
+ && (db->autoCommit==0 || db->activeVdbeCnt>1) ){
assert( sqlite3BtreeIsInTrans(pBt) );
assert( (p->btreeMask & (1<<i))!=0 );
if( !sqlite3BtreeIsInStmt(pBt) ){
#endif
if( iCnt>1 ){
rc = SQLITE_LOCKED;
+ p->errorAction = OE_Abort;
}else{
assert( iCnt==1 );
assert( (p->btreeMask & (1<<pOp->p2))!=0 );
** entries that static analysis reveals this program might need.
**
** This routine also does the following optimization: It scans for
-** Halt instructions where P1==SQLITE_CONSTRAINT or P2==OE_Abort or for
-** IdxInsert instructions where P2!=0. If no such instruction is
-** found, then every Statement instruction is changed to a Noop. In
-** this way, we avoid creating the statement journal file unnecessarily.
+** instructions that might cause a statement rollback. Such instructions
+** are:
+**
+** * OP_Halt with P1=SQLITE_CONSTRAINT and P2=OE_Abort.
+** * OP_Destroy
+** * OP_VUpdate
+** * OP_VRename
+**
+** If no such instruction is found, then every Statement instruction
+** is changed to a Noop. In this way, we avoid creating the statement
+** journal file unnecessarily.
*/
static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs, int *pMaxStack){
int i;
}
}else if( opcode==OP_Statement ){
hasStatementBegin = 1;
+ }else if( opcode==OP_Destroy ){
+ doesStatementRollback = 1;
#ifndef SQLITE_OMIT_VIRTUALTABLE
}else if( opcode==OP_VUpdate || opcode==OP_VRename ){
doesStatementRollback = 1;
/* Check for one of the special errors */
mrc = p->rc & 0xff;
isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR
- || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL ;
+ || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL;
if( isSpecialError ){
/* This loop does static analysis of the query to see which of the
** following three categories it falls into:
--- /dev/null
+# 2007 Dec 4
+#
+# 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 is to test that ticket #2820 has been fixed.
+# Ticket #2820 observes that a DROP TABLE statement that
+# occurs while a query is in process will fail with a
+# "database is locked" error, but the entry in the sqlite_master
+# table will still be removed. This is incorrect. The
+# entry in the sqlite_master table should persist when
+# the DROP fails due to an error.
+#
+# $Id: tkt2820.test,v 1.1 2007/12/04 16:54:53 drh Exp $
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+proc test_schema_change {testid init ddl res} {
+ db close
+ file delete -force test.db test.db-journal
+ sqlite3 db test.db
+ execsql $init
+ do_test tkt2820-$testid.1 {
+ set STMT [sqlite3_prepare db {SELECT * FROM sqlite_master} -1 DUMMY]
+ sqlite3_step $STMT
+ } {SQLITE_ROW}
+#if {$testid==3} {execsql {PRAGMA vdbe_trace=ON}}
+ do_test tkt2820-$testid.2 "catchsql [list $ddl]" \
+ {1 {database table is locked}}
+ do_test tkt2820-$testid.3 {
+ sqlite3_finalize $STMT
+ execsql {SELECT name FROM sqlite_master ORDER BY 1}
+ } $res
+ integrity_check tkt2820-$testid.4
+ db close
+ sqlite3 db test.db
+ integrity_check tkt2820-$testid.5
+}
+
+test_schema_change 1 {
+ CREATE TABLE t1(a);
+} {
+ DROP TABLE t1
+} {t1}
+test_schema_change 2 {
+ CREATE TABLE t1(a);
+ CREATE TABLE t2(b);
+} {
+ DROP TABLE t2
+} {t1 t2}
+test_schema_change 3 {
+ CREATE TABLE t1(a);
+ CREATE INDEX i1 ON t1(a);
+} {
+ DROP INDEX i1
+} {i1 t1}
+
+# We further observe that prior to the fix associated with ticket #2820,
+# no statement journal would be created on an SQL statement that was run
+# while a second statement was active, as long as we are in autocommit
+# mode. This is incorrect.
+#
+do_test tkt2820-4.1 {
+ db close
+ file delete -force test.db test.db-journal
+ sqlite3 db test.db
+ db eval {
+ CREATE TABLE t1(a INTEGER PRIMARY KEY);
+ INSERT INTO t1 VALUES(1);
+ INSERT INTO t1 VALUES(2);
+ }
+
+ # The INSERT statement within the loop should fail on a
+ # constraint violation on the second inserted row. This
+ # should cause the entire INSERT to rollback using a statement
+ # journal.
+ #
+ db eval {SELECT name FROM sqlite_master} {
+ catch {db eval {
+ INSERT INTO t1 SELECT a+1 FROM t1 ORDER BY a DESC
+ }}
+ }
+ db eval {SELECT a FROM t1 ORDER BY a}
+} {1 2}
+
+finish_test
# of this test is reading and writing to the database from within a
# virtual table xSync() callback.
#
-# $Id: vtab7.test,v 1.3 2007/10/09 08:29:33 danielk1977 Exp $
+# $Id: vtab7.test,v 1.4 2007/12/04 16:54:53 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
} {abc abc2 log newtab}
# Drop a database table from within xSync callback.
+# This is not allowed. Tables cannot be dropped while
+# any other statement is active.
+#
do_test vtab7-2.6 {
set ::callbacks(xSync,abc) {
- execsql { DROP TABLE newtab }
+ set ::rc [catchsql { DROP TABLE newtab }]
}
execsql {
INSERT INTO abc2 VALUES(1, 2, 3);
SELECT name FROM sqlite_master ORDER BY name;
}
-} {abc abc2 log}
+} {abc abc2 log newtab}
+do_test vtab7-2.6.1 {
+ set ::rc
+} {1 {database table is locked}}
+execsql {DROP TABLE newtab}
# Write to an attached database from xSync().
ifcapable attach {
unset -nocomplain ::callbacks
finish_test
-