SQLite

Changes On Branch deferred-open
Login

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

Changes In Branch deferred-open Excluding Merge-Ins

This is equivalent to a diff from 0a8bcbbd to f352ef57

2014-02-12
15:05
Various fixes and test case updates so that veryquick.test passes again. (Leaf check-in: f352ef57 user: dan tags: deferred-open)
14:43
Make sure "rowid" columns are correctly resolved in joins between normal tables and WITHOUT ROWID tables. Fix for ticket [c34d0557f740c45070]. (check-in: 5d01426d user: drh tags: trunk)
14:43
Merge latest trunk changes. (check-in: 4d7057c4 user: dan tags: deferred-open)
2014-02-11
16:31
Sync with trunk. Bring in the command-line shell updates and the new 3.8.4 version number. (check-in: 2cd35ff6 user: drh tags: sessions)
16:24
Increase the version number to 3.8.4 (check-in: 0a8bcbbd user: drh tags: trunk)
16:22
Updates to the command-line shell. Simplify the banner message. Add the ".save" command as an alias for ".backup". When starting with no arguments, include a banner message warning that the database is transient and in-memory and mention the ".open" command. (check-in: f5ad1e1b user: drh tags: trunk)

Changes to src/os_unix.c.

199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
  sqlite3_int64 mmapSizeMax;          /* Configured FCNTL_MMAP_SIZE value */
  void *pMapRegion;                   /* Memory mapped region */
#endif
#ifdef __QNXNTO__
  int sectorSize;                     /* Device sector size */
  int deviceCharacteristics;          /* Precomputed device characteristics */
#endif
#if SQLITE_ENABLE_LOCKING_STYLE
  int openFlags;                      /* The flags specified at open() */
#endif
#if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
  unsigned fsFlags;                   /* cached details from statfs() */
#endif
#if OS_VXWORKS
  struct vxworksFileId *pId;          /* Unique file ID */
#endif
#ifdef SQLITE_DEBUG







<

<







199
200
201
202
203
204
205

206

207
208
209
210
211
212
213
  sqlite3_int64 mmapSizeMax;          /* Configured FCNTL_MMAP_SIZE value */
  void *pMapRegion;                   /* Memory mapped region */
#endif
#ifdef __QNXNTO__
  int sectorSize;                     /* Device sector size */
  int deviceCharacteristics;          /* Precomputed device characteristics */
#endif

  int openFlags;                      /* The flags specified at open() */

#if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
  unsigned fsFlags;                   /* cached details from statfs() */
#endif
#if OS_VXWORKS
  struct vxworksFileId *pId;          /* Unique file ID */
#endif
#ifdef SQLITE_DEBUG
251
252
253
254
255
256
257
258

259
260
261
262
263
264
265
#else
# define UNIXFILE_DIRSYNC    0x00
#endif
#define UNIXFILE_PSOW        0x10     /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
#define UNIXFILE_DELETE      0x20     /* Delete on close */
#define UNIXFILE_URI         0x40     /* Filename might have query parameters */
#define UNIXFILE_NOLOCK      0x80     /* Do no file locking */
#define UNIXFILE_WARNED    0x0100     /* verifyDbFile() warnings have been issued */


/*
** Include code that is common to all os_*.c files
*/
#include "os_common.h"

/*







|
>







249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
#else
# define UNIXFILE_DIRSYNC    0x00
#endif
#define UNIXFILE_PSOW        0x10     /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
#define UNIXFILE_DELETE      0x20     /* Delete on close */
#define UNIXFILE_URI         0x40     /* Filename might have query parameters */
#define UNIXFILE_NOLOCK      0x80     /* Do no file locking */
#define UNIXFILE_WARNED    0x0100     /* verifyDbFile() has issued warnings */
#define UNIXFILE_DEFERRED  0x0200     /* File has not yet been opened */

/*
** Include code that is common to all os_*.c files
*/
#include "os_common.h"

/*
1353
1354
1355
1356
1357
1358
1359

1360
1361




1362
1363
1364
1365
1366
1367
1368
1369
** is set to SQLITE_OK unless an I/O error occurs during lock checking.
*/
static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
  int rc = SQLITE_OK;
  int reserved = 0;
  unixFile *pFile = (unixFile*)id;


  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );





  assert( pFile );
  unixEnterMutex(); /* Because pFile->pInode is shared across threads */

  /* Check if a thread in this process holds such a lock */
  if( pFile->pInode->eFileLock>SHARED_LOCK ){
    reserved = 1;
  }








>


>
>
>
>
|







1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
** is set to SQLITE_OK unless an I/O error occurs during lock checking.
*/
static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
  int rc = SQLITE_OK;
  int reserved = 0;
  unixFile *pFile = (unixFile*)id;

  assert( pFile );
  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );

  if( pFile->ctrlFlags & UNIXFILE_DEFERRED ){
    *pResOut = 0;
    return SQLITE_OK;
  }

  unixEnterMutex(); /* Because pFile->pInode is shared across threads */

  /* Check if a thread in this process holds such a lock */
  if( pFile->pInode->eFileLock>SHARED_LOCK ){
    reserved = 1;
  }

1434
1435
1436
1437
1438
1439
1440















1441
1442
1443
1444
1445
1446
1447
      rc = 0;
    }
  }else{
    rc = osFcntl(pFile->h, F_SETLK, pLock);
  }
  return rc;
}
















