/ Check-in [45362437]
Login

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

Overview
Comment:Increase the maximum page size from 32k to 64k.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 45362437d491fbe0f033a67b398f8ba68cbf1b3b
User & Date: drh 2010-08-12 02:41:12
Context
2010-08-12
11:25
Add coverage tests for pager.c. check-in: 228c5b16 user: dan tags: trunk
02:41
Increase the maximum page size from 32k to 64k. check-in: 45362437 user: drh tags: trunk
2010-08-11
18:56
Improve coverage of pager.c. check-in: 2fa05d01 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

  1151   1151     usableSize = pPage->pBt->usableSize;
  1152   1152     assert( nByte < usableSize-8 );
  1153   1153   
  1154   1154     nFrag = data[hdr+7];
  1155   1155     assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf );
  1156   1156     gap = pPage->cellOffset + 2*pPage->nCell;
  1157   1157     top = get2byte(&data[hdr+5]);
         1158  +  if( top==0 ) top = 65536;
  1158   1159     if( gap>top ) return SQLITE_CORRUPT_BKPT;
  1159   1160     testcase( gap+2==top );
  1160   1161     testcase( gap+1==top );
  1161   1162     testcase( gap==top );
  1162   1163   
  1163   1164     if( nFrag>=60 ){
  1164   1165       /* Always defragment highly fragmented pages */
  1165   1166       rc = defragmentPage(pPage);
  1166   1167       if( rc ) return rc;
  1167   1168       top = get2byte(&data[hdr+5]);
         1169  +    if( top==0 ) top = 65536;
  1168   1170     }else if( gap+2<=top ){
  1169   1171       /* Search the freelist looking for a free slot big enough to satisfy 
  1170   1172       ** the request. The allocation is made from the first free slot in 
  1171   1173       ** the list that is large enough to accomadate it.
  1172   1174       */
  1173   1175       int pc, addr;
  1174   1176       for(addr=hdr+1; (pc = get2byte(&data[addr]))>0; addr=pc){
................................................................................
  1203   1205     ** the allocation.  If not, defragment.
  1204   1206     */
  1205   1207     testcase( gap+2+nByte==top );
  1206   1208     if( gap+2+nByte>top ){
  1207   1209       rc = defragmentPage(pPage);
  1208   1210       if( rc ) return rc;
  1209   1211       top = get2byte(&data[hdr+5]);
         1212  +    if( top==0 ) top = 65536;
  1210   1213       assert( gap+nByte<=top );
  1211   1214     }
  1212   1215   
  1213   1216   
  1214   1217     /* Allocate memory from the gap in between the cell pointer array
  1215   1218     ** and the cell content area.  The btreeInitPage() call has already
  1216   1219     ** validated the freelist.  Given that the freelist is valid, there
................................................................................
  1368   1371     assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) );
  1369   1372   
  1370   1373     if( !pPage->isInit ){
  1371   1374       u16 pc;            /* Address of a freeblock within pPage->aData[] */
  1372   1375       u8 hdr;            /* Offset to beginning of page header */
  1373   1376       u8 *data;          /* Equal to pPage->aData */
  1374   1377       BtShared *pBt;        /* The main btree structure */
  1375         -    u16 usableSize;    /* Amount of usable space on each page */
  1376         -    u16 cellOffset;    /* Offset from start of page to first cell pointer */
  1377         -    u16 nFree;         /* Number of unused bytes on the page */
  1378         -    u16 top;           /* First byte of the cell content area */
         1378  +    int usableSize;    /* Amount of usable space on each page */
         1379  +    int cellOffset;    /* Offset from start of page to first cell pointer */
         1380  +    int nFree;         /* Number of unused bytes on the page */
         1381  +    int top;           /* First byte of the cell content area */
  1379   1382       int iCellFirst;    /* First allowable cell or freeblock offset */
  1380   1383       int iCellLast;     /* Last possible cell or freeblock offset */
  1381   1384   
  1382   1385       pBt = pPage->pBt;
  1383   1386   
  1384   1387       hdr = pPage->hdrOffset;
  1385   1388       data = pPage->aData;
  1386   1389       if( decodeFlags(pPage, data[hdr]) ) return SQLITE_CORRUPT_BKPT;
  1387         -    assert( pBt->pageSize>=512 && pBt->pageSize<=32768 );
  1388         -    pPage->maskPage = pBt->pageSize - 1;
         1390  +    assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
         1391  +    pPage->maskPage = (u16)(pBt->pageSize - 1);
  1389   1392       pPage->nOverflow = 0;
  1390   1393       usableSize = pBt->usableSize;
  1391   1394       pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf;
  1392   1395       top = get2byte(&data[hdr+5]);
         1396  +    if( top==0 ) top = 65536;
  1393   1397       pPage->nCell = get2byte(&data[hdr+3]);
  1394   1398       if( pPage->nCell>MX_CELL(pBt) ){
  1395   1399         /* To many cells for a single page.  The page must be corrupt */
  1396   1400         return SQLITE_CORRUPT_BKPT;
  1397   1401       }
  1398   1402       testcase( pPage->nCell==MX_CELL(pBt) );
  1399   1403   
................................................................................
  1489   1493     data[hdr+7] = 0;
  1490   1494     put2byte(&data[hdr+5], pBt->usableSize);
  1491   1495     pPage->nFree = pBt->usableSize - first;
  1492   1496     decodeFlags(pPage, flags);
  1493   1497     pPage->hdrOffset = hdr;
  1494   1498     pPage->cellOffset = first;
  1495   1499     pPage->nOverflow = 0;
  1496         -  assert( pBt->pageSize>=512 && pBt->pageSize<=32768 );
  1497         -  pPage->maskPage = pBt->pageSize - 1;
         1500  +  assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
         1501  +  pPage->maskPage = (u16)(pBt->pageSize - 1);
  1498   1502     pPage->nCell = 0;
  1499   1503     pPage->isInit = 1;
  1500   1504   }
  1501   1505   
  1502   1506   
  1503   1507   /*
  1504   1508   ** Convert a DbPage obtained from the pager into a MemPage used by
................................................................................
  1798   1802     
  1799   1803       pBt->pCursor = 0;
  1800   1804       pBt->pPage1 = 0;
  1801   1805       pBt->readOnly = sqlite3PagerIsreadonly(pBt->pPager);
  1802   1806   #ifdef SQLITE_SECURE_DELETE
  1803   1807       pBt->secureDelete = 1;
  1804   1808   #endif
  1805         -    pBt->pageSize = get2byte(&zDbHeader[16]);
         1809  +    pBt->pageSize = (zDbHeader[16]<<8) | (zDbHeader[17]<<16);
  1806   1810       if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE
  1807   1811            || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){
  1808   1812         pBt->pageSize = 0;
  1809   1813   #ifndef SQLITE_OMIT_AUTOVACUUM
  1810   1814         /* If the magic name ":memory:" will create an in-memory database, then
  1811   1815         ** leave the autoVacuum mode at 0 (do not auto-vacuum), even if
  1812   1816         ** SQLITE_DEFAULT_AUTOVACUUM is true. On the other hand, if
................................................................................
  2112   2116       nReserve = pBt->pageSize - pBt->usableSize;
  2113   2117     }
  2114   2118     assert( nReserve>=0 && nReserve<=255 );
  2115   2119     if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
  2116   2120           ((pageSize-1)&pageSize)==0 ){
  2117   2121       assert( (pageSize & 7)==0 );
  2118   2122       assert( !pBt->pPage1 && !pBt->pCursor );
  2119         -    pBt->pageSize = (u16)pageSize;
         2123  +    pBt->pageSize = (u32)pageSize;
  2120   2124       freeTempSpace(pBt);
  2121   2125     }
  2122   2126     rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve);
  2123   2127     pBt->usableSize = pBt->pageSize - (u16)nReserve;
  2124   2128     if( iFix ) pBt->pageSizeFixed = 1;
  2125   2129     sqlite3BtreeLeave(p);
  2126   2130     return rc;
................................................................................
  2306   2310       ** embedded fraction must be 12.5% for both leaf-data and non-leaf-data.
  2307   2311       ** The original design allowed these amounts to vary, but as of
  2308   2312       ** version 3.6.0, we require them to be fixed.
  2309   2313       */
  2310   2314       if( memcmp(&page1[21], "\100\040\040",3)!=0 ){
  2311   2315         goto page1_init_failed;
  2312   2316       }
  2313         -    pageSize = get2byte(&page1[16]);
  2314         -    if( ((pageSize-1)&pageSize)!=0 || pageSize<512 ||
  2315         -        (SQLITE_MAX_PAGE_SIZE<32768 && pageSize>SQLITE_MAX_PAGE_SIZE)
         2317  +    pageSize = (page1[16]<<8) | (page1[17]<<16);
         2318  +    if( ((pageSize-1)&pageSize)!=0
         2319  +     || pageSize>SQLITE_MAX_PAGE_SIZE 
         2320  +     || pageSize<=256 
  2316   2321       ){
  2317   2322         goto page1_init_failed;
  2318   2323       }
  2319   2324       assert( (pageSize & 7)==0 );
  2320   2325       usableSize = pageSize - page1[20];
  2321   2326       if( pageSize!=pBt->pageSize ){
  2322   2327         /* After reading the first page of the database assuming a page size
  2323   2328         ** of BtShared.pageSize, we have discovered that the page-size is
  2324   2329         ** actually pageSize. Unlock the database, leave pBt->pPage1 at
  2325   2330         ** zero and return SQLITE_OK. The caller will call this function
  2326   2331         ** again with the correct page-size.
  2327   2332         */
  2328   2333         releasePage(pPage1);
  2329         -      pBt->usableSize = (u16)usableSize;
  2330         -      pBt->pageSize = (u16)pageSize;
         2334  +      pBt->usableSize = (u32)usableSize;
         2335  +      pBt->pageSize = (u32)pageSize;
  2331   2336         freeTempSpace(pBt);
  2332   2337         rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize,
  2333   2338                                      pageSize-usableSize);
  2334   2339         return rc;
  2335   2340       }
  2336   2341       if( nPageHeader>nPageFile ){
  2337   2342         rc = SQLITE_CORRUPT_BKPT;
  2338   2343         goto page1_init_failed;
  2339   2344       }
  2340   2345       if( usableSize<480 ){
  2341   2346         goto page1_init_failed;
  2342   2347       }
  2343         -    pBt->pageSize = (u16)pageSize;
  2344         -    pBt->usableSize = (u16)usableSize;
         2348  +    pBt->pageSize = (u32)pageSize;
         2349  +    pBt->usableSize = (u32)usableSize;
  2345   2350   #ifndef SQLITE_OMIT_AUTOVACUUM
  2346   2351       pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0);
  2347   2352       pBt->incrVacuum = (get4byte(&page1[36 + 7*4])?1:0);
  2348   2353   #endif
  2349   2354     }
  2350   2355   
  2351   2356     /* maxLocal is the maximum amount of payload to store locally for
................................................................................
  2413   2418     pP1 = pBt->pPage1;
  2414   2419     assert( pP1!=0 );
  2415   2420     data = pP1->aData;
  2416   2421     rc = sqlite3PagerWrite(pP1->pDbPage);
  2417   2422     if( rc ) return rc;
  2418   2423     memcpy(data, zMagicHeader, sizeof(zMagicHeader));
  2419   2424     assert( sizeof(zMagicHeader)==16 );
  2420         -  put2byte(&data[16], pBt->pageSize);
         2425  +  data[16] = (pBt->pageSize>>8)&0xff;
         2426  +  data[17] = (pBt->pageSize>>16)&0xff;
  2421   2427     data[18] = 1;
  2422   2428     data[19] = 1;
  2423   2429     assert( pBt->usableSize<=pBt->pageSize && pBt->usableSize+255>=pBt->pageSize);
  2424   2430     data[20] = (u8)(pBt->pageSize - pBt->usableSize);
  2425   2431     data[21] = 64;
  2426   2432     data[22] = 32;
  2427   2433     data[23] = 32;
................................................................................
  4424   4430           }else{
  4425   4431             assert( nCellKey>intKey );
  4426   4432             c = +1;
  4427   4433           }
  4428   4434           pCur->validNKey = 1;
  4429   4435           pCur->info.nKey = nCellKey;
  4430   4436         }else{
  4431         -        /* The maximum supported page-size is 32768 bytes. This means that
         4437  +        /* The maximum supported page-size is 65536 bytes. This means that
  4432   4438           ** the maximum number of record bytes stored on an index B-Tree
  4433         -        ** page is at most 8198 bytes, which may be stored as a 2-byte
         4439  +        ** page is less than 16384 bytes and may be stored as a 2-byte
  4434   4440           ** varint. This information is used to attempt to avoid parsing 
  4435   4441           ** the entire cell by checking for the cases where the record is 
  4436   4442           ** stored entirely within the b-tree page by inspecting the first 
  4437   4443           ** 2 bytes of the cell.
  4438   4444           */
  4439   4445           int nCell = pCell[0];
  4440   4446           if( !(nCell & 0x80) && nCell<=pPage->maxLocal ){
................................................................................
  5395   5401     u8 *ptr;          /* Used for moving information around in data[] */
  5396   5402   
  5397   5403     int nSkip = (iChild ? 4 : 0);
  5398   5404   
  5399   5405     if( *pRC ) return;
  5400   5406   
  5401   5407     assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
  5402         -  assert( pPage->nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=5460 );
         5408  +  assert( pPage->nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=10921 );
  5403   5409     assert( pPage->nOverflow<=ArraySize(pPage->aOvfl) );
  5404   5410     assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  5405   5411     /* The cell should normally be sized correctly.  However, when moving a
  5406   5412     ** malformed cell from a leaf page to an interior page, if the cell size
  5407   5413     ** wanted to be less than 4 but got rounded up to 4 on the leaf, then size
  5408   5414     ** might be less than 8 (leaf-size + pointer) on the interior node.  Hence
  5409   5415     ** the term after the || in the following assert(). */
................................................................................
  5475   5481     int cellbody;     /* Address of next cell body */
  5476   5482     u8 * const data = pPage->aData;             /* Pointer to data for pPage */
  5477   5483     const int hdr = pPage->hdrOffset;           /* Offset of header on pPage */
  5478   5484     const int nUsable = pPage->pBt->usableSize; /* Usable size of page */
  5479   5485   
  5480   5486     assert( pPage->nOverflow==0 );
  5481   5487     assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  5482         -  assert( nCell>=0 && nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=5460 );
         5488  +  assert( nCell>=0 && nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=10921);
  5483   5489     assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  5484   5490   
  5485   5491     /* Check that the page has just been zeroed by zeroPage() */
  5486   5492     assert( pPage->nCell==0 );
  5487         -  assert( get2byte(&data[hdr+5])==nUsable );
         5493  +  assert( get2byte(&data[hdr+5])==(nUsable&0xffff) );
  5488   5494   
  5489   5495     pCellptr = &data[pPage->cellOffset + nCell*2];
  5490   5496     cellbody = nUsable;
  5491   5497     for(i=nCell-1; i>=0; i--){
  5492   5498       pCellptr -= 2;
  5493   5499       cellbody -= aSize[i];
  5494   5500       put2byte(pCellptr, cellbody);
................................................................................
  7655   7661     */
  7656   7662     data = pPage->aData;
  7657   7663     hdr = pPage->hdrOffset;
  7658   7664     hit = sqlite3PageMalloc( pBt->pageSize );
  7659   7665     if( hit==0 ){
  7660   7666       pCheck->mallocFailed = 1;
  7661   7667     }else{
  7662         -    u16 contentOffset = get2byte(&data[hdr+5]);
         7668  +    int contentOffset = get2byte(&data[hdr+5]);
         7669  +    if( contentOffset==0 ) contentOffset = 65536;
  7663   7670       assert( contentOffset<=usableSize );  /* Enforced by btreeInitPage() */
  7664   7671       memset(hit+contentOffset, 0, usableSize-contentOffset);
  7665   7672       memset(hit, 1, contentOffset);
  7666   7673       nCell = get2byte(&data[hdr+3]);
  7667   7674       cellStart = hdr + 12 - 4*pPage->leaf;
  7668   7675       for(i=0; i<nCell; i++){
  7669   7676         int pc = get2byte(&data[cellStart+i*2]);

Changes to src/btreeInt.h.

    42     42   ** page has a small header which contains the Ptr(N) pointer and other
    43     43   ** information such as the size of key and data.
    44     44   **
    45     45   ** FORMAT DETAILS
    46     46   **
    47     47   ** The file is divided into pages.  The first page is called page 1,
    48     48   ** the second is page 2, and so forth.  A page number of zero indicates
    49         -** "no such page".  The page size can be any power of 2 between 512 and 32768.
           49  +** "no such page".  The page size can be any power of 2 between 512 and 65536.
    50     50   ** Each page can be either a btree page, a freelist page, an overflow
    51     51   ** page, or a pointer-map page.
    52     52   **
    53     53   ** The first page is always a btree page.  The first 100 bytes of the first
    54     54   ** page contain a special header (the "file header") that describes the file.
    55     55   ** The format of the file header is as follows:
    56     56   **
................................................................................
   409    409     u8 pageSizeFixed;     /* True if the page size can no longer be changed */
   410    410     u8 secureDelete;      /* True if secure_delete is enabled */
   411    411     u8 initiallyEmpty;    /* Database is empty at start of transaction */
   412    412   #ifndef SQLITE_OMIT_AUTOVACUUM
   413    413     u8 autoVacuum;        /* True if auto-vacuum is enabled */
   414    414     u8 incrVacuum;        /* True if incr-vacuum is enabled */
   415    415   #endif
   416         -  u16 pageSize;         /* Total number of bytes on a page */
   417         -  u16 usableSize;       /* Number of usable bytes on each page */
   418    416     u16 maxLocal;         /* Maximum local payload in non-LEAFDATA tables */
   419    417     u16 minLocal;         /* Minimum local payload in non-LEAFDATA tables */
   420    418     u16 maxLeaf;          /* Maximum local payload in a LEAFDATA table */
   421    419     u16 minLeaf;          /* Minimum local payload in a LEAFDATA table */
   422    420     u8 inTransaction;     /* Transaction state */
   423    421     u8 doNotUseWAL;       /* If true, do not open write-ahead-log file */
          422  +  u32 pageSize;         /* Total number of bytes on a page */
          423  +  u32 usableSize;       /* Number of usable bytes on each page */
   424    424     int nTransaction;     /* Number of open transactions (read + write) */
   425    425     u32 nPage;            /* Number of pages in the database */
   426    426     void *pSchema;        /* Pointer to space allocated by sqlite3BtreeSchema() */
   427    427     void (*xFreeSchema)(void*);  /* Destructor for BtShared.pSchema */
   428    428     sqlite3_mutex *mutex; /* Non-recursive mutex required to access this struct */
   429    429     Bitvec *pHasContent;  /* Set of pages moved to free-list this transaction */
   430    430   #ifndef SQLITE_OMIT_SHARED_CACHE

Changes to src/pager.c.

  1501   1501     ){
  1502   1502       return rc;
  1503   1503     }
  1504   1504   
  1505   1505     if( pPager->journalOff==0 ){
  1506   1506       u32 iPageSize;               /* Page-size field of journal header */
  1507   1507       u32 iSectorSize;             /* Sector-size field of journal header */
  1508         -    u16 iPageSize16;             /* Copy of iPageSize in 16-bit variable */
  1509   1508   
  1510   1509       /* Read the page-size and sector-size journal header fields. */
  1511   1510       if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+20, &iSectorSize))
  1512   1511        || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+24, &iPageSize))
  1513   1512       ){
  1514   1513         return rc;
  1515   1514       }
