/ Changes On Branch pcache1-zero-page
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.

Changes In Branch pcache1-zero-page Excluding Merge-Ins

This is equivalent to a diff from 2842bc60 to b0810ac1

2016-12-30
14:15
Avoid passing NULL pointers to memcmp() or memcpy(), even when the "number-of-bytes" argument is passed 0. check-in: 56ff72ab user: dan tags: trunk
13:55
Clarify the expectations for the behavior of the xFetch method on the sqlite3_pcache_methods object for the case when the key is zero. Closed-Leaf check-in: b0810ac1 user: drh tags: pcache1-zero-page
13:40
Improved detection of zero page numbers in the page cache. check-in: 5550e815 user: drh tags: pcache1-zero-page
12:10
Fix a harmless compiler warning in fuzzcheck.c check-in: 2842bc60 user: drh tags: trunk
12:06
Disable the pagerAcquireMapPage() routine if memory-mapped I/O is disabled. This fixes a harmless compiler warning on OpenBSD. check-in: 3e25ba6e user: drh tags: trunk

Changes to src/pager.c.

5372
5373
5374
5375
5376
5377
5378



5379

5380
5381
5382
5383
5384
5385
5386
....
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406

5407
5408
5409
5410
5411
5412
5413
5414
  assert( pPager->eState>=PAGER_READER );
  assert( assert_pager_state(pPager) );
  assert( pPager->hasHeldSharedLock==1 );

  pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3);
  if( pBase==0 ){
    pPg = 0;



    rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase);

    if( rc!=SQLITE_OK ) goto pager_acquire_err;
    if( pBase==0 ){
      rc = SQLITE_NOMEM_BKPT;
      goto pager_acquire_err;
    }
  }
  pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase);
................................................................................
    pPager->aStat[PAGER_STAT_HIT]++;
    return SQLITE_OK;

  }else{
    /* The pager cache has created a new page. Its content needs to 
    ** be initialized. But first some error checks:
    **
    ** (1) Minimum page number is 1
    ** (2) The maximum page number is 2^31
    ** (3) Never try to fetch the locking page
    */

    if( pgno==0 || pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){
      rc = SQLITE_CORRUPT_BKPT;
      goto pager_acquire_err;
    }

    pPg->pPager = pPager;

    assert( !isOpen(pPager->fd) || !MEMDB );







>
>
>
|
>







 







<
|
|

>
|







5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
....
5400
5401
5402
5403
5404
5405
5406

5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
  assert( pPager->eState>=PAGER_READER );
  assert( assert_pager_state(pPager) );
  assert( pPager->hasHeldSharedLock==1 );

  pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3);
  if( pBase==0 ){
    pPg = 0;
    if( pgno==0 ){
      rc = SQLITE_CORRUPT_BKPT;
    }else{
      rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase);
    }
    if( rc!=SQLITE_OK ) goto pager_acquire_err;
    if( pBase==0 ){
      rc = SQLITE_NOMEM_BKPT;
      goto pager_acquire_err;
    }
  }
  pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase);
................................................................................
    pPager->aStat[PAGER_STAT_HIT]++;
    return SQLITE_OK;

  }else{
    /* The pager cache has created a new page. Its content needs to 
    ** be initialized. But first some error checks:
    **

    ** (1) The maximum page number is 2^31
    ** (2) Never try to fetch the locking page
    */
    assert( pgno>0 );
    if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){
      rc = SQLITE_CORRUPT_BKPT;
      goto pager_acquire_err;
    }

    pPg->pPager = pPager;

    assert( !isOpen(pPager->fd) || !MEMDB );

Changes to src/pcache1.c.

993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
  ** subsequent steps to try to create the page. */
  if( pPage ){
    if( !pPage->isPinned ){
      return pcache1PinPage(pPage);
    }else{
      return pPage;
    }
  }else if( createFlag ){
    /* Steps 3, 4, and 5 implemented by this subroutine */
    return pcache1FetchStage2(pCache, iKey, createFlag);
  }else{
    return 0;
  }
}
#if PCACHE1_MIGHT_USE_GROUP_MUTEX







