From: drh Date: Tue, 16 Jun 2009 17:49:36 +0000 (+0000) Subject: Changes sqlite3_prepare_v2() (and related routines) so that if it fails due X-Git-Tag: cvs-to-fossil-cutover~203 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9da742f9695fb32d9e70f57eed5095846258ad7d;p=thirdparty%2Fsqlite.git Changes sqlite3_prepare_v2() (and related routines) so that if it fails due to a missing table and the schema is out of date, it retries once before returning SQLITE_SCHEMA. Other changes to prepare.c to facilitate coverage testing. (CVS 6769) FossilOrigin-Name: 256ec3c6af41c2324db82e4deb54edbba5b581e8 --- diff --git a/manifest b/manifest index d89de0785e..984485e3f8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sto\sbalance_nonroot()\sand\sBtreeDelete()\sto\ssimplify\sdelete\soperations\sand\sreduce\sstack/heap\susage\swhile\sbalancing\sb-tree\sstructures.\s(CVS\s6768) -D 2009-06-16T16:50:22 +C Changes\ssqlite3_prepare_v2()\s(and\srelated\sroutines)\sso\sthat\sif\sit\sfails\sdue\r\nto\sa\smissing\stable\sand\sthe\sschema\sis\sout\sof\sdate,\sit\sretries\sonce\sbefore\r\nreturning\sSQLITE_SCHEMA.\s\sOther\schanges\sto\sprepare.c\sto\sfacilitate\scoverage\r\ntesting.\s(CVS\s6769) +D 2009-06-16T17:49:36 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 8b8fb7823264331210cddf103831816c286ba446 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -153,7 +153,7 @@ F src/pcache.c 395f752a13574120bd7513a400ba02a265aaa76d F src/pcache.h 9b927ccc5a538e31b4c3bc7eec4f976db42a1324 F src/pcache1.c 97e7e8e6e34026fb43b47d08532b0c02e959c26c F src/pragma.c 06b3a4b93a5e587f1c04b4a40016eb360792cdf3 -F src/prepare.c 889208e3567a98bb3d345a30f63240beb9ac90f9 +F src/prepare.c cc0cc08be09bef8b435fa3d4a5cb83e5eaddc9c9 F src/printf.c 508a1c59433353552b6553cba175eaa7331f8fc1 F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628 F src/resolve.c 4a61d03e49b15440878096e6030863fc628828f0 @@ -436,7 +436,7 @@ F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da F test/limit.test 2db7b3b34fb925b8e847d583d2eb67531d0ce67e F test/loadext.test 0393ce12d9616aa87597dd0ec88181de181f6db0 F test/loadext2.test 0bcaeb4d81cd5b6e883fdfea3c1bdbe1f173cbca -F test/lock.test edf5585398a33534db71a2a6108308d9e89c16d1 +F test/lock.test 842e80b6be816c79525a20b098cca066989feed7 F test/lock2.test 7bb642551df59b3de135291d62ee82409420181e F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00 F test/lock4.test f4f36271aa5ae1da449646bf43c7341f6b2b4c4e @@ -564,7 +564,7 @@ F test/table.test bf102a5669c4db7a41330802f24a4a81a4204f83 F test/tableapi.test 505031f15b18a750184d967d2c896cf88fcc969c F test/tclsqlite.test 8b1150d0486c4848c70d96422513a91c5342be0e F test/tempdb.test 1bf52da28a9c24e29717362a87722dff08feb72b -F test/temptable.test 5d8ca46be28cc06c887c5a77df650843b7edbae1 +F test/temptable.test f42121a0d29a62f00f93274464164177ab1cc24a F test/temptrigger.test b0273db072ce5f37cf19140ceb1f0d524bbe9f05 F test/tester.tcl b22f925f3c6eea6283e29a81a7379091ca89ab40 F test/thread001.test a3e6a7254d1cb057836cb3145b60c10bf5b7e60f @@ -734,7 +734,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746 -P 793c93be16af535e102dba147125384f6814cf5f -R 1442776f9e8f0f6893a042c65b60b787 -U danielk1977 -Z 5d9498adf02b6707d99160646d666866 +P 092b276e7d89bbfa3d8637a90ee5d458935a12a9 +R b6fd3af60cc74167321a8d8b03927552 +U drh +Z 9f245bb4702e4a85aca9a1d8b8f3ca18 diff --git a/manifest.uuid b/manifest.uuid index 82db0ce6b2..322a0f64b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -092b276e7d89bbfa3d8637a90ee5d458935a12a9 \ No newline at end of file +256ec3c6af41c2324db82e4deb54edbba5b581e8 \ No newline at end of file diff --git a/src/prepare.c b/src/prepare.c index fd01b77dd1..9e6b393bfe 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -13,7 +13,7 @@ ** interface, and routines that contribute to loading the database schema ** from disk. ** -** $Id: prepare.c,v 1.121 2009/06/04 00:11:56 drh Exp $ +** $Id: prepare.c,v 1.122 2009/06/16 17:49:36 drh Exp $ */ #include "sqliteInt.h" @@ -31,12 +31,12 @@ static void corruptSchema( if( zObj==0 ) zObj = "?"; sqlite3SetString(pData->pzErrMsg, pData->db, "malformed database schema (%s)", zObj); - if( zExtra && zExtra[0] ){ + if( zExtra ){ *pData->pzErrMsg = sqlite3MAppendf(pData->db, *pData->pzErrMsg, "%s - %s", *pData->pzErrMsg, zExtra); } } - pData->rc = SQLITE_CORRUPT; + pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT; } /* @@ -62,7 +62,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ DbClearProperty(db, iDb, DB_Empty); if( db->mallocFailed ){ corruptSchema(pData, argv[0], 0); - return SQLITE_NOMEM; + return 1; } assert( iDb>=0 && iDbnDb ); @@ -87,7 +87,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&0xff)!=SQLITE_LOCKED ){ + }else if( rc!=SQLITE_INTERRUPT ){ corruptSchema(pData, argv[0], zErr); } sqlite3DbFree(db, zErr); @@ -103,15 +103,15 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ */ Index *pIndex; pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zName); - if( pIndex==0 || pIndex->tnum!=0 ){ + if( pIndex==0 ){ /* This can occur if there exists an index on a TEMP table which ** has the same name as another index on a permanent index. Since ** the permanent table is hidden by the TEMP table, we can also ** safely ignore the index on the permanent table. */ /* Do Nothing */; - }else{ - pIndex->tnum = atoi(argv[1]); + }else if( sqlite3GetInt32(argv[1], &pIndex->tnum)==0 ){ + corruptSchema(pData, argv[0], "invalid rootpage"); } } return 0; @@ -197,7 +197,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ goto error_out; } pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName); - if( pTab ){ + if( ALWAYS(pTab) ){ pTab->tabFlags |= TF_Readonly; } @@ -205,7 +205,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ */ pDb = &db->aDb[iDb]; if( pDb->pBt==0 ){ - if( !OMIT_TEMPDB && iDb==1 ){ + if( !OMIT_TEMPDB && ALWAYS(iDb==1) ){ DbSetProperty(db, 1, DB_SchemaLoaded); } return SQLITE_OK; @@ -303,10 +303,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ /* Read the schema information out of the schema tables */ assert( db->init.busy ); - if( rc==SQLITE_EMPTY ){ - /* For an empty database, there is nothing to read */ - rc = SQLITE_OK; - }else{ + { char *zSql; zSql = sqlite3MPrintf(db, "SELECT name, rootpage, sql FROM '%q'.%s", @@ -380,7 +377,6 @@ int sqlite3Init(sqlite3 *db, char **pzErrMsg){ int commit_internal = !(db->flags&SQLITE_InternChanges); assert( sqlite3_mutex_held(db->mutex) ); - if( db->init.busy ) return SQLITE_OK; rc = SQLITE_OK; db->init.busy = 1; for(i=0; rc==SQLITE_OK && inDb; i++){ @@ -396,7 +392,8 @@ int sqlite3Init(sqlite3 *db, char **pzErrMsg){ ** schema may contain references to objects in other databases. */ #ifndef SQLITE_OMIT_TEMPDB - if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){ + if( rc==SQLITE_OK && ALWAYS(db->nDb>1) + && !DbHasProperty(db, 1, DB_SchemaLoaded) ){ rc = sqlite3InitOne(db, 1, pzErrMsg); if( rc ){ sqlite3ResetInternalSchema(db, 1); @@ -683,6 +680,10 @@ static int sqlite3LockAndPrepare( sqlite3_mutex_enter(db->mutex); sqlite3BtreeEnterAll(db); rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, ppStmt, pzTail); + if( rc==SQLITE_SCHEMA ){ + sqlite3_finalize(*ppStmt); + rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, ppStmt, pzTail); + } sqlite3BtreeLeaveAll(db); sqlite3_mutex_leave(db->mutex); return rc; diff --git a/test/lock.test b/test/lock.test index 03cd0e50dd..82da4b0d1a 100644 --- a/test/lock.test +++ b/test/lock.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this script is database locks. # -# $Id: lock.test,v 1.39 2009/03/28 15:04:24 drh Exp $ +# $Id: lock.test,v 1.40 2009/06/16 17:49:36 drh Exp $ set testdir [file dirname $argv0] @@ -80,7 +80,7 @@ do_test lock-1.13 { } {8 9} do_test lock-1.14.1 { catchsql {SELECT * FROM t2} db2 -} {1 {no such table: t2}} +} {0 {8 9}} do_test lock-1.14.2 { catchsql {SELECT * FROM t1} db2 } {0 {2 1}} diff --git a/test/temptable.test b/test/temptable.test index e6f3855158..ad85f7e9f6 100644 --- a/test/temptable.test +++ b/test/temptable.test @@ -12,7 +12,7 @@ # # This file implements tests for temporary tables and indices. # -# $Id: temptable.test,v 1.20 2009/02/10 11:17:43 danielk1977 Exp $ +# $Id: temptable.test,v 1.21 2009/06/16 17:49:36 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -180,7 +180,7 @@ do_test temptable-4.4.2 { catchsql { SELECT * FROM main.t2; } db2 -} {1 {no such table: main.t2}} +} {0 {9 8 7}} #do_test temptable-4.4.3 { # catchsql { # SELECT name FROM main.sqlite_master WHERE type='table';