/ Check-in [9c458acba5]
Login

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

Overview
Comment:Improve the ".recover" command so that it handles intkey pages linked into non-intkey b-trees, and vice-versa, better.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 9c458acba5a100a76148a3efb78ea9f57b85751e80788e4532694bd8976608a0
User & Date: dan 2019-07-24 20:10:27
Context
2019-07-24
23:15
Fix faulty asserts in the code generator. Ticket [c52b09c7f38903b1] check-in: 01cdc590f7 user: drh tags: trunk
20:10
Improve the ".recover" command so that it handles intkey pages linked into non-intkey b-trees, and vice-versa, better. check-in: 9c458acba5 user: dan tags: trunk
19:20
Improve the ".recover" command's handling of corrupt database schemas. check-in: becaaa4d29 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/shell.c.in.

  6736   6736     pLoop = 0;
  6737   6737   
  6738   6738     shellPrepare(pState->db, &rc,
  6739   6739         "SELECT pgno FROM recovery.map WHERE root=?", &pPages
  6740   6740     );
  6741   6741     shellPrepare(pState->db, &rc,
  6742   6742         "SELECT max(field), group_concat(shell_escape_crnl(quote(value)), ', ')"
         6743  +      ", min(field) "
  6743   6744         "FROM sqlite_dbdata WHERE pgno = ? AND field != ?"
  6744   6745         "GROUP BY cell", &pCells
  6745   6746     );
  6746   6747   
  6747   6748     /* Loop through each root page. */
  6748   6749     shellPrepare(pState->db, &rc, 
  6749   6750         "SELECT root, intkey, max(maxlen) FROM recovery.map" 
................................................................................
  6754   6755     while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){
  6755   6756       int iRoot = sqlite3_column_int(pLoop, 0);
  6756   6757       int bIntkey = sqlite3_column_int(pLoop, 1);
  6757   6758       int nCol = sqlite3_column_int(pLoop, 2);
  6758   6759       int bNoop = 0;
  6759   6760       RecoverTable *pTab;
  6760   6761   
         6762  +    assert( bIntkey==0 || bIntkey==1 );
  6761   6763       pTab = recoverFindTable(pState, &rc, iRoot, bIntkey, nCol, &bNoop);
  6762   6764       if( bNoop || rc ) continue;
  6763   6765       if( pTab==0 ){
  6764   6766         if( pOrphan==0 ){
  6765   6767           pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan);
  6766   6768         }
  6767   6769         pTab = pOrphan;
................................................................................
  6775   6777       sqlite3_bind_int(pCells, 2, pTab->iPk);
  6776   6778   
  6777   6779       while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPages) ){
  6778   6780         int iPgno = sqlite3_column_int(pPages, 0);
  6779   6781         sqlite3_bind_int(pCells, 1, iPgno);
  6780   6782         while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){
  6781   6783           int nField = sqlite3_column_int(pCells, 0);
         6784  +        int iMin = sqlite3_column_int(pCells, 2);
  6782   6785           const char *zVal = (const char*)sqlite3_column_text(pCells, 1);
         6786  +
         6787  +        RecoverTable *pTab2 = pTab;
         6788  +        if( pTab!=pOrphan && (iMin<0)!=bIntkey ){
         6789  +          if( pOrphan==0 ){
         6790  +            pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan);
         6791  +          }
         6792  +          pTab2 = pOrphan;
         6793  +          if( pTab2==0 ) break;
         6794  +        }
  6783   6795   
  6784   6796           nField = nField+1;
  6785         -        if( pTab==pOrphan ){
         6797  +        if( pTab2==pOrphan ){
  6786   6798             raw_printf(pState->out, 
  6787   6799                 "INSERT INTO %s VALUES(%d, %d, %d, %s%s%s);\n",
  6788         -              pTab->zQuoted, iRoot, iPgno, nField, 
  6789         -              bIntkey ? "" : "NULL, ", zVal, pTab->azlCol[nField]
         6800  +              pTab2->zQuoted, iRoot, iPgno, nField,
         6801  +              iMin<0 ? "" : "NULL, ", zVal, pTab2->azlCol[nField]
  6790   6802             );
  6791   6803           }else{
  6792   6804             raw_printf(pState->out, "INSERT INTO %s(%s) VALUES( %s );\n", 
  6793         -              pTab->zQuoted, pTab->azlCol[nField], zVal
         6805  +              pTab2->zQuoted, pTab2->azlCol[nField], zVal
  6794   6806             );
  6795   6807           }
  6796   6808         }
  6797   6809         shellReset(&rc, pCells);
  6798   6810       }
  6799   6811       shellReset(&rc, pPages);
  6800   6812       if( pTab!=pOrphan ) recoverFreeTable(pTab);