/*
** Lock the file with the lock specified by parameter eFileLock - one
** of the following:
**
**     (1) SHARED_LOCK
**     (2) RESERVED_LOCK







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
      rc = 0;
    }
  }else{
    rc = osFcntl(pFile->h, F_SETLK, pLock);
  }
  return rc;
}

static int unixOpen(sqlite3_vfs*, const char*, sqlite3_file*, int, int *);

static int unixOpenAndLock(unixFile *pFile){
  sqlite3_file *id = (sqlite3_file*)pFile;
  int eOrigLock = pFile->eFileLock;
  int rc;

  assert( pFile->ctrlFlags & UNIXFILE_DEFERRED );
  rc = unixOpen(pFile->pVfs, pFile->zPath, id, pFile->openFlags, 0);
  if( rc==SQLITE_OK && eOrigLock ){
    rc = id->pMethods->xLock(id, eOrigLock);
  }
  return rc;
}

/*
** Lock the file with the lock specified by parameter eFileLock - one
** of the following:
**
**     (1) SHARED_LOCK
**     (2) RESERVED_LOCK
1519
1520
1521
1522
1523
1524
1525




















1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
  */
  if( pFile->eFileLock>=eFileLock ){
    OSTRACE(("LOCK    %d %s ok (already held) (unix)\n", pFile->h,
            azFileLock(eFileLock)));
    return SQLITE_OK;
  }





















  /* Make sure the locking sequence is correct.
  **  (1) We never move from unlocked to anything higher than shared lock.
  **  (2) SQLite never explicitly requests a pendig lock.
  **  (3) A shared lock is always held when a reserve lock is requested.
  */
  assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK );
  assert( eFileLock!=PENDING_LOCK );
  assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK );

  /* This mutex is needed because pFile->pInode is shared across threads







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|







1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
  */
  if( pFile->eFileLock>=eFileLock ){
    OSTRACE(("LOCK    %d %s ok (already held) (unix)\n", pFile->h,
            azFileLock(eFileLock)));
    return SQLITE_OK;
  }

  if( pFile->ctrlFlags & UNIXFILE_DEFERRED ){
    const char *zPath = pFile->zPath;       /* Full-path to database file */
    int eOrigLock;                          /* Current lock held on pFile */

    assert( pFile->eFileLock==SHARED_LOCK || pFile->eFileLock==NO_LOCK );

    /* If SQLite is requesting a SHARED lock and the database file does
    ** not exist, return early without opening the file. */ 
    if( eFileLock==SHARED_LOCK && osAccess(zPath, F_OK) && errno==ENOENT ){
      pFile->eFileLock = SHARED_LOCK;
      return SQLITE_OK;
    }

    /* Or, if the database file has been created or a write lock is 
    ** requested, open the database file now.  */
    rc = unixOpenAndLock(pFile);
    if( rc!=SQLITE_OK ) return rc;
  }
  assert( (pFile->ctrlFlags & UNIXFILE_DEFERRED)==0 );

  /* Make sure the locking sequence is correct.
  **  (1) We never move from unlocked to anything higher than shared lock.
  **  (2) SQLite never explicitly requests a pending lock.
  **  (3) A shared lock is always held when a reserve lock is requested.
  */
  assert( pFile->eFileLock!=NO_LOCK || eFileLock==SHARED_LOCK );
  assert( eFileLock!=PENDING_LOCK );
  assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK );

  /* This mutex is needed because pFile->pInode is shared across threads
1722
1723
1724
1725
1726
1727
1728

1729
1730
1731
1732
1733
1734
1735
      getpid()));

  assert( eFileLock<=SHARED_LOCK );
  if( pFile->eFileLock<=eFileLock ){
    return SQLITE_OK;
  }
  unixEnterMutex();

  pInode = pFile->pInode;
  assert( pInode->nShared!=0 );
  if( pFile->eFileLock>SHARED_LOCK ){
    assert( pInode->eFileLock==pFile->eFileLock );

#ifdef SQLITE_DEBUG
    /* When reducing a lock such that other processes can start







>







1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
      getpid()));

  assert( eFileLock<=SHARED_LOCK );
  if( pFile->eFileLock<=eFileLock ){
    return SQLITE_OK;
  }
  unixEnterMutex();
  if( pFile->ctrlFlags & UNIXFILE_DEFERRED ) goto end_unlock;
  pInode = pFile->pInode;
  assert( pInode->nShared!=0 );
  if( pFile->eFileLock>SHARED_LOCK ){
    assert( pInode->eFileLock==pFile->eFileLock );

#ifdef SQLITE_DEBUG
    /* When reducing a lock such that other processes can start
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938




1939
1940
1941
1942
1943
1944
1945
1946
1947

1948
1949
1950
1951
1952
1953
1954
static int unixClose(sqlite3_file *id){
  int rc = SQLITE_OK;
  unixFile *pFile = (unixFile *)id;
  verifyDbFile(pFile);
  unixUnlock(id, NO_LOCK);
  unixEnterMutex();

  /* unixFile.pInode is always valid here. Otherwise, a different close
  ** routine (e.g. nolockClose()) would be called instead.
  */
  assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 );




  if( ALWAYS(pFile->pInode) && pFile->pInode->nLock ){
    /* If there are outstanding locks, do not actually close the file just
    ** yet because that would clear those locks.  Instead, add the file
    ** descriptor to pInode->pUnused list.  It will be automatically closed 
    ** when the last lock is cleared.
    */
    setPendingFd(pFile);
  }
  releaseInodeInfo(pFile);

  rc = closeUnixFile(id);
  unixLeaveMutex();
  return rc;
}

/************** End of the posix advisory lock implementation *****************
******************************************************************************/







|
<

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







1968
1969
1970
1971
1972
1973
1974
1975

1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
static int unixClose(sqlite3_file *id){
  int rc = SQLITE_OK;
  unixFile *pFile = (unixFile *)id;
  verifyDbFile(pFile);
  unixUnlock(id, NO_LOCK);
  unixEnterMutex();

  /* unixFile.pInode may be NULL here if the file was never opened.

  */
  assert( pFile->pInode==0 
       || pFile->pInode->nLock>0 
       || pFile->pInode->bProcessLock==0 
  );
  if( pFile->pInode ){
    if( pFile->pInode->nLock ){
      /* If there are outstanding locks, do not actually close the file just
      ** yet because that would clear those locks.  Instead, add the file
      ** descriptor to pInode->pUnused list.  It will be automatically closed 
      ** when the last lock is cleared.
      */
      setPendingFd(pFile);
    }
    releaseInodeInfo(pFile);
  }
  rc = closeUnixFile(id);
  unixLeaveMutex();
  return rc;
}

/************** End of the posix advisory lock implementation *****************
******************************************************************************/
3169
3170
3171
3172
3173
3174
3175














3176
3177
3178
3179
3180
3181
3182
#if 0
  assert( pFile->pUnused==0
       || offset>=PENDING_BYTE+512
       || offset+amt<=PENDING_BYTE 
  );
#endif