................................................................................
  1531   1530         return SQLITE_DONE;
  1532   1531       }
  1533   1532   
  1534   1533       /* Update the page-size to match the value read from the journal. 
  1535   1534       ** Use a testcase() macro to make sure that malloc failure within 
  1536   1535       ** PagerSetPagesize() is tested.
  1537   1536       */
  1538         -    iPageSize16 = (u16)iPageSize;
  1539         -    rc = sqlite3PagerSetPagesize(pPager, &iPageSize16, -1);
         1537  +    rc = sqlite3PagerSetPagesize(pPager, &iPageSize, -1);
  1540   1538       testcase( rc!=SQLITE_OK );
  1541         -    assert( rc!=SQLITE_OK || iPageSize16==(u16)iPageSize );
  1542   1539   
  1543   1540       /* Update the assumed sector-size to match the value used by 
  1544   1541       ** the process that created this journal. If this journal was
  1545   1542       ** created by a process other than this one, then this routine
  1546   1543       ** is being called from within pager_playback(). The local value
  1547   1544       ** of Pager.sectorSize is restored at the end of that routine.
  1548   1545       */
................................................................................
  3352   3349   ** In all other cases, SQLITE_OK is returned.
  3353   3350   **
  3354   3351   ** If the page size is not changed, either because one of the enumerated
  3355   3352   ** conditions above is not true, the pager was in error state when this
  3356   3353   ** function was called, or because the memory allocation attempt failed, 
  3357   3354   ** then *pPageSize is set to the old, retained page size before returning.
  3358   3355   */
  3359         -int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize, int nReserve){
         3356  +int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){
  3360   3357     /* It is not possible to do a full assert_pager_state() here, as this
  3361   3358     ** function may be called from within PagerOpen(), before the state
  3362   3359     ** of the Pager object is internally consistent.
  3363   3360     **
  3364   3361     ** At one point this function returned an error if the pager was in 
  3365   3362     ** PAGER_ERROR state. But since PAGER_ERROR state guarantees that
  3366   3363     ** there is at least one outstanding page reference, this function
  3367   3364     ** is a no-op for that case anyhow.
  3368   3365     */
  3369   3366   
  3370         -  u16 pageSize = *pPageSize;
         3367  +  u32 pageSize = *pPageSize;
  3371   3368     assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) );
  3372   3369     if( (pPager->memDb==0 || pPager->dbSize==0)
  3373   3370      && sqlite3PcacheRefCount(pPager->pPCache)==0 
  3374   3371      && pageSize && pageSize!=pPager->pageSize 
  3375   3372     ){
  3376   3373       char *pNew;                 /* New temp space */
  3377   3374       i64 nByte = 0;
................................................................................
  3388   3385         pPager->pageSize = pageSize;
  3389   3386         sqlite3PageFree(pPager->pTmpSpace);
  3390   3387         pPager->pTmpSpace = pNew;
  3391   3388         sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
  3392   3389       }
  3393   3390     }
  3394   3391   
  3395         -  *pPageSize = (u16)pPager->pageSize;
         3392  +  *pPageSize = pPager->pageSize;
  3396   3393     if( nReserve<0 ) nReserve = pPager->nReserve;
  3397   3394     assert( nReserve>=0 && nReserve<1000 );
  3398   3395     pPager->nReserve = (i16)nReserve;
  3399   3396     pagerReportSize(pPager);
  3400   3397     return SQLITE_OK;
  3401   3398   }
  3402   3399   
