SQLite

Check-in [375dfe288f]
Login

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

Overview
Comment:Merge updates from trunk.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | toTypeFuncs
Files: files | file ages | folders
SHA1: 375dfe288fd0c4eb3c343a3cb23a7e3851903805
User & Date: mistachkin 2013-08-29 01:11:45.298
Context
2013-08-29
01:17
Prevent the implementation of the toreal() SQL function from being 'optimized' by MSVC. (check-in: 047bd1c245 user: mistachkin tags: toTypeFuncs)
01:11
Merge updates from trunk. (check-in: 375dfe288f user: mistachkin tags: toTypeFuncs)
01:09
Small enhancements to unit testing infrastructure. (check-in: 9229aeb361 user: mistachkin tags: trunk)
01:01
Fix boundary case for the toreal() SQL function. (check-in: abe82c634c user: mistachkin tags: toTypeFuncs)
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to Makefile.msc.
89
90
91
92
93
94
95








96
97
98
99
100
101
102
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110







+
+
+
+
+
+
+
+







# 3 == SQLITE_WIN32_MALLOC_VALIDATE: Validate the Win32 native heap per call.
# 4 == SQLITE_DEBUG_OS_TRACE: Enables output from the OSTRACE() macros.
# 5 == SQLITE_ENABLE_IOTRACE: Enables output from the IOTRACE() macros.
#
!IFNDEF DEBUG
DEBUG = 0
!ENDIF

# Enable use of available compiler optimizations?  Normally, this should be
# non-zero.  Setting this to zero, thus disabling all compiler optimizations,
# can be useful for testing.
#
!IFNDEF OPTIMIZATIONS
OPTIMIZATIONS = 2
!ENDIF

# Check for the predefined command macro CC.  This should point to the compiler
# binary for the target platform.  If it is not defined, simply define it to
# the legacy default value 'cl.exe'.
#
!IFNDEF CC
CC = cl.exe
339
340
341
342
343
344
345

346

347
348
349

350

351
352
353
354
355
356
357
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369







+

+



+

+







#
!IFNDEF TCLSH_CMD
TCLSH_CMD = tclsh85
!ENDIF

# Compiler options needed for programs that use the readline() library.
#
!IFNDEF READLINE_FLAGS
READLINE_FLAGS = -DHAVE_READLINE=0
!ENDIF

# The library that programs using readline() must link against.
#
!IFNDEF LIBREADLINE
LIBREADLINE =
!ENDIF

# Should the database engine be compiled threadsafe
#
TCC = $(TCC) -DSQLITE_THREADSAFE=1
RCC = $(RCC) -DSQLITE_THREADSAFE=1

# Do threads override each others locks by default (1), or do we test (-1)
393
394
395
396
397
398
399
400
401

402
403
404


405
406











407
408



409
410

411
412
413
414
415
416
417
405
406
407
408
409
410
411


412
413


414
415
416

417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442







-
-
+

-
-
+
+

-
+
+
+
+
+
+
+
+
+
+
+


+
+
+


+







RCC = $(RCC) $(OPT_FEATURE_FLAGS)

# Add in any optional parameters specified on the make commane line
# ie.  make "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1".
TCC = $(TCC) $(OPTS)
RCC = $(RCC) $(OPTS)

# If symbols are enabled, enable PDBs.
# If debugging is enabled, disable all optimizations and enable PDBs.
# If compiling for debugging, add some defines.
!IF $(DEBUG)>0
TCC = $(TCC) -Od -D_DEBUG
BCC = $(BCC) -Od -D_DEBUG
TCC = $(TCC) -D_DEBUG
BCC = $(BCC) -D_DEBUG
RCC = $(RCC) -D_DEBUG
!ELSE
!ENDIF

# If optimizations are enabled or disabled (either implicitly or
# explicitly), add the necessary flags.
!IF $(DEBUG)>0 || $(OPTIMIZATIONS)==0
TCC = $(TCC) -Od
BCC = $(BCC) -Od
!ELSEIF $(OPTIMIZATIONS)>=3
TCC = $(TCC) -Ox
BCC = $(BCC) -Ox
!ELSEIF $(OPTIMIZATIONS)==2
TCC = $(TCC) -O2
BCC = $(BCC) -O2
!ELSEIF $(OPTIMIZATIONS)==1
TCC = $(TCC) -O1
BCC = $(BCC) -O1
!ENDIF

