]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Merge the latest trunk enhancements into the reuse-schema branch.
authordrh <>
Tue, 15 Feb 2022 20:56:16 +0000 (20:56 +0000)
committerdrh <>
Tue, 15 Feb 2022 20:56:16 +0000 (20:56 +0000)
FossilOrigin-Name: b9ba43fcb3b727fc344ab754a0132a62ff640daff8cc2ca17fd41e57fba2168d

1  2 
manifest
manifest.uuid
src/alter.c
src/build.c
src/main.c
src/shell.c.in
src/sqlite.h.in
src/sqliteInt.h
src/trigger.c
src/vdbeaux.c

diff --cc manifest
index 6c9ee7db58fe01f961c62867cd47e237733274d9,220535e5db7139e3fe1ac0d1e4956bfa7b4bab80..d4b4609f937e5d99e6f98a900824415572bb060e
+++ 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 8e124129b45881746d6caea1f8e0eae7496d6944,cf24b67f55d60373e3186fdcf36b36a90e108da1..dc4dc792729ab00c0bc683c4f8421935ec538733
@@@ -1,1 -1,1 +1,1 @@@
- 5744e1020b63f9eb89c12d6ea3ba33e17a6fea1478625c22240dcae50b50203e
 -9edaeed56f2282fd4da935454178c38ab49d259aed96d4e720aae09050a53006
++b9ba43fcb3b727fc344ab754a0132a62ff640daff8cc2ca17fd41e57fba2168d
diff --cc src/alter.c
Simple merge
diff --cc src/build.c
Simple merge
diff --cc src/main.c
Simple merge
diff --cc src/shell.c.in
index 77e45bc37432be6fdea7671e0b04c9885cee6573,3ff1f62c72da3e63a1c7b740e436250fee244a1a..c9ae8d2c89e2b389bf2140f5896a680785aca81e
@@@ -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 && i<nArg; i++){
 +    int eFix = 0;
 +    rc = sharedSchemaCheck(pState, azArg[i], bFix ? &eFix : 0);
 +    if( rc==SQLITE_OK && bFix && eFix ){
 +      utf8_printf(pState->out, "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
diff --cc src/sqlite.h.in
Simple merge
diff --cc src/sqliteInt.h
Simple merge
diff --cc src/trigger.c
Simple merge
diff --cc src/vdbeaux.c
Simple merge