................................................................................
  4180   4177     int readOnly = 0;        /* True if this is a read-only file */
  4181   4178     int journalFileSize;     /* Bytes to allocate for each journal fd */
  4182   4179     char *zPathname = 0;     /* Full path to database file */
  4183   4180     int nPathname = 0;       /* Number of bytes in zPathname */
  4184   4181     int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */
  4185   4182     int noReadlock = (flags & PAGER_NO_READLOCK)!=0;  /* True to omit read-lock */
  4186   4183     int pcacheSize = sqlite3PcacheSize();       /* Bytes to allocate for PCache */
  4187         -  u16 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE;  /* Default page size */
         4184  +  u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE;  /* Default page size */
  4188   4185   
  4189   4186     /* Figure out how much space is required for each journal file-handle
  4190   4187     ** (there are two of them, the main journal and the sub-journal). This
  4191   4188     ** is the maximum space required for an in-memory journal file handle 
  4192   4189     ** and a regular journal file-handle. Note that a "regular journal-handle"
  4193   4190     ** may be a wrapper capable of caching the first portion of the journal
  4194   4191     ** file in memory to implement the atomic-write optimization (see 
................................................................................
  4315   4312       if( rc==SQLITE_OK && !readOnly ){
  4316   4313         setSectorSize(pPager);
  4317   4314         assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE);
  4318   4315         if( szPageDflt<pPager->sectorSize ){
  4319   4316           if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){
  4320   4317             szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE;
  4321   4318           }else{
  4322         -          szPageDflt = (u16)pPager->sectorSize;
         4319  +          szPageDflt = (u32)pPager->sectorSize;
  4323   4320           }
  4324   4321         }
  4325   4322   #ifdef SQLITE_ENABLE_ATOMIC_WRITE
  4326   4323         {
  4327   4324           int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
  4328   4325           int ii;
  4329   4326           assert(SQLITE_IOCAP_ATOMIC512==(512>>8));

Changes to src/pager.h.

    95     95     void(*)(DbPage*)
    96     96   );
    97     97   int sqlite3PagerClose(Pager *pPager);
    98     98   int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
    99     99   
   100    100   /* Functions used to configure a Pager object. */
   101    101   void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
   102         -int sqlite3PagerSetPagesize(Pager*, u16*, int);
          102  +int sqlite3PagerSetPagesize(Pager*, u32*, int);
   103    103   int sqlite3PagerMaxPageCount(Pager*, int);
   104    104   void sqlite3PagerSetCachesize(Pager*, int);
   105    105   void sqlite3PagerSetSafetyLevel(Pager*,int,int);
   106    106   int sqlite3PagerLockingMode(Pager *, int);
   107    107   int sqlite3PagerSetJournalMode(Pager *, int);
   108    108   int sqlite3PagerGetJournalMode(Pager*);
   109    109   int sqlite3PagerOkToChangeJournalMode(Pager*);

