/ Check-in [4e894062]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Check that the leaf count on each freelist trunk page is in range as part of checkfreelist processing.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | dbpage
Files: files | file ages | folders
SHA3-256: 4e89406248f51d3b83d61e5472fb493f3d3b4ff2a69bf256c7e15445eeb2f3ec
User & Date: dan 2017-10-11 18:21:44
Context
2017-10-11
18:26
Add the checkfreelist extension to the command-line shell. check-in: 48418f2e user: drh tags: dbpage
18:21
Check that the leaf count on each freelist trunk page is in range as part of checkfreelist processing. check-in: 4e894062 user: dan tags: dbpage
18:00
Add new extension "checkfreelist", which uses sqlite_dbpage to check that there are no invalid entries on the database free-list. check-in: 21930ef5 user: dan tags: dbpage
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ext/misc/checkfreelist.c.

165
166
167
168
169
170
171








172
173
174
175
176
177
178
  while( rc==SQLITE_OK && sqlite3_step(pTrunk)==SQLITE_ROW ){
    u32 i;
    u32 iTrunk = (u32)sqlite3_column_int(pTrunk, 0);
    const u8 *aData = (const u8*)sqlite3_column_blob(pTrunk, 1);
    int nData = sqlite3_column_bytes(pTrunk, 1);
    u32 iNext = get4byte(&aData[0]);
    u32 nLeaf = get4byte(&aData[4]);









    nFree += 1+nLeaf;
    if( iNext>nPage ){
      rc = checkFreelistError(pzOut, 
          "trunk page %d is out of range", (int)iNext
      );
    }







>
>
>
>
>
>
>
>







165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
  while( rc==SQLITE_OK && sqlite3_step(pTrunk)==SQLITE_ROW ){
    u32 i;
    u32 iTrunk = (u32)sqlite3_column_int(pTrunk, 0);
    const u8 *aData = (const u8*)sqlite3_column_blob(pTrunk, 1);
    int nData = sqlite3_column_bytes(pTrunk, 1);
    u32 iNext = get4byte(&aData[0]);
    u32 nLeaf = get4byte(&aData[4]);

    if( nLeaf>((nData/4)-2-6) ){
      rc = checkFreelistError(pzOut, 
          "leaf count out of range (%d) on trunk page %d", 
          (int)nLeaf, (int)iTrunk
      );
      nLeaf = (nData/4) - 2 - 6;
    }

    nFree += 1+nLeaf;
    if( iNext>nPage ){
      rc = checkFreelistError(pzOut, 
          "trunk page %d is out of range", (int)iNext
      );
    }

Changes to test/checkfreelist.test.

106
107
108
109
110
111
112









113
114
    UPDATE sqlite_dbpage 
      SET data = set_int(data, get_int(data, 1)+1, 0)
      WHERE pgno=5;
    SELECT checkfreelist('main');
  ROLLBACK;
} {{leaf page 0 is out of range (child 247 of trunk page 5)}}










finish_test








>
>
>
>
>
>
>
>
>


106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
    UPDATE sqlite_dbpage 
      SET data = set_int(data, get_int(data, 1)+1, 0)
      WHERE pgno=5;
    SELECT checkfreelist('main');
  ROLLBACK;
} {{leaf page 0 is out of range (child 247 of trunk page 5)}}

do_execsql_test 1.11 {
  BEGIN;
    UPDATE sqlite_dbpage 
      SET data = set_int(data, 1, 249)
      WHERE pgno=5;
    SELECT checkfreelist('main');
  ROLLBACK;
} {{leaf count out of range (249) on trunk page 5}}

finish_test