Index: src/vdbe.c ================================================================== --- src/vdbe.c +++ src/vdbe.c @@ -3304,11 +3304,11 @@ #endif /* See note about index shifting on OP_ReadCookie */ rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, pOp->p3); if( pOp->p2==BTREE_SCHEMA_VERSION ){ /* When the schema cookie changes, record the new cookie internally */ - assert( db->bConcurrent==0 ); + assert( pOp->p1==1 || db->bConcurrent==0 ); pDb->pSchema->schema_cookie = pOp->p3; db->mDbFlags |= DBFLAG_SchemaChange; }else if( pOp->p2==BTREE_FILE_FORMAT ){ /* Record changes in the file format */ pDb->pSchema->file_format = pOp->p3; @@ -6507,11 +6507,11 @@ ** used to generate an error message if the lock cannot be obtained. */ case OP_TableLock: { u8 isWriteLock = (u8)pOp->p3; #ifndef SQLITE_OMIT_CONCURRENT - if( isWriteLock && db->bConcurrent && pOp->p2==1 ){ + if( isWriteLock && db->bConcurrent && pOp->p2==1 && pOp->p1!=1 ){ rc = SQLITE_ERROR; sqlite3VdbeError(p, "cannot modify database schema within CONCURRENT transaction"); goto abort_due_to_error; } Index: test/concurrent.test ================================================================== --- test/concurrent.test +++ test/concurrent.test @@ -110,23 +110,51 @@ foreach {tn sql} { 1 { CREATE TABLE xx(a, b) } 2 { DROP TABLE t1 } 3 { CREATE INDEX i1 ON t1(a) } 4 { CREATE VIEW v1 AS SELECT * FROM t1 } - 5 { CREATE TEMP TABLE xx(a, b) } } { - do_catchsql_test 1.7.$tn.1 " + do_catchsql_test 1.7.0.$tn.1 " BEGIN CONCURRENT; $sql " {1 {cannot modify database schema within CONCURRENT transaction}} - do_execsql_test 1.7.$tn.2 { + do_execsql_test 1.7.0.$tn.2 { SELECT sql FROM sqlite_master; SELECT sql FROM sqlite_temp_master; } {{CREATE TABLE t1(a, b)}} - do_execsql_test 1.7.$tn.3 COMMIT + do_execsql_test 1.7.0.$tn.3 COMMIT +} + +# Except the temp db schema. +foreach {tn sql} { + 1 { CREATE TEMP TABLE xx(a, b) } + 2 { DROP TABLE xx } + 3 { CREATE TEMP TABLE yy(a, b) } + 4 { CREATE VIEW temp.v1 AS SELECT * FROM t1 } + 5 { CREATE INDEX yyi1 ON yy(a); } + 6 { CREATE TABLE temp.zz(a, b) } +} { + do_catchsql_test 1.7.1.$tn.1 " + BEGIN CONCURRENT; + $sql + " {0 {}} + + do_execsql_test 1.7.1.$tn.2 COMMIT +} + + +do_execsql_test 1.7.1.x { + SELECT sql FROM sqlite_master; + SELECT sql FROM sqlite_temp_master; +} { + {CREATE TABLE t1(a, b)} + {CREATE TABLE yy(a, b)} + {CREATE VIEW v1 AS SELECT * FROM t1} + {CREATE INDEX yyi1 ON yy(a)} + {CREATE TABLE zz(a, b)} } #------------------------------------------------------------------------- # If an auto-vacuum database is written within an CONCURRENT transaction, it # is handled in the same way as for a non-CONCURRENT transaction.