From: drh <> Date: Tue, 15 Feb 2022 20:56:16 +0000 (+0000) Subject: Merge the latest trunk enhancements into the reuse-schema branch. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cee8c84dc9d69930ac747924efee8bd2e1621751;p=thirdparty%2Fsqlite.git Merge the latest trunk enhancements into the reuse-schema branch. FossilOrigin-Name: b9ba43fcb3b727fc344ab754a0132a62ff640daff8cc2ca17fd41e57fba2168d --- cee8c84dc9d69930ac747924efee8bd2e1621751 diff --cc manifest index 6c9ee7db58,220535e5db..d4b4609f93 --- a/manifest +++ b/manifest @@@ -1,5 -1,5 +1,5 @@@ - C Merge\strunk\senhancements\sinto\sthe\sreuse-schema\sbranch. - D 2022-02-04T18:12:18.943 -C Improved\srendering\sof\sfloating\spoint\snumbers\swithout\sa\sfractional\spart\sin\n".dump"\soutput\sfrom\sthe\sCLI.\n[forum:/forumpost/550d877659f37cb2|Forum\spost\s550d877659f37cb2]. -D 2022-02-15T13:23:09.386 ++C Merge\sthe\slatest\strunk\senhancements\sinto\sthe\sreuse-schema\sbranch. ++D 2022-02-15T20:56:16.683 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@@ -486,21 -485,21 +486,21 @@@ F spec.template 86a4a43b99ebb3e75e6b9a7 F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a - F src/alter.c 8b4666867e919cae666dbd25384eeda184b5234ab36199662b32684cd4e6bfd0 -F src/alter.c e31cae888bc3077e34f9a82c6b4a96e4e44d37861eeb6472d68a378f1e8e46ba -F src/analyze.c 7518b99e07c5494111fe3bd867f28f804b6c5c1ad0703ec3d116de9bab3fa516 -F src/attach.c f26d400f3ffe2cdca01406bca70e5f58c5488bf165b4fc37c228136dfcf1b583 ++F src/alter.c 49c50b6b66b9d28269f1213ae7515c273a745a7837044745429bb66108248ad7 +F src/analyze.c b619f92ad33aa38c234d9620f576bceef56465088ed37f28c56d136a15c1a909 +F src/attach.c f8ca7d5c85edad72f2f21a9ae0589a93c75376938b90bdb6de777ce6aae1fb3d F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7 F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 - F src/btree.c ddab31c38d5f16114bc68392430556b1063fe14e0020f9a56d2c35ddd58ba7e3 + F src/btree.c 117808943727d27e38c69de4e79237e52c89ee40f6f1a70de4e6e14b5e596cbc F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h ee9348c4cb9077243b049edc93a82c1f32ca48baeabf2140d41362b9f9139ff7 - F src/build.c e47080c4ccf6f480b5764de136850c17e028f4ebf24bfc6f27f0a8e37bc8c6eb -F src/build.c b59ff41525c10b429adc277d3bca6e433b09d055b0df8c1529385763cea8bb04 -F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c ++F src/build.c 51694f9aaa4192038b9a4a353254494a5d032a76ed3def46192cf5830762bba9 +F src/callback.c f733593c95ed7ab24e0a0f57db6755b9bd433862d187766ec9f161ef7c79efeb F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c 2cce39df1a13e05b7633e6d21b651f21492471f991dd7b323a4ee4e7b7f0b7f1 +F src/ctime.c da293ceb565f07ad8ced251417913aec93030334d479dd4ce79946f7af464b0d - F src/date.c 41627dec396f3d33e2c317a065f9d59bb535982b2ea3a561c96e4d4cf1137b65 + F src/date.c 1fcc64294b0e81cc9fa05cf8f773e862dd004f74d023544d43edeeacbcfde7e5 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c b5f1716b4d723db48254ee0f896e362cd029e865e05414139ea7f539f3884e1d @@@ -517,7 -516,7 +517,7 @@@ F src/insert.c 1eea44389de3768ac98588c1 F src/json.c 225b00422112ecd7094a555f3ace16b25d7d5894062b823269ed03899907c2a2 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c aa919a6a7884f8b34d7b791841b24d14b1b0ab43f45b3940f4851043b2855c0c - F src/main.c 4c4bbf25bad9ec76e795e6b8dace2d43b09ff12fb498ce64a0101b371f4fa6e9 -F src/main.c 0840cee6984034c7e73cc747a1562c7eaed4673694bf20b00980aaa0672c0405 ++F src/main.c 36d30a911044d71060cb882f5ac80c75f27c7b3bef4012dfaef39ac76c12c043 F src/malloc.c fec841aa0a0400a6f7d20706178a5d8e8219a6bf562b6fe712c17f6c26813266 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@@ -546,24 -545,24 +546,24 @@@ F src/parse.y 0f02b27cdaa334441463153ff F src/pcache.c 084e638432c610f95aea72b8509f0845d2791293f39d1b82f0c0a7e089c3bb6b F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65 -F src/pragma.c 7c024d690a3dc93f61830f11f900e4af2357f31d081b0c79099ca5e28919cba7 -F src/pragma.h 87330ed2fbfa2a1274de93ca0ab850fba336189228cb256089202c3b52766fad -F src/prepare.c a187dade741c1f09ae118fcbbf0302511807bfc0355880927d7152eb75b8260d +F src/pragma.c 770a2ce23196a4d6b88026848ec2a347264fb2e23efc0a0a0ce58e55c99680a1 +F src/pragma.h 270bff5fefbc3c56ddcb5627d706904ec289853a5ef65662f6fac810b5a1923f +F src/prepare.c d4db4954fb04c76ed20cd478818fbcc49163487197c95dfac871d48a29dfe445 - F src/printf.c 975f1f5417f2526365b6e6d7f22332e3e11806dad844701d92846292b654ba9a + F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c - F src/resolve.c 0dd8e23fda88411d63b2e6650f2380fdb08e88112e9a095fc23d5a08de4b2641 + F src/resolve.c ea935b87d6fb36c78b70cdc7b28561dc8f33f2ef37048389549c7b5ef9b0ba5e F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 - F src/select.c a6d2d4bed279d7fe4fcedaf297eaf6441e8e17c6e3947a32d24d23be52ac02f2 - F src/shell.c.in b10eb9d17bcb1e83977a23d11834064c03951709db2771d8cd05f777c61b4cf5 - F src/sqlite.h.in 6e3f9a292c2733c5893d3ce4e93a9e6860b5035e3e0710b7afc8d272f1d9126e + F src/select.c 3baa9dd8cf240654773c7974e2bcce398ac9dd24419c36684156963defe43b35 -F src/shell.c.in b5b44c2ebfd3942e60dbcc47b94a74337a482a5f1c3766fbfb9f578a605ecf50 -F src/sqlite.h.in 7047c4b60fa550264d6363bb1d983540e7828fb19d2d1e5aa43b52ca13144807 ++F src/shell.c.in c69ef43b1e41faba024659dbf397a0306f7618a6bdfda0fe1d28e0f67ea3a46e ++F src/sqlite.h.in 8c07906adabb35f13401545d47093bdaf7697bc32af9c447d5dbdc58daa01a6b F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h a95cb9ed106e3d39e2118e4dcc15a14faec3fa50d0093425083d340d9dfd96e6 - F src/sqliteInt.h 2a03a8fd759b8eb4e80febdcc365176963c56d9603a2274b0beb8e249a8cbbac -F src/sqliteInt.h f8814239fb1f95056555e2d7fa475750e64681cac4221fb03610d1fde0b79d53 ++F src/sqliteInt.h 698eac5ed8c0b7abc5a0cfc64db79c4984b7c7d824fc145153e5d76bc1207508 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 -F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 +F src/status.c d0956e57c71160155f620a3efeb1e5c05a3f8b9a897dd09c5263268e5d237579 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 -F src/tclsqlite.c 48f291e1a7e672a7204884d4c164a8ed3a522ff087c361ada2991f5d54e987f6 +F src/tclsqlite.c d59959ac596aa96b60575ebf863e295a105e617f6aa28bc0188252e134e15308 - F src/test1.c 9287559cc1f7c5a25f927aa172e69778237f0e037960dbcdb4257d0bea500114 + F src/test1.c 87fda59eea3ac1eba1baef37c1967565cb1b8d6d264649f2e57f252ca5989914 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 F src/test4.c 7c4420e01c577b5c4add2cb03119743b1a357543d347773b9e717195ea967159 @@@ -618,20 -616,20 +618,20 @@@ F src/test_windirent.h 90dfbe95442c9762 F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c - F src/tokenize.c b74d878aa7c82ec8460779468061a96185e22257f68ab785b69abce354b70446 - F src/treeview.c 9dfdb7ff7f6645d0a6458dbdf4ffac041c071c4533a6db8bb6e502b979ac67bc - F src/trigger.c d3acee607e4394d542486ec3791f542d677f2c26f1e4914c2db6cb5bc4e4b18d + F src/tokenize.c 6661a9fa660ecbd3ac0df1acd2ec788b3a8122b4316022bcdaf476ea6754a8de + F src/treeview.c a84b57d15e46007d8b1ae249344b3f0b7f3c62def908b98baaa54935a57c8476 -F src/trigger.c 19fc6fe696a2409b04496df1ff044e6a942dad6ed3b6e897b1c9093b88cc2c62 ++F src/trigger.c fd9e95f81ea08b673e7f7c34d09eb391ad0c8a2a25b4ec957e6daa8052fba7ba F src/update.c f875b0d59da5c3055a0b2ac20560e1650229c6787e78de5e9836267b5cbb8359 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 -F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 13a4de20ee07bdfb3dc74ab49b7912208e309caf762a8d1678fb111e2223af35 -F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe +F src/vacuum.c 97424abbd3b5831d0142349a3c2dad52c364e39fab67f7e0f5c60d2694463940 +F src/vdbe.c d2c9c7253a45904e54fcacd27aa95a11afa81a8629c54bc2ece48f31975fe0d4 +F src/vdbe.h bfde0b0f429a0ba4203e5319780a6a1c8b2a809c5cd6baa9ae22e257a657b8b3 F src/vdbeInt.h b45599a2b59f1ce042512ab6786b0b82a8cf3002f6b0fa60b4834e2cd3ac61d8 - F src/vdbeapi.c 06bff35393ca5daa3e02e38fb516df320bd52720a2781eb70c2db23ea1c746dd - F src/vdbeaux.c 3610e6cd3dce57f7343a2f72e68b31bff9f9f6b234ed93f86c23fbea075a9467 + F src/vdbeapi.c 8863ffb5a7bac42fe9a68aaa3526ee29fc18fb02a9b27188b756de41e33856e9 -F src/vdbeaux.c 0d7659fe8cb38ce86092b9bc5131c99a834a04eb78745e54acb77d79d7af2fb5 -F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd ++F src/vdbeaux.c 3a86053ed0f9ffbbbab8562d9d67657f64223d5e5ef9b23f82d76c9b5c0a4ceb +F src/vdbeblob.c aa23a326ff86bdde8f7ba74cf23c3e1795b13bee749314feaf26273be2f63e89 F src/vdbemem.c eb6042667c02c3ef1f968235b4a170e31b23a4b6a57f65a8454eab4d36f14b7f F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 @@@ -1953,8 -1944,8 +1954,8 @@@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a9 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 - P 6e4154d414afe2562b488149b10c175d1f15bd1d5060ee479d5ae9386a2e277e 70049342d5ad57ea3e863bba19253934b868bacdd1c26c9371bac024a829badf - R 248ce427f0306aa7b258afb10db1e13b -P d74ec88c2f9b9e056988add8322186750229e14a609d1a6969ba393a5b8c5174 -R d44a4dfcecd9d59ae3b06dca8b590f27 ++P 5744e1020b63f9eb89c12d6ea3ba33e17a6fea1478625c22240dcae50b50203e 9edaeed56f2282fd4da935454178c38ab49d259aed96d4e720aae09050a53006 ++R 1142ea2f6e5625fc0a7892851ce38f11 U drh - Z c006aaa0e3998853163eb4c36b2cbc85 -Z 28d22f7919d651ae0bfc81a1c20dfd1c ++Z 5e31661c5cd02a28b5f1a814ad2ce795 # Remove this line to create a well-formed Fossil manifest. diff --cc manifest.uuid index 8e124129b4,cf24b67f55..dc4dc79272 --- a/manifest.uuid +++ b/manifest.uuid @@@ -1,1 -1,1 +1,1 @@@ - 5744e1020b63f9eb89c12d6ea3ba33e17a6fea1478625c22240dcae50b50203e -9edaeed56f2282fd4da935454178c38ab49d259aed96d4e720aae09050a53006 ++b9ba43fcb3b727fc344ab754a0132a62ff640daff8cc2ca17fd41e57fba2168d diff --cc src/shell.c.in index 77e45bc374,3ff1f62c72..c9ae8d2c89 --- a/src/shell.c.in +++ b/src/shell.c.in @@@ -7227,238 -7227,8 +7239,239 @@@ static char *shellMPrintf(int *pRc, con } return z; } +static int sharedSchemaFix(ShellState *pState, const char *zDb, int eFix){ + int rc = SQLITE_OK; + i64 iLast = 0; + int iCookie = 0; + int iAutoVacuum = 0; + sqlite3_stmt *pStmt = 0; + + shellExecPrintf(pState->db, &rc, "ATTACH '%q' AS _shared_schema_tmp", zDb); + shellExecPrintf(pState->db, &rc, "PRAGMA writable_schema = 1"); + shellExecPrintf(pState->db, &rc, "BEGIN"); + shellPreparePrintf(pState->db, &rc, &pStmt, + "SELECT max(rowid) FROM _shared_schema_tmp.sqlite_master" + ); + sqlite3_step(pStmt); + iLast = sqlite3_column_int64(pStmt, 0); + shellFinalize(&rc, pStmt); + shellPreparePrintf(pState->db, &rc, &pStmt, + "INSERT INTO _shared_schema_tmp.sqlite_master SELECT " + " type, name, tbl_name, (" + " SELECT rootpage FROM _shared_schema_tmp.sqlite_master WHERE " + " type IS o.type AND name IS o.name AND rowid<=?" + " ), sql FROM main.sqlite_master AS o" + ); + sqlite3_bind_int64(pStmt, 1, iLast); + sqlite3_step(pStmt); + shellFinalize(&rc, pStmt); + + shellExecPrintf(pState->db, &rc, + "DELETE FROM _shared_schema_tmp.sqlite_master WHERE rowid<=%lld", + iLast + ); + shellExecPrintf(pState->db, &rc, "COMMIT"); + sqlite3_exec(pState->db, "PRAGMA writable_schema = 0", 0, 0, 0); + + /* Copy the auto-vacuum setting from main to the target db */ + shellPreparePrintf(pState->db, &rc, &pStmt, "PRAGMA main.auto_vacuum"); + sqlite3_step(pStmt); + iAutoVacuum = sqlite3_column_int(pStmt, 0); + shellFinalize(&rc, pStmt); + shellExecPrintf(pState->db, &rc, + "PRAGMA _shared_schema_tmp.auto_vacuum = %d", iAutoVacuum + ); + + /* Vacuum the db in order to standardize the rootpage numbers. */ + shellExecPrintf(pState->db, &rc, "VACUUM _shared_schema_tmp"); + + /* Set the schema-cookie value to the same as database "main" */ + shellPreparePrintf(pState->db, &rc, &pStmt, "PRAGMA main.schema_version"); + sqlite3_step(pStmt); + iCookie = sqlite3_column_int(pStmt, 0); + shellFinalize(&rc, pStmt); + shellExecPrintf(pState->db, &rc, + "PRAGMA _shared_schema_tmp.schema_version = %d", iCookie + ); + + sqlite3_exec(pState->db, "DETACH _shared_schema_tmp", 0, 0, 0); + return rc; +} + +static int sharedSchemaCheck(ShellState *pState, const char *zDb, int *peFix){ + int rc = SQLITE_OK; + int bFailed = 0; + sqlite3_stmt *pStmt = 0; + + if( peFix ) *peFix = 0; + shellExecPrintf(pState->db, &rc, "ATTACH '%q' AS _shared_schema_tmp", zDb); + + /* Check if this database has the same set of objects as the current db */ + shellPreparePrintf(pState->db, &rc, &pStmt, + "SELECT type, name FROM _shared_schema_tmp.sqlite_master AS o " + "WHERE NOT EXISTS (" + " SELECT 1 FROM main.sqlite_master " + " WHERE name IS o.name AND type IS o.type" + ")" + " UNION ALL " + "SELECT type, name FROM main.sqlite_master AS o " + "WHERE NOT EXISTS (" + " SELECT 1 FROM _shared_schema_tmp.sqlite_master " + " WHERE name IS o.name AND type IS o.type" + ")" + ); + if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + utf8_printf(pState->out, "%s is NOT compatible (objects)\n", zDb); + bFailed = 1; + } + shellFinalize(&rc, pStmt); + + /* Check if this database has the same set of SQL statements as the + ** current db. */ + if( bFailed==0 ){ + shellPreparePrintf(pState->db, &rc, &pStmt, + "SELECT 1 FROM _shared_schema_tmp.sqlite_master AS o " + "WHERE sql IS NOT (" + " SELECT sql FROM main.sqlite_master " + " WHERE name IS o.name AND type IS o.type" + ")" + ); + if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + utf8_printf(pState->out, "%s is NOT compatible (SQL)\n", zDb); + bFailed = 1; + } + shellFinalize(&rc, pStmt); + } + + /* Check if this database has the same set of root pages as the current + ** db. */ + if( bFailed==0 ){ + shellPreparePrintf(pState->db, &rc, &pStmt, + "SELECT 1 FROM _shared_schema_tmp.sqlite_master AS o " + "WHERE rootpage IS NOT (" + " SELECT rootpage FROM main.sqlite_master " + " WHERE name IS o.name AND type IS o.type" + ")" + ); + if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + if( peFix==0 ){ + utf8_printf(pState->out, "%s is NOT compatible (root pages)\n", zDb); + } + bFailed = 1; + if( peFix ) *peFix = 1; + } + shellFinalize(&rc, pStmt); + } + + if( bFailed==0 ){ + shellPreparePrintf(pState->db, &rc, &pStmt, + "SELECT 1 WHERE (" + " SELECT group_concat(rootpage || '.' || name || '.' || sql, '.') " + " FROM _shared_schema_tmp.sqlite_master" + ") IS NOT (" + " SELECT group_concat(rootpage || '.' || name || '.' || sql, '.') " + " FROM main.sqlite_master" + ")" + ); + if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + if( peFix==0 ){ + utf8_printf(pState->out, + "%s is NOT compatible (order of sqlite_master rows)\n", zDb + ); + } + bFailed = 1; + if( peFix ) *peFix = 2; + } + shellFinalize(&rc, pStmt); + } + + if( bFailed==0 ){ + int iMain = -1; + int iNew = +1; + shellPreparePrintf(pState->db, &rc, &pStmt, + "PRAGMA main.schema_version" + ); + if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + iMain = sqlite3_column_int(pStmt, 0); + } + shellFinalize(&rc, pStmt); + shellPreparePrintf(pState->db, &rc, &pStmt, + "PRAGMA _shared_schema_tmp.schema_version" + ); + if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + iNew = sqlite3_column_int(pStmt, 0); + } + shellFinalize(&rc, pStmt); + if( rc==SQLITE_OK && iMain!=iNew ){ + if( peFix==0 ){ + utf8_printf(pState->out, + "%s is NOT compatible (schema cookie)\n", zDb + ); + } + bFailed = 1; + if( peFix ) *peFix = 3; + } + } + + if( rc==SQLITE_OK && bFailed==0 ){ + utf8_printf(pState->out, "%s is compatible\n", zDb); + } + + sqlite3_exec(pState->db, "DETACH _shared_schema_tmp", 0, 0, 0); + return rc; +} + +/* +** .shared-schema check|fix DB1 DB2... +*/ +static int sharedSchemaDotCommand( + ShellState *pState, /* Current shell tool state */ + char **azArg, /* Array of arguments passed to dot command */ + int nArg /* Number of entries in azArg[] */ +){ + int rc = SQLITE_OK; + int bFix = 0; /* Fix databases if possible */ + int n1; + int i; + if( nArg<3 ){ + goto shared_schema_usage; + } + + n1 = (int)strlen(azArg[1]); + if( n1>0 && n1<=3 && memcmp("fix", azArg[1], n1)==0 ){ + bFix = 1; + }else if( n1==0 || n1>5 || memcmp("check", azArg[1], n1) ){ + goto shared_schema_usage; + } + + for(i=2; rc==SQLITE_OK && iout, "Fixing %s... ", azArg[i]); + fflush(pState->out); + rc = sharedSchemaFix(pState, azArg[i], eFix); + if( rc==SQLITE_OK ){ + rc = sharedSchemaCheck(pState, azArg[i], &eFix); + if( rc==SQLITE_OK && eFix ){ + utf8_printf(pState->out, "VACUUMing main... "); + fflush(pState->out); + rc = sqlite3_exec(pState->db, "VACUUM main", 0, 0, 0); + if( rc==SQLITE_OK ){ + rc = sharedSchemaCheck(pState, azArg[i], 0); + } + } + } + } + } + + return rc; + shared_schema_usage: + raw_printf(stderr, "usage: .shared-schema check|fix DB1 DB2...\n"); + return SQLITE_ERROR; +} + /* ** When running the ".recover" command, each output table, and the special ** orphaned row table if it is required, is represented by an instance