|







993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
  ** subsequent steps to try to create the page. */
  if( pPage ){
    if( !pPage->isPinned ){
      return pcache1PinPage(pPage);
    }else{
      return pPage;
    }
  }else if( createFlag && iKey ){
    /* Steps 3, 4, and 5 implemented by this subroutine */
    return pcache1FetchStage2(pCache, iKey, createFlag);
  }else{
    return 0;
  }
}
#if PCACHE1_MIGHT_USE_GROUP_MUTEX

Changes to src/sqlite.h.in.

7211
7212
7213
7214
7215
7216
7217

7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232

7233
7234
7235
7236
7237
7238
7239
7240
** The pBuf element of the returned sqlite3_pcache_page object will be a
** pointer to a buffer of szPage bytes used to store the content of a 
** single database page.  The pExtra element of sqlite3_pcache_page will be
** a pointer to the szExtra bytes of extra storage that SQLite has requested
** for each entry in the page cache.
**
** The page to be fetched is determined by the key. ^The minimum key value

** is 1.  After it has been retrieved using xFetch, the page is considered
** to be "pinned".
**
** If the requested page is already in the page cache, then the page cache
** implementation must return a pointer to the page buffer with its content
** intact.  If the requested page is not already in the cache, then the
** cache implementation should use the value of the createFlag
** parameter to help it determined what action to take:
**
** <table border=1 width=85% align=center>
** <tr><th> createFlag <th> Behavior when page is not already in cache
** <tr><td> 0 <td> Do not allocate a new page.  Return NULL.
** <tr><td> 1 <td> Allocate a new page if it easy and convenient to do so.
**                 Otherwise return NULL.
** <tr><td> 2 <td> Make every effort to allocate a new page.  Only return

**                 NULL if allocating a new page is effectively impossible.
** </table>
**
** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1.  SQLite
** will only use a createFlag of 2 after a prior call with a createFlag of 1
** failed.)^  In between the to xFetch() calls, SQLite may
** attempt to unpin one or more cache pages by spilling the content of
** pinned pages to disk and synching the operating system disk cache.







>
|











|
|

>
|







7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
** The pBuf element of the returned sqlite3_pcache_page object will be a
** pointer to a buffer of szPage bytes used to store the content of a 
** single database page.  The pExtra element of sqlite3_pcache_page will be
** a pointer to the szExtra bytes of extra storage that SQLite has requested
** for each entry in the page cache.
**
** The page to be fetched is determined by the key. ^The minimum key value
** is 1.  The xFetch() method must return NULL if passed a key of 0.
** After it has been retrieved using xFetch, the page is considered
** to be "pinned".
**
** If the requested page is already in the page cache, then the page cache
** implementation must return a pointer to the page buffer with its content
** intact.  If the requested page is not already in the cache, then the
** cache implementation should use the value of the createFlag
** parameter to help it determined what action to take:
**
** <table border=1 width=85% align=center>
** <tr><th> createFlag <th> Behavior when page is not already in cache
** <tr><td> 0 <td> Do not allocate a new page.  Return NULL.
** <tr><td> 1 <td> Allocate a new page if it easy and convenient to do so
**                 and the key is not zero.  Otherwise return NULL.
** <tr><td> 2 <td> Make every effort to allocate a new page.  Only return
**                 NULL if the key is zero or if allocating a new page is 
**                 effectively impossible.
** </table>
**
** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1.  SQLite
** will only use a createFlag of 2 after a prior call with a createFlag of 1
** failed.)^  In between the to xFetch() calls, SQLite may
** attempt to unpin one or more cache pages by spilling the content of
** pinned pages to disk and synching the operating system disk cache.