# If symbols are enabled (or compiling for debugging), enable PDBs.
!IF $(DEBUG)>0 || $(SYMBOLS)!=0
TCC = $(TCC) -Zi
BCC = $(BCC) -Zi
!ENDIF

# If ICU support is enabled, add the compiler options for it.
!IF $(USE_ICU)!=0
461
462
463
464
465
466
467

468

469
470
471
472
473
474
475
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502







+

+







# If ICU support is enabled, add the linker options for it.
!IF $(USE_ICU)!=0
LTLIBPATHS = $(LTLIBPATHS) /LIBPATH:$(ICULIBDIR)
LTLIBS = $(LTLIBS) $(LIBICU)
!ENDIF

# nawk compatible awk.
!IFNDEF NAWK
NAWK = gawk.exe
!ENDIF

# You should not have to change anything below this line
###############################################################################

# Object files for the SQLite library (non-amalgamation).
#
LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \
Changes to test/tester.tcl.
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24







-
+







#***********************************************************************
# This file implements some common TCL routines used for regression
# testing the SQLite library
#
# $Id: tester.tcl,v 1.143 2009/04/09 01:23:49 drh Exp $

#-------------------------------------------------------------------------
# The commands provided by the code in this file to help with creating 
# The commands provided by the code in this file to help with creating
# test cases are as follows:
#
# Commands to manipulate the db and the file-system at a high level:
#
#      is_relative_file
#      test_pwd
#      get_pwd
38
39
40
41
42
43
44

45
46
47
48
49
50
51
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52







+







#
#      dbcksum                DB DBNAME
#      allcksum               ?DB?
#      cksum                  ?DB?
#
# Commands to execute/explain SQL statements:
#
#      memdbsql               SQL
#      stepsql                DB SQL
#      execsql2               SQL
#      explain_no_trace       SQL
#      explain                SQL ?DB?
#      catchsql               SQL ?DB?
#      execsql                SQL ?DB?
#
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
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







-
+









-
+







#      wal_is_wal_mode
#      wal_set_journal_mode   ?DB?
#      wal_check_journal_mode TESTNAME?DB?
#      permutation
#      presql
#

# Set the precision of FP arithmatic used by the interpreter. And 
# Set the precision of FP arithmatic used by the interpreter. And
# configure SQLite to take database file locks on the page that begins
# 64KB into the database file instead of the one 1GB in. This means
# the code that handles that special case can be tested without creating
# very large database files.
#
set tcl_precision 15
sqlite3_test_control_pending_byte 0x0010000


# If the pager codec is available, create a wrapper for the [sqlite3] 
# If the pager codec is available, create a wrapper for the [sqlite3]
# command that appends "-key {xyzzy}" to the command line. i.e. this:
#
#     sqlite3 db test.db
#
# becomes
#
#     sqlite3 db test.db -key {xyzzy}
118
119
120
121
122
123
124
125

126
127
128
129
130
131
132
119
120
121
122
123
124
125

126
127
128
129
130
131
132
133







-
+







      }
      if {[info exists ::G(perm:dbconfig)]} {
        set ::dbhandle [lindex $args 0]
        uplevel #0 $::G(perm:dbconfig)
      }
      set res
    } else {
      # This command is not opening a new database connection. Pass the 
      # This command is not opening a new database connection. Pass the
      # arguments through to the C implementation as the are.
      #
      uplevel 1 sqlite_orig $args
    }
  }
}

286
287
288
289
290
291
292




























































293
294
295
296
297
298
299
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
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
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







        file delete -force $filename
      } else {
        file delete $filename
      }
    }
  }
}