Changes to src/sqliteLimit.h.

   129    129   /*
   130    130   ** The maximum value of a ?nnn wildcard that the parser will accept.
   131    131   */
   132    132   #ifndef SQLITE_MAX_VARIABLE_NUMBER
   133    133   # define SQLITE_MAX_VARIABLE_NUMBER 999
   134    134   #endif
   135    135   
   136         -/* Maximum page size.  The upper bound on this value is 32768.  This a limit
   137         -** imposed by the necessity of storing the value in a 2-byte unsigned integer
   138         -** and the fact that the page size must be a power of 2.
          136  +/* Maximum page size.  The upper bound on this value is 65536.  This a limit
          137  +** imposed by the use of 16-bit offsets within each page.
   139    138   **
   140    139   ** If this limit is changed, then the compiled library is technically
   141    140   ** incompatible with an SQLite library compiled with a different limit. If
   142    141   ** a process operating on a database with a page-size of 65536 bytes 
   143    142   ** crashes, then an instance of SQLite compiled with the default page-size 
   144    143   ** limit will not be able to rollback the aborted transaction. This could
   145    144   ** lead to database corruption.
   146    145   */
   147    146   #ifndef SQLITE_MAX_PAGE_SIZE
   148         -# define SQLITE_MAX_PAGE_SIZE 32768
          147  +# define SQLITE_MAX_PAGE_SIZE 65536
   149    148   #endif
   150    149   
   151    150   
   152    151   /*
   153    152   ** The default size of a database page.
   154    153   */
   155    154   #ifndef SQLITE_DEFAULT_PAGE_SIZE

