/ Check-in [2662d8fe]
Login

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

Overview
Comment:Modify the permutations.test script so as to set any permutation specific configuration values before running each individual test script.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | permutations-fix
Files: files | file ages | folders
SHA1:2662d8fef791f7b8b3b14f9c27dfedec84620dee
User & Date: dan 2016-04-27 18:54:49
Context
2016-04-28
09:53
Ensure that quota.test deletes the directory named "test.db" that it creates. check-in: 045edd4b user: dan tags: permutations-fix
2016-04-27
18:54
Modify the permutations.test script so as to set any permutation specific configuration values before running each individual test script. check-in: 2662d8fe user: dan tags: permutations-fix
15:24
More simplification of the sqlite3AtoF() routine. Add special comments to indicate branches that are for optimization purposes only and that give the correct answer even if always or never taken. check-in: 0065fe97 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ext/session/sessionfault.test.

13
14
15
16
17
18
19

20
21
22
23
24
25
26
#

if {![info exists testdir]} {
  set testdir [file join [file dirname [info script]] .. .. test]
} 
source [file join [file dirname [info script]] session_common.tcl]
source $testdir/tester.tcl


set testprefix sessionfault

forcedelete test.db2
sqlite3 db2 test.db2
do_common_sql {
  CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b));







>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#

if {![info exists testdir]} {
  set testdir [file join [file dirname [info script]] .. .. test]
} 
source [file join [file dirname [info script]] session_common.tcl]
source $testdir/tester.tcl
ifcapable !session {finish_test; return}

set testprefix sessionfault

forcedelete test.db2
sqlite3 db2 test.db2
do_common_sql {
  CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b));

Changes to ext/session/sessionfault2.test.

13
14
15
16
17
18
19

20
21
22
23
24
25
26
#

if {![info exists testdir]} {
  set testdir [file join [file dirname [info script]] .. .. test]
} 
source [file join [file dirname [info script]] session_common.tcl]
source $testdir/tester.tcl

set testprefix sessionfault2

do_execsql_test 1.0.0 {
  CREATE TABLE t1(a PRIMARY KEY, b UNIQUE);
  INSERT INTO t1 VALUES(1, 1);
  INSERT INTO t1 VALUES(2, 2);
  INSERT INTO t1 VALUES(3, 3);







>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#

if {![info exists testdir]} {
  set testdir [file join [file dirname [info script]] .. .. test]
} 
source [file join [file dirname [info script]] session_common.tcl]
source $testdir/tester.tcl
ifcapable !session {finish_test; return}
set testprefix sessionfault2

do_execsql_test 1.0.0 {
  CREATE TABLE t1(a PRIMARY KEY, b UNIQUE);
  INSERT INTO t1 VALUES(1, 1);
  INSERT INTO t1 VALUES(2, 2);
  INSERT INTO t1 VALUES(3, 3);

Changes to src/test1.c.

5209
5210
5211
5212
5213
5214
5215
5216


5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
  }
  nVfs = i;
  return TCL_OK;
}
/*
** tclcmd:   vfs_reregister_all
**
** Restore all VFSes that were removed using vfs_unregister_all


*/
static int vfs_reregister_all(
  ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int objc,              /* Number of arguments */
  Tcl_Obj *CONST objv[]  /* Command arguments */
){
  int i;
  for(i=0; i<nVfs; i++){
    sqlite3_vfs_register(apVfs[i], i==0);
  }
  return TCL_OK;
}


/*
** tclcmd:   file_control_test DB







|
>
>








|
|







5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
  }
  nVfs = i;
  return TCL_OK;
}
/*
** tclcmd:   vfs_reregister_all
**
** Restore all VFSes that were removed using vfs_unregister_all. Taking
** care to put the linked list back together in the same order as it was
** in before vfs_unregister_all was invoked.
*/
static int vfs_reregister_all(
  ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int objc,              /* Number of arguments */
  Tcl_Obj *CONST objv[]  /* Command arguments */
){
  int i;
  for(i=nVfs-1; i>=0; i--){
    sqlite3_vfs_register(apVfs[i], 1);
  }
  return TCL_OK;
}


/*
** tclcmd:   file_control_test DB

Changes to src/test6.c.

697
698
699
700
701
702
703




704
705
706
707
708
709
710
...
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
...
936
937
938
939
940
941
942





















943
944
945
946
947
948
949
....
1006
1007
1008
1009
1010
1011
1012

1013
1014
1015
1016
1017
1018
1019
  sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
  return pVfs->xSleep(pVfs, nMicro);
}
static int cfCurrentTime(sqlite3_vfs *pCfVfs, double *pTimeOut){
  sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
  return pVfs->xCurrentTime(pVfs, pTimeOut);
}





static int processDevSymArgs(
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[],
  int *piDeviceChar,
  int *piSectorSize
................................................................................
    cfDlOpen,             /* xDlOpen */
    cfDlError,            /* xDlError */
    cfDlSym,              /* xDlSym */
    cfDlClose,            /* xDlClose */
    cfRandomness,         /* xRandomness */
    cfSleep,              /* xSleep */
    cfCurrentTime,        /* xCurrentTime */
    0,                    /* xGetlastError */
    0,                    /* xCurrentTimeInt64 */
  };

  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "ENABLE");
    return TCL_ERROR;
  }
