Index: ext/fts5/test/fts5simple3.test ================================================================== --- ext/fts5/test/fts5simple3.test +++ ext/fts5/test/fts5simple3.test @@ -53,15 +53,15 @@ lappend cols "c$i" lappend vals "'val$i'" } execsql "CREATE VIRTUAL TABLE t2 USING fts5(detail=%DETAIL%,[join $cols ,])" } {} - + do_test 2.2 { execsql "INSERT INTO t2 VALUES([join $vals ,])" } {} - + foreach {tn q res} { 1 { c1:val1 } 1 2 { c300:val300 } 1 3 { c300:val1 } {} 4 { c1:val300 } {} @@ -78,8 +78,23 @@ INSERT INTO x3 VALUES('c b a'); INSERT INTO x3 VALUES('o t t'); SELECT * FROM x3('x OR y OR z'); } + +#------------------------------------------------------------------------- +# Check that if a CREATE VIRTUAL TABLE statement fails within a +# transaction, any changes made to the database are reverted before +# continuing. +# +reset_db +do_catchsql_test 4.0 { + BEGIN; + CREATE VIRTUAL TABLE t1 USING fts5; +} {1 {vtable constructor failed: t1}} + +do_execsql_test 4.1 { SELECT * FROM sqlite_master } {} +do_execsql_test 4.2 { COMMIT } +do_execsql_test 4.3 { SELECT * FROM sqlite_master } {} finish_test Index: src/vdbeaux.c ================================================================== --- src/vdbeaux.c +++ src/vdbeaux.c @@ -507,10 +507,13 @@ ){ hasAbort = 1; break; } if( opcode==OP_CreateTable ) hasCreateTable = 1; +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( opcode==OP_VCreate ) hasAbort = 1; +#endif if( opcode==OP_InitCoroutine ) hasInitCoroutine = 1; #ifndef SQLITE_OMIT_FOREIGN_KEY if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){ hasFkCounter = 1; } Index: src/vtab.c ================================================================== --- src/vtab.c +++ src/vtab.c @@ -314,10 +314,11 @@ int iDb; /* The database the table is being created in */ Table *pTable; /* The new virtual table */ sqlite3 *db; /* Database connection */ sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, ifNotExists); + sqlite3MayAbort(pParse); pTable = pParse->pNewTable; if( pTable==0 ) return; assert( 0==pTable->pIndex ); db = pParse->db;