Changes to src/test2.c.

    68     68   */
    69     69   static int pager_open(
    70     70     void *NotUsed,
    71     71     Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
    72     72     int argc,              /* Number of arguments */
    73     73     const char **argv      /* Text of each argument */
    74     74   ){
    75         -  u16 pageSize;
           75  +  u32 pageSize;
    76     76     Pager *pPager;
    77     77     int nPage;
    78     78     int rc;
    79     79     char zBuf[100];
    80     80     if( argc!=3 ){
    81     81       Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    82     82          " FILENAME N-PAGE\"", 0);

Changes to src/test_vfs.c.

   996    996           Tcl_AppendResult(interp, "no such file: ", Tcl_GetString(objv[2]), 0);
   997    997           return TCL_ERROR;
   998    998         }
   999    999         if( objc==4 ){
  1000   1000           int n;
  1001   1001           u8 *a = Tcl_GetByteArrayFromObj(objv[3], &n);
  1002   1002           int pgsz = pBuffer->pgsz;
  1003         -        if( pgsz==0 ) pgsz = 32768;
         1003  +        if( pgsz==0 ) pgsz = 65536;
  1004   1004           for(i=0; i*pgsz<n; i++){
  1005   1005             int nByte = pgsz;
  1006   1006             tvfsAllocPage(pBuffer, i, pgsz);
  1007   1007             if( n-i*pgsz<pgsz ){
  1008   1008               nByte = n;
  1009   1009             }
  1010   1010             memcpy(pBuffer->aPage[i], &a[i*pgsz], nByte);
  1011   1011           }
  1012   1012         }
  1013   1013   
  1014   1014         pObj = Tcl_NewObj();
  1015   1015         for(i=0; pBuffer->aPage[i]; i++){
  1016   1016           int pgsz = pBuffer->pgsz;
  1017         -        if( pgsz==0 ) pgsz = 32768;
         1017  +        if( pgsz==0 ) pgsz = 65536;
  1018   1018           Tcl_AppendObjToObj(pObj, Tcl_NewByteArrayObj(pBuffer->aPage[i], pgsz));
  1019   1019         }
  1020   1020         Tcl_SetObjResult(interp, pObj);
  1021   1021         break;
  1022   1022       }
  1023   1023   
  1024   1024       case CMD_FILTER: {

Changes to src/wal.c.

   406    406   struct Wal {
   407    407     sqlite3_vfs *pVfs;         /* The VFS used to create pDbFd */
   408    408     sqlite3_file *pDbFd;       /* File handle for the database file */
   409    409     sqlite3_file *pWalFd;      /* File handle for WAL file */
   410    410     u32 iCallback;             /* Value to pass to log callback (or 0) */
   411    411     int nWiData;               /* Size of array apWiData */
   412    412     volatile u32 **apWiData;   /* Pointer to wal-index content in memory */
   413         -  u16 szPage;                /* Database page size */
          413  +  u32 szPage;                /* Database page size */
   414    414     i16 readLock;              /* Which read lock is being held.  -1 for none */
   415    415     u8 exclusiveMode;          /* Non-zero if connection is in exclusive mode */
   416    416     u8 writeLock;              /* True if in a write transaction */
   417    417     u8 ckptLock;               /* True if holding a checkpoint lock */
   418    418     u8 readOnly;               /* True if the WAL file is open read-only */
   419    419     WalIndexHdr hdr;           /* Wal-index header for current transaction */
   420    420     const char *zWalName;      /* Name of WAL file */
................................................................................
  1077   1077        || szPage&(szPage-1) 
  1078   1078        || szPage>SQLITE_MAX_PAGE_SIZE 
  1079   1079        || szPage<512 
  1080   1080       ){
  1081   1081         goto finished;
  1082   1082       }
  1083   1083       pWal->hdr.bigEndCksum = (u8)(magic&0x00000001);
  1084         -    pWal->szPage = (u16)szPage;
         1084  +    pWal->szPage = szPage;
  1085   1085       pWal->nCkpt = sqlite3Get4byte(&aBuf[12]);
  1086   1086       memcpy(&pWal->hdr.aSalt, &aBuf[16], 8);
  1087   1087   
  1088   1088       /* Verify that the WAL header checksum is correct */
  1089   1089       walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, 
  1090   1090           aBuf, WAL_HDRSIZE-2*4, 0, pWal->hdr.aFrameCksum
  1091   1091       );