if {$::tcl_platform(platform) eq "windows"} {
  proc do_remove_win32_dir {args} {
    set nRetry [getFileRetries]     ;# Maximum number of retries.
    set nDelay [getFileRetryDelay]  ;# Delay in ms before retrying.

    foreach dirName $args {
      # On windows, sometimes even a [remove_win32_dir] can fail just after
      # a directory is emptied. The cause is usually "tag-alongs" - programs
      # like anti-virus software, automatic backup tools and various explorer
      # extensions that keep a file open a little longer than we expect,
      # causing the delete to fail.
      #
      # The solution is to wait a short amount of time before retrying the
      # removal.
      #
      if {$nRetry > 0} {
        for {set i 0} {$i < $nRetry} {incr i} {
          set rc [catch {
            remove_win32_dir $dirName
          } msg]
          if {$rc == 0} break
          if {$nDelay > 0} { after $nDelay }
        }
        if {$rc} { error $msg }
      } else {
        remove_win32_dir $dirName
      }
    }
  }

  proc do_delete_win32_file {args} {
    set nRetry [getFileRetries]     ;# Maximum number of retries.
    set nDelay [getFileRetryDelay]  ;# Delay in ms before retrying.

    foreach fileName $args {
      # On windows, sometimes even a [delete_win32_file] can fail just after
      # a file is closed. The cause is usually "tag-alongs" - programs like
      # anti-virus software, automatic backup tools and various explorer
      # extensions that keep a file open a little longer than we expect,
      # causing the delete to fail.
      #
      # The solution is to wait a short amount of time before retrying the
      # delete.
      #
      if {$nRetry > 0} {
        for {set i 0} {$i < $nRetry} {incr i} {
          set rc [catch {
            delete_win32_file $fileName
          } msg]
          if {$rc == 0} break
          if {$nDelay > 0} { after $nDelay }
        }
        if {$rc} { error $msg }
      } else {
        delete_win32_file $fileName
      }
    }
  }
}

proc execpresql {handle args} {
  trace remove execution $handle enter [list execpresql $handle]
  if {[info exists ::G(perm:presql)]} {
    $handle eval $::G(perm:presql)
  }
}
308
309
310
311
312
313
314
315
316


317
318
319
320
321
322
323
369
370
371
372
373
374
375


376
377
378
379
380
381
382
383
384







-
-
+
+








