From 239f69e204c7878042db1dbddac535b542b40ed4 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 20 Feb 2019 18:44:28 +0000 Subject: [PATCH] Further test cases and fixes for SQLITE_OPEN_SHARED_SCHEMA. FossilOrigin-Name: ba0ab042f401a9d3b81dc546573214bbe2ad712c932aafcf0c045f189bbf09ca --- manifest | 21 ++++++++++--------- manifest.uuid | 2 +- src/build.c | 2 +- src/callback.c | 35 +++++++++++++++---------------- src/prepare.c | 5 ++++- src/vdbe.c | 14 ++++++------- test/reuse3.test | 32 +++++++++++++++++++++++++++++ test/reusefault.test | 49 ++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 121 insertions(+), 39 deletions(-) create mode 100644 test/reusefault.test diff --git a/manifest b/manifest index ba04044a8a..43ff01c5d9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\sand\sfixes\sfor\sSQLITE_OPEN_SHARED_SCHEMA\smode. -D 2019-02-20T17:36:10.699 +C Further\stest\scases\sand\sfixes\sfor\sSQLITE_OPEN_SHARED_SCHEMA. +D 2019-02-20T18:44:28.122 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in 56456706c4da271309914c756c9c8ea537685f1c79f8785afa72f968d6810482 @@ -459,8 +459,8 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 161b6a57b91d160065e512a4d0be180e402a16a059034a380cbdc2411924f8ac F src/btree.h 63b94fb38ce571c15eb6a3661815561b501d23d5948b2d1e951fbd7a2d04e8d3 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f -F src/build.c 80f9e220e3a519e3a78324f20826285f473fe99b9ae5c95267b98f302013fe74 -F src/callback.c df42b5473587c3322038d594be585a6d92d532e1a67f5c340b324de887b8a44a +F src/build.c f0bc756bdb18bd5733b1b7cc35a3d4d637c307908a21c279d5a348d7b4b22085 +F src/callback.c f8b769a9344624b8df474480762ea7d2e7e925fe754f7eca53457b6ed88a1116 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 109e58d00f62e8e71ee1eb5944ac18b90171c928ab2e082e058056e1137cc20b F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957 @@ -510,7 +510,7 @@ F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c a72804486dfa8e4b6bc30d666c97ecf1155f91a4351fc6e48ea4097e4eb304fb F src/pragma.c af67dedaad8bafe9a5f9adcec32a0da6dd118617dd8220ad1d118f5a6bf83a02 F src/pragma.h a776bb9c915207e9d1117b5754743ddf1bf6a39cc092a4a44e74e6cb5fab1177 -F src/prepare.c 3e1c9aefe1bbb1efe6e07e2486acb8c2d5c533cb059b9be4fc7eaadc7303477a +F src/prepare.c 48cea94dcae45d83ab1a3db75c23c8b4d610a4c1199542242e7bd110047dc961 F src/printf.c cbf27c320091a83279d1738f68a27a9fe01698c607ce80516ab6bdb5a9c36a1a F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 1588690ee4cc39b4b9ea3230d4e3543d5ec3b5e898c87521f1375af0f1934cd4 @@ -587,7 +587,7 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5 F src/util.c 82a2e3f691a3b654be872e305dab1f455e565dedf5e6a90c818c1ab307c00432 F src/vacuum.c 7dbed4a756f014f3ce54e6ae3c403ee725e8179cf73fc6dd5c064e5627649f9f -F src/vdbe.c c67c8c46bea825421ee97511328fe1405537b586cbbe4db06e17c4ac5ab4dbed +F src/vdbe.c fbf91457c385c1606c3aa329ced716f51b31a1eed00b964547acd9c0f65d9e11 F src/vdbe.h 323218c4bfd64c719ba85d05fbc87cdd126991cadb39e73ccac7b59f30c3d53e F src/vdbeInt.h a76d5eed62c76bcd8de7afd3147fac1bc40c5a870582664bcd7d071ef437c37f F src/vdbeapi.c 57a2d794a8833f269b878dbc24e955369bdb379af6c4e93ebc5ce1a20fa3daf4 @@ -1229,8 +1229,9 @@ F test/resetdb.test 8062cf10a09d8c048f8de7711e94571c38b38168db0e5877ba7561789e5e F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/reuse1.test 31c312375ccfcc5c2abc1fca5e4a89d6309c57ea6b1fa3179a5eee68016f9c74 F test/reuse2.test 04d88621f0c51a8b3bf5512b9e61a5d7a61059e33097a1a6b1c6f6cf2d1f2a35 -F test/reuse3.test ff322d93790008578ca1c3e716d3fc981e9c4d870a99c3177521764f1ec5550c +F test/reuse3.test 75071034556d4915066adc249bfac364c6ed0fc62c997c4b02410fdacd3bfb9d F test/reuse4.test 1aef94898fd51bc87750d81074185a4f57cccd0bf87b9f98ae58b9c799452d42 +F test/reusefault.test 5d60bfbcaccfaffa02132f2137d849dc4b3802da8a929054e23f483bf5dc06e4 F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa F test/rollback2.test bc868d57899dc6972e2b4483faae0e03365a0556941474eec487ae21d8d38bb6 F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a @@ -1810,7 +1811,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8ac75b8a880447ea67cf7646fc5af1379ce35861f396634119d7381e1dde404a -R 5f4776749e5c7ce4a4f932d0629de2a0 +P 9a78d89c8427ae737d4798cc146e41ada7cb83f4e39dcf3ac9469c510ed37673 +R 6a956f8e6aa6f2bdacdc692c9ff15631 U dan -Z c8bea540cedb5b2e606c76fa8a2b79be +Z 822fb161bbeb9af3ca5278592f9b92a4 diff --git a/manifest.uuid b/manifest.uuid index 95f8251524..22ab9c315f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9a78d89c8427ae737d4798cc146e41ada7cb83f4e39dcf3ac9469c510ed37673 \ No newline at end of file +ba0ab042f401a9d3b81dc546573214bbe2ad712c932aafcf0c045f189bbf09ca \ No newline at end of file diff --git a/src/build.c b/src/build.c index 42690f1f50..78270d2378 100644 --- a/src/build.c +++ b/src/build.c @@ -304,7 +304,7 @@ int sqlite3SchemaLoad(sqlite3 *db, int iDb, int *pbUnload, char **pzErr){ memset(&db->init, 0, sizeof(struct sqlite3InitInfo)); rc = sqlite3InitOne(db, iDb, pzErr, 0); db->init = sv; - *pbUnload = (iDb!=1); + *pbUnload = (rc==SQLITE_OK && (iDb!=1)); } return rc; } diff --git a/src/callback.c b/src/callback.c index 8baecc5f47..c3abfb1dce 100644 --- a/src/callback.c +++ b/src/callback.c @@ -678,7 +678,7 @@ int sqlite3SchemaConnect(sqlite3 *db, int iDb, u64 cksum){ /* If the SchemaPool contains one or more free schemas at the moment, ** delete one of them. */ - if( p->pSchema ){ + if( p && p->pSchema ){ Schema *pDel = p->pSchema; p->pSchema = pDel->pNext; schemaDelete(pDel); @@ -707,7 +707,7 @@ int sqlite3SchemaConnect(sqlite3 *db, int iDb, u64 cksum){ */ int sqlite3SchemaDisconnect(sqlite3 *db, int iDb, int bNew){ int rc = SQLITE_OK; - if( IsReuseSchema(db) && iDb!=1 ){ + if( IsReuseSchema(db) ){ Db *pDb = &db->aDb[iDb]; SchemaPool *pSPool = pDb->pSPool; assert_schema_state_ok(db); @@ -715,10 +715,9 @@ int sqlite3SchemaDisconnect(sqlite3 *db, int iDb, int bNew){ if( pSPool==0 ){ assert( pDb->pVTable==0 ); - if( bNew==0 ){ - schemaDelete(pDb->pSchema); - pDb->pSchema = 0; - } + assert( bNew==0 ); + schemaDelete(pDb->pSchema); + pDb->pSchema = 0; }else{ VTable *p; VTable *pNext; @@ -768,15 +767,13 @@ int sqlite3SchemaDisconnect(sqlite3 *db, int iDb, int bNew){ */ Schema *sqlite3SchemaExtract(SchemaPool *pSPool){ Schema *pRet = 0; - if( pSPool ){ - sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); - if( pSPool->pSchema ){ - pRet = pSPool->pSchema; - pSPool->pSchema = pRet->pNext; - pRet->pNext = 0; - } - sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); + sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); + if( pSPool->pSchema ){ + pRet = pSPool->pSchema; + pSPool->pSchema = pRet->pNext; + pRet->pNext = 0; } + sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); return pRet; } @@ -811,9 +808,7 @@ void sqlite3SchemaRelease(sqlite3 *db, int iDb){ assert( iDb!=1 ); assert_schema_state_ok(db); sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); - if( pDb->pSPool && DbHasProperty(db, iDb, DB_SchemaLoaded) ){ - schemaRelease(db, pDb); - } + schemaRelease(db, pDb); sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); } @@ -827,9 +822,11 @@ void sqlite3SchemaRelease(sqlite3 *db, int iDb){ Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ Schema *p; if( pBt && (db->openFlags & SQLITE_OPEN_SHARED_SCHEMA)==0 ){ - p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaClear); + p = (Schema*)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaClear); }else{ - p = (Schema *)sqlite3DbMallocZero(0, sizeof(Schema)); + db->lookaside.bDisable++; + p = (Schema*)sqlite3DbMallocZero(db, sizeof(Schema)); + db->lookaside.bDisable--; } if( !p ){ sqlite3OomFault(db); diff --git a/src/prepare.c b/src/prepare.c index 6496de215b..573771a352 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -140,7 +140,10 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ pData->rc = rc; if( rc==SQLITE_NOMEM ){ sqlite3OomFault(db); - }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ + }else if( rc!=SQLITE_INTERRUPT + && (rc&0xFF)!=SQLITE_LOCKED + && (rc&0xFF)!=SQLITE_IOERR + ){ corruptSchema(pData, argv[0], sqlite3_errmsg(db)); } } diff --git a/src/vdbe.c b/src/vdbe.c index 880d16adfe..13ab3b6880 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3292,13 +3292,6 @@ case OP_Transaction: { && (iMeta!=pOp->p3 || db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i) ){ - /* - ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema - ** version is checked to ensure that the schema has not changed since the - ** SQL statement was prepared. - */ - sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); /* If the schema-cookie from the database file matches the cookie ** stored with the in-memory representation of the schema, do ** not reload the schema from the database file. @@ -3315,6 +3308,13 @@ case OP_Transaction: { if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){ sqlite3ResetOneSchema(db, pOp->p1); } + /* + ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema + ** version is checked to ensure that the schema has not changed since the + ** SQL statement was prepared. + */ + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); p->expired = 1; rc = SQLITE_SCHEMA; } diff --git a/test/reuse3.test b/test/reuse3.test index 8de51682de..f155bf7cbb 100644 --- a/test/reuse3.test +++ b/test/reuse3.test @@ -273,5 +273,37 @@ do_test 5.5 { catchsql { SELECT nref,nschema FROM schemapool } db2 } {0 {1 1}} +db2 close +db close +do_test 5.6.1 { + forcedelete test.db2 test.db2-wal test.db2-journal + forcecopy test.db test.db2 + sqlite3 db test.db + sqlite3 db2 test.db -shared-schema 1 + sqlite3 db3 test.db2 -shared-schema 1 + register_schemapool_module db +} {} + +do_execsql_test -db db2 5.6.2 { SELECT * FROM t1 } +do_execsql_test -db db3 5.6.3 { SELECT * FROM t1 } +do_execsql_test 5.6.4 { + SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool; + CREATE TABLE t4(x); + DROP TABLE t4; +} {nref=2 nschema=1} +do_execsql_test -db db2 5.6.5 { SELECT * FROM t1 } +do_execsql_test -db db3 5.6.6 { SELECT * FROM t1 } +do_execsql_test 5.6.7 { + SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool; + ATTACH 'test.db2' AS db2; + CREATE TABLE db2.t4(x); + DROP TABLE db2.t4; +} {nref=1 nschema=1 nref=1 nschema=1} +do_execsql_test -db db2 5.6.8 { SELECT * FROM t1 } +do_execsql_test -db db3 5.6.9 { SELECT * FROM t1 } +do_execsql_test 5.6.10 { + SELECT 'nref=' || nRef, 'nschema=' || nSchema FROM schemapool; +} {nref=2 nschema=1} + finish_test diff --git a/test/reusefault.test b/test/reusefault.test new file mode 100644 index 0000000000..fabc5aedc4 --- /dev/null +++ b/test/reusefault.test @@ -0,0 +1,49 @@ +# 2019 February 12 +# +# 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. +# +#*********************************************************************** +# +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix reusefault + +do_execsql_test 1.0 { + PRAGMA cache_size = 10; + CREATE TABLE t1(a UNIQUE, b UNIQUE); + INSERT INTO t1 VALUES(1, 2), (3, 4); +} +faultsim_save_and_close + +do_faultsim_test 1.1 -prep { + faultsim_restore + sqlite3 db test.db -shared-schema 1 +} -body { + execsql { SELECT * FROM t1 } +} -test { + faultsim_test_result {0 {1 2 3 4}} +} + +do_faultsim_test 1.2 -prep { + faultsim_restore + sqlite3 db test.db -shared-schema 1 + execsql { SELECT * FROM t1 } + sqlite3 db2 test.db + db2 eval {CREATE TABLE a(a)} + db2 close +} -body { + execsql { SELECT * FROM t1 } +} -test { + faultsim_test_result {0 {1 2 3 4}} +} + + +finish_test +