................................................................................
  1127   1127         rc = walIndexAppend(pWal, ++iFrame, pgno);
  1128   1128         if( rc!=SQLITE_OK ) break;
  1129   1129   
  1130   1130         /* If nTruncate is non-zero, this is a commit record. */
  1131   1131         if( nTruncate ){
  1132   1132           pWal->hdr.mxFrame = iFrame;
  1133   1133           pWal->hdr.nPage = nTruncate;
  1134         -        pWal->hdr.szPage = (u16)szPage;
         1134  +        pWal->hdr.szPage = (szPage>=0x10000) ? (szPage>>16) : szPage;
  1135   1135           aFrameCksum[0] = pWal->hdr.aFrameCksum[0];
  1136   1136           aFrameCksum[1] = pWal->hdr.aFrameCksum[1];
  1137   1137         }
  1138   1138       }
  1139   1139   
  1140   1140       sqlite3_free(aFrame);
  1141   1141     }
................................................................................
  1512   1512   static int walCheckpoint(
  1513   1513     Wal *pWal,                      /* Wal connection */
  1514   1514     int sync_flags,                 /* Flags for OsSync() (or 0) */
  1515   1515     int nBuf,                       /* Size of zBuf in bytes */
  1516   1516     u8 *zBuf                        /* Temporary buffer to use */
  1517   1517   ){
  1518   1518     int rc;                         /* Return code */
  1519         -  int szPage = pWal->hdr.szPage;  /* Database page-size */
         1519  +  int szPage;                     /* Database page-size */
  1520   1520     WalIterator *pIter = 0;         /* Wal iterator context */
  1521   1521     u32 iDbpage = 0;                /* Next database page to write */
  1522   1522     u32 iFrame = 0;                 /* Wal frame containing data for iDbpage */
  1523   1523     u32 mxSafeFrame;                /* Max frame that can be backfilled */
  1524   1524     u32 mxPage;                     /* Max database page to write */
  1525   1525     int i;                          /* Loop counter */
  1526   1526     volatile WalCkptInfo *pInfo;    /* The checkpoint status information */
  1527   1527   
         1528  +  szPage = pWal->hdr.szPage;
         1529  +  if( szPage<512 ) szPage <<= 16;
  1528   1530     if( pWal->hdr.mxFrame==0 ) return SQLITE_OK;
  1529   1531   
  1530   1532     /* Allocate the iterator */
  1531   1533     rc = walIteratorInit(pWal, &pIter);
  1532   1534     if( rc!=SQLITE_OK ){
  1533   1535       return rc;
  1534   1536     }
  1535   1537     assert( pIter );
  1536   1538   
  1537   1539     /*** TODO:  Move this test out to the caller.  Make it an assert() here ***/
  1538         -  if( pWal->hdr.szPage!=nBuf ){
         1540  +  if( szPage!=nBuf ){
  1539   1541       rc = SQLITE_CORRUPT_BKPT;
  1540   1542       goto walcheckpoint_out;
  1541   1543     }
  1542   1544   
  1543   1545     /* Compute in mxSafeFrame the index of the last frame of the WAL that is
  1544   1546     ** safe to write into the database.  Frames beyond mxSafeFrame might
  1545   1547     ** overwrite database pages that are in use by active readers and thus
................................................................................
  1723   1725       return 1;   /* Checksum does not match */
  1724   1726     }
  1725   1727   
  1726   1728     if( memcmp(&pWal->hdr, &h1, sizeof(WalIndexHdr)) ){
  1727   1729       *pChanged = 1;
  1728   1730       memcpy(&pWal->hdr, &h1, sizeof(WalIndexHdr));
  1729   1731       pWal->szPage = pWal->hdr.szPage;
         1732  +    if( pWal->szPage<512 ) pWal->szPage <<= 16;
  1730   1733     }
  1731   1734   
  1732   1735     /* The header was successfully read. Return zero. */
  1733   1736     return 0;
  1734   1737   }
  1735   1738   
  1736   1739   /*
................................................................................
  2152   2155     }
  2153   2156   #endif
  2154   2157   
  2155   2158     /* If iRead is non-zero, then it is the log frame number that contains the
  2156   2159     ** required page. Read and return data from the log file.
  2157   2160     */
  2158   2161     if( iRead ){
  2159         -    i64 iOffset = walFrameOffset(iRead, pWal->hdr.szPage) + WAL_FRAME_HDRSIZE;
         2162  +    int sz;
         2163  +    i64 iOffset;
         2164  +    sz = pWal->hdr.szPage;
         2165  +    if( sz<512 ) sz <<= 16;
         2166  +    iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE;
  2160   2167       *pInWal = 1;
  2161   2168       /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
  2162   2169       return sqlite3OsRead(pWal->pWalFd, pOut, nOut, iOffset);
  2163   2170     }
  2164   2171   
  2165   2172     *pInWal = 0;
  2166   2173     return SQLITE_OK;