................................................................................

  if( processDevSymArgs(interp, objc-1, &objv[1], &iDc, &iSectorSize) ){
    return TCL_ERROR;
  }
  devsym_register(iDc, iSectorSize);

  return TCL_OK;





















}

/*
** tclcmd: register_jt_vfs ?-default? PARENT-VFS
*/
static int jtObjCmd(
  void * clientData,
................................................................................
** This procedure registers the TCL procedures defined in this file.
*/
int Sqlitetest6_Init(Tcl_Interp *interp){
#ifndef SQLITE_OMIT_DISKIO
  Tcl_CreateObjCommand(interp, "sqlite3_crash_enable", crashEnableCmd, 0, 0);
  Tcl_CreateObjCommand(interp, "sqlite3_crashparams", crashParamsObjCmd, 0, 0);
  Tcl_CreateObjCommand(interp, "sqlite3_simulate_device", devSymObjCmd, 0, 0);

  Tcl_CreateObjCommand(interp, "register_jt_vfs", jtObjCmd, 0, 0);
  Tcl_CreateObjCommand(interp, "unregister_jt_vfs", jtUnregisterObjCmd, 0, 0);
#endif
  return TCL_OK;
}

#endif /* SQLITE_TEST */







>
>
>
>







 







|







 







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







 







>







697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
...
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
...
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
....
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
  sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
  return pVfs->xSleep(pVfs, nMicro);
}
static int cfCurrentTime(sqlite3_vfs *pCfVfs, double *pTimeOut){
  sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
  return pVfs->xCurrentTime(pVfs, pTimeOut);
}
static int cfGetLastError(sqlite3_vfs *pCfVfs, int n, char *z){
  sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
  return pVfs->xGetLastError(pVfs, n, z);
}

static int processDevSymArgs(
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[],
  int *piDeviceChar,
  int *piSectorSize
................................................................................
    cfDlOpen,             /* xDlOpen */
    cfDlError,            /* xDlError */
    cfDlSym,              /* xDlSym */
    cfDlClose,            /* xDlClose */
    cfRandomness,         /* xRandomness */
    cfSleep,              /* xSleep */
    cfCurrentTime,        /* xCurrentTime */
    cfGetLastError,       /* xGetLastError */
    0,                    /* xCurrentTimeInt64 */
  };

  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "ENABLE");
    return TCL_ERROR;
  }
................................................................................

  if( processDevSymArgs(interp, objc-1, &objv[1], &iDc, &iSectorSize) ){
    return TCL_ERROR;
  }
  devsym_register(iDc, iSectorSize);

  return TCL_OK;

}

/*
** tclcmd: unregister_devsim
*/
static int dsUnregisterObjCmd(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  void devsym_unregister(void);

  if( objc!=1 ){
    Tcl_WrongNumArgs(interp, 1, objv, "");
    return TCL_ERROR;
  }

  devsym_unregister();
  return TCL_OK;
}

/*
** tclcmd: register_jt_vfs ?-default? PARENT-VFS
*/
static int jtObjCmd(
  void * clientData,
................................................................................
** This procedure registers the TCL procedures defined in this file.
*/
int Sqlitetest6_Init(Tcl_Interp *interp){
#ifndef SQLITE_OMIT_DISKIO
  Tcl_CreateObjCommand(interp, "sqlite3_crash_enable", crashEnableCmd, 0, 0);
  Tcl_CreateObjCommand(interp, "sqlite3_crashparams", crashParamsObjCmd, 0, 0);
  Tcl_CreateObjCommand(interp, "sqlite3_simulate_device", devSymObjCmd, 0, 0);
  Tcl_CreateObjCommand(interp, "unregister_devsim", dsUnregisterObjCmd, 0, 0);
  Tcl_CreateObjCommand(interp, "register_jt_vfs", jtObjCmd, 0, 0);
  Tcl_CreateObjCommand(interp, "unregister_jt_vfs", jtUnregisterObjCmd, 0, 0);
#endif
  return TCL_OK;
}

#endif /* SQLITE_TEST */

Changes to src/test_devsym.c.

391
392
393
394
395
396
397
398







399
  }
  if( iSectorSize>=0 ){
    g.iSectorSize = iSectorSize;
  }else{
    g.iSectorSize = 512;
  }
}








#endif








>
>
>
>
>
>
>

391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
  }
  if( iSectorSize>=0 ){
    g.iSectorSize = iSectorSize;
  }else{
    g.iSectorSize = 512;
  }
}

void devsym_unregister(){
  sqlite3_vfs_unregister(&devsym_vfs);
  g.pVfs = 0;
  g.iDeviceChar = 0;
  g.iSectorSize = 0;
}

#endif

Changes to src/test_journal.c.

156
157
158
159
160
161
162

163
164
165
166
167
168
169
...
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
...
281
282
283
284
285
286
287
288

289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
...
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
...
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
...
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
...
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
...
820
821
822
823
824
825
826




827
828
829
830
831
832
833
static void jtDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
static void (*jtDlSym(sqlite3_vfs*,void*, const char *zSymbol))(void);
static void jtDlClose(sqlite3_vfs*, void*);
static int jtRandomness(sqlite3_vfs*, int nByte, char *zOut);
static int jtSleep(sqlite3_vfs*, int microseconds);
static int jtCurrentTime(sqlite3_vfs*, double*);
static int jtCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);


