/ Check-in [01d71b94]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add the --no-rowids option to the ".recover" command.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 01d71b947a7422081d5c7d6ac2c91b9c936dc41926ab58c92f4a088a64e8c051
User & Date: dan 2019-09-14 16:44:51
Context
2019-09-16
05:34
Fix a problem with processing CTEs that use a WINDOW clause. check-in: ca564d4b user: dan tags: trunk
2019-09-14
16:44
Add the --no-rowids option to the ".recover" command. check-in: 01d71b94 user: dan tags: trunk
16:21
Extra comments on fields of the Window object. check-in: 3dbed162 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/shell.c.in.

  3584   3584     ".quit                    Exit this program",
  3585   3585     ".read FILE               Read input from FILE",
  3586   3586   #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
  3587   3587     ".recover                 Recover as much data as possible from corrupt db.",
  3588   3588     "   --freelist-corrupt       Assume the freelist is corrupt",
  3589   3589     "   --recovery-db NAME       Store recovery metadata in database file NAME",
  3590   3590     "   --lost-and-found TABLE   Alternative name for the lost-and-found table",
         3591  +  "   --no-rowids              Do not attempt to recover rowid values",
         3592  +  "                            that are not also INTEGER PRIMARY KEYs",
  3591   3593   #endif
  3592   3594     ".restore ?DB? FILE       Restore content of DB (default \"main\") from FILE",
  3593   3595     ".save FILE               Write in-memory database into FILE",
  3594   3596     ".scanstats on|off        Turn sqlite3_stmt_scanstatus() metrics on or off",
  3595   3597     ".schema ?PATTERN?        Show the CREATE statements matching PATTERN",
  3596   3598     "     Options:",
  3597   3599     "         --indent            Try to pretty-print the schema",
................................................................................
  6588   6590     const char *zRecoveryDb = "";   /* Name of "recovery" database */
  6589   6591     const char *zLostAndFound = "lost_and_found";
  6590   6592     int i;
  6591   6593     int nOrphan = -1;
  6592   6594     RecoverTable *pOrphan = 0;
  6593   6595   
  6594   6596     int bFreelist = 1;              /* 0 if --freelist-corrupt is specified */
         6597  +  int bRowids = 1;                /* 0 if --no-rowids */
  6595   6598     for(i=1; i<nArg; i++){
  6596   6599       char *z = azArg[i];
  6597   6600       int n;
  6598   6601       if( z[0]=='-' && z[1]=='-' ) z++;
  6599   6602       n = strlen30(z);
  6600   6603       if( n<=17 && memcmp("-freelist-corrupt", z, n)==0 ){
  6601   6604         bFreelist = 0;
................................................................................
  6603   6606       if( n<=12 && memcmp("-recovery-db", z, n)==0 && i<(nArg-1) ){
  6604   6607         i++;
  6605   6608         zRecoveryDb = azArg[i];
  6606   6609       }else
  6607   6610       if( n<=15 && memcmp("-lost-and-found", z, n)==0 && i<(nArg-1) ){
  6608   6611         i++;
  6609   6612         zLostAndFound = azArg[i];
         6613  +    }else
         6614  +    if( n<=10 && memcmp("-no-rowids", z, n)==0 ){
         6615  +      bRowids = 0;
  6610   6616       }
  6611   6617       else{
  6612   6618         utf8_printf(stderr, "unexpected option: %s\n", azArg[i]); 
  6613   6619         showHelp(pState->out, azArg[0]);
  6614   6620         return 1;
  6615   6621       }
  6616   6622     }
................................................................................
  6768   6774     }
  6769   6775     shellFinalize(&rc, pLoop);
  6770   6776     pLoop = 0;
  6771   6777   
  6772   6778     shellPrepare(pState->db, &rc,
  6773   6779         "SELECT pgno FROM recovery.map WHERE root=?", &pPages
  6774   6780     );
         6781  +
  6775   6782     shellPrepare(pState->db, &rc,
  6776         -      "SELECT max(field), group_concat(shell_escape_crnl(quote(value)), ', ')"
         6783  +      "SELECT max(field), group_concat(shell_escape_crnl(quote"
         6784  +      "(case when (? AND field<0) then NULL else value end)"
         6785  +      "), ', ')"
  6777   6786         ", min(field) "
  6778   6787         "FROM sqlite_dbdata WHERE pgno = ? AND field != ?"
  6779   6788         "GROUP BY cell", &pCells
  6780   6789     );
  6781   6790   
  6782   6791     /* Loop through each root page. */
  6783   6792     shellPrepare(pState->db, &rc, 
................................................................................
  6804   6813         if( pTab==0 ) break;
  6805   6814       }
  6806   6815   
  6807   6816       if( 0==sqlite3_stricmp(pTab->zQuoted, "\"sqlite_sequence\"") ){
  6808   6817         raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n");
  6809   6818       }
  6810   6819       sqlite3_bind_int(pPages, 1, iRoot);
  6811         -    sqlite3_bind_int(pCells, 2, pTab->iPk);
         6820  +    if( bRowids==0 && pTab->iPk<0 ){
         6821  +      sqlite3_bind_int(pCells, 1, 1);
         6822  +    }else{
         6823  +      sqlite3_bind_int(pCells, 1, 0);
         6824  +    }
         6825  +    sqlite3_bind_int(pCells, 3, pTab->iPk);
  6812   6826   
  6813   6827       while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPages) ){
  6814   6828         int iPgno = sqlite3_column_int(pPages, 0);
  6815         -      sqlite3_bind_int(pCells, 1, iPgno);
         6829  +      sqlite3_bind_int(pCells, 2, iPgno);
  6816   6830         while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){
  6817   6831           int nField = sqlite3_column_int(pCells, 0);
  6818   6832           int iMin = sqlite3_column_int(pCells, 2);
  6819   6833           const char *zVal = (const char*)sqlite3_column_text(pCells, 1);
  6820   6834   
  6821   6835           RecoverTable *pTab2 = pTab;
  6822   6836           if( pTab!=pOrphan && (iMin<0)!=bIntkey ){