................................................................................
  2435   2442       sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt);
  2436   2443       sqlite3_randomness(8, pWal->hdr.aSalt);
  2437   2444       memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8);
  2438   2445       walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum);
  2439   2446       sqlite3Put4byte(&aWalHdr[24], aCksum[0]);
  2440   2447       sqlite3Put4byte(&aWalHdr[28], aCksum[1]);
  2441   2448       
  2442         -    pWal->szPage = (u16)szPage;
         2449  +    pWal->szPage = szPage;
  2443   2450       pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN;
  2444   2451       pWal->hdr.aFrameCksum[0] = aCksum[0];
  2445   2452       pWal->hdr.aFrameCksum[1] = aCksum[1];
  2446   2453   
  2447   2454       rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0);
  2448   2455       WALTRACE(("WAL%p: wal-header write %s\n", pWal, rc ? "failed" : "ok"));
  2449   2456       if( rc!=SQLITE_OK ){
................................................................................
  2530   2537       iFrame++;
  2531   2538       nLast--;
  2532   2539       rc = walIndexAppend(pWal, iFrame, pLast->pgno);
  2533   2540     }
  2534   2541   
  2535   2542     if( rc==SQLITE_OK ){
  2536   2543       /* Update the private copy of the header. */
  2537         -    pWal->hdr.szPage = (u16)szPage;
         2544  +    pWal->hdr.szPage = szPage>=0x10000 ? (szPage >> 16) : szPage;
  2538   2545       pWal->hdr.mxFrame = iFrame;
  2539   2546       if( isCommit ){
  2540   2547         pWal->hdr.iChange++;
  2541   2548         pWal->hdr.nPage = nTruncate;
  2542   2549       }
  2543   2550       /* If this is a commit, update the wal-index header too. */
  2544   2551       if( isCommit ){

Changes to test/pager1.test.

   498    498             3   20    32       {1 2 3 4}
   499    499             4   20    33       {1 2 3 4}
   500    500             5   20    65536    {1 2 3 4}
   501    501             6   20    131072   {1 2 3 4}
   502    502   
   503    503             7   24    511      {1 2 3 4}
   504    504             8   24    513      {1 2 3 4}
   505         -          9   24    65536    {1 2 3 4}
          505  +          9   24    131072   {1 2 3 4}
   506    506   
   507    507            10   32    65536    {1 2}
   508    508   } {
   509    509     do_test pager1.4.3.$tn {
   510    510       faultsim_restore_and_reopen
   511    511       hexio_write test.db-journal $ofst [format %.8x $value]
   512    512       execsql { SELECT * FROM t1 }

Changes to test/wal.test.

  1235   1235     3    512    1
  1236   1236     4   1024    1
  1237   1237     5   2048    1
  1238   1238     6   4096    1
  1239   1239     7   8192    1
  1240   1240     8  16384    1
  1241   1241     9  32768    1
  1242         - 10  65536    0
         1242  + 10  65536    1
         1243  + 11 131072    0
  1243   1244    11   1016    0
  1244   1245   } {
  1245   1246   
  1246   1247     if {$::SQLITE_MAX_PAGE_SIZE < $pgsz} {
  1247   1248       set works 0
  1248   1249     }
  1249   1250