SQLite

Check-in [88b763e8d7]
Login

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

Overview
Comment:Make sure SQLITE_FCNTL_SIZE_HINT a no-op if the chunk size is not greater than zero.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 88b763e8d73fafa1538b08af28b1c8b723b39c61
User & Date: mistachkin 2011-08-30 01:23:34.101
Context
2011-08-30
01:29
Change the build process so that it does not require the unix "sort" command. This avoids confusion between ms-sort and mingw-sort on windows systems. (check-in: f1bd5bbae5 user: drh tags: trunk)
01:23
Make sure SQLITE_FCNTL_SIZE_HINT a no-op if the chunk size is not greater than zero. (check-in: 88b763e8d7 user: mistachkin tags: trunk)
00:58
Fix a total unimportant file descriptor leak in lemon. This is to silence warning messages. (check-in: e95cf2c576 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/os_unix.c.
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
/* 
** This function is called to handle the SQLITE_FCNTL_SIZE_HINT 
** file-control operation.  Enlarge the database to nBytes in size
** (rounded up to the next chunk-size).  If the database is already
** nBytes or larger, this routine is a no-op.
*/
static int fcntlSizeHint(unixFile *pFile, i64 nByte){
  if( pFile->szChunk ){
    i64 nSize;                    /* Required file size */
    struct stat buf;              /* Used to hold return values of fstat() */
   
    if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT;

    nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk;
    if( nSize>(i64)buf.st_size ){







|







3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
/* 
** This function is called to handle the SQLITE_FCNTL_SIZE_HINT 
** file-control operation.  Enlarge the database to nBytes in size
** (rounded up to the next chunk-size).  If the database is already
** nBytes or larger, this routine is a no-op.
*/
static int fcntlSizeHint(unixFile *pFile, i64 nByte){
  if( pFile->szChunk>0 ){
    i64 nSize;                    /* Required file size */
    struct stat buf;              /* Used to hold return values of fstat() */
   
    if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT;

    nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk;
    if( nSize>(i64)buf.st_size ){
Changes to src/os_win.c.
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
  SimulateIOError(return SQLITE_IOERR_TRUNCATE);

  /* If the user has configured a chunk-size for this file, truncate the
  ** file so that it consists of an integer number of chunks (i.e. the
  ** actual file size after the operation may be larger than the requested
  ** size).
  */
  if( pFile->szChunk ){
    nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
  }

  /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
  if( seekWinFile(pFile, nByte) ){
    rc = winLogError(SQLITE_IOERR_TRUNCATE, "winTruncate1", pFile->zPath);
  }else if( 0==SetEndOfFile(pFile->h) ){







|







1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
  SimulateIOError(return SQLITE_IOERR_TRUNCATE);

  /* If the user has configured a chunk-size for this file, truncate the
  ** file so that it consists of an integer number of chunks (i.e. the
  ** actual file size after the operation may be larger than the requested
  ** size).
  */
  if( pFile->szChunk>0 ){
    nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
  }

  /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
  if( seekWinFile(pFile, nByte) ){
    rc = winLogError(SQLITE_IOERR_TRUNCATE, "winTruncate1", pFile->zPath);
  }else if( 0==SetEndOfFile(pFile->h) ){
1599
1600
1601
1602
1603
1604
1605

1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617


1618
1619
1620
1621
1622
1623
1624
      return SQLITE_OK;
    }
    case SQLITE_FCNTL_CHUNK_SIZE: {
      pFile->szChunk = *(int *)pArg;
      return SQLITE_OK;
    }
    case SQLITE_FCNTL_SIZE_HINT: {

      winFile *pFile = (winFile*)id;
      sqlite3_int64 oldSz;
      int rc = winFileSize(id, &oldSz);
      if( rc==SQLITE_OK ){
        sqlite3_int64 newSz = *(sqlite3_int64*)pArg;
        if( newSz>oldSz ){
          SimulateIOErrorBenign(1);
          rc = winTruncate(id, newSz);
          SimulateIOErrorBenign(0);
        }
      }
      return rc;


    }
    case SQLITE_FCNTL_PERSIST_WAL: {
      int bPersist = *(int*)pArg;
      if( bPersist<0 ){
        *(int*)pArg = pFile->bPersistWal;
      }else{
        pFile->bPersistWal = bPersist!=0;







>
|
|
|
|
|
|
|
|
|
|
|
|
>
>







1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
      return SQLITE_OK;
    }
    case SQLITE_FCNTL_CHUNK_SIZE: {
      pFile->szChunk = *(int *)pArg;
      return SQLITE_OK;
    }
    case SQLITE_FCNTL_SIZE_HINT: {
      if( pFile->szChunk>0 ){
        winFile *pFile = (winFile*)id;
        sqlite3_int64 oldSz;
        int rc = winFileSize(id, &oldSz);
        if( rc==SQLITE_OK ){
          sqlite3_int64 newSz = *(sqlite3_int64*)pArg;
          if( newSz>oldSz ){
            SimulateIOErrorBenign(1);
            rc = winTruncate(id, newSz);
            SimulateIOErrorBenign(0);
          }
        }
        return rc;
      }
      return SQLITE_OK;
    }
    case SQLITE_FCNTL_PERSIST_WAL: {
      int bPersist = *(int*)pArg;
      if( bPersist<0 ){
        *(int*)pArg = pFile->bPersistWal;
      }else{
        pFile->bPersistWal = bPersist!=0;
Changes to test/wal5.test.
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
    } {}
    do_test 2.3.$tn.2 { file_page_counts } {1 5 1 5}
    do_test 2.3.$tn.3 { sql2 { BEGIN; SELECT * FROM t1 } } {1 2}
    do_test 2.3.$tn.4 { sql1 { INSERT INTO t1 VALUES(3, 4) } } {}
    do_test 2.3.$tn.5 { sql1 { INSERT INTO t2 VALUES(3, 4) } } {}
    do_test 2.3.$tn.6 { file_page_counts } {1 7 1 7}
    do_test 2.3.$tn.7 { code1 { do_wal_checkpoint db -mode full } } {1 7 5}
    if {$tcl_platform(platform) == "windows"} {
        # on unix, the size_hint is a no-op if no chunk size is set.
        # the windows implementation does not have a similar check,
        # and because of this, the db file size has an extra page.
        do_test 2.3.$tn.8 { file_page_counts } {2 7 2 7}
    } {
        do_test 2.3.$tn.8 { file_page_counts } {1 7 2 7}
    }
  }

  # Check that checkpoints block on the correct locks. And respond correctly
  # if they cannot obtain those locks. There are three locks that a checkpoint
  # may block on (in the following order):
  #
  #   1. The writer lock: FULL and RESTART checkpoints block until any writer







<
<
<
<
<
<
|
<







231
232
233
234
235
236
237






238

239
240
241
242
243
244
245
    } {}
    do_test 2.3.$tn.2 { file_page_counts } {1 5 1 5}
    do_test 2.3.$tn.3 { sql2 { BEGIN; SELECT * FROM t1 } } {1 2}
    do_test 2.3.$tn.4 { sql1 { INSERT INTO t1 VALUES(3, 4) } } {}
    do_test 2.3.$tn.5 { sql1 { INSERT INTO t2 VALUES(3, 4) } } {}
    do_test 2.3.$tn.6 { file_page_counts } {1 7 1 7}
    do_test 2.3.$tn.7 { code1 { do_wal_checkpoint db -mode full } } {1 7 5}






    do_test 2.3.$tn.8 { file_page_counts } {1 7 2 7}

  }

  # Check that checkpoints block on the correct locks. And respond correctly
  # if they cannot obtain those locks. There are three locks that a checkpoint
  # may block on (in the following order):
  #
  #   1. The writer lock: FULL and RESTART checkpoints block until any writer