From b7af4452d90be40cec561da111589c73d1d98c67 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 2 May 2007 17:54:55 +0000 Subject: [PATCH] Allow CREATE TABLE to occur while other queries are running. DROP TABLE is still prohibited, however, since we do not want to delete a table out from under an running query. (CVS 3902) FossilOrigin-Name: 5b4bf1fce4d589337cfb1b46d75c751bbdc607d5 --- manifest | 23 ++++---- manifest.uuid | 2 +- src/btree.c | 11 +--- test/createtab.test | 134 +++++++++++++++++++++++++++++++++++++++++++ test/incrvacuum.test | 10 +++- test/schema.test | 9 ++- test/schema2.test | 8 ++- test/table.test | 14 ++--- 8 files changed, 174 insertions(+), 37 deletions(-) create mode 100644 test/createtab.test diff --git a/manifest b/manifest index 52f59bd036..9be67451d2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Combine\sthe\sinternal\sbtree\sfunctions\sBtreePutData()\sand\sgetPayload().\s(CVS\s3901) -D 2007-05-02T17:48:46 +C Allow\sCREATE\sTABLE\sto\soccur\swhile\sother\squeries\sare\srunning.\s\sDROP\sTABLE\sis\nstill\sprohibited,\showever,\ssince\swe\sdo\snot\swant\sto\sdelete\sa\stable\sout\nfrom\sunder\san\srunning\squery.\s(CVS\s3902) +D 2007-05-02T17:54:56 F Makefile.in 8cab54f7c9f5af8f22fd97ddf1ecfd1e1860de62 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -59,7 +59,7 @@ F src/alter.c 2c79ec40f65e33deaf90ca493422c74586e481a3 F src/analyze.c 4bbf5ddf9680587c6d4917e02e378b6037be3651 F src/attach.c a16ada4a4654a0d126b8223ec9494ebb81bc5c3c F src/auth.c 902f4722661c796b97f007d9606bd7529c02597f -F src/btree.c ecd0a02c8f867509b5439379208f0ee4d801389e +F src/btree.c a84c848ee737354441ab443ccc50710e34dcac62 F src/btree.h 2c187d60cf76d74c2b4767294d6b5fa267037ff0 F src/build.c 02e01ec7907c7d947ab3041fda0e81eaed05db42 F src/callback.c 6414ed32d55859d0f65067aa5b88d2da27b3af9e @@ -193,6 +193,7 @@ F test/corrupt3.test 263e8bb04e2728df832fddf6973cf54c91db0c32 F test/crash.test 167eb4652eccbedb199b6f21850346c3f5d779fb F test/crash2.test 423c6ec404d15b7d7d0e40aef0a26740cce6075f F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 +F test/createtab.test 9f122ca39bae0decf59416779d4d7d1eeb26e18f F test/date.test 09786cf0145147014867d822224b9bced2012b61 F test/default.test 252298e42a680146b1dd64f563b95bdf088d94fb F test/delete.test 525a6953bc3978780cae35f3eaf1027cf4ce887d @@ -242,7 +243,7 @@ F test/func.test 6727c7729472ae52b5acd86e802f89aa350ba50f F test/hook.test 7e7645fd9a033f79cce8fdff151e32715e7ec50a F test/in.test 369cb2aa1eab02296b4ec470732fe8c131260b1d F test/incrblob.test 09db22f90137dc4f449cf6c7f8e554156fb68fd2 -F test/incrvacuum.test a4c9022d7b26b10495616cc5a255f11afb683be8 +F test/incrvacuum.test 2173bc075c7b3b96ccf228d737dd4f5c29500dc4 F test/incrvacuum_ioerr.test 0ebc382bcc2036ec58cf49cc5ffada45f75d907b F test/index.test e65df12bed94b2903ee89987115e1578687e9266 F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6 @@ -311,8 +312,8 @@ F test/reindex.test 38b138abe36bf9a08c791ed44d9f76cd6b97b78b F test/rollback.test 673cd8c44c685ad54987fe7f0eeba84efa09685d F test/rowid.test d125991eea1ffdea800d48471afd8fc4acc10b01 F test/safety.test 4a06934e45d03b8b50ebcd8d174eb0367d2fd851 -F test/schema.test 8a2ae440fb15f5798a68059e8746402f3137be46 -F test/schema2.test d815923e57e90b8c60ddf5e0d8fd65075e94f57f +F test/schema.test b479341d04cc40a11f47929b0198c07ddd6b2565 +F test/schema2.test b438d2c7fd627227f405887c2328b4aed5dad012 F test/select1.test 1a35bf8201c8a42a44d65acc3e6c9796a9c43dfb F test/select2.test f3c2678c3a9f3cf08ec4988a3845bda64be6d9e3 F test/select3.test 2d473f45c57c0526833e045fca0537badec0dd04 @@ -331,7 +332,7 @@ F test/speed2.test 53177056baf6556dcbdcf032bbdfc41c1aa74ded F test/subquery.test ae324ee928c5fb463a3ce08a8860d6e7f1ca5797 F test/subselect.test 974e87f8fc91c5f00dd565316d396a5a6c3106c4 F test/sync.test d05397b8f89f423dd6dba528692019ab036bc1c3 -F test/table.test feea6a3eb08cf166f570255eea5447e42ef82498 +F test/table.test dbdfd06aef054ad5aed8e57a782137d57d5c5528 F test/tableapi.test 036575a98dcce7c92e9f39056839bbad8a715412 F test/tclsqlite.test 726c301d35a2c1f4181fb772a607f785dd9e284e F test/temptable.test c36f3e5a94507abb64f7ba23deeb4e1a8a8c3821 @@ -471,7 +472,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P 83ab25014e890b1cc6ea08ca1ebeeee0078da466 -R 6382007c866ff2246040af323c0a9f53 -U danielk1977 -Z 54f827912c39196d14fa4e08648aa7ab +P a100a5304b0e7cbbdb6dac71a39c78eb71d44a03 +R c9f54fc44781d76345fb394cf6f2ebe4 +U drh +Z 2dba2ac56ac693c05f71eb4014af1de4 diff --git a/manifest.uuid b/manifest.uuid index 81951b1b25..6da7e5c454 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a100a5304b0e7cbbdb6dac71a39c78eb71d44a03 \ No newline at end of file +5b4bf1fce4d589337cfb1b46d75c751bbdc607d5 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index b34aec967e..6e59747783 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.367 2007/05/02 17:48:46 danielk1977 Exp $ +** $Id: btree.c,v 1.368 2007/05/02 17:54:56 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -5755,15 +5755,6 @@ int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){ } assert( !pBt->readOnly ); - /* It is illegal to create a table if any cursors are open on the - ** database. This is because in auto-vacuum mode the backend may - ** need to move a database page to make room for the new root-page. - ** If an open cursor was using the page a problem would occur. - */ - if( pBt->pCursor ){ - return SQLITE_LOCKED; - } - #ifdef SQLITE_OMIT_AUTOVACUUM rc = allocateBtreePage(pBt, &pRoot, &pgnoRoot, 1, 0); if( rc ) return rc; diff --git a/test/createtab.test b/test/createtab.test new file mode 100644 index 0000000000..f56bcb241b --- /dev/null +++ b/test/createtab.test @@ -0,0 +1,134 @@ +# 2007 May 02 +# +# 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 implements regression tests for SQLite library. The +# focus of this file is testing that it is OK to create new tables +# and indices while creating existing tables and indices. +# +# $Id: createtab.test,v 1.1 2007/05/02 17:54:56 drh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# Run these tests for all possible values of autovacuum. +# +for {set av 0} {$av<=2} {incr av} { + db close + file delete -force test.db test.db-journal + sqlite3 db test.db + + # Create a table that spans multiple pages. It is important + # that part of the database be in pages beyond the root page. + # + do_test createtab-$av.1 { + execsql "PRAGMA auto_vacuum=$av" + execsql { + PRAGMA page_size=1024; + CREATE TABLE t1(x INTEGER PRIMARY KEY, y); + INSERT INTO t1 VALUES(1, hex(randomblob(200))); + INSERT INTO t1 VALUES(2, hex(randomblob(200))); + INSERT INTO t1 VALUES(3, hex(randomblob(200))); + INSERT INTO t1 VALUES(4, hex(randomblob(200))); + SELECT count(*) FROM t1; + } + } {4} + do_test createtab-$av.2 { + file size test.db + } [expr {1024*(4+($av!=0)+([execsql {PRAGMA encoding}]!="UTF-8")*2)}] + + # Start reading the table + # + do_test createtab-$av.3 { + set STMT [sqlite3_prepare db {SELECT x FROM t1} -1 TAIL] + sqlite3_step $STMT + } {SQLITE_ROW} + do_test createtab-$av.4 { + sqlite3_column_int $STMT 0 + } {1} + + # While still reading the table, create a new table. + # + do_test createtab-$av.5 { + execsql { + CREATE TABLE t2(a,b); + INSERT INTO t2 VALUES(1,2); + SELECT * FROM t2; + } + } {1 2} + + # Continue reading the original table. + # + do_test createtab-$av.6 { + sqlite3_column_int $STMT 0 + } {1} + do_test createtab-$av.7 { + sqlite3_step $STMT + } {SQLITE_ROW} + do_test createtab-$av.8 { + sqlite3_column_int $STMT 0 + } {2} + + # Do another cycle of creating a new database table while contining + # to read the original table. + # + do_test createtab-$av.11 { + execsql { + CREATE TABLE t3(a,b); + INSERT INTO t3 VALUES(4,5); + SELECT * FROM t3; + } + } {4 5} + do_test createtab-$av.12 { + sqlite3_column_int $STMT 0 + } {2} + do_test createtab-$av.13 { + sqlite3_step $STMT + } {SQLITE_ROW} + do_test createtab-$av.14 { + sqlite3_column_int $STMT 0 + } {3} + + # One more cycle. + # + do_test createtab-$av.21 { + execsql { + CREATE TABLE t4(a,b); + INSERT INTO t4 VALUES('abc','xyz'); + SELECT * FROM t4; + } + } {abc xyz} + do_test createtab-$av.22 { + sqlite3_column_int $STMT 0 + } {3} + do_test createtab-$av.23 { + sqlite3_step $STMT + } {SQLITE_ROW} + do_test createtab-$av.24 { + sqlite3_column_int $STMT 0 + } {4} + + # Finish reading. Do an integrity check on the database. + # + do_test createtab-$av.30 { + sqlite3_step $STMT + } {SQLITE_DONE} + do_test createtab-$av.31 { + sqlite3_finalize $STMT + } {SQLITE_OK} + do_test createtab-$av.32 { + execsql { + SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1 + } + } {t1 t2 t3 t4} + integrity_check createtab-$av.40 + +} + +finish_test diff --git a/test/incrvacuum.test b/test/incrvacuum.test index 78c6d742ec..5fb6d2d134 100644 --- a/test/incrvacuum.test +++ b/test/incrvacuum.test @@ -14,7 +14,7 @@ # Note: There are also some tests for incremental vacuum and IO # errors in incrvacuum_ioerr.test. # -# $Id: incrvacuum.test,v 1.4 2007/04/28 15:47:44 danielk1977 Exp $ +# $Id: incrvacuum.test,v 1.5 2007/05/02 17:54:56 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -89,6 +89,13 @@ do_test incrvacuum-2.2 { pragma auto_vacuum; } } {1} +do_test incrvacuum-2.2.1 { + db close + sqlite3 db test.db + execsql { + pragma auto_vacuum; + } +} {1} do_test incrvacuum-2.3 { execsql { pragma auto_vacuum = 'incremental'; @@ -430,4 +437,3 @@ while 1 { } finish_test - diff --git a/test/schema.test b/test/schema.test index 1606f162d4..c7fc9c5b10 100644 --- a/test/schema.test +++ b/test/schema.test @@ -13,7 +13,7 @@ # This file tests the various conditions under which an SQLITE_SCHEMA # error should be returned. # -# $Id: schema.test,v 1.5 2005/12/06 12:53:01 danielk1977 Exp $ +# $Id: schema.test,v 1.6 2007/05/02 17:54:56 drh Exp $ #--------------------------------------------------------------------- # When any of the following types of SQL statements or actions are @@ -259,6 +259,10 @@ ifcapable view { # btree cursors open on the same database file it does not corrupt # the sqlite_master table. # +# 2007-05-02: These tests have been overcome by events. Open btree +# cursors no longer block CREATE TABLE. But there is no reason not +# to keep the tests in the test suite. +# do_test schema-10.1 { execsql { INSERT INTO abc VALUES(1, 2, 3); @@ -271,7 +275,7 @@ do_test schema-10.2 { catchsql { CREATE TABLE t2(a, b, c); } -} {1 {database table is locked}} +} {0 {}} do_test schema-10.3 { sqlite3_finalize $::STMT } {SQLITE_OK} @@ -330,4 +334,3 @@ do_test schema-11.8 { } {SQLITE_OK} finish_test - diff --git a/test/schema2.test b/test/schema2.test index 1bce2cd35b..593c80d6f1 100644 --- a/test/schema2.test +++ b/test/schema2.test @@ -14,7 +14,7 @@ # error should be returned. This is a copy of schema.test that # has been altered to use sqlite3_prepare_v2 instead of sqlite3_prepare # -# $Id: schema2.test,v 1.1 2006/11/09 00:24:55 drh Exp $ +# $Id: schema2.test,v 1.2 2007/05/02 17:54:56 drh Exp $ #--------------------------------------------------------------------- # When any of the following types of SQL statements or actions are @@ -261,6 +261,10 @@ ifcapable view { # btree cursors open on the same database file it does not corrupt # the sqlite_master table. # +# 2007-05-02: These tests have been overcome by events. Open btree +# cursors no longer block CREATE TABLE. But there is no reason not +# to keep the tests in the test suite. +# do_test schema2-10.1 { execsql { INSERT INTO abc VALUES(1, 2, 3); @@ -273,7 +277,7 @@ do_test schema2-10.2 { catchsql { CREATE TABLE t2(a, b, c); } -} {1 {database table is locked}} +} {0 {}} do_test schema2-10.3 { sqlite3_finalize $::STMT } {SQLITE_OK} diff --git a/test/table.test b/test/table.test index e9c0ec2d4d..718f1715e5 100644 --- a/test/table.test +++ b/test/table.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the CREATE TABLE statement. # -# $Id: table.test,v 1.46 2006/09/01 15:49:06 drh Exp $ +# $Id: table.test,v 1.47 2007/05/02 17:54:56 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -590,6 +590,10 @@ set sqlite_current_time 0 # auto-vacuum mode the btree-layer may need to move the root-pages of # a table for which there is an open cursor. # +# 2007-05-02: A open btree cursor no longer blocks CREATE TABLE. +# But DROP TABLE is still prohibited because we do not want to +# delete a table out from under a running query. +# # db eval { # pragma vdbe_trace = 0; @@ -605,13 +609,7 @@ do_test table-14.1 { } msg ] set result [list $rc $msg] -} {1 {database table is locked}} - -do_test table-14.2 { - execsql { - CREATE TABLE t9(a, b, c) - } -} {} +} {0 {}} # Try to drop a table from within a callback: do_test table-14.3 {