static sqlite3_vfs jt_vfs = {
  2,                             /* iVersion */
  sizeof(jt_file),               /* szOsFile */
  JT_MAX_PATHNAME,               /* mxPathname */
  0,                             /* pNext */
  JT_VFS_NAME,                   /* zName */
................................................................................
  jtDlOpen,                      /* xDlOpen */
  jtDlError,                     /* xDlError */
  jtDlSym,                       /* xDlSym */
  jtDlClose,                     /* xDlClose */
  jtRandomness,                  /* xRandomness */
  jtSleep,                       /* xSleep */
  jtCurrentTime,                 /* xCurrentTime */
  0,                             /* xGetLastError */
  jtCurrentTimeInt64             /* xCurrentTimeInt64 */
};

static sqlite3_io_methods jt_io_methods = {
  1,                             /* iVersion */
  jtClose,                       /* xClose */
  jtRead,                        /* xRead */
................................................................................
** following properties:
**
**   a) SQLITE_OPEN_MAIN_DB was specified when the file was opened.
**
**   b) The file-name specified when the file was opened matches
**      all but the final 8 characters of the journal file name.
**
**   c) There is currently a reserved lock on the file.

**/
static jt_file *locateDatabaseHandle(const char *zJournal){
  jt_file *pMain = 0;
  enterJtMutex();
  for(pMain=g.pList; pMain; pMain=pMain->pNext){
    int nName = (int)(strlen(zJournal) - strlen("-journal"));
    if( (pMain->flags&SQLITE_OPEN_MAIN_DB)
     && ((int)strlen(pMain->zName)==nName)
     && 0==memcmp(pMain->zName, zJournal, nName)
     && (pMain->eLock>=SQLITE_LOCK_RESERVED)
    ){
      break;
    }
  }
  leaveJtMutex();
  return pMain;
}
................................................................................
  int iAmt, 
  sqlite_int64 iOfst
){
  int rc;
  jt_file *p = (jt_file *)pFile;
  if( p->flags&SQLITE_OPEN_MAIN_JOURNAL ){
    if( iOfst==0 ){
      jt_file *pMain = locateDatabaseHandle(p->zName);
      assert( pMain );
  
      if( iAmt==28 ){
        /* Zeroing the first journal-file header. This is the end of a
        ** transaction. */
        closeTransaction(pMain);
      }else if( iAmt!=12 ){
................................................................................
      assert( pgno<=p->nPage || p->nSync>0 );
      assert( pgno>p->nPage || sqlite3BitvecTest(p->pWritable, pgno) );
    }
  }

  rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
  if( (p->flags&SQLITE_OPEN_MAIN_JOURNAL) && iAmt==12 ){
    jt_file *pMain = locateDatabaseHandle(p->zName);
    int rc2 = readJournalFile(p, pMain);
    if( rc==SQLITE_OK ) rc = rc2;
  }
  return rc;
}

/*
** Truncate an jt-file.
*/
static int jtTruncate(sqlite3_file *pFile, sqlite_int64 size){
  jt_file *p = (jt_file *)pFile;
  if( p->flags&SQLITE_OPEN_MAIN_JOURNAL && size==0 ){
    /* Truncating a journal file. This is the end of a transaction. */
    jt_file *pMain = locateDatabaseHandle(p->zName);
    closeTransaction(pMain);
  }
  if( p->flags&SQLITE_OPEN_MAIN_DB && p->pWritable ){
    u32 pgno;
    u32 locking_page = (u32)(PENDING_BYTE/p->nPagesize+1);
    for(pgno=(u32)(size/p->nPagesize+1); pgno<=p->nPage; pgno++){
      assert( pgno==locking_page || sqlite3BitvecTest(p->pWritable, pgno) );
................................................................................
    jt_file *pMain;                   /* The associated database file */

    /* The journal file is being synced. At this point, we inspect the 
    ** contents of the file up to this point and set each bit in the 
    ** jt_file.pWritable bitvec of the main database file associated with
    ** this journal file.
    */
    pMain = locateDatabaseHandle(p->zName);
    assert(pMain);

    /* Set the bitvec values */
    if( pMain->pWritable ){
      pMain->nSync++;
      rc = readJournalFile(p, pMain);
      if( rc!=SQLITE_OK ){
        return rc;
      }
    }
  }
................................................................................
** ensure the file-system modifications are synced to disk before
** returning.
*/
static int jtDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
  int nPath = (int)strlen(zPath);
  if( nPath>8 && 0==strcmp("-journal", &zPath[nPath-8]) ){
    /* Deleting a journal file. The end of a transaction. */
    jt_file *pMain = locateDatabaseHandle(zPath);
    if( pMain ){
      closeTransaction(pMain);
    }
  }

  return sqlite3OsDelete(g.pVfs, zPath, dirSync);
}
................................................................................
}
/*
** Return the current time as a Julian Day number in *pTimeOut.
*/
static int jtCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
  return g.pVfs->xCurrentTimeInt64(g.pVfs, pTimeOut);
}





/**************************************************************************
** Start of public API.
*/

