From: dan Date: Tue, 6 Jul 2010 07:36:18 +0000 (+0000) Subject: Ensure the correct error code is returned if an attempt to parse a database schema... X-Git-Tag: version-3.7.2~189 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9859c427a27a6c813c8a0a11966b20d2f221a6d2;p=thirdparty%2Fsqlite.git Ensure the correct error code is returned if an attempt to parse a database schema made by an ATTACH statement fails. FossilOrigin-Name: c272196115ab3926e56b6f4183ec127e3f98ef9c --- diff --git a/manifest b/manifest index b0f587eecf..957ae13e82 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Modify\sthe\sVFS\sxAccess()\smethod\son\swinNT\sso\sthat\sit\sreturns\sfalse\sfor\nan\sexists\stest\sof\sa\szero-length\sfile.\s\sThis\smakes\sthe\swindows\sVFS\swork\nthe\ssame\sas\sthe\sunix\sVFS. -D 2010-07-05T21:00:43 +C Ensure\sthe\scorrect\serror\scode\sis\sreturned\sif\san\sattempt\sto\sparse\sa\sdatabase\sschema\smade\sby\san\sATTACH\sstatement\sfails. +D 2010-07-06T07:36:18 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -166,7 +163,7 @@ F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07 F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050 F src/pcache1.c 3a7c28f46a61b43ff0b5c087a7983c154f4b264c F src/pragma.c 423865323a4074f1e0d4ab02af0be014653e8863 -F src/prepare.c fd1398cb1da54385ba5bd68d93928f10d10a1d9c +F src/prepare.c 48105b1a6082ac4f47cd6ebebe3678284733e1ea F src/printf.c 5f5b65a83e63f2096a541a340722a509fa0240a7 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706 @@ -534,7 +531,7 @@ F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test f3a0bcc6ca1acaa370efc5a7571e89507fb5927d F test/notify1.test 8433bc74bd952fb8a6e3f8d7a4c2b28dfd69e310 F test/notify2.test 195a467e021f74197be2c4fb02d6dee644b8d8db -F test/notify3.test feb03d697f4a5327c1beb158c3e7e51c5e400703 +F test/notify3.test 7eeba3628c4e707c004b72a2489c48fbdbc5c2ee F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347 F test/null.test a8b09b8ed87852742343b33441a9240022108993 F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec @@ -833,14 +830,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P a1324d125e2dd7004eaf8680f5f832ef17285087 -R b7b5ca572f0c4cfc846cea3094607313 -U drh -Z 13fb6b591c3748fd040ab5e5168b969e ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFMMkf+oxKgR168RlERAmH+AJ4mV5XQd4nFP0MCayWKQVj6n5imSQCffrGL -fAmeRw3++Xx1yEVjikEuOhY= -=4bOD ------END PGP SIGNATURE----- +P ec35f25403744f7441ac5ae1486b84d8ebc13e98 +R 6f882aa18788a523ea19d9f06c59ec5f +U dan +Z 4ac3c8c3cdfa6e85afde2c4c5d30b8ea diff --git a/manifest.uuid b/manifest.uuid index ac24f9bc0d..ffd60bbeca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ec35f25403744f7441ac5ae1486b84d8ebc13e98 \ No newline at end of file +c272196115ab3926e56b6f4183ec127e3f98ef9c \ No newline at end of file diff --git a/src/prepare.c b/src/prepare.c index e729f420dd..5a861a1bdb 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -73,6 +73,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ ** or executed. All the parser does is build the internal data ** structures that describe the table, index, or view. */ + TESTONLY(int rcp); /* Return code from sqlite3_prepare() */ int rc; sqlite3_stmt *pStmt; @@ -80,7 +81,9 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ db->init.iDb = iDb; db->init.newTnum = atoi(argv[1]); db->init.orphanTrigger = 0; - rc = sqlite3_prepare(db, argv[2], -1, &pStmt, 0); + TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0); + rc = db->errCode; + assert( (rc&0xFF)==(rcp&0xFF) ); db->init.iDb = 0; if( SQLITE_OK!=rc ){ if( db->init.orphanTrigger ){ @@ -89,7 +92,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ pData->rc = rc; if( rc==SQLITE_NOMEM ){ db->mallocFailed = 1; - }else if( rc!=SQLITE_INTERRUPT && rc!=SQLITE_LOCKED ){ + }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ corruptSchema(pData, argv[0], sqlite3_errmsg(db)); } } diff --git a/test/notify3.test b/test/notify3.test index 80d147a443..7c7d5acf5c 100644 --- a/test/notify3.test +++ b/test/notify3.test @@ -50,6 +50,7 @@ do_test notify3-1.3 { do_test notify3-1.4 { catchsql { ATTACH 'test.db2' AS aux } } {0 {}} + do_test notify3-1.5 { catchsql { SELECT * FROM t2 } } {1 {database schema is locked: aux}} @@ -74,6 +75,71 @@ do_test notify3-1.8 { do_test notify3-1.9 { catchsql { SELECT * FROM t2 } } {0 {{t2 A} {t2 B} {t2 C} {t2 D}}} +db close + + +set err {{1 {unable to open database: test.db2}}} +set noerr {{0 {}}} + +# When a new database is attached, the connection doing the attaching +# tries to load any unloaded schemas for both the new database and any +# already attached databases (including the main database). If it is +# unable to load any such schemas, then the ATTACH statement fails. +# +# This block tests that if the loading of schemas as a result of an +# ATTACH fails due to locks on the schema table held by other shared-cache +# connections the extended error code is SQLITE_LOCKED_SHAREDCACHE and +# it is possible to use the unlock-notify mechanism to determine when +# the ATTACH might succeed. +# +foreach { + tn + db1_loaded + db2_loaded + enable_extended_errors + result + error1 error2 +} " + 0 0 0 0 $err SQLITE_LOCKED SQLITE_LOCKED_SHAREDCACHE + 1 0 0 1 $err SQLITE_LOCKED_SHAREDCACHE SQLITE_LOCKED_SHAREDCACHE + 2 0 1 0 $err SQLITE_LOCKED SQLITE_LOCKED_SHAREDCACHE + 3 0 1 1 $err SQLITE_LOCKED_SHAREDCACHE SQLITE_LOCKED_SHAREDCACHE + 4 1 0 0 $err SQLITE_LOCKED SQLITE_LOCKED_SHAREDCACHE + 5 1 0 1 $err SQLITE_LOCKED_SHAREDCACHE SQLITE_LOCKED_SHAREDCACHE + 6 1 1 0 $noerr SQLITE_OK SQLITE_OK + 7 1 1 1 $noerr SQLITE_OK SQLITE_OK +" { + + do_test notify3-2.$tn.1 { + catch { db1 close } + catch { db2 close } + sqlite3 db1 test.db + sqlite3 db2 test.db2 + + sqlite3_extended_result_codes db1 $enable_extended_errors + sqlite3_extended_result_codes db2 $enable_extended_errors + + if { $db1_loaded } { db1 eval "SELECT * FROM sqlite_master" } + if { $db2_loaded } { db2 eval "SELECT * FROM sqlite_master" } + + db2 eval "BEGIN EXCLUSIVE" + catchsql "ATTACH 'test.db2' AS two" db1 + } $result + + do_test notify3-2.$tn.2 { + list [sqlite3_errcode db1] [sqlite3_extended_errcode db1] + } [list $error1 $error2] + + do_test notify3-2.$tn.3 { + db1 unlock_notify {set invoked 1} + set invoked 0 + db2 eval commit + set invoked + } [lindex $result 0] +} +catch { db1 close } +catch { db2 close } + sqlite3_enable_shared_cache $esc finish_test