# The following block only runs the first time this file is sourced. It
# does not run in slave interpreters (since the ::cmdlinearg array is
# populated before the test script is run in slave interpreters).
#
if {[info exists cmdlinearg]==0} {

  # Parse any options specified in the $argv array. This script accepts the 
  # following options: 
  # Parse any options specified in the $argv array. This script accepts the
  # following options:
  #
  #   --pause
  #   --soft-heap-limit=NN
  #   --maxerror=NN
  #   --malloctrace=N
  #   --backtrace=N
  #   --binarylog=N
338
339
340
341
342
343
344
345

346
347
348
349
350
351
352
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413







-
+







  set cmdlinearg(start)             ""
  set cmdlinearg(match)             ""

  set leftover [list]
  foreach a $argv {
    switch -regexp -- $a {
      {^-+pause$} {
        # Wait for user input before continuing. This is to give the user an 
        # Wait for user input before continuing. This is to give the user an
        # opportunity to connect profiling tools to the process.
        puts -nonewline "Press RETURN to begin..."
        flush stdout
        gets stdin
      }
      {^-+soft-heap-limit=.+$} {
        foreach {dummy cmdlinearg(soft-heap-limit)} [split $a =] break
401
402
403
404
405
406
407
408
409


410
411
412
413
414
415
416
462
463
464
465
466
467
468


469
470
471
472
473
474
475
476
477







-
-
+
+







    }
  }
  set argv $leftover

  # Install the malloc layer used to inject OOM errors. And the 'automatic'
  # extensions. This only needs to be done once for the process.
  #
  sqlite3_shutdown 
  install_malloc_faultsim 1 
  sqlite3_shutdown
  install_malloc_faultsim 1
  sqlite3_initialize
  autoinstall_test_functions

  # If the --binarylog option was specified, create the logging VFS. This
  # call installs the new VFS as the default for all SQLite connections.
  #
  if {$cmdlinearg(binarylog)} {
512
513
514
515
516
517
518
519

520
521
522
523
524
525
526
527
528

529
530
531
532
533
534
535
573
574
575
576
577
578
579

580
581
582
583
584
585
586
587
588

589
590
591
592
593
594
595
596







-
+








-
+







# Increment the number of tests run
#
proc incr_ntest {} {
  set_test_counter count [expr [set_test_counter count] + 1]
}


# Invoke the do_test procedure to run a single test 
# Invoke the do_test procedure to run a single test
#
proc do_test {name cmd expected} {
  global argv cmdlinearg

  fix_testname name

  sqlite3_memdebug_settitle $name

#  if {[llength $argv]==0} { 
#  if {[llength $argv]==0} {
#    set go 1
#  } else {
#    set go 0
#    foreach pattern $argv {
#      if {[string match $pattern $name]} {
#        set go 1
#        break
624
625
626
627
628
629
630
631

632
633
634
635
636
637

638
639
640
641
642
643
644
685
686
687
688
689
690
691

692
693
694
695
696
697

698
699
700
701
702
703
704
705







-
+





-
+







  uplevel [list do_test $name [
    subst -nocommands { realnum_normalize [ $cmd ] }
  ] [realnum_normalize $expected]]
}

proc fix_testname {varname} {
  upvar $varname testname
  if {[info exists ::testprefix] 
  if {[info exists ::testprefix]
   && [string is digit [string range $testname 0 0]]
  } {
    set testname "${::testprefix}-$testname"
  }
}
    

proc do_execsql_test {testname sql {result {}}} {
  fix_testname testname
  uplevel do_test [list $testname] [list "execsql {$sql}"] [list [list {*}$result]]
}
proc do_catchsql_test {testname sql result} {
  fix_testname testname
  uplevel do_test [list $testname] [list "catchsql {$sql}"] [list $result]
716
717
718
719
720
721
722
723

724
725
726
727
728
729
730
777
778
779
780
781
782
783

784
785
786
787
788
789
790
791







-
+








proc delete_all_data {} {
  db eval {SELECT tbl_name AS t FROM sqlite_master WHERE type = 'table'} {
    db eval "DELETE FROM '[string map {' ''} $t]'"
  }
}

# Run an SQL script.  
# Run an SQL script.
# Return the number of microseconds per statement.
#
proc speed_trial {name numstmt units sql} {
  puts -nonewline [format {%-21.21s } $name...]
  flush stdout
  set speed [time {sqlite3_exec_nr db $sql}]
  set tm [lindex $speed 0]
979
980
981
982
983
984
985









986
987
988
989
990
991
992
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062







+
+
+
+
+
+
+
+
+







  db eval $sql data {
    foreach f $data(*) {
      lappend result $f $data($f)
    }
  }
  return $result
}

# Use a temporary in-memory database to execute SQL statements
#
proc memdbsql {sql} {
  sqlite3 memdb :memory:
  set result [memdb eval $sql]
  memdb close
  return $result
}

# Use the non-callback API to execute multiple SQL statements
#
proc stepsql {dbptr sql} {
  set sql [string trim $sql]
  set r 0
  while {[string length $sql]>0} {
1094
1095
1096
1097
1098
1099
1100
1101

1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120

1121
1122
1123
1124
1125
1126
1127
1164
1165
1166
1167
1168
1169
1170

1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189

1190
1191
1192
1193
1194
1195
1196
1197







-
+


















-
+







  set blocksize ""
  set crashdelay 1
  set prngseed 0
  set tclbody {}
  set crashfile ""
  set dc ""
  set sql [lindex $args end]
  

  for {set ii 0} {$ii < [llength $args]-1} {incr ii 2} {
    set z [lindex $args $ii]
    set n [string length $z]
    set z2 [lindex $args [expr $ii+1]]

    if     {$n>1 && [string first $z -delay]==0}     {set crashdelay $z2} \
    elseif {$n>1 && [string first $z -seed]==0}      {set prngseed $z2} \
    elseif {$n>1 && [string first $z -file]==0}      {set crashfile $z2}  \
    elseif {$n>1 && [string first $z -tclbody]==0}   {set tclbody $z2}  \
    elseif {$n>1 && [string first $z -blocksize]==0} {set blocksize "-s $z2" } \
    elseif {$n>1 && [string first $z -characteristics]==0} {set dc "-c {$z2}" } \
    else   { error "Unrecognized option: $z" }
  }

  if {$crashfile eq ""} {
    error "Compulsory option -file missing"
  }

  # $crashfile gets compared to the native filename in 
  # $crashfile gets compared to the native filename in
  # cfSync(), which can be different then what TCL uses by
  # default, so here we force it to the "nativename" format.
  set cfile [string map {\\ \\\\} [file nativename [file join [get_pwd] $crashfile]]]

  set f [open crash.tcl w]
  puts $f "sqlite3_crash_enable 1"
  puts $f "sqlite3_crashparams $blocksize $dc $crashdelay $cfile"
1148
1149
1150
1151
1152
1153
1154
1155

1156
1157
1158
1159
1160
1161
1162
1163
1164
1165

1166
1167
1168
1169
1170
1171
1172
1218
1219
1220
1221
1222
1223
1224

1225
1226
1227
1228
1229
1230
1231
1232
1233
1234

1235
1236
1237
1238
1239
1240
1241
1242







-
+









-
+







    puts $f   "$sql"
    puts $f "}"
  }
  close $f
  set r [catch {
    exec [info nameofexec] crash.tcl >@stdout
  } msg]
  

  # Windows/ActiveState TCL returns a slightly different
  # error message.  We map that to the expected message
  # so that we don't have to change all of the test
  # cases.
  if {$::tcl_platform(platform)=="windows"} {
    if {$msg=="child killed: unknown signal"} {
      set msg "child process exited abnormally"
    }
  }
  

  lappend r $msg
}

proc run_ioerr_prep {} {
  set ::sqlite_io_error_pending 0
  catch {db close}
  catch {db2 close}
1184
1185
1186
1187
1188
1189
1190
1191

1192
1193
1194
1195
1196
1197
1198
1254
1255
1256
1257
1258
1259
1260

1261
1262
1263
1264
1265
1266
1267
1268







-
+







  }
  expr 0
}

# Usage: do_ioerr_test <test number> <options...>
#
# This proc is used to implement test cases that check that IO errors
# are correctly handled. The first argument, <test number>, is an integer 
# are correctly handled. The first argument, <test number>, is an integer
# used to name the tests executed by this proc. Options are as follows:
#
#     -tclprep          TCL script to run to prepare test.
#     -sqlprep          SQL script to run to prepare test.
#     -tclbody          TCL script to run with IO error simulation.
#     -sqlbody          TCL script to run with IO error simulation.
#     -exclude          List of 'N' values not to test.
1213
1214
1215
1216
1217
1218
1219
1220

1221
1222
1223
1224
1225
1226
1227
1283
1284
1285
1286
1287
1288
1289

1290
1291
1292
1293
1294
1295
1296
1297







-
+







  set ::ioerropts(-ckrefcount) 0
  set ::ioerropts(-restoreprng) 1
  array set ::ioerropts $args

  # TEMPORARY: For 3.5.9, disable testing of extended result codes. There are
  # a couple of obscure IO errors that do not return them.
  set ::ioerropts(-erc) 0
  

  # Create a single TCL script from the TCL and SQL specified
  # as the body of the test.
  set ::ioerrorbody {}
  if {[info exists ::ioerropts(-tclbody)]} {
    append ::ioerrorbody "$::ioerropts(-tclbody)\n"
  }
  if {[info exists ::ioerropts(-sqlbody)]} {
1237
1238
1239
1240
1241
1242
1243
1244

1245
1246
1247
1248
1249
1250
1251
1252
1253

1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271

1272
1273
1274
1275
1276
1277
1278
1307
1308
1309
1310
1311
1312
1313

1314
1315
1316
1317
1318
1319
1320
1321
1322

1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340

1341
1342
1343
1344
1345
1346
1347
1348







-
+








-
+

















-
+








  set ::go 1
  #reset_prng_state
  for {set n $::ioerropts(-start)} {$::go} {incr n} {
    set ::TN $n
    incr ::ioerropts(-count) -1
    if {$::ioerropts(-count)<0} break
 

    # Skip this IO error if it was specified with the "-exclude" option.
    if {[info exists ::ioerropts(-exclude)]} {
      if {[lsearch $::ioerropts(-exclude) $n]!=-1} continue
    }
    if {$::ioerropts(-restoreprng)} {
      restore_prng_state
    }

    # Delete the files test.db and test2.db, then execute the TCL and 
    # Delete the files test.db and test2.db, then execute the TCL and
    # SQL (in that order) to prepare for the test case.
    do_test $testname.$n.1 {
      run_ioerr_prep
    } {0}

    # Read the 'checksum' of the database.
    if {$::ioerropts(-cksum)} {
      set ::checksum [cksum]
    }

    # Set the Nth IO error to fail.
    do_test $testname.$n.2 [subst {
      set ::sqlite_io_error_persist $::ioerropts(-persist)
      set ::sqlite_io_error_pending $n
    }] $n

    # Execute the TCL script created for the body of this test. If
    # at least N IO operations performed by SQLite as a result of 
    # at least N IO operations performed by SQLite as a result of
    # the script, the Nth will fail.
    do_test $testname.$n.3 {
      set ::sqlite_io_error_hit 0
      set ::sqlite_io_error_hardhit 0
      set r [catch $::ioerrorbody msg]
      set ::errseen $r
      set rc [sqlite3_errcode $::DB]
1318
1319
1320
1321
1322
1323
1324
1325
1326


1327
1328
1329
1330

1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346

1347
1348
1349
1350
1351
1352
1353
1388
1389
1390
1391
1392
1393
1394


1395
1396
1397
1398
1399

1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415

1416
1417
1418
1419
1420
1421
1422
1423







-
-
+
+



-
+















-
+







      #puts "s=$s r=$r q=$q"
      expr { ($s && !$r && !$q) || (!$s && $r && $q) }
    } {1}

    set ::sqlite_io_error_hit 0
    set ::sqlite_io_error_pending 0

    # Check that no page references were leaked. There should be 
    # a single reference if there is still an active transaction, 
    # Check that no page references were leaked. There should be
    # a single reference if there is still an active transaction,
    # or zero otherwise.
    #
    # UPDATE: If the IO error occurs after a 'BEGIN' but before any
    # locks are established on database files (i.e. if the error 
    # locks are established on database files (i.e. if the error
    # occurs while attempting to detect a hot-journal file), then
    # there may 0 page references and an active transaction according
    # to [sqlite3_get_autocommit].
    #
    if {$::go && $::sqlite_io_error_hardhit && $::ioerropts(-ckrefcount)} {
      do_test $testname.$n.4 {
        set bt [btree_from_db db]
        db_enter db
        array set stats [btree_pager_stats $bt]
        db_leave db
        set nRef $stats(ref)
        expr {$nRef == 0 || ([sqlite3_get_autocommit db]==0 && $nRef == 1)}
      } {1}
    }

    # If there is an open database handle and no open transaction, 
    # If there is an open database handle and no open transaction,
    # and the pager is not running in exclusive-locking mode,
    # check that the pager is in "unlocked" state. Theoretically,
    # if a call to xUnlock() failed due to an IO error the underlying
    # file may still be locked.
    #
    ifcapable pragma {
      if { [info commands db] ne ""
1443
1444
1445
1446
1447
1448
1449
1450

1451
1452
1453
1454
1455
1456
1457
1513
1514
1515
1516
1517
1518
1519

1520
1521
1522
1523
1524
1525
1526
1527







-
+







    append txt $prag-[$db eval "PRAGMA $prag"]\n
  }
  # puts txt=$txt
  return [md5 $txt]
}

# Generate a checksum based on the contents of a single database with
# a database connection.  The name of the database is $dbname.  
# a database connection.  The name of the database is $dbname.
# Examples of $dbname are "temp" or "main".
#
proc dbcksum {db dbname} {
  if {$dbname=="temp"} {
    set master sqlite_temp_master
  } else {
    set master $dbname.sqlite_master
1537
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
1607
1608
1609
1610
1611
1612
1613


1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629

1630
1631

1632
1633
1634
1635
1636
1637
1638
1639







-
-
+
+














-
+

-
+







  ifcapable trigger&&foreignkey {
    $db eval "PRAGMA foreign_keys = $pk"
  }
}

#-------------------------------------------------------------------------
# If a test script is executed with global variable $::G(perm:name) set to
# "wal", then the tests are run in WAL mode. Otherwise, they should be run 
# in rollback mode. The following Tcl procs are used to make this less 
# "wal", then the tests are run in WAL mode. Otherwise, they should be run
# in rollback mode. The following Tcl procs are used to make this less
# intrusive:
#
#   wal_set_journal_mode ?DB?
#
#     If running a WAL test, execute "PRAGMA journal_mode = wal" using
#     connection handle DB. Otherwise, this command is a no-op.
#
#   wal_check_journal_mode TESTNAME ?DB?
#
#     If running a WAL test, execute a tests case that fails if the main
#     database for connection handle DB is not currently a WAL database.
#     Otherwise (if not running a WAL permutation) this is a no-op.
#
#   wal_is_wal_mode
#   
#
#     Returns true if this test should be run in WAL mode. False otherwise.
# 
#
proc wal_is_wal_mode {} {
  expr {[permutation] eq "wal"}
}
proc wal_set_journal_mode {{db db}} {
  if { [wal_is_wal_mode] } {
    $db eval "PRAGMA journal_mode = WAL"
  }
1656
1657
1658
1659
1660
1661
1662
1663

1664
1665
1666

1667
1668
1669
1670
1671
1672
1673
1726
1727
1728
1729
1730
1731
1732

1733
1734
1735

1736
1737
1738
1739
1740
1741
1742
1743







-
+


-
+







  # is not thread-safe.
  #
  if {[info exists ::run_thread_tests_called]==0} {
    do_test ${tail}-closeallfiles { expr {$::sqlite_open_file_count>0} } {0}
  }
  set ::sqlite_open_file_count 0

  # Test that the global "shared-cache" setting was not altered by 
  # Test that the global "shared-cache" setting was not altered by
  # the test script.
  #
  ifcapable shared_cache { 
  ifcapable shared_cache {
    set res [expr {[sqlite3_enable_shared_cache] == $scs}]
    do_test ${tail}-sharedcachesetting [list set {} $res] 1
  }

  # Add some info to the output.
  #
  puts "Time: $tail $ms ms"
Changes to test/wild001.test.
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
38
39
40
41
42
43
44




45
46
47
48
49
50
51







-
-
-
-







# This test should work the same with and without SQLITE_ENABLE_STAT3
#
###############################################################################

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

# TODO: Reenable this test.
  finish_test
  return

ifcapable !stat3 {
  finish_test
  return
}

do_execsql_test wild001.01 {
  CREATE TABLE "items" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "secid" integer, "parent_id" integer, "metadata_type" integer, "guid" varchar(255), "media_item_count" integer, "title" varchar(255), "title_sort" varchar(255) COLLATE NOCASE, "original_title" varchar(255), "studio" varchar(255), "rating" float, "rating_count" integer, "tagline" varchar(255), "summary" text, "trivia" text, "quotes" text, "content_rating" varchar(255), "content_rating_age" integer, "index" integer, "absolute_index" integer, "duration" integer, "user_thumb_url" varchar(255), "user_art_url" varchar(255), "user_banner_url" varchar(255), "user_music_url" varchar(255), "user_fields" varchar(255), "tags_genre" varchar(255), "tags_collection" varchar(255), "tags_director" varchar(255), "tags_writer" varchar(255), "tags_star" varchar(255), "originally_available_at" datetime, "available_at" datetime, "expires_at" datetime, "refreshed_at" datetime, "year" integer, "added_at" datetime, "created_at" datetime, "updated_at" datetime, "deleted_at" datetime, "tags_country" varchar(255), "extra_data" varchar(255), "hash" varchar(255));
Changes to test/win32longpath.test.
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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
15
16
17
18
19
20
21


























































22
23
24
25
26
27
28







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-








if {$tcl_platform(platform)!="windows"} return

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

proc do_remove_win32_dir {args} {
  set nRetry [getFileRetries]     ;# Maximum number of retries.
  set nDelay [getFileRetryDelay]  ;# Delay in ms before retrying.

  foreach dirName $args {
    # On windows, sometimes even a [remove_win32_dir] can fail just after
    # a directory is emptied. The cause is usually "tag-alongs" - programs
    # like anti-virus software, automatic backup tools and various explorer
    # extensions that keep a file open a little longer than we expect,
    # causing the delete to fail.
    #
    # The solution is to wait a short amount of time before retrying the
    # removal.
    #
    if {$nRetry > 0} {
      for {set i 0} {$i < $nRetry} {incr i} {
        set rc [catch {
          remove_win32_dir $dirName
        } msg]
        if {$rc == 0} break
        if {$nDelay > 0} { after $nDelay }
      }
      if {$rc} { error $msg }
    } else {
      remove_win32_dir $dirName
    }
  }
}

proc do_delete_win32_file {args} {
  set nRetry [getFileRetries]     ;# Maximum number of retries.
  set nDelay [getFileRetryDelay]  ;# Delay in ms before retrying.

  foreach fileName $args {
    # On windows, sometimes even a [delete_win32_file] can fail just after
    # a file is closed. The cause is usually "tag-alongs" - programs like
    # anti-virus software, automatic backup tools and various explorer
    # extensions that keep a file open a little longer than we expect,
    # causing the delete to fail.
    #
    # The solution is to wait a short amount of time before retrying the
    # delete.
    #
    if {$nRetry > 0} {
      for {set i 0} {$i < $nRetry} {incr i} {
        set rc [catch {
          delete_win32_file $fileName
        } msg]
        if {$rc == 0} break
        if {$nDelay > 0} { after $nDelay }
      }
      if {$rc} { error $msg }
    } else {
      delete_win32_file $fileName
    }
  }
}

db close
set path [file nativename [get_pwd]]
sqlite3 db [file join $path test.db] -vfs win32-longpath

do_test 1.1 {
  db eval {
    BEGIN EXCLUSIVE;