/*
** Configure the jt VFS as a wrapper around the VFS named by parameter 







>







 







|







 







|
>

|







|







 







|







 







|













|







 







|
<


|







 







|







 







>
>
>
>







156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
...
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
...
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
...
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
...
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
...
602
603
604
605
606
607
608
609

610
611
612
613
614
615
616
617
618
619
...
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
...
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
static void jtDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
static void (*jtDlSym(sqlite3_vfs*,void*, const char *zSymbol))(void);
static void jtDlClose(sqlite3_vfs*, void*);
static int jtRandomness(sqlite3_vfs*, int nByte, char *zOut);
static int jtSleep(sqlite3_vfs*, int microseconds);
static int jtCurrentTime(sqlite3_vfs*, double*);
static int jtCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
static int jtGetLastError(sqlite3_vfs*, int, char*);

static sqlite3_vfs jt_vfs = {
  2,                             /* iVersion */
  sizeof(jt_file),               /* szOsFile */
  JT_MAX_PATHNAME,               /* mxPathname */
  0,                             /* pNext */
  JT_VFS_NAME,                   /* zName */
................................................................................
  jtDlOpen,                      /* xDlOpen */
  jtDlError,                     /* xDlError */
  jtDlSym,                       /* xDlSym */
  jtDlClose,                     /* xDlClose */
  jtRandomness,                  /* xRandomness */
  jtSleep,                       /* xSleep */
  jtCurrentTime,                 /* xCurrentTime */
  jtGetLastError,                /* xGetLastError */
  jtCurrentTimeInt64             /* xCurrentTimeInt64 */
};

static sqlite3_io_methods jt_io_methods = {
  1,                             /* iVersion */
  jtClose,                       /* xClose */
  jtRead,                        /* xRead */
................................................................................
** following properties:
**
**   a) SQLITE_OPEN_MAIN_DB was specified when the file was opened.
**
**   b) The file-name specified when the file was opened matches
**      all but the final 8 characters of the journal file name.
**
**   c) There is currently a reserved lock on the file. This 
**      condition is waived if the noLock argument is non-zero.
**/
static jt_file *locateDatabaseHandle(const char *zJournal, int noLock){
  jt_file *pMain = 0;
  enterJtMutex();
  for(pMain=g.pList; pMain; pMain=pMain->pNext){
    int nName = (int)(strlen(zJournal) - strlen("-journal"));
    if( (pMain->flags&SQLITE_OPEN_MAIN_DB)
     && ((int)strlen(pMain->zName)==nName)
     && 0==memcmp(pMain->zName, zJournal, nName)
     && ((pMain->eLock>=SQLITE_LOCK_RESERVED) || noLock)
    ){
      break;
    }
  }
  leaveJtMutex();
  return pMain;
}
................................................................................
  int iAmt, 
  sqlite_int64 iOfst
){
  int rc;
  jt_file *p = (jt_file *)pFile;
  if( p->flags&SQLITE_OPEN_MAIN_JOURNAL ){
    if( iOfst==0 ){
      jt_file *pMain = locateDatabaseHandle(p->zName, 0);
      assert( pMain );
  
      if( iAmt==28 ){
        /* Zeroing the first journal-file header. This is the end of a
        ** transaction. */
        closeTransaction(pMain);
      }else if( iAmt!=12 ){
................................................................................
      assert( pgno<=p->nPage || p->nSync>0 );
      assert( pgno>p->nPage || sqlite3BitvecTest(p->pWritable, pgno) );
    }
  }

  rc = sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
  if( (p->flags&SQLITE_OPEN_MAIN_JOURNAL) && iAmt==12 ){
    jt_file *pMain = locateDatabaseHandle(p->zName, 0);
    int rc2 = readJournalFile(p, pMain);
    if( rc==SQLITE_OK ) rc = rc2;
  }
  return rc;
}

/*
** Truncate an jt-file.
*/
static int jtTruncate(sqlite3_file *pFile, sqlite_int64 size){
  jt_file *p = (jt_file *)pFile;
  if( p->flags&SQLITE_OPEN_MAIN_JOURNAL && size==0 ){
    /* Truncating a journal file. This is the end of a transaction. */
    jt_file *pMain = locateDatabaseHandle(p->zName, 0);
    closeTransaction(pMain);
  }
  if( p->flags&SQLITE_OPEN_MAIN_DB && p->pWritable ){
    u32 pgno;
    u32 locking_page = (u32)(PENDING_BYTE/p->nPagesize+1);
    for(pgno=(u32)(size/p->nPagesize+1); pgno<=p->nPage; pgno++){
      assert( pgno==locking_page || sqlite3BitvecTest(p->pWritable, pgno) );
................................................................................
    jt_file *pMain;                   /* The associated database file */

    /* The journal file is being synced. At this point, we inspect the 
    ** contents of the file up to this point and set each bit in the 
    ** jt_file.pWritable bitvec of the main database file associated with
    ** this journal file.
    */
    pMain = locateDatabaseHandle(p->zName, 0);


    /* Set the bitvec values */
    if( pMain && pMain->pWritable ){
      pMain->nSync++;
      rc = readJournalFile(p, pMain);
      if( rc!=SQLITE_OK ){
        return rc;
      }
    }
  }
................................................................................
** ensure the file-system modifications are synced to disk before
** returning.
*/
static int jtDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
  int nPath = (int)strlen(zPath);
  if( nPath>8 && 0==strcmp("-journal", &zPath[nPath-8]) ){
    /* Deleting a journal file. The end of a transaction. */
    jt_file *pMain = locateDatabaseHandle(zPath, 0);
    if( pMain ){
      closeTransaction(pMain);
    }
  }

  return sqlite3OsDelete(g.pVfs, zPath, dirSync);
}
................................................................................
}
/*
** Return the current time as a Julian Day number in *pTimeOut.
*/
static int jtCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
  return g.pVfs->xCurrentTimeInt64(g.pVfs, pTimeOut);
}

