]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Enhance the ".imposter" command in the CLI so that the first argument
authordrh <drh@noemail.net>
Fri, 18 Oct 2019 15:58:50 +0000 (15:58 +0000)
committerdrh <drh@noemail.net>
Fri, 18 Oct 2019 15:58:50 +0000 (15:58 +0000)
can be an existing WITHOUT ROWID table instead of an index.  The resulting
imposter is the same table, but with columns in storage order and with
all constraints removed.

FossilOrigin-Name: 9dc0d34586eebf6705d9bd81494c417ac76707b8625d1ff99eda18b4ca2d8a50

manifest
manifest.uuid
src/shell.c.in

index be0eda8fcc97beff5cbf93dea132aaf075a4b31e..2cc6986f5ffd56bf9ebed378550750362ff73613 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Avoid\san\sinfinite\sloop\sin\sfts3/4\sincremental-merge\sin\sthe\scase\swhere\sthe\slowest\slevel\sin\sthe\sdatabase\scontains\ssegments\sbut\sno\sdata\s(because\sthere\sis\sa\sdelete-marker\sfor\seach\svalid\sentry).\sFix\sfor\s[bf1aab89].
-D 2019-10-17T15:41:36.813
+C Enhance\sthe\s".imposter"\scommand\sin\sthe\sCLI\sso\sthat\sthe\sfirst\sargument\ncan\sbe\san\sexisting\sWITHOUT\sROWID\stable\sinstead\sof\san\sindex.\s\sThe\sresulting\nimposter\sis\sthe\ssame\stable,\sbut\swith\scolumns\sin\sstorage\sorder\sand\swith\nall\sconstraints\sremoved.
+D 2019-10-18T15:58:50.284
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -526,7 +526,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c e021be0c1c4a2125fa38aabcd8dbb764bf5b2c889a948c30d3708430ec6ccd00
 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
 F src/select.c 7ef05eeb7f686f84dd1428cbdca280c898915bbf56e1ea97bd42ecc070af78d3
-F src/shell.c.in d70bcf630c4073eaa994fa74be98886c781918e794cb8b562be8df10f018e274
+F src/shell.c.in 3093bdf5eedd91da08f0268f1442aa510a60798c9441868149ddbecdf8bcaa79
 F src/sqlite.h.in 5725a6b20190a1e8d662077a1c1c8ea889ad7be90dd803f914c2de226f5fe6ab
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31
@@ -1847,7 +1847,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 bba975c7af3de9aeb5c62fb8b05d61b96e4ecd0b030008442bbdd345e1e5f134
-R c0ee123c55e0634eada3c2d56906af99
-U dan
-Z 5c41036d47f05063f5938d5d5c2f4f4a
+P 35beaee059a6cccead4311886ca928d936f23584cf435e35e265e98feea723dc
+R 79321ef818ef0b98008c7f3041b73ac3
+U drh
+Z 758d9d25f4ac17fe1f5333a4da39c6af
index 076e023d3b2f2844184414ce31de00e96eb8c060..c818b549f570bd5d82b36751e1e300cad8f03923 100644 (file)
@@ -1 +1 @@
-35beaee059a6cccead4311886ca928d936f23584cf435e35e265e98feea723dc
\ No newline at end of file
+9dc0d34586eebf6705d9bd81494c417ac76707b8625d1ff99eda18b4ca2d8a50
\ No newline at end of file
index 7f82675e3529289284db555c0a8360e2358da744..f2473ce1554996523fb2308f34e0ee701861e1d8 100644 (file)
@@ -7758,10 +7758,19 @@ static int do_meta_command(char *zLine, ShellState *p){
     char *zCollist = 0;
     sqlite3_stmt *pStmt;
     int tnum = 0;
+    int isWO = 0;  /* True if making an imposter of a WITHOUT ROWID table */
+    int lenPK = 0; /* Length of the PRIMARY KEY string for isWO tables */
     int i;
     if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){
       utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n"
                           "       .imposter off\n");
+      /* Also allowed, but not documented:
+      **
+      **    .imposter TABLE IMPOSTER
+      **
+      ** where TABLE is a WITHOUT ROWID table.  In that case, the
+      ** imposter is another WITHOUT ROWID table with the columns in
+      ** storage order. */
       rc = 1;
       goto meta_command_exit;
     }
@@ -7770,19 +7779,22 @@ static int do_meta_command(char *zLine, ShellState *p){
       sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 1);
       goto meta_command_exit;
     }
-    zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_master"
-                           " WHERE name='%q' AND type='index'", azArg[1]);
+    zSql = sqlite3_mprintf(
+      "SELECT rootpage, 0 FROM sqlite_master"
+      " WHERE name='%q' AND type='index'"
+      "UNION ALL "
+      "SELECT rootpage, 1 FROM sqlite_master"
+      " WHERE name='%q' AND type='table'"
+      "   AND sql LIKE '%%without%%rowid%%'",
+      azArg[1], azArg[1]
+    );
     sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
     sqlite3_free(zSql);
     if( sqlite3_step(pStmt)==SQLITE_ROW ){
       tnum = sqlite3_column_int(pStmt, 0);
+      isWO = sqlite3_column_int(pStmt, 1);
     }
     sqlite3_finalize(pStmt);
-    if( tnum==0 ){
-      utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]);
-      rc = 1;
-      goto meta_command_exit;
-    }
     zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]);
     rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
     sqlite3_free(zSql);
@@ -7799,6 +7811,9 @@ static int do_meta_command(char *zLine, ShellState *p){
           zCol = zLabel;
         }
       }
+      if( isWO && lenPK==0 && sqlite3_column_int(pStmt,5)==0 && zCollist ){
+        lenPK = (int)strlen(zCollist);
+      }
       if( zCollist==0 ){
         zCollist = sqlite3_mprintf("\"%w\"", zCol);
       }else{
@@ -7806,9 +7821,16 @@ static int do_meta_command(char *zLine, ShellState *p){
       }
     }
     sqlite3_finalize(pStmt);
+    if( i==0 || tnum==0 ){
+      utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]);
+      rc = 1;
+      sqlite3_free(zCollist);
+      goto meta_command_exit;
+    }
+    if( lenPK==0 ) lenPK = 100000;
     zSql = sqlite3_mprintf(
-          "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%s))WITHOUT ROWID",
-          azArg[2], zCollist, zCollist);
+          "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%.*s))WITHOUT ROWID",
+          azArg[2], zCollist, lenPK, zCollist);
     sqlite3_free(zCollist);
     rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum);
     if( rc==SQLITE_OK ){
@@ -7819,7 +7841,8 @@ static int do_meta_command(char *zLine, ShellState *p){
       }else{
         utf8_printf(stdout, "%s;\n", zSql);
         raw_printf(stdout,
-           "WARNING: writing to an imposter table will corrupt the index!\n"
+          "WARNING: writing to an imposter table will corrupt the \"%s\" %s!\n",
+          azArg[1], isWO ? "table" : "index"
         );
       }
     }else{