#if SQLITE_MAX_MMAP_SIZE>0
  /* Deal with as much of this read request as possible by transfering
  ** data from the memory mapping using memcpy().  */
  if( offset<pFile->mmapSize ){
    if( offset+amt <= pFile->mmapSize ){
      memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt);
      return SQLITE_OK;







>
>
>
>
>
>
>
>
>
>
>
>
>
>







3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
#if 0
  assert( pFile->pUnused==0
       || offset>=PENDING_BYTE+512
       || offset+amt<=PENDING_BYTE 
  );
#endif

  if( pFile->ctrlFlags & UNIXFILE_DEFERRED ){
    int rc;
    if( osAccess(pFile->zPath, F_OK) && errno==ENOENT ){
      memset(pBuf, 0, amt);
      rc = SQLITE_IOERR_SHORT_READ;
    }else{
      rc = unixOpen(pFile->pVfs, pFile->zPath, id, pFile->openFlags, 0);
    }
    if( rc!=SQLITE_OK ){
      return rc;
    }
  }
  assert( (pFile->ctrlFlags & UNIXFILE_DEFERRED)==0 );

#if SQLITE_MAX_MMAP_SIZE>0
  /* Deal with as much of this read request as possible by transfering
  ** data from the memory mapping using memcpy().  */
  if( offset<pFile->mmapSize ){
    if( offset+amt <= pFile->mmapSize ){
      memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt);
      return SQLITE_OK;
3272
3273
3274
3275
3276
3277
3278









3279
3280
3281
3282
3283
3284
3285
  int amt,
  sqlite3_int64 offset 
){
  unixFile *pFile = (unixFile*)id;
  int wrote = 0;
  assert( id );
  assert( amt>0 );










  /* If this is a database file (not a journal, master-journal or temp
  ** file), the bytes in the locking range should never be read or written. */
#if 0
  assert( pFile->pUnused==0
       || offset>=PENDING_BYTE+512
       || offset+amt<=PENDING_BYTE 







>
>
>
>
>
>
>
>
>







3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
  int amt,
  sqlite3_int64 offset 
){
  unixFile *pFile = (unixFile*)id;
  int wrote = 0;
  assert( id );
  assert( amt>0 );

  /* SQLite never actually calls xWrite on an empty file before obtaining
  ** a RESERVED lock on it. So the following condition is never true if 
  ** the VFS is being used directly by SQLite. But it may be if this module
  ** is being used in some other way. By the multiplexor VFS, for example. */
  if( pFile->ctrlFlags & UNIXFILE_DEFERRED ){
    int rc = unixOpenAndLock(pFile);
    if( rc!=SQLITE_OK ) return rc;
  }

  /* If this is a database file (not a journal, master-journal or temp
  ** file), the bytes in the locking range should never be read or written. */
#if 0
  assert( pFile->pUnused==0
       || offset>=PENDING_BYTE+512
       || offset+amt<=PENDING_BYTE 
3621
3622
3623
3624
3625
3626
3627

3628
3629
3630







3631

3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
  }
}

/*
** Determine the current size of a file in bytes
*/
static int unixFileSize(sqlite3_file *id, i64 *pSize){

  int rc;
  struct stat buf;
  assert( id );







  rc = osFstat(((unixFile*)id)->h, &buf);

  SimulateIOError( rc=1 );
  if( rc!=0 ){
    ((unixFile*)id)->lastErrno = errno;
    return SQLITE_IOERR_FSTAT;
  }
  *pSize = buf.st_size;

  /* When opening a zero-size database, the findInodeInfo() procedure
  ** writes a single byte into that file in order to work around a bug
  ** in the OS-X msdos filesystem.  In order to avoid problems with upper
  ** layers, we need to report this file size as zero even though it is
  ** really 1.   Ticket #3260.
  */
  if( *pSize==1 ) *pSize = 0;


  return SQLITE_OK;
}

#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
/*
** Handler for proxy-locking file-control verbs.  Defined below in the







>



>
>
>
>
>
>
>
|
>














<







3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721

3722
3723
3724
3725
3726
3727
3728
  }
}

/*
** Determine the current size of a file in bytes
*/
static int unixFileSize(sqlite3_file *id, i64 *pSize){
  unixFile *pFile = (unixFile*)id;
  int rc;
  struct stat buf;
  assert( id );
  if( pFile->ctrlFlags & UNIXFILE_DEFERRED ){
    rc = osStat(pFile->zPath, &buf);
    if( rc && errno==ENOENT ){
      rc = 0;
      buf.st_size = 0;
    }
  }else{
    rc = osFstat(pFile->h, &buf);
  }
  SimulateIOError( rc=1 );
  if( rc!=0 ){
    ((unixFile*)id)->lastErrno = errno;
    return SQLITE_IOERR_FSTAT;
  }
  *pSize = buf.st_size;

  /* When opening a zero-size database, the findInodeInfo() procedure
  ** writes a single byte into that file in order to work around a bug
  ** in the OS-X msdos filesystem.  In order to avoid problems with upper
  ** layers, we need to report this file size as zero even though it is
  ** really 1.   Ticket #3260.
  */
  if( *pSize==1 ) *pSize = 0;


  return SQLITE_OK;
}

#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
/*
** Handler for proxy-locking file-control verbs.  Defined below in the
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
  /* No locking occurs in temporary files */
  assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 );

  OSTRACE(("OPEN    %-3d %s\n", h, zFilename));
  pNew->h = h;
  pNew->pVfs = pVfs;
  pNew->zPath = zFilename;
  pNew->ctrlFlags = (u8)ctrlFlags;
#if SQLITE_MAX_MMAP_SIZE>0
  pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap;
#endif
  if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0),
                           "psow", SQLITE_POWERSAFE_OVERWRITE) ){
    pNew->ctrlFlags |= UNIXFILE_PSOW;
  }
  if( strcmp(pVfs->zName,"unix-excl")==0 ){
    pNew->ctrlFlags |= UNIXFILE_EXCL;
  }

#if OS_VXWORKS
  pNew->pId = vxworksFindFileId(zFilename);
  if( pNew->pId==0 ){







|
<
<
<
<
<
<
<







5247
5248
5249
5250
5251
5252
5253
5254







5255
5256
5257
5258
5259
5260
5261
  /* No locking occurs in temporary files */
  assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 );

  OSTRACE(("OPEN    %-3d %s\n", h, zFilename));
  pNew->h = h;
  pNew->pVfs = pVfs;
  pNew->zPath = zFilename;
  pNew->ctrlFlags = (unsigned short)ctrlFlags;







  if( strcmp(pVfs->zName,"unix-excl")==0 ){
    pNew->ctrlFlags |= UNIXFILE_EXCL;
  }

#if OS_VXWORKS
  pNew->pId = vxworksFindFileId(zFilename);
  if( pNew->pId==0 ){
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
    pNew->ctrlFlags |= UNIXFILE_DELETE;
  }
#endif
  if( rc!=SQLITE_OK ){
    if( h>=0 ) robust_close(pNew, h, __LINE__);
  }else{
    pNew->pMethod = pLockingStyle;
    OpenCounter(+1);
    verifyDbFile(pNew);
  }
  return rc;
}

/*
** Return the name of a directory in which to put temporary files.







<







5386
5387
5388
5389
5390
5391
5392

5393
5394
5395
5396
5397
5398
5399
    pNew->ctrlFlags |= UNIXFILE_DELETE;
  }
#endif
  if( rc!=SQLITE_OK ){
    if( h>=0 ) robust_close(pNew, h, __LINE__);
  }else{
    pNew->pMethod = pLockingStyle;

    verifyDbFile(pNew);
  }
  return rc;
}

/*
** Return the name of a directory in which to put temporary files.
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
){
  unixFile *p = (unixFile *)pFile;
  int fd = -1;                   /* File descriptor returned by open() */
  int openFlags = 0;             /* Flags to pass to open() */
  int eType = flags&0xFFFFFF00;  /* Type of file to open */
  int noLock;                    /* True to omit locking primitives */
  int rc = SQLITE_OK;            /* Function Return Code */
  int ctrlFlags = 0;             /* UNIXFILE_* flags */

  int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
  int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
  int isCreate     = (flags & SQLITE_OPEN_CREATE);
  int isReadonly   = (flags & SQLITE_OPEN_READONLY);
  int isReadWrite  = (flags & SQLITE_OPEN_READWRITE);
#if SQLITE_ENABLE_LOCKING_STYLE







|







5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
){
  unixFile *p = (unixFile *)pFile;
  int fd = -1;                   /* File descriptor returned by open() */
  int openFlags = 0;             /* Flags to pass to open() */
  int eType = flags&0xFFFFFF00;  /* Type of file to open */
  int noLock;                    /* True to omit locking primitives */
  int rc = SQLITE_OK;            /* Function Return Code */
  int ctrlFlags;                 /* UNIXFILE_* flags */

  int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
  int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
  int isCreate     = (flags & SQLITE_OPEN_CREATE);
  int isReadonly   = (flags & SQLITE_OPEN_READONLY);
  int isReadWrite  = (flags & SQLITE_OPEN_READWRITE);
#if SQLITE_ENABLE_LOCKING_STYLE
5604
5605
5606
5607
5608
5609
5610





5611
5612
5613
5614
5615
5616
5617
  ));

  /* If argument zPath is a NULL pointer, this function is required to open
  ** a temporary file. Use this buffer to store the file name in.
  */
  char zTmpname[MAX_PATHNAME+2];
  const char *zName = zPath;






  /* Check the following statements are true: 
  **
  **   (a) Exactly one of the READWRITE and READONLY flags must be set, and 
  **   (b) if CREATE is set, then READWRITE must also be set, and
  **   (c) if EXCLUSIVE is set, then CREATE must also be set.
  **   (d) if DELETEONCLOSE is set, then CREATE must also be set.







>
>
>
>
>







5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
  ));

  /* If argument zPath is a NULL pointer, this function is required to open
  ** a temporary file. Use this buffer to store the file name in.
  */
  char zTmpname[MAX_PATHNAME+2];
  const char *zName = zPath;

  assert( p->pInode==0 && (p->h==-1 || p->h==0) );
  p->ctrlFlags &= ~UNIXFILE_DEFERRED;
  p->eFileLock = NO_LOCK;
  ctrlFlags = p->ctrlFlags;

  /* Check the following statements are true: 
  **
  **   (a) Exactly one of the READWRITE and READONLY flags must be set, and 
  **   (b) if CREATE is set, then READWRITE must also be set, and
  **   (c) if EXCLUSIVE is set, then CREATE must also be set.
  **   (d) if DELETEONCLOSE is set, then CREATE must also be set.
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
  ** are harmless.
  */
  if( randomnessPid!=getpid() ){
    randomnessPid = getpid();
    sqlite3_randomness(0,0);
  }

  memset(p, 0, sizeof(unixFile));

  if( eType==SQLITE_OPEN_MAIN_DB ){
    UnixUnusedFd *pUnused;
    pUnused = findReusableFd(zName, flags);
    if( pUnused ){
      fd = pUnused->fd;
    }else{







<







5713
5714
5715
5716
5717
5718
5719

5720
5721
5722
5723
5724
5725
5726
  ** are harmless.
  */
  if( randomnessPid!=getpid() ){
    randomnessPid = getpid();
    sqlite3_randomness(0,0);
  }



  if( eType==SQLITE_OPEN_MAIN_DB ){
    UnixUnusedFd *pUnused;
    pUnused = findReusableFd(zName, flags);
    if( pUnused ){
      fd = pUnused->fd;
    }else{
5814
5815
5816
5817
5818
5819
5820

5821
5822
5823
5824


























































5825
5826
5827
5828
5829
5830
5831
#endif
  
  rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags);

open_finished:
  if( rc!=SQLITE_OK ){
    sqlite3_free(p->pUnused);

  }
  return rc;
}




























































/*
** Delete the file at zPath. If the dirSync argument is true, fsync()
** the directory after deleting the file.
*/
static int unixDelete(
  sqlite3_vfs *NotUsed,     /* VFS containing this as the xDelete method */







>




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
#endif
  
  rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags);

open_finished:
  if( rc!=SQLITE_OK ){
    sqlite3_free(p->pUnused);
    p->pUnused = 0;
  }
  return rc;
}

static int unixOpenDeferred(
  sqlite3_vfs *pVfs,           /* The VFS for which this is the xOpen method */
  const char *zPath,           /* Pathname of file to be opened */
  sqlite3_file *pFile,         /* The file descriptor to be filled in */
  int flags,                   /* Input flags to control the opening */
  int *pOutFlags               /* Output flags returned to SQLite core */
){
  const int mask1 = SQLITE_OPEN_MAIN_DB | SQLITE_OPEN_READWRITE
                  | SQLITE_OPEN_CREATE;
  const int mask2 = SQLITE_OPEN_READONLY  | SQLITE_OPEN_DELETEONCLOSE
                  | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_AUTOPROXY;

  int rc;                         /* Return code */
  unixFile *p = (unixFile*)pFile; /* File object to populate */
  const char *zUri = (flags & UNIXFILE_URI) ? zPath : 0;

  /* Zero the file object */
  memset(p, 0, sizeof(unixFile));
  if( sqlite3_uri_boolean(zUri, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
    p->ctrlFlags |= UNIXFILE_PSOW;
  }
#if SQLITE_MAX_MMAP_SIZE>0
  p->mmapSizeMax = sqlite3GlobalConfig.szMmap;
#endif

  /* If all the flags in mask1 are set, and all the flags in mask2 are
  ** clear, the file does not exist but the directory does and is
  ** writable, then this is a deferred open.  */
  if( zPath && (flags & (mask1 | mask2))==mask1 ){
    int posixrc;
    posixrc = osAccess(zPath, F_OK);
    if( posixrc && errno==ENOENT ){
      char zDirname[MAX_PATHNAME+1];
      int i;
      for(i=(int)strlen(zPath); i>1 && zPath[i]!='/'; i--);
      memcpy(zDirname, zPath, i);
      zDirname[i] = '\0';
      posixrc = osAccess(zDirname, W_OK);
      if( posixrc==0 ){
        p->pMethod = (**(finder_type*)pVfs->pAppData)(0, 0);
        if( p->pMethod->xLock==unixLock ){
          p->pVfs = pVfs;
          p->h = -1;
          p->ctrlFlags |= UNIXFILE_DEFERRED;
          p->openFlags = flags;
          p->zPath = zPath;
          if( pOutFlags ) *pOutFlags = flags;
          OpenCounter(+1);
          return SQLITE_OK;
        }
      }
    }
  }

  rc = unixOpen(pVfs, zPath, pFile, flags, pOutFlags);
  OpenCounter( rc==SQLITE_OK );
  return rc;
}

/*
** Delete the file at zPath. If the dirSync argument is true, fsync()
** the directory after deleting the file.
*/
static int unixDelete(
  sqlite3_vfs *NotUsed,     /* VFS containing this as the xDelete method */
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
  #define UNIXVFS(VFSNAME, FINDER) {                        \
    3,                    /* iVersion */                    \
    sizeof(unixFile),     /* szOsFile */                    \
    MAX_PATHNAME,         /* mxPathname */                  \
    0,                    /* pNext */                       \
    VFSNAME,              /* zName */                       \
    (void*)&FINDER,       /* pAppData */                    \
    unixOpen,             /* xOpen */                       \
    unixDelete,           /* xDelete */                     \
    unixAccess,           /* xAccess */                     \
    unixFullPathname,     /* xFullPathname */               \
    unixDlOpen,           /* xDlOpen */                     \
    unixDlError,          /* xDlError */                    \
    unixDlSym,            /* xDlSym */                      \
    unixDlClose,          /* xDlClose */                    \







|







7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
  #define UNIXVFS(VFSNAME, FINDER) {                        \
    3,                    /* iVersion */                    \
    sizeof(unixFile),     /* szOsFile */                    \
    MAX_PATHNAME,         /* mxPathname */                  \
    0,                    /* pNext */                       \
    VFSNAME,              /* zName */                       \
    (void*)&FINDER,       /* pAppData */                    \
    unixOpenDeferred,     /* xOpen */                       \
    unixDelete,           /* xDelete */                     \
    unixAccess,           /* xAccess */                     \
    unixFullPathname,     /* xFullPathname */               \
    unixDlOpen,           /* xDlOpen */                     \
    unixDlError,          /* xDlError */                    \
    unixDlSym,            /* xDlSym */                      \
    unixDlClose,          /* xDlClose */                    \

Changes to src/test2.c.

530
531
532
533
534
535
536


537

538
539
540
541
542
543
544
  if( rc ){
    Tcl_AppendResult(interp, "open failed: ", sqlite3ErrName(rc), 0);
    sqlite3_free(zFile);
    return TCL_ERROR;
  }
  offset = n;
  offset *= 1024*1024;


  rc = sqlite3OsWrite(fd, "Hello, World!", 14, offset);

  sqlite3OsCloseFree(fd);
  sqlite3_free(zFile);
  if( rc ){
    Tcl_AppendResult(interp, "write failed: ", sqlite3ErrName(rc), 0);
    return TCL_ERROR;
  }
  return TCL_OK;







>
>

>







530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
  if( rc ){
    Tcl_AppendResult(interp, "open failed: ", sqlite3ErrName(rc), 0);
    sqlite3_free(zFile);
    return TCL_ERROR;
  }
  offset = n;
  offset *= 1024*1024;
  sqlite3OsLock(fd, SHARED_LOCK);
  sqlite3OsLock(fd, EXCLUSIVE_LOCK);
  rc = sqlite3OsWrite(fd, "Hello, World!", 14, offset);
  sqlite3OsUnlock(fd, NO_LOCK);
  sqlite3OsCloseFree(fd);
  sqlite3_free(zFile);
  if( rc ){
    Tcl_AppendResult(interp, "write failed: ", sqlite3ErrName(rc), 0);
    return TCL_ERROR;
  }
  return TCL_OK;

Changes to test/backup.test.

329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
do_test backup-3.$iTest.1 {
  catch { forcedelete test.db }
  catch { forcedelete test2.db }
  sqlite3 db test.db
  set iTab 1

  db eval { PRAGMA page_size = 512 }
  while {[file size test.db] <= $::sqlite_pending_byte} {
    db eval "CREATE TABLE t${iTab}(a, b, c)"
    incr iTab
  }

  sqlite3 db2 test2.db
  db2 eval { PRAGMA page_size = 4096 }
  while {[file size test2.db] < $::sqlite_pending_byte} {
    db2 eval "CREATE TABLE t${iTab}(a, b, c)"
    incr iTab
  }

  sqlite3_backup B db2 main db main
  B step -1
} {SQLITE_DONE}







|






|







329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
do_test backup-3.$iTest.1 {
  catch { forcedelete test.db }
  catch { forcedelete test2.db }
  sqlite3 db test.db
  set iTab 1

  db eval { PRAGMA page_size = 512 }
  while {[file_size test.db] <= $::sqlite_pending_byte} {
    db eval "CREATE TABLE t${iTab}(a, b, c)"
    incr iTab
  }

  sqlite3 db2 test2.db
  db2 eval { PRAGMA page_size = 4096 }
  while {[file_size test2.db] < $::sqlite_pending_byte} {
    db2 eval "CREATE TABLE t${iTab}(a, b, c)"
    incr iTab
  }

  sqlite3_backup B db2 main db main
  B step -1
} {SQLITE_DONE}

Changes to test/backup4.test.

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
do_test 2.3 {
  sqlite3 db1 test.db2
  db1 backup test.db
  db1 close
  file size test.db
} {1024}

do_test 2.4 { file size test.db2 } 0

db close
forcedelete test.db
forcedelete test.db2
sqlite3 db test.db

#-------------------------------------------------------------------------







|







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
do_test 2.3 {
  sqlite3 db1 test.db2
  db1 backup test.db
  db1 close
  file size test.db
} {1024}

do_test 2.4 { file_size test.db2 } 0

db close
forcedelete test.db
forcedelete test.db2
sqlite3 db test.db

#-------------------------------------------------------------------------
94
95
96
97
98
99
100
101
102
103
do_test 3.3 {
  sqlite3 db1 test.db2
  db1 backup test.db
  db1 close
  file size test.db
} {1024}

do_test 3.4 { file size test.db2 } 0

finish_test







|


94
95
96
97
98
99
100
101
102
103
do_test 3.3 {
  sqlite3 db1 test.db2
  db1 backup test.db
  db1 close
  file size test.db
} {1024}

do_test 3.4 { file_size test.db2 } 0

finish_test

Changes to test/capi3e.test.

66
67
68
69
70
71
72



73
74
75
76
77
78
79
80
81
82
foreach name $names {
  incr i
  do_test capi3e-1.1.$i {
    set db2 [sqlite3_open $name {}]
    sqlite3_errcode $db2
  } {SQLITE_OK}
  do_test capi3e-1.2.$i {



    sqlite3_close $db2
  } {SQLITE_OK}
  do_test capi3e-1.3.$i {
    file isfile $name
  } {1}
}

ifcapable {utf16} {
  set i 0
  foreach name $names {







>
>
>


|







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
foreach name $names {
  incr i
  do_test capi3e-1.1.$i {
    set db2 [sqlite3_open $name {}]
    sqlite3_errcode $db2
  } {SQLITE_OK}
  do_test capi3e-1.2.$i {
    sqlite3_exec $db2 { CREATE TABLE t1(x) }
  } {0 {}}
  do_test capi3e-1.3.$i {
    sqlite3_close $db2
  } {SQLITE_OK}
  do_test capi3e-1.4.$i {
    file isfile $name
  } {1}
}

ifcapable {utf16} {
  set i 0
  foreach name $names {

Changes to test/e_uri.test.

60
61
62
63
64
65
66

67
68
69
70
71
72
73

74
75
76
77
78
79

80
81
82
83
84
85
86

87
88
89
90
91
92
93
94
95
96
97
98

99
100
101
102
103
104
105

106
107
108
109
110
111

112
113
114
115
116
117
118

119
120
121
122
123
124
125
  # Tests with SQLITE_CONFIG_URI configured to false. URI intepretation is
  # only enabled if the SQLITE_OPEN_URI flag is specified.
  sqlite3_shutdown
  sqlite3_config_uri 0
  do_test 1.1 {
    forcedelete file:test.db test.db
    set DB [sqlite3_open_v2 file:test.db [concat $flags SQLITE_OPEN_URI] ""]

    list [file exists file:test.db] [file exists test.db]
  } {0 1}
  do_test 1.2 {
    forcedelete file:test.db2 test.db2
    set STMT [sqlite3_prepare $DB "ATTACH 'file:test.db2' AS aux" -1 dummy]
    sqlite3_step $STMT
    sqlite3_finalize $STMT

    list [file exists file:test.db2] [file exists test.db2]
  } {0 1}
  sqlite3_close $DB
  do_test 1.3 {
    forcedelete file:test.db test.db
    set DB [sqlite3_open_v2 file:test.db [concat $flags] ""]

    list [file exists file:test.db] [file exists test.db]
  } {1 0}
  do_test 1.4 {
    forcedelete file:test.db2 test.db2
    set STMT [sqlite3_prepare $DB "ATTACH 'file:test.db2' AS aux" -1 dummy]
    sqlite3_step $STMT
    sqlite3_finalize $STMT

    list [file exists file:test.db2] [file exists test.db2]
  } {1 0}
  sqlite3_close $DB

  # Tests with SQLITE_CONFIG_URI configured to true. URI intepretation is
  # enabled with or without SQLITE_OPEN_URI.
  #
  sqlite3_shutdown
  sqlite3_config_uri 1
  do_test 1.5 {
    forcedelete file:test.db test.db
    set DB [sqlite3_open_v2 file:test.db [concat $flags SQLITE_OPEN_URI] ""]

    list [file exists file:test.db] [file exists test.db]
  } {0 1}
  do_test 1.6 {
    forcedelete file:test.db2 test.db2
    set STMT [sqlite3_prepare $DB "ATTACH 'file:test.db2' AS aux" -1 dummy]
    sqlite3_step $STMT
    sqlite3_finalize $STMT

    list [file exists file:test.db2] [file exists test.db2]
  } {0 1}
  sqlite3_close $DB
  do_test 1.7 {
    forcedelete file:test.db test.db
    set DB [sqlite3_open_v2 file:test.db [concat $flags] ""]

    list [file exists file:test.db] [file exists test.db]
  } {0 1}
  do_test 1.8 {
    forcedelete file:test.db2 test.db2
    set STMT [sqlite3_prepare $DB "ATTACH 'file:test.db2' AS aux" -1 dummy]
    sqlite3_step $STMT
    sqlite3_finalize $STMT

    list [file exists file:test.db2] [file exists test.db2]
  } {0 1}
  sqlite3_close $DB
}

# ensure uri processing enabled for the rest of the tests
sqlite3_shutdown







>







>






>







>












>







>






>







>







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
  # Tests with SQLITE_CONFIG_URI configured to false. URI intepretation is
  # only enabled if the SQLITE_OPEN_URI flag is specified.
  sqlite3_shutdown
  sqlite3_config_uri 0
  do_test 1.1 {
    forcedelete file:test.db test.db
    set DB [sqlite3_open_v2 file:test.db [concat $flags SQLITE_OPEN_URI] ""]
    sqlite3_exec $DB {CREATE TABLE t1(x)}
    list [file exists file:test.db] [file exists test.db]
  } {0 1}
  do_test 1.2 {
    forcedelete file:test.db2 test.db2
    set STMT [sqlite3_prepare $DB "ATTACH 'file:test.db2' AS aux" -1 dummy]
    sqlite3_step $STMT
    sqlite3_finalize $STMT
    sqlite3_exec $DB {CREATE TABLE aux.t1(x)}
    list [file exists file:test.db2] [file exists test.db2]
  } {0 1}
  sqlite3_close $DB
  do_test 1.3 {
    forcedelete file:test.db test.db
    set DB [sqlite3_open_v2 file:test.db [concat $flags] ""]
    sqlite3_exec $DB {CREATE TABLE t1(x)}
    list [file exists file:test.db] [file exists test.db]
  } {1 0}
  do_test 1.4 {
    forcedelete file:test.db2 test.db2
    set STMT [sqlite3_prepare $DB "ATTACH 'file:test.db2' AS aux" -1 dummy]
    sqlite3_step $STMT
    sqlite3_finalize $STMT
    sqlite3_exec $DB {CREATE TABLE aux.t1(x)}
    list [file exists file:test.db2] [file exists test.db2]
  } {1 0}
  sqlite3_close $DB

  # Tests with SQLITE_CONFIG_URI configured to true. URI intepretation is
  # enabled with or without SQLITE_OPEN_URI.
  #
  sqlite3_shutdown
  sqlite3_config_uri 1
  do_test 1.5 {
    forcedelete file:test.db test.db
    set DB [sqlite3_open_v2 file:test.db [concat $flags SQLITE_OPEN_URI] ""]
    sqlite3_exec $DB {CREATE TABLE t1(x)}
    list [file exists file:test.db] [file exists test.db]
  } {0 1}
  do_test 1.6 {
    forcedelete file:test.db2 test.db2
    set STMT [sqlite3_prepare $DB "ATTACH 'file:test.db2' AS aux" -1 dummy]
    sqlite3_step $STMT
    sqlite3_finalize $STMT
    sqlite3_exec $DB {CREATE TABLE aux.t1(x)}
    list [file exists file:test.db2] [file exists test.db2]
  } {0 1}
  sqlite3_close $DB
  do_test 1.7 {
    forcedelete file:test.db test.db
    set DB [sqlite3_open_v2 file:test.db [concat $flags] ""]
    sqlite3_exec $DB {CREATE TABLE t1(x)}
    list [file exists file:test.db] [file exists test.db]
  } {0 1}
  do_test 1.8 {
    forcedelete file:test.db2 test.db2
    set STMT [sqlite3_prepare $DB "ATTACH 'file:test.db2' AS aux" -1 dummy]
    sqlite3_step $STMT
    sqlite3_finalize $STMT
    sqlite3_exec $DB {CREATE TABLE aux.t1(x)}
    list [file exists file:test.db2] [file exists test.db2]
  } {0 1}
  sqlite3_close $DB
}

# ensure uri processing enabled for the rest of the tests
sqlite3_shutdown
310
311
312
313
314
315
316

317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341

# EVIDENCE-OF: R-20590-08726 It is an error to specify a value for the
# mode parameter that is less restrictive than that specified by the
# flags passed in the third parameter to sqlite3_open_v2().
#
forcedelete test.db
sqlite3 db test.db

db close
foreach {tn uri flags error} {
  1   {file:test.db?mode=ro}   ro    {not an error}
  2   {file:test.db?mode=ro}   rw    {not an error}
  3   {file:test.db?mode=ro}   rwc   {not an error}

  4   {file:test.db?mode=rw}   ro    {access mode not allowed: rw}
  5   {file:test.db?mode=rw}   rw    {not an error}
  6   {file:test.db?mode=rw}   rwc   {not an error}

  7   {file:test.db?mode=rwc}  ro    {access mode not allowed: rwc}
  8   {file:test.db?mode=rwc}  rw    {access mode not allowed: rwc}
  9   {file:test.db?mode=rwc}  rwc   {not an error}
} {
  set f(ro)  [list SQLITE_OPEN_READONLY SQLITE_OPEN_URI]
  set f(rw)  [list SQLITE_OPEN_READWRITE SQLITE_OPEN_URI]
  set f(rwc) [list SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_URI]

  set DB [sqlite3_open_v2 $uri $f($flags) ""]
  set e [sqlite3_errmsg $DB]
  sqlite3_close $DB

  do_test 9.$tn { set e } $error
}








>

















|







318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350

# EVIDENCE-OF: R-20590-08726 It is an error to specify a value for the
# mode parameter that is less restrictive than that specified by the
# flags passed in the third parameter to sqlite3_open_v2().
#
forcedelete test.db
sqlite3 db test.db
db eval {CREATE TABLE t1(x)}
db close
foreach {tn uri flags error} {
  1   {file:test.db?mode=ro}   ro    {not an error}
  2   {file:test.db?mode=ro}   rw    {not an error}
  3   {file:test.db?mode=ro}   rwc   {not an error}

  4   {file:test.db?mode=rw}   ro    {access mode not allowed: rw}
  5   {file:test.db?mode=rw}   rw    {not an error}
  6   {file:test.db?mode=rw}   rwc   {not an error}

  7   {file:test.db?mode=rwc}  ro    {access mode not allowed: rwc}
  8   {file:test.db?mode=rwc}  rw    {access mode not allowed: rwc}
  9   {file:test.db?mode=rwc}  rwc   {not an error}
} {
  set f(ro)  [list SQLITE_OPEN_READONLY SQLITE_OPEN_URI]
  set f(rw)  [list SQLITE_OPEN_READWRITE SQLITE_OPEN_URI]
  set f(rwc) [list SQLITE_OPEN_READWRITE SQLITE_OPEN_CREATE SQLITE_OPEN_URI]
breakpoint
  set DB [sqlite3_open_v2 $uri $f($flags) ""]
  set e [sqlite3_errmsg $DB]
  sqlite3_close $DB

  do_test 9.$tn { set e } $error
}

Changes to test/exclusive2.test.

65
66
67
68
69
70
71

72
73
74
75
76
77
78
79
80
81
82
83



84
85
86
87
88
89
90
  incr ret [expr ($d&0x000000FF)<<0]

  if {$needClose} {close $fd}
  return $ret
}

proc readPagerChangeCounter {filename} {

  set fd [open $filename RDONLY]
  fconfigure $fd -translation binary -encoding binary

  seek $fd 24
  foreach {a b c d} [list 0 0 0 0] {}
  binary scan [read $fd 4] cccc a b c d
  set  ret [expr ($a&0x000000FF)<<24]
  incr ret [expr ($b&0x000000FF)<<16]
  incr ret [expr ($c&0x000000FF)<<8]
  incr ret [expr ($d&0x000000FF)<<0]

  close $fd



  return $ret
}


proc t1sig {{db db}} {
  execsql {SELECT count(*), md5sum(a) FROM t1} $db
}







>
|
|
<
|
|
|
|
|
|
|
<
|
>
>
>







65
66
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91
92
  incr ret [expr ($d&0x000000FF)<<0]

  if {$needClose} {close $fd}
  return $ret
}

proc readPagerChangeCounter {filename} {
  if {[file exists $filename]} {
    set fd [open $filename RDONLY]
    fconfigure $fd -translation binary -encoding binary

    seek $fd 24
    foreach {a b c d} [list 0 0 0 0] {}
    binary scan [read $fd 4] cccc a b c d
    set  ret [expr ($a&0x000000FF)<<24]
    incr ret [expr ($b&0x000000FF)<<16]
    incr ret [expr ($c&0x000000FF)<<8]
    incr ret [expr ($d&0x000000FF)<<0]

    close $fd
  } else {
    set ret 0
  }
  return $ret
}


proc t1sig {{db db}} {
  execsql {SELECT count(*), md5sum(a) FROM t1} $db
}

Changes to test/incrvacuum.test.

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
    pragma auto_vacuum;
  }
} $sqlite_options(default_autovacuum)
do_test incrvacuum-1.2.0 {
  # File size is sometimes 1 instead of 0 due to the hack we put in
  # to work around ticket #3260.  Search for comments on #3260 in
  # os_unix.c.
  expr {[file size test.db] > 1}
} {0}
do_test incrvacuum-1.2 {
  # This command will create the database.
  execsql {
    pragma auto_vacuum = 'full';
    pragma auto_vacuum;
  }







|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
    pragma auto_vacuum;
  }
} $sqlite_options(default_autovacuum)
do_test incrvacuum-1.2.0 {
  # File size is sometimes 1 instead of 0 due to the hack we put in
  # to work around ticket #3260.  Search for comments on #3260 in
  # os_unix.c.
  expr {[file_size test.db] > 1}
} {0}
do_test incrvacuum-1.2 {
  # This command will create the database.
  execsql {
    pragma auto_vacuum = 'full';
    pragma auto_vacuum;
  }
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
sqlite3 db test.db  ;  set ::DB [sqlite3_connection_pointer db]
sqlite3 db2 test.db

do_test incrvacuum-13.1 {
  # File size is sometimes 1 instead of 0 due to the hack we put in
  # to work around ticket #3260.  Search for comments on #3260 in
  # os_unix.c.
  expr {[file size test.db]>1}
} {0}
do_test incrvacuum-13.2 {
  set ::STMT [sqlite3_prepare $::DB {PRAGMA auto_vacuum = 2} -1 DUMMY]
  execsql {
    PRAGMA auto_vacuum = none;
    PRAGMA default_cache_size = 1024;
    PRAGMA auto_vacuum;







|







696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
sqlite3 db test.db  ;  set ::DB [sqlite3_connection_pointer db]
sqlite3 db2 test.db

do_test incrvacuum-13.1 {
  # File size is sometimes 1 instead of 0 due to the hack we put in
  # to work around ticket #3260.  Search for comments on #3260 in
  # os_unix.c.
  expr {[file_size test.db]>1}
} {0}
do_test incrvacuum-13.2 {
  set ::STMT [sqlite3_prepare $::DB {PRAGMA auto_vacuum = 2} -1 DUMMY]
  execsql {
    PRAGMA auto_vacuum = none;
    PRAGMA default_cache_size = 1024;
    PRAGMA auto_vacuum;

Changes to test/io.test.

387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
    forcedelete test.db test.db-journal
    sqlite3 db test.db -vfs devsym
    db eval {
      PRAGMA auto_vacuum=OFF;
    }
    # File size might be 1 due to the hack to work around ticket #3260.
    # Search for #3260 in os_unix.c for additional information.
    expr {[file size test.db]>1}
  } {0}
  do_test io-3.2 {
    execsql { CREATE TABLE abc(a, b) }
    nSync
    execsql {
      PRAGMA temp_store = memory;
      PRAGMA cache_size = 10;







|







387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
    forcedelete test.db test.db-journal
    sqlite3 db test.db -vfs devsym
    db eval {
      PRAGMA auto_vacuum=OFF;
    }
    # File size might be 1 due to the hack to work around ticket #3260.
    # Search for #3260 in os_unix.c for additional information.
    expr {[file_size test.db]>1}
  } {0}
  do_test io-3.2 {
    execsql { CREATE TABLE abc(a, b) }
    nSync
    execsql {
      PRAGMA temp_store = memory;
      PRAGMA cache_size = 10;

Changes to test/pager1.test.

1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
    CREATE TABLE t1(a, b);
    CREATE TABLE t2(a, b);
  } db2
  sqlite3_backup B db2 main db main
  list [B step 10000] [B finish]
} {SQLITE_DONE SQLITE_OK}
do_test pager1-9.4.2 {
  list [file size test.db2] [file size test.db]
} {1024 0}
db2 close

#-------------------------------------------------------------------------
# Test that regardless of the value returned by xSectorSize(), the
# minimum effective sector-size is 512 and the maximum 65536 bytes.
#







|







1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
    CREATE TABLE t1(a, b);
    CREATE TABLE t2(a, b);
  } db2
  sqlite3_backup B db2 main db main
  list [B step 10000] [B finish]
} {SQLITE_DONE SQLITE_OK}
do_test pager1-9.4.2 {
  list [file_size test.db2] [file_size test.db]
} {1024 0}
db2 close

#-------------------------------------------------------------------------
# Test that regardless of the value returned by xSectorSize(), the
# minimum effective sector-size is 512 and the maximum 65536 bytes.
#

Changes to test/permutations.test.

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
lappend ::testsuitelist xxx

test_suite "veryquick" -prefix "" -description {
  "Very" quick test suite. Runs in less than 5 minutes on a workstation. 
  This test suite is the same as the "quick" tests, except that some files
  that test malloc and IO errors are omitted.
} -files [
  test_set $allquicktests -exclude *malloc* *ioerr* *fault*
]

test_suite "mmap" -prefix "mm-" -description {
  Similar to veryquick. Except with memory mapping disabled.
} -presql {
  pragma mmap_size = 268435456;
} -files [







|







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
lappend ::testsuitelist xxx

test_suite "veryquick" -prefix "" -description {
  "Very" quick test suite. Runs in less than 5 minutes on a workstation. 
  This test suite is the same as the "quick" tests, except that some files
  that test malloc and IO errors are omitted.
} -files [
  test_set $allquicktests -exclude *malloc* *ioerr* *fault* 
]

test_suite "mmap" -prefix "mm-" -description {
  Similar to veryquick. Except with memory mapping disabled.
} -presql {
  pragma mmap_size = 268435456;
} -files [

Changes to test/syscall.test.

232
233
234
235
236
237
238

239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258

259
260
261
262
263
264
265

#-------------------------------------------------------------------------
# 
catch { db close }
forcedelete test.db test.db2

do_test 8.1 {

  sqlite3 db test.db
  file_control_chunksize_test db main 4096
  file size test.db
} {0}
foreach {tn hint size} {
  1  1000    4096 
  2  1000    4096 
  3  3000    4096 
  4  4096    4096 
  5  4197    8192 
} {
  do_test 8.2.$tn {
    file_control_sizehint_test db main $hint
    file size test.db
  } $size
}

do_test 8.3 {
  db close
  forcedelete test.db test.db2

  sqlite3 db test.db
  file_control_chunksize_test db main 16
  file size test.db
} {0}
foreach {tn hint size} {
  1  5       16 
  2  13      16 







>


|










|






>







232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267

#-------------------------------------------------------------------------
# 
catch { db close }
forcedelete test.db test.db2

do_test 8.1 {
  close [open test.db w]
  sqlite3 db test.db
  file_control_chunksize_test db main 4096
  file_size test.db
} {0}
foreach {tn hint size} {
  1  1000    4096 
  2  1000    4096 
  3  3000    4096 
  4  4096    4096 
  5  4197    8192 
} {
  do_test 8.2.$tn {
    file_control_sizehint_test db main $hint
    file_size test.db
  } $size
}

do_test 8.3 {
  db close
  forcedelete test.db test.db2
  close [open test.db w]
  sqlite3 db test.db
  file_control_chunksize_test db main 16
  file size test.db
} {0}
foreach {tn hint size} {
  1  5       16 
  2  13      16 

Changes to test/tester.tcl.

180
181
182
183
184
185
186










187
188
189
190
191
192
193
proc copy_file {from to} {
  do_copy_file false $from $to
}

proc forcecopy {from to} {
  do_copy_file true $from $to
}











proc do_copy_file {force from to} {
  set nRetry [getFileRetries]     ;# Maximum number of retries.
  set nDelay [getFileRetryDelay]  ;# Delay in ms before retrying.

  # On windows, sometimes even a [file copy -force] can fail. The cause is
  # usually "tag-alongs" - programs like anti-virus software, automatic backup







>
>
>
>
>
>
>
>
>
>







180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
proc copy_file {from to} {
  do_copy_file false $from $to
}

proc forcecopy {from to} {
  do_copy_file true $from $to
}

# If file $zFile exists in the file system, return its size in bytes. 
# Otherwise, return zero.
proc file_size {zFile} {
  if {[file exists $zFile]} {
    return [file size $zFile]
  }
  return 0
}


proc do_copy_file {force from to} {
  set nRetry [getFileRetries]     ;# Maximum number of retries.
  set nDelay [getFileRetryDelay]  ;# Delay in ms before retrying.

  # On windows, sometimes even a [file copy -force] can fail. The cause is
  # usually "tag-alongs" - programs like anti-virus software, automatic backup

Changes to test/tkt4018.test.

42
43
44
45
46
47
48

49
50
51
52
53
54
55
  }
} {}

# The database is locked by connection [db]. Open and close a second
# connection to test.db 10000 times. If file-descriptors are not being
# reused, then the process will quickly exceed its maximum number of
# file descriptors (1024 by default on linux).

do_test tkt4018-1.2 {
  for {set i 0} {$i < 10000} {incr i} {
    sqlite3 db2 test.db
    db2 close
  }
} {}








>







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  }
} {}

# The database is locked by connection [db]. Open and close a second
# connection to test.db 10000 times. If file-descriptors are not being
# reused, then the process will quickly exceed its maximum number of
# file descriptors (1024 by default on linux).
breakpoint
do_test tkt4018-1.2 {
  for {set i 0} {$i < 10000} {incr i} {
    sqlite3 db2 test.db
    db2 close
  }
} {}

Changes to test/uri.test.

72
73
74
75
76
77
78

79
80
81
82
83
84
85

86
87
88
89
90
91
92
    set uri  [string map [list PWD/ [test_pwd /]] $uri]
  }

  if {[file isdir $file]} {error "$file is a directory"}
  forcedelete $file
  do_test 1.$tn.1 { file exists $file } 0
  set DB [sqlite3_open $uri]

  do_test 1.$tn.2 { file exists $file } 1
  sqlite3_close $DB
  forcedelete $file

  do_test 1.$tn.3 { file exists $file } 0
  sqlite3 db xxx.db
  catchsql { ATTACH $uri AS aux }

  do_test 1.$tn.4 { file exists $file } 1
  db close
}

#-------------------------------------------------------------------------
# Test that URI query parameters are passed through to the VFS layer
# correctly.







>







>







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
    set uri  [string map [list PWD/ [test_pwd /]] $uri]
  }

  if {[file isdir $file]} {error "$file is a directory"}
  forcedelete $file
  do_test 1.$tn.1 { file exists $file } 0
  set DB [sqlite3_open $uri]
  sqlite3_exec $DB {CREATE TABLE t1(x)}
  do_test 1.$tn.2 { file exists $file } 1
  sqlite3_close $DB
  forcedelete $file

  do_test 1.$tn.3 { file exists $file } 0
  sqlite3 db xxx.db
  catchsql { ATTACH $uri AS aux }
  db eval {CREATE TABLE aux.t1(x)}
  do_test 1.$tn.4 { file exists $file } 1
  db close
}

#-------------------------------------------------------------------------
# Test that URI query parameters are passed through to the VFS layer
# correctly.

Changes to test/wal4.test.

52
53
54
55
56
57
58
59
60
61
62
63
64
  # deleted. In no case should the database file have been written, so
  # it should still be zero bytes in size regardless of whether or not
  # a fault was injected. Test these assertions:
  #
  if { $testrc==0 && [file exists test.db-wal] } { 
    error "Wal file was not deleted"
  }
  if { [file size test.db]!=0 } { 
    error "Db file grew to [file size test.db] bytes"
  }
}

finish_test







|
|




52
53
54
55
56
57
58
59
60
61
62
63
64
  # deleted. In no case should the database file have been written, so
  # it should still be zero bytes in size regardless of whether or not
  # a fault was injected. Test these assertions:
  #
  if { $testrc==0 && [file exists test.db-wal] } { 
    error "Wal file was not deleted"
  }
  if { [file_size test.db]!=0 } { 
    error "Db file grew to [file_size test.db] bytes"
  }
}

finish_test