static int jtGetLastError(sqlite3_vfs *pVfs, int n, char *z){
  return g.pVfs->xGetLastError(g.pVfs, n, z);
}

/**************************************************************************
** Start of public API.
*/

/*
** Configure the jt VFS as a wrapper around the VFS named by parameter 

Changes to src/test_syscall.c.

718
719
720
721
722
723
724

725
726
727
728
729




730
731
732

733
734
735
736
737
738
739
    { "list",       test_syscall_list },
    { "defaultvfs", test_syscall_defaultvfs },
    { "pagesize",   test_syscall_pagesize },
    { 0, 0 }
  };
  int iCmd;
  int rc;


  if( objc<2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "SUB-COMMAND ...");
    return TCL_ERROR;
  }




  rc = Tcl_GetIndexFromObjStruct(interp, 
      objv[1], aCmd, sizeof(aCmd[0]), "sub-command", 0, &iCmd
  );

  if( rc!=TCL_OK ) return rc;
  return aCmd[iCmd].xCmd(clientData, interp, objc, objv);
}

int SqlitetestSyscall_Init(Tcl_Interp *interp){
  struct SyscallCmd {
    const char *zName;







>





>
>
>
>
|
|
|
>







718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
    { "list",       test_syscall_list },
    { "defaultvfs", test_syscall_defaultvfs },
    { "pagesize",   test_syscall_pagesize },
    { 0, 0 }
  };
  int iCmd;
  int rc;
  sqlite3_vfs *pVfs = sqlite3_vfs_find(0);

  if( objc<2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "SUB-COMMAND ...");
    return TCL_ERROR;
  }
  if( pVfs->iVersion<3 || pVfs->xSetSystemCall==0 ){
    Tcl_AppendResult(interp, "VFS does not support xSetSystemCall", 0);
    rc = TCL_ERROR;
  }else{
    rc = Tcl_GetIndexFromObjStruct(interp, 
        objv[1], aCmd, sizeof(aCmd[0]), "sub-command", 0, &iCmd
    );
  }
  if( rc!=TCL_OK ) return rc;
  return aCmd[iCmd].xCmd(clientData, interp, objc, objv);
}

int SqlitetestSyscall_Init(Tcl_Interp *interp){
  struct SyscallCmd {
    const char *zName;

Changes to test/dbstatus2.test.

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
  execsql { INSERT INTO t1 VALUES(4, randomblob(600)) }
  db_write db
} {0 4 0}
do_test 2.3 { db_write db 1 } {0 4 0}
do_test 2.4 { db_write db 0 } {0 0 0}
do_test 2.5 { db_write db 1 } {0 0 0}

ifcapable wal {
  do_test 2.6 { 
    execsql { PRAGMA journal_mode = WAL }
    db_write db 1
  } {0 1 0}
}
do_test 2.7 { 
  execsql { INSERT INTO t1 VALUES(5, randomblob(600)) }
  db_write db
} {0 4 0}
do_test 2.8 { db_write db 1 } {0 4 0}
do_test 2.9 { db_write db 0 } {0 0 0}
 
finish_test







|













82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
  execsql { INSERT INTO t1 VALUES(4, randomblob(600)) }
  db_write db
} {0 4 0}
do_test 2.3 { db_write db 1 } {0 4 0}
do_test 2.4 { db_write db 0 } {0 0 0}
do_test 2.5 { db_write db 1 } {0 0 0}

if {[wal_is_capable]} {
  do_test 2.6 { 
    execsql { PRAGMA journal_mode = WAL }
    db_write db 1
  } {0 1 0}
}
do_test 2.7 { 
  execsql { INSERT INTO t1 VALUES(5, randomblob(600)) }
  db_write db
} {0 4 0}
do_test 2.8 { db_write db 1 } {0 4 0}
do_test 2.9 { db_write db 0 } {0 0 0}
 
finish_test

Changes to test/e_vacuum.test.

172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
    execsql VACUUM
    execsql { PRAGMA page_size ; PRAGMA auto_vacuum }
  } {2048 0}
  
  # EVIDENCE-OF: R-48521-51450 When in write-ahead log mode, only the
  # auto_vacuum support property can be changed using VACUUM.
  #
  ifcapable wal {
    do_test e_vacuum-1.3.3.1 {
      execsql { PRAGMA journal_mode = wal }
      execsql { PRAGMA page_size ; PRAGMA auto_vacuum }
    } {2048 0}
    do_test e_vacuum-1.3.3.2 {
      execsql { PRAGMA page_size = 1024 }
      execsql { PRAGMA auto_vacuum = FULL }







|







172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
    execsql VACUUM
    execsql { PRAGMA page_size ; PRAGMA auto_vacuum }
  } {2048 0}
  
  # EVIDENCE-OF: R-48521-51450 When in write-ahead log mode, only the
  # auto_vacuum support property can be changed using VACUUM.
  #
  if {[wal_is_capable]} {
    do_test e_vacuum-1.3.3.1 {
      execsql { PRAGMA journal_mode = wal }
      execsql { PRAGMA page_size ; PRAGMA auto_vacuum }
    } {2048 0}
    do_test e_vacuum-1.3.3.2 {
      execsql { PRAGMA page_size = 1024 }
      execsql { PRAGMA auto_vacuum = FULL }

Changes to test/exists.test.

15
16
17
18
19
20
21

22
23
24
25
26
27
28

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/lock_common.tcl


foreach jm {rollback wal} {


  set testprefix exists-$jm

  # This block of tests is targeted at CREATE XXX IF NOT EXISTS statements.
  #
  do_multiclient_test tn {








>







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/lock_common.tcl


foreach jm {rollback wal} {
  if {![wal_is_capable] && $jm=="wal"} continue

  set testprefix exists-$jm

  # This block of tests is targeted at CREATE XXX IF NOT EXISTS statements.
  #
  do_multiclient_test tn {

Changes to test/hook.test.

700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
do_execsql_test 7.5.2.0 {
  CREATE TABLE t8(a, b);
  INSERT INTO t8 VALUES('one', 'two');
  INSERT INTO t8 VALUES('three', 'four');
  ALTER TABLE t8 ADD COLUMN c DEFAULT 'xxx';
}

ifcapable !session {
  # At time of writing, these two are broken. They demonstrate that the
  # sqlite3_preupdate_old() method does not handle the case where ALTER TABLE
  # has been used to add a column with a default value other than NULL.
  #
  do_preupdate_test 7.5.2.1 {
    DELETE FROM t8 WHERE a = 'one'
  } {







|







700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
do_execsql_test 7.5.2.0 {
  CREATE TABLE t8(a, b);
  INSERT INTO t8 VALUES('one', 'two');
  INSERT INTO t8 VALUES('three', 'four');
  ALTER TABLE t8 ADD COLUMN c DEFAULT 'xxx';
}

if 0 {
  # At time of writing, these two are broken. They demonstrate that the
  # sqlite3_preupdate_old() method does not handle the case where ALTER TABLE
  # has been used to add a column with a default value other than NULL.
  #
  do_preupdate_test 7.5.2.1 {
    DELETE FROM t8 WHERE a = 'one'
  } {

Changes to test/incrvacuum2.test.

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
    PRAGMA incremental_vacuum;
    COMMIT;
  }
} {}

integrity_check incrvacuum2-3.3

ifcapable wal {
  # At one point, when a specific page was being extracted from the b-tree
  # free-list (e.g. during an incremental-vacuum), all trunk pages that
  # occurred before the specific page in the free-list trunk were being
  # written to the journal or wal file. This is not necessary. Only the 
  # extracted page and the page that contains the pointer to it need to
  # be journalled.
  #







|







130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
    PRAGMA incremental_vacuum;
    COMMIT;
  }
} {}

integrity_check incrvacuum2-3.3

if {[wal_is_capable]} {
  # At one point, when a specific page was being extracted from the b-tree
  # free-list (e.g. during an incremental-vacuum), all trunk pages that
  # occurred before the specific page in the free-list trunk were being
  # written to the journal or wal file. This is not necessary. Only the 
  # extracted page and the page that contains the pointer to it need to
  # be journalled.
  #

Changes to test/journal2.test.

200
201
202
203
204
205
206
207
208
209
210
211
212
213
214

#-------------------------------------------------------------------------
# Test that it is possible to switch from journal_mode=truncate to
# journal_mode=WAL on a SAFE_DELETE file-system. SQLite should close and
# delete the journal file when committing the transaction that switches
# the system to WAL mode.
#
ifcapable wal {
  do_test journal2-2.1 {
    faultsim_delete_and_reopen
    set ::oplog [list]
    execsql { PRAGMA journal_mode = persist }
    set ::oplog
  } {}
  do_test journal2-2.2 {







|







200
201
202
203
204
205
206
207
208
209
210
211
212
213
214

#-------------------------------------------------------------------------
# Test that it is possible to switch from journal_mode=truncate to
# journal_mode=WAL on a SAFE_DELETE file-system. SQLite should close and
# delete the journal file when committing the transaction that switches
# the system to WAL mode.
#
if {[wal_is_capable]} {
  do_test journal2-2.1 {
    faultsim_delete_and_reopen
    set ::oplog [list]
    execsql { PRAGMA journal_mode = persist }
    set ::oplog
  } {}
  do_test journal2-2.2 {

Changes to test/permutations.test.

938
939
940
941
942
943
944
945


946
947
948
949
950
951
952
....
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055

1056
1057
1058
1059
1060
1061

1062
1063
1064
1065
1066
1067
1068
} -initialize {
  catch {db close}
  register_jt_vfs -default ""
} -shutdown {
  unregister_jt_vfs
} -files [test_set $::allquicktests -exclude {
  wal* incrvacuum.test ioerr.test corrupt4.test io.test crash8.test 
  async4.test bigfile.test backcompat.test


}]

if {[info commands register_demovfs] != ""} {
  test_suite "demovfs" -description {
    Check that the demovfs (code in test_demovfs.c) more or less works.
  } -initialize {
    register_demovfs
................................................................................

  set ::G(perm:name)         $name
  set ::G(perm:prefix)       $options(-prefix)
  set ::G(perm:presql)       $options(-presql)
  set ::G(isquick)           1
  set ::G(perm:dbconfig)     $options(-dbconfig)

  uplevel $options(-initialize)

  foreach file [lsort $options(-files)] {

    if {[file tail $file] == $file} { set file [file join $::testdir $file] }
    slave_test_file $file
  }

  uplevel $options(-shutdown)


  unset ::G(perm:name)
  unset ::G(perm:prefix)
  unset ::G(perm:presql)
  unset ::G(perm:dbconfig)
}

proc run_test_suite {name} {







|
>
>







 







<
<

>


<
<
|
|
>







938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
....
1048
1049
1050
1051
1052
1053
1054


1055
1056
1057
1058


1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
} -initialize {
  catch {db close}
  register_jt_vfs -default ""
} -shutdown {
  unregister_jt_vfs
} -files [test_set $::allquicktests -exclude {
  wal* incrvacuum.test ioerr.test corrupt4.test io.test crash8.test 
  async4.test bigfile.test backcompat.test e_wal* fstat.test mmap2.test
  pager1.test syscall.test tkt3457.test *malloc* mmap* multiplex* nolock*
  pager2.test *fault* rowal* snapshot* superlock* symlink.test
}]

if {[info commands register_demovfs] != ""} {
  test_suite "demovfs" -description {
    Check that the demovfs (code in test_demovfs.c) more or less works.
  } -initialize {
    register_demovfs
................................................................................

  set ::G(perm:name)         $name
  set ::G(perm:prefix)       $options(-prefix)
  set ::G(perm:presql)       $options(-presql)
  set ::G(isquick)           1
  set ::G(perm:dbconfig)     $options(-dbconfig)



  foreach file [lsort $options(-files)] {
    uplevel $options(-initialize)
    if {[file tail $file] == $file} { set file [file join $::testdir $file] }
    slave_test_file $file


    uplevel $options(-shutdown)
  }

  unset ::G(perm:name)
  unset ::G(perm:prefix)
  unset ::G(perm:presql)
  unset ::G(perm:dbconfig)
}

proc run_test_suite {name} {

Changes to test/pragma3.test.

217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
}

# Make sure this also works in WAL mode
#
# This will not work with the in-memory journal permutation, as opening
# [db2] switches the journal mode back to "memory"
#
ifcapable wal {
if {[permutation]!="inmemory_journal"} {

  sqlite3 db test.db
  db eval {PRAGMA journal_mode=WAL}
  sqlite3 db2 test.db
  do_test pragma3-400 {
    db eval {







|







217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
}

# Make sure this also works in WAL mode
#
# This will not work with the in-memory journal permutation, as opening
# [db2] switches the journal mode back to "memory"
#
if {[wal_is_capable]} {
if {[permutation]!="inmemory_journal"} {

  sqlite3 db test.db
  db eval {PRAGMA journal_mode=WAL}
  sqlite3 db2 test.db
  do_test pragma3-400 {
    db eval {

Changes to test/stat.test.

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
register_dbstat_vtab db
do_execsql_test stat-0.0 {
  PRAGMA auto_vacuum = OFF;
  CREATE VIRTUAL TABLE temp.stat USING dbstat;
  SELECT * FROM stat;
} {}

ifcapable wal {
  do_execsql_test stat-0.1 {
    PRAGMA journal_mode = WAL;
    PRAGMA journal_mode = delete;
    SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload
      FROM stat;
  } {wal delete sqlite_master / 1 leaf 0 0 916 0}
}







|







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
register_dbstat_vtab db
do_execsql_test stat-0.0 {
  PRAGMA auto_vacuum = OFF;
  CREATE VIRTUAL TABLE temp.stat USING dbstat;
  SELECT * FROM stat;
} {}

if {[wal_is_capable]} {
  do_execsql_test stat-0.1 {
    PRAGMA journal_mode = WAL;
    PRAGMA journal_mode = delete;
    SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload
      FROM stat;
  } {wal delete sqlite_master / 1 leaf 0 0 916 0}
}

Changes to test/sync.test.

77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
92
93
94
95

96
97
98
99
    INSERT INTO t2 VALUES(5,6);
    COMMIT;
  }
  cond_incr_sync_count 4
  set sqlite_sync_count
} 11
ifcapable pager_pragmas {

  do_test sync-1.4 {
    set sqlite_sync_count 0
    execsql {
      PRAGMA main.synchronous=off;
      PRAGMA db2.synchronous=off;
      BEGIN;
      INSERT INTO t1 VALUES(5,6);
      INSERT INTO t2 VALUES(7,8);
      COMMIT;
    }
    set sqlite_sync_count
  } 0

}


finish_test







>












>




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
    INSERT INTO t2 VALUES(5,6);
    COMMIT;
  }
  cond_incr_sync_count 4
  set sqlite_sync_count
} 11
ifcapable pager_pragmas {
if {[permutation]!="journaltest"} {
  do_test sync-1.4 {
    set sqlite_sync_count 0
    execsql {
      PRAGMA main.synchronous=off;
      PRAGMA db2.synchronous=off;
      BEGIN;
      INSERT INTO t1 VALUES(5,6);
      INSERT INTO t2 VALUES(7,8);
      COMMIT;
    }
    set sqlite_sync_count
  } 0
}
}


finish_test

Changes to test/tester.tcl.

1939
1940
1941
1942
1943
1944
1945






1946
1947
1948
1949
1950
1951
1952
}
proc wal_check_journal_mode {testname {db db}} {
  if { [wal_is_wal_mode] } {
    $db eval { SELECT * FROM sqlite_master }
    do_test $testname [list $db eval "PRAGMA main.journal_mode"] {wal}
  }
}







proc permutation {} {
  set perm ""
  catch {set perm $::G(perm:name)}
  set perm
}
proc presql {} {







>
>
>
>
>
>







1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
}
proc wal_check_journal_mode {testname {db db}} {
  if { [wal_is_wal_mode] } {
    $db eval { SELECT * FROM sqlite_master }
    do_test $testname [list $db eval "PRAGMA main.journal_mode"] {wal}
  }
}

proc wal_is_capable {} {
  ifcapable !wal { return 0 }
  if {[permutation]=="journaltest"} { return 0 }
  return 1
}

proc permutation {} {
  set perm ""
  catch {set perm $::G(perm:name)}
  set perm
}
proc presql {} {

Changes to test/tkt-2d1a5c67d.test.

15
16
17
18
19
20
21
22

23
24
25
26
27
28
29
# 
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix tkt-2d1a5c67d

ifcapable {!wal || !vtab} {finish_test; return}


for {set ii 1} {$ii<=10} {incr ii} {
  do_test tkt-2d1a5c67d.1.$ii {
    db close
    forcedelete test.db test.db-wal
    sqlite3 db test.db
    db eval "PRAGMA cache_size=$::ii"







|
>







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix tkt-2d1a5c67d

ifcapable {!vtab} {finish_test; return}
if {[wal_is_capable]==0} {finish_test; return}

for {set ii 1} {$ii<=10} {incr ii} {
  do_test tkt-2d1a5c67d.1.$ii {
    db close
    forcedelete test.db test.db-wal
    sqlite3 db test.db
    db eval "PRAGMA cache_size=$::ii"

Changes to test/tkt-313723c356.test.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# fixed.  
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl

ifcapable !wal { finish_test ; return }

do_execsql_test tkt-313723c356.1 {
  PRAGMA page_size = 1024;
  PRAGMA journal_mode = WAL;
  CREATE TABLE t1(a, b);
  CREATE INDEX i1 ON t1(a, b);
  INSERT INTO t1 VALUES(randomblob(400), randomblob(400));







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# fixed.  
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl

if {![wal_is_capable]} { finish_test ; return }

do_execsql_test tkt-313723c356.1 {
  PRAGMA page_size = 1024;
  PRAGMA journal_mode = WAL;
  CREATE TABLE t1(a, b);
  CREATE INDEX i1 ON t1(a, b);
  INSERT INTO t1 VALUES(randomblob(400), randomblob(400));

Changes to test/tkt-5d863f876e.test.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# fixed.  
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/lock_common.tcl
set ::testprefix tkt-5d863f876e
ifcapable !wal {finish_test ; return }

do_multiclient_test tn {
  do_test $tn.1 {
    sql1 {
      CREATE TABLE t1(a, b);
      CREATE INDEX i1 ON t1(a, b);
      INSERT INTO t1 VALUES(1, 2);







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# fixed.  
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/lock_common.tcl
set ::testprefix tkt-5d863f876e
if {![wal_is_capable]} {finish_test ; return }

do_multiclient_test tn {
  do_test $tn.1 {
    sql1 {
      CREATE TABLE t1(a, b);
      CREATE INDEX i1 ON t1(a, b);
      INSERT INTO t1 VALUES(1, 2);

Changes to test/tkt-9d68c883.test.

46
47
48
49
50
51
52


53
    sqlite3_memdebug_fail -1

    catchsql { ROLLBACK }
    execsql { PRAGMA integrity_check }
  } {ok}
}



finish_test







>
>

46
47
48
49
50
51
52
53
54
55
    sqlite3_memdebug_fail -1

    catchsql { ROLLBACK }
    execsql { PRAGMA integrity_check }
  } {ok}
}

catch { db close } 
unregister_devsim
finish_test

Changes to test/zerodamage.test.

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  sqlite3 db file:test.db?psow=FALSE -uri 1
  db eval {
    UPDATE t1 SET y=randomblob(50) WHERE x=124;
  }
  concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size]
} {0 0 24704}

ifcapable wal {
  # Run a WAL-mode transaction with POWERSAFE_OVERWRITE on to verify that the
  # WAL file does not get too big.
  #
  do_test zerodamage-3.0 {
    db eval {
       PRAGMA journal_mode=WAL;
    }







|







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  sqlite3 db file:test.db?psow=FALSE -uri 1
  db eval {
    UPDATE t1 SET y=randomblob(50) WHERE x=124;
  }
  concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size]
} {0 0 24704}

if {[wal_is_capable]} {
  # Run a WAL-mode transaction with POWERSAFE_OVERWRITE on to verify that the
  # WAL file does not get too big.
  #
  do_test zerodamage-3.0 {
    db eval {
       PRAGMA journal_mode=WAL;
    }