System.Data.SQLite

Check-in Differences
Login

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

Difference From a81eb9b135e0fd97 To 0ca77b6031ec1c78

2013-01-30
01:00
Support automatic value conversions for columns with a declared type of INTEGER8, INTEGER16, INTEGER32, INTEGER64, UNSIGNEDINTEGER, UNSIGNEDINTEGER8, UNSIGNEDINTEGER16, UNSIGNEDINTEGER32, UNSIGNEDINTEGER64, INT8, INT16, INT32, INT64, UINT, UINT8, UINT16, UINT32, or UINT64. check-in: ad2b42f3cc user: mistachkin tags: trunk
2013-01-29
20:39
Skip checking loaded assemblies for classes tagged with the SQLiteFunction attribute when the No_SQLiteFunctions environment variable is set. check-in: 52000f7d30 user: mistachkin tags: skipFunctions
03:35
Add test pursuant to ticket [e235a52c82]. check-in: 4647779e7a user: mistachkin tags: tkt-e235a52c82
03:34
Remove superfluous 'using' statements from some tests. check-in: 0ca77b6031 user: mistachkin tags: trunk
2013-01-17
21:01
Bump all versions to 1.0.85.0. Add static Execute method to the SQLiteCommand class. Add public constructor to the SQLiteDataAdapter class that allows passing the parseViaFramework parameter to the SQLiteConnection constructor. When built with the CHECK_STATE compile-time option, skip throwing exceptions from the SQLiteDataReader class when the object is being disposed. check-in: b2c5c6e2a0 user: mistachkin tags: trunk
2012-10-14
01:07
Add workload to the stress test that allocates (large amounts of) native heap memory. check-in: 977ba2a5fb user: mistachkin tags: trunk
2012-10-13
22:38
Revise handling of errors in the stress test. check-in: a81eb9b135 user: mistachkin tags: trunk
20:28
Make the stress test failure handling more flexible, add more comments, and improve readability. check-in: 742684b09c user: mistachkin tags: trunk

Added .fossil-settings/crnl-glob.

1
+
*
Added .fossil-settings/ignore-glob.


1
2
+
+
*.mistachkin.eagle
Externals/Eagle/bin/Eagle*.pdb
Changes to Doc/Extra/dbfactorysupport.html.
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95







-
+







<configuration>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SQLite"/>
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" 
           description=".Net Framework Data Provider for SQLite"
           type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite,
                 Version=1.0.83.0, Culture=neutral,
                 Version=1.0.85.0, Culture=neutral,
                 PublicKeyToken=db937bc2d44ff139"/>
    </DbProviderFactories>
  </system.data>
</configuration>
</pre>
      </div>
      <p>
Changes to Doc/Extra/environment.html.
74
75
76
77
78
79
80
81




82
83
84
85
86
87
88
74
75
76
77
78
79
80

81
82
83
84
85
86
87
88
89
90
91







-
+
+
+
+







          "x64") or platform-specific (e.g. "Win32") directories that reside
          underneath the application base directory.</td>
        </tr>
        <tr valign="top">
          <td>PreLoadSQLite_BaseDirectory</td>
          <td>If this environment variable is set [to anything], it will be
          used instead of the application base directory by the native
          library pre-loader.</td>
          library pre-loader.  This environment variable can be especially
          useful in ASP.NET and other hosted environments where direct control
          of the location of the managed assemblies is not under the control
          of the application.</td>
        </tr>
        <tr valign="top">
          <td>PreLoadSQLite_ProcessorArchitecture</td>
          <td>If this environment variable is set [to anything], it will be
          used instead of the processor architecture value contained in the
          PROCESSOR_ARCHITECTURE environment variable to help build the path
          of the native library to pre-load.</td>
Changes to Doc/Extra/version.html.
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
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
87
88
89
90
91
92
93
94
95
96
97
98







-
+

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




+
+
+













-
+



+

+
+
+







          </td>
        </tr>
      </table>
    </div>
    <div id="mainSection">
    <div id="mainBody">
    <h1 class="heading">Version History</h1>
    <p><b>1.0.83.0 - December XX, 2012 <font color="red">(release scheduled)</font></b></p>
    <p><b>1.0.85.0 - March XX, 2013 <font color="red">(release scheduled)</font></b></p>
    <ul>
      <li>Updated to <a href="http://www.sqlite.org/src/info/trunk">SQLite 3.7.15</a>.</li>
      <li>Updated to <a href="http://www.sqlite.org/src/info/trunk">SQLite 3.7.16</a>.</li>
      <li>Add static Execute method to the SQLiteCommand class.</li>
      <li>Add public constructor to the SQLiteDataAdapter class that allows passing the parseViaFramework parameter to the SQLiteConnection constructor.</li>
      <li>When built with the CHECK_STATE compile-time option, skip throwing exceptions from the SQLiteDataReader class when the object is being disposed.</li>
    </ul>
    <p><b>1.0.84.0 - January 9, 2013</b></p>
    <ul>
      <li>Updated to <a href="http://www.sqlite.org/releaselog/3_7_15_2.html">SQLite 3.7.15.2</a>.</li>
      <li>Explicitly dispose of all SQLiteCommand objects managed by the DbDataAdapter class. Fix for <a href="http://system.data.sqlite.org/index.html/info/6434e23a0f">[6434e23a0f]</a>.</li>
      <li>Add Cancel method to the SQLiteConnection class to interrupt a long running query.</li>
      <li>Improve thread safety of the SQLiteLog.LogMessage method.</li>
    </ul>
    <p><b>1.0.83.0 - December 29, 2012</b></p>
    <ul>
      <li>Updated to <a href="http://www.sqlite.org/releaselog/3_7_15_1.html">SQLite 3.7.15.1</a>.</li>
      <li>Add Visual Studio 2012 support to all the applicable solution/project files, their associated supporting files, and the test suite.</li>
      <li>Add Visual Studio 2012 support to the redesigned designer support installer.</li>
      <li>Allow opened connections to skip adding the extension functions included in the interop assembly via the new NoExtensionFunctions connection flag.</li>
      <li>Support loading of SQLite extensions via the new EnableExtensions and LoadExtension methods of the SQLiteConnection class. Pursuant to <a href="http://system.data.sqlite.org/index.html/info/17045010df">[17045010df]</a>.</li>
      <li>Remove one set of surrounding single or double quotes from property names and values parsed from the connection string. Fix for <a href="http://system.data.sqlite.org/index.html/info/b4cc611998">[b4cc611998]</a>.</li>
      <li>Modify parsing of connection strings to allow property names and values to be quoted.&nbsp;<b>** Potentially Incompatible Change **</b></li>
      <li>Add ParseViaFramework property to the SQLiteConnection class to allow the built-in (i.e. framework provided) connection string parser to be used when opening a connection. Pursuant to <a href="http://system.data.sqlite.org/index.html/info/b4cc611998">[b4cc611998]</a>.</li>
      <li>Add notifications before and after any connection is opened and closed, as well as other related notifications, via the new static Changed event.</li>
      <li>Add an overload of the SQLiteLog.LogMessage method that takes a single string parameter.</li>
      <li>Add an overload of the SQLiteConnection.LogMessage method that takes a SQLiteErrorCode parameter.</li>
      <li>All applicable calls into the SQLite core library now return a SQLiteErrorCode instead of an integer error code.</li>
      <li>Make sure the error code of the SQLiteException class gets serialized.</li>
      <li>Make the test project for the .NET Compact Framework more flexible.</li>
      <li>When available, the new sqlite3_errstr function from the core library is used to get the error message for a specific return code.</li>
      <li>The SetMemoryStatus, Shutdown, ResultCode, ExtendedResultCode, and SetAvRetry methods of the SQLiteConnection class now return a SQLiteErrorCode instead of an integer error code.&nbsp;<b>** Potentially Incompatible Change **</b></li>
      <li>The public constructor for the SQLiteException now takes a SQLiteErrorCode instead of an integer error code.&nbsp;<b>** Potentially Incompatible Change **</b></li>
      <li>The ErrorCode property of the SQLiteException is now an Int32, to allow the property inherited from the base class to be properly overridden.&nbsp;<b>** Potentially Incompatible Change **</b></li>
      <li>The ErrorCode field of the LogEventArgs is now an object instead of an integer.&nbsp;<b>** Potentially Incompatible Change **</b></li>
      <li>The names and messages associated with the SQLiteErrorCode enumeration values have been normalized to match those in the SQLite core library.&nbsp;<b>** Potentially Incompatible Change **</b></li>
      <li>Implement more robust locking semantics for the CriticalHandle derived classes when compiled for the .NET Compact Framework.</li>
      <li>Cache column indexes are they are looked up when using the SQLiteDataReader to improve performance.</li>
      <li>Cache column indexes as they are looked up when using the SQLiteDataReader to improve performance.</li>
      <li>Prevent the SQLiteConnection.Close method from throwing non-fatal exceptions during its disposal.</li>
      <li>Rename the interop assembly functions sqlite3_cursor_rowid, sqlite3_context_collcompare, sqlite3_context_collseq, sqlite3_cursor_rowid, and sqlite3_table_cursor to include an &quot;_interop&quot; suffix.&nbsp;<b>** Potentially Incompatible Change **</b></li>
      <li>Prevent the LastInsertRowId, MemoryUsed, and MemoryHighwater connection properties from throwing NotSupportedException when running on the .NET Compact Framework. Fix for <a href="http://system.data.sqlite.org/index.html/info/dd45aba387">[dd45aba387]</a>.</li>
      <li>Improve automatic detection of the sqlite3_close_v2 function when compiled to use the standard SQLite library.</li>
      <li>Add protection against ThreadAbortException asynchronously interrupting native resource initialization and finalization.</li>
      <li>Add native logging callback for use with the sqlite3_log function to the interop assembly, enabled via the INTEROP_LOG preprocessor definition.</li>
      <li>Add various diagnostic messages to the interop assembly, enabled via flags in the INTEROP_DEBUG preprocessor definition.</li>
      <li>Further enhancements to the build and test automation.</li>
      <li>Add test automation for the Windows CE binaries.</li>
    </ul>
    <p><b>1.0.82.0 - September 3, 2012</b></p>
    <ul>
      <li>Updated to <a href="http://www.sqlite.org/releaselog/3_7_14.html">SQLite 3.7.14</a>.</li>
      <li>Properly handle quoted data source values in the connection string. Fix for <a href="http://system.data.sqlite.org/index.html/info/8c3bee31c8">[8c3bee31c8]</a>.</li>
      <li>The <a href="http://nuget.org/packages/System.Data.SQLite">primary NuGet package</a> now supports x86 / x64 and the .NET Framework 2.0 / 4.0 (i.e. in a single package).</li>
Changes to Doc/Extra/welcome.html.
156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
156
157
158
159
160
161
162

163
164
165
166
167
168
169
170







-
+







        <font color="red">
          Itanium processor support not currently included.
        </font>
      </p>
      <h1 class="heading">Distributing the Binaries (Compact Framework)</h1>
      <p>Both the <b>System.Data.SQLite.DLL </b>and <b>SQLite.Interop.XXX.DLL</b> files
        must be deployed on the Compact Framework.&nbsp; The XXX is the build number of
        the System.Data.SQLite library (e.g. &quot;083&quot;).&nbsp; The
        the System.Data.SQLite library (e.g. &quot;085&quot;).&nbsp; The
        <b>SQLite.Interop.XXX.DLL</b> file is a fully native assembly compiled for
        the ARM processor, and System.Data.SQLite is the fully-managed Compact
        Framework assembly.</p>
      <hr />
      <div id="footer">
        <p>
          <a href="mailto:sqlite-users@sqlite.org?subject=SQLite.NET%20Class%20Library%20Documentation%20Feedback:%20Welcome">
Changes to Doc/SQLite.NET.chm.

cannot compute difference between binary files

Changes to Externals/Eagle/bin/Eagle.dll.

cannot compute difference between binary files

Changes to Externals/Eagle/bin/EagleShell.exe.

cannot compute difference between binary files

Changes to Externals/Eagle/bin/EagleShell.exe.mda.config.
9
10
11
12
13
14
15
16


17
18
19
20
21
22
23
9
10
11
12
13
14
15

16
17
18
19
20
21
22
23
24







-
+
+







 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: $
 *
-->
<mdaConfig xmlns="http://schemas.microsoft.com/CLR/2004/10/mda">
  <assistants>
    <!--
    <!--++
    <asynchronousThreadAbort />
    <bindingFailure />
    <callbackOnCollectedDelegate listSize="50" />
    <contextSwitchDeadlock enable="true" />
    <dangerousThreadingAPI />
    <dateTimeInvalidLocalFormat />
    <dirtyCastAndCallOnInterface />
    <disconnectedContext enable="true" />
60
61
62
63
64
65
66

67
68
69
70
71
72
73
74
75
76
77
78
79
80

81
82
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

82
83
84







+













-
+


    <overlappedFreeError />
    <pInvokeLog>
      <filter>
        <match dllName="advapi32.dll" />
        <match dllName="advpack.dll" />
        <match dllName="kernel32.dll" />
        <match dllName="mscoree.dll" />
        <match dllName="msvcrt.dll" />
        <match dllName="ntdll.dll" />
        <match dllName="shell32.dll" />
        <match dllName="user32.dll" />
        <match dllName="wintrust.dll" />
      </filter>
    </pInvokeLog>
    <pInvokeStackImbalance />
    <raceOnRCWCleanup />
    <reentrancy />
    <releaseHandleFailed />
    <reportAvOnComRelease allowAv="true" />
    <streamWriterBufferedDataLost />
    <virtualCERCall />
    -->
    ++-->
  </assistants>
</mdaConfig>
Changes to Externals/Eagle/lib/Eagle1.0/init.eagle.
139
140
141
142
143
144
145
146

147
148
149
150
151
152
153
139
140
141
142
143
144
145

146
147
148
149
150
151
152
153







-
+







    set result ""; eval append result $args
  }

  proc lappendArgs { args } {
    #
    # NOTE: This should work properly in both Tcl and Eagle.
    #
    eval lappend result $args
    set result [list]; eval lappend result $args
  }

  proc getDictionaryValue { dictionary name {default ""} {wrap ""} } {
    #
    # NOTE: Locate the named value we are interested in.  The dictionary must
    #       be a list with an even number of elements in the following format:
    #
975
976
977
978
979
980
981





982
983
984
985
986
987
988
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993







+
+
+
+
+







      # NOTE: We no longer need the collection of compiler errors;
      #       therefore, dispose it now.
      #
      unset errors; # dispose

      return $code
    }

    proc matchEnginePublicKeyToken { publicKeyToken } {
      return [expr {[string length $publicKeyToken] == 0 || \
          $publicKeyToken eq [info engine PublicKeyToken]}]
    }

    proc matchEngineName { name } {
      return [expr {[string length $name] == 0 || \
          $name eq [info engine Name]}]
    }

    proc matchEngineCulture { culture } {
1038
1039
1040
1041
1042
1043
1044
1045

1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057


1058
1059

1060
1061
1062
1063



1064
1065

1066
1067

1068
1069
1070


1071
1072

1073
1074
1075
1076
1077
1078
1079
1080
1081


1082
1083
1084
1085
1086
1087
1088
1043
1044
1045
1046
1047
1048
1049

1050












1051
1052
1053

1054




1055
1056
1057
1058

1059


1060



1061
1062


1063





1064
1065


1066
1067
1068
1069
1070
1071
1072
1073
1074







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

-
+
-
-
-
-
+
+
+

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


-
-
+
+







              set components [list $baseUri releases $patchLevel]

              #
              # NOTE: Next, figure out what type of download is being
              #       requested.
              #
              switch -exact -nocase -- $type {
                source {
                source -
                  #
                  # NOTE: Source code download.  This may be a RAR or an EXE
                  #       file.  Append the appropriate file name and then
                  #       join all the URI components to form the final URI.
                  #
                  set fileName [appendArgs EagleSource $patchLevel $extension]
                  lappend components $fileName

                  set result [list [eval uri join $components] \
                      [file join $directory $fileName]]
                }
                setup {
                setup -
                binary {
                  #
                  # NOTE: Windows setup download.  Always append an ".exe"
                  # NOTE: Source code, setup, or binary download.  This may be
                  #       extension because we never distribute the setup as
                  #       a RAR file.  Append the appropriate file name and
                  #       then join all the URI components to form the final
                  #       URI.
                  #       a RAR or an EXE file.  Append the appropriate file
                  #       name and then join all the URI components to form the
                  #       final URI.
                  #
                  set fileName [appendArgs EagleSetup $patchLevel .exe]
                  set fileName [appendArgs \
                  lappend components $fileName

                      [info engine] [string totitle $type] $patchLevel \
                  set result [list [eval uri join $components] \
                      [file join $directory $fileName]]
                }
                      [expr {[string tolower $type] eq "setup" ? ".exe" : \
                      $extension}]]
                binary {
                  #

                  # NOTE: Binary file download.  This may be a RAR or an EXE
                  #       file.  Append the appropriate file name and then
                  #       join all the URI components to form the final URI.
                  #
                  set fileName [appendArgs EagleBinary $patchLevel $extension]
                  lappend components $fileName

                  set result [list [eval uri join $components] \
                      [file join $directory $fileName]]
                  set result [list [eval uri join $components] [file join \
                      $directory $fileName]]
                }
              }
            }
          }
        }
      }

1248
1249
1250
1251
1252
1253
1254
1255

1256
1257
1258
1259
1260
1261
1262
1234
1235
1236
1237
1238
1239
1240

1241
1242
1243
1244
1245
1246
1247
1248







-
+







            #       make sure we get the same "flavor" of the engine.
            #       The lines are organized so that the "latest stable
            #       version" is on the first line (for a given public key
            #       token), followed by development builds, experimental
            #       builds, etc.
            #
            if {$protocolId eq "1" && \
                $publicKeyToken eq [info engine PublicKeyToken] && \
                [matchEnginePublicKeyToken $publicKeyToken] && \
                [matchEngineName $name] && \
                [matchEngineCulture $culture]} then {
              #
              # NOTE: Grab the patch level field.
              #
              set patchLevel [lindex $fields 4]

1437
1438
1439
1440
1441
1442
1443
1444
1445


1446
1447
1448


1449
1450
1451
1452
1453
1454
1455
1423
1424
1425
1426
1427
1428
1429


1430
1431
1432


1433
1434
1435
1436
1437
1438
1439
1440
1441







-
-
+
+

-
-
+
+








        #
        # HACK: Mono does not currently support calling the String.Format
        #       overload that takes a variable number of arguments via
        #       reflection (Mono bug #636939).
        #
        if {![isMono]} then {
          set line [string format -verbatim -- "{0,-$maxLength} = {1}" \
              $nameString $valueString]
          set line [string format -verbatim -- [appendArgs "\{0,-" \
              $maxLength "\} = {1}"] $nameString $valueString]
        } else {
          set line [object invoke String Format "{0,-$maxLength} = {1}" \
              $nameString $valueString]
          set line [object invoke String Format [appendArgs "\{0,-" \
              $maxLength "\} = {1}"] $nameString $valueString]
        }

        puts stdout $line
      }
    }

    proc pdict { d } {
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
1575


1576
1577
1578
1579
1580
1581

1582
1583
1584
1585
1586
1587
1588
1589
1590







1591
1592
1593
1594

1595






1596
1597


1598
1599
1600
1601
1602
1603

1604
1605
1606
1607
1608
1609
1610


1611
1612
1613
1614
1615
1616

1617
1618
1619
1620
1621
1622
1623
1624
1625







1626
1627
1628
1629

1630






1631
1632


1633
1634
1635
1636
1637
1638

1639
1640
1641
1642
1643
1644
1645


1646
1647
1648
1649
1650
1651

1652
1653
1654
1655
1656
1657
1658
1533
1534
1535
1536
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


1570
1571
1572
1573
1574
1575
1576

1577
1578
1579
1580
1581
1582


1583
1584
1585
1586
1587
1588
1589

1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609

1610
1611
1612
1613
1614
1615
1616
1617


1618
1619
1620
1621
1622
1623
1624

1625
1626
1627
1628
1629
1630


1631
1632
1633
1634
1635
1636
1637

1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657

1658
1659
1660
1661
1662
1663
1664
1665


1666
1667
1668
1669
1670
1671
1672

1673
1674
1675
1676
1677
1678


1679
1680
1681
1682
1683
1684
1685

1686
1687
1688
1689
1690
1691
1692
1693








+
+
+
+
+
+
+
+
+
+

+
+
+
+
+
+
+



-
+

+
+
+
+
+
+
-
-
+
+





-
+





-
-
+
+





-
+









+
+
+
+
+
+
+



-
+

+
+
+
+
+
+
-
-
+
+





-
+





-
-
+
+





-
+









+
+
+
+
+
+
+



-
+

+
+
+
+
+
+
-
-
+
+





-
+





-
-
+
+





-
+








    proc tclLog { string } {
      #
      # NOTE: This should work properly in both Tcl and Eagle.
      #
      catch {puts stderr $string}
    }

    proc makeVariableFast { name fast } {
      #
      # NOTE: This should work properly in Eagle only.
      #
      catch {
        uplevel 1 [list object invoke -flags +NonPublic \
            Interpreter.GetActive MakeVariableFast $name $fast]
      }
    }

    proc findDirectories { pattern } {
      #
      # NOTE: Block non-Windows platforms since this is Windows specific.
      #
      if {$::tcl_platform(platform) ne "windows"} then {
        error "not supported on this operating system"
      }

      #
      # NOTE: This should work properly in Eagle only.
      #
      set result [list]
      set dir ""; set result [list]

      #
      # HACK: Optimize the variable access in this procedure to be
      #       as fast as possible.
      #
      makeVariableFast dir true; makeVariableFast result true

      foreach dir [split [exec $::env(ComSpec) /c dir /ad /b \
          [appendArgs \" [file nativename $pattern] \"]] \n] {
      foreach dir [split [exec -unicode $::env(ComSpec) /u /c dir \
          /ad /b [appendArgs \" [file nativename $pattern] \"]] \n] {
        set dir [string trim $dir]

        if {[string length $dir] > 0} then {
          set dir [getDirResultPath $pattern $dir]

          if {[lsearch -exact -nocase $result $dir] == -1} then {
          if {[lsearch -variable -exact -nocase result $dir] == -1} then {
            lappend result $dir
          }
        }
      }

      foreach dir [split [exec $::env(ComSpec) /c dir /ahd /b \
          [appendArgs \" [file nativename $pattern] \"]] \n] {
      foreach dir [split [exec -unicode $::env(ComSpec) /u /c dir \
          /ahd /b [appendArgs \" [file nativename $pattern] \"]] \n] {
        set dir [string trim $dir]

        if {[string length $dir] > 0} then {
          set dir [getDirResultPath $pattern $dir]

          if {[lsearch -exact -nocase $result $dir] == -1} then {
          if {[lsearch -variable -exact -nocase result $dir] == -1} then {
            lappend result $dir
          }
        }
      }

      return $result
    }

    proc findFiles { pattern } {
      #
      # NOTE: Block non-Windows platforms since this is Windows specific.
      #
      if {$::tcl_platform(platform) ne "windows"} then {
        error "not supported on this operating system"
      }

      #
      # NOTE: This should work properly in Eagle only.
      #
      set result [list]
      set fileName ""; set result [list]

      #
      # HACK: Optimize the variable access in this procedure to be
      #       as fast as possible.
      #
      makeVariableFast fileName true; makeVariableFast result true

      foreach fileName [split [exec $::env(ComSpec) /c dir /a-d /b \
          [appendArgs \" [file nativename $pattern] \"]] \n] {
      foreach fileName [split [exec -unicode $::env(ComSpec) /u /c dir \
          /a-d /b [appendArgs \" [file nativename $pattern] \"]] \n] {
        set fileName [string trim $fileName]

        if {[string length $fileName] > 0} then {
          set fileName [getDirResultPath $pattern $fileName]

          if {[lsearch -exact -nocase $result $fileName] == -1} then {
          if {[lsearch -variable -exact -nocase result $fileName] == -1} then {
            lappend result $fileName
          }
        }
      }

      foreach fileName [split [exec $::env(ComSpec) /c dir /ah-d /b \
          [appendArgs \" [file nativename $pattern] \"]] \n] {
      foreach fileName [split [exec -unicode $::env(ComSpec) /u /c dir \
          /ah-d /b [appendArgs \" [file nativename $pattern] \"]] \n] {
        set fileName [string trim $fileName]

        if {[string length $fileName] > 0} then {
          set fileName [getDirResultPath $pattern $fileName]

          if {[lsearch -exact -nocase $result $fileName] == -1} then {
          if {[lsearch -variable -exact -nocase result $fileName] == -1} then {
            lappend result $fileName
          }
        }
      }

      return $result
    }

    proc findFilesRecursive { pattern } {
      #
      # NOTE: Block non-Windows platforms since this is Windows specific.
      #
      if {$::tcl_platform(platform) ne "windows"} then {
        error "not supported on this operating system"
      }

      #
      # NOTE: This should work properly in Eagle only.
      #
      set result [list]
      set fileName ""; set result [list]

      #
      # HACK: Optimize the variable access in this procedure to be
      #       as fast as possible.
      #
      makeVariableFast fileName true; makeVariableFast result true

      foreach fileName [split [exec $::env(ComSpec) /c dir /a-d /s /b \
          [appendArgs \" [file nativename $pattern] \"]] \n] {
      foreach fileName [split [exec -unicode $::env(ComSpec) /u /c dir \
          /a-d /s /b [appendArgs \" [file nativename $pattern] \"]] \n] {
        set fileName [string trim $fileName]

        if {[string length $fileName] > 0} then {
          set fileName [getDirResultPath $pattern $fileName]

          if {[lsearch -exact -nocase $result $fileName] == -1} then {
          if {[lsearch -variable -exact -nocase result $fileName] == -1} then {
            lappend result $fileName
          }
        }
      }

      foreach fileName [split [exec $::env(ComSpec) /c dir /ah-d /s /b \
          [appendArgs \" [file nativename $pattern] \"]] \n] {
      foreach fileName [split [exec -unicode $::env(ComSpec) /u /c dir \
          /ah-d /s /b [appendArgs \" [file nativename $pattern] \"]] \n] {
        set fileName [string trim $fileName]

        if {[string length $fileName] > 0} then {
          set fileName [getDirResultPath $pattern $fileName]

          if {[lsearch -exact -nocase $result $fileName] == -1} then {
          if {[lsearch -variable -exact -nocase result $fileName] == -1} then {
            lappend result $fileName
          }
        }
      }

      return $result
    }
1702
1703
1704
1705
1706
1707
1708







1709
1710
1711
1712
1713
1714
1715
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757







+
+
+
+
+
+
+







      eval lappend result [glob -nocomplain -types {f hidden} \
          [file normalize $pattern]]

      return $result
    }

    proc findFilesRecursive { pattern } {
      #
      # NOTE: Block non-Windows platforms since this is Windows specific.
      #
      if {$::tcl_platform(platform) ne "windows"} then {
        error "not supported on this operating system"
      }

      #
      # NOTE: This should work properly in Tcl only.
      #
      set result [list]

      catch {
        foreach fileName [split [exec $::env(ComSpec) /c dir /a-d /s /b \
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799









1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1831
1832
1833
1834
1835
1836
1837




1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859







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













    }

    #
    # NOTE: Exports the necessary commands from this package and import them
    #       into the global namespace.
    #
    exportAndImportPackageCommands [namespace current] [list \
        exportAndImportPackageCommands isEagle isMono getEnvironmentVariable \
        getPluginPath getDictionaryValue getColumnValue getRowColumnValue \
        appendArgs haveGaruda lappendArgs readFile filter map reduce \
        getPlatformInfo execShell combineFlags tqputs tqlog] false false
        isEagle haveGaruda isMono getEnvironmentVariable combineFlags \
        getCompileInfo getPlatformInfo getPluginPath appendArgs lappendArgs \
        getDictionaryValue getColumnValue getRowColumnValue tqputs tqlog \
        readFile readSharedFile writeFile appendFile appendLogFile \
        appendSharedFile appendSharedLogFile readAsciiFile writeAsciiFile \
        readUnicodeFile writeUnicodeFile getDirResultPath addToPath \
        removeFromPath execShell ldifference filter map reduce \
        getLengthModifier debug findDirectories findFiles findFilesRecursive \
        exportAndImportPackageCommands] false false

    ###########################################################################
    ############################## END Tcl ONLY ###############################
    ###########################################################################
  }

  #
  # NOTE: Provide the Eagle library package to the interpreter.
  #
  package provide Eagle.Library \
    [expr {[isEagle] ? [info engine PatchLevel] : "1.0"}]
}

Changes to Externals/Eagle/lib/Eagle1.0/test.eagle.
295
296
297
298
299
300
301
302

303
304

305
306
307
308
309

310
311
312
313
314
315
316
295
296
297
298
299
300
301

302
303

304
305
306
307
308

309
310
311
312
313
314
315
316







-
+

-
+




-
+








      #
      # NOTE: Calculate how many whole seconds we need to spin for.
      #
      set seconds [expr {$milliseconds / 1000}]

      #
      # NOTE: Calculate the value of [clock seconds] now and at the stop time.
      # NOTE: Calculate the starting and ending values of [clock seconds].
      #
      set start [clock seconds]; set stop [expr {$start + $seconds}]
      set now [clock seconds]; set start $now; set stop [expr {$now + $seconds}]

      #
      # NOTE: Do nothing for X seconds (i.e. except call [clock seconds]).
      #
      while {$start <= [clock seconds] && [clock seconds] < $stop} {}
      while {$start <= $now && $now < $stop} {set now [clock seconds]}

      #
      # NOTE: Record the final Tcl command count.
      #
      set after [info cmdcount]

      #
385
386
387
388
389
390
391
392

393
394
395
396
397
398
399
385
386
387
388
389
390
391

392
393
394
395
396
397
398
399







-
+







    upvar 1 $varName array

    #
    # TODO: Add more support for standard tcltest options here.
    #
    set options [list -configuration -constraints -exitOnComplete -file \
        -logFile -match -no -notFile -postTest -preTest -skip -stopOnFailure \
        -suffix -threshold]
        -suffix -tclsh -threshold]

    foreach {name value} $args {
      #
      # NOTE: Use the [tqputs] command here just in case the test log file
      #       has not been setup yet (i.e. by default, this procedure is
      #       almost always called by the test prologue file prior to the
      #       test log file having been setup and we do not want to just
413
414
415
416
417
418
419



























420
421
422
423
424
425
426
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
443
444
445
446
447
448
449
450
451
452
453







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







    }

    #
    # NOTE: Now, attempt to flush the test log queue, if available.
    #
    tlog ""
  }

  proc getTclShellFileName {} {
    #
    # NOTE: Check the environment variables we know about that
    #       may contain the path where the Tcl shell is located.
    #
    foreach name [list Eagle_Tcl_Shell Tcl_Shell] {
      set value [getEnvironmentVariable $name]

      #
      # TODO: Possibly add a check if the file actually exists
      #       here.
      #
      if {[string length $value] > 0} then {
        #
        # NOTE: *EXTERNAL* Return verbatim, no normalization.
        #
        return $value
      }
    }

    #
    # NOTE: None of the environment variables returned anything
    #       valid, return the fallback default.
    #
    return tclsh
  }

  proc getTemporaryPath {} {
    #
    # NOTE: Build the list of "temporary directory" override
    #       environment variables to check.
    #
    set names [list]
675
676
677
678
679
680
681
682

683
684
685
686
687
688
689
702
703
704
705
706
707
708

709
710
711
712
713
714
715
716







-
+







    #
    proc [namespace current]::testPuts { args } {
      switch [llength $args] {
        1 {
          #
          # NOTE: Only the string to be printed is specified (stdout).
          #
          return [tputs $::test_channel [lindex $args 0]]
          return [tputs $::test_channel [appendArgs [lindex $args 0] \n]]
        }
        2 {
          #
          # NOTE: Either -nonewline or channelId has been specified.
          #
          if {[lindex $args 0] eq "-nonewline"} then {
            return [tputs $::test_channel [lindex $args end]]
920
921
922
923
924
925
926
927

928
929
930
931
932

933
934
935
936
937
938
939
947
948
949
950
951
952
953

954
955
956
957
958

959
960
961
962
963
964
965
966







-
+




-
+







        incr count

        tputs $channel [appendArgs "==== \"" $fileName "\" LEAKED " \
            $statistic \n]

        if {[info exists array($statistic,before,list)]} then {
          tputs $channel [appendArgs "---- " $statistic " BEFORE: " \
              $array($statistic,before,list) \n]
              [formatList $array($statistic,before,list)] \n]
        }

        if {[info exists array($statistic,after,list)]} then {
          tputs $channel [appendArgs "---- " $statistic " AFTER: " \
              $array($statistic,after,list) \n]
              [formatList $array($statistic,after,list)] \n]
        }
      }
    }

    #
    # NOTE: Make sure this file name is recorded in the list of file names with
    #       leaking tests.
1087
1088
1089
1090
1091
1092
1093
1094

1095
1096
1097

1098
1099
1100
1101
1102
1103
1104
1114
1115
1116
1117
1118
1119
1120

1121
1122
1123

1124
1125
1126
1127
1128
1129
1130
1131







-
+


-
+







    #
    # NOTE: Show the exact arguments we received since they may not
    #       have been displayed by the caller (or anybody else).
    #
    tputs $channel [appendArgs "---- test run path: \"" $path \"\n]

    tputs $channel [appendArgs "---- test run file names: " \
        [list [removePathFromFileNames $path $fileNames]] \n]
        [formatList [removePathFromFileNames $path $fileNames]] \n]

    tputs $channel [appendArgs "---- test run skip file names: " \
        [list $skipFileNames] \n]
        [formatList $skipFileNames] \n]

    #
    # NOTE: Keep going unless this becomes true (i.e. if one of the
    #       test files signals us to stop).
    #
    set stop false

1289
1290
1291
1292
1293
1294
1295






1296
1297
1298
1299
1300
1301
1302
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335







+
+
+
+
+
+







            #
            # NOTE: Determine if any resource leaks have occurred and
            #       output diagnostics as necessary if they have.
            #
            reportTestStatistics $channel $fileName leaks leaked
          }
        } else {
          #
          # NOTE: This entire file has been skipped.  Record that fact in the
          #       test suite log file.
          #
          tputs $channel [appendArgs "==== \"" $fileName "\" NON_TEST_FILE\n"]

          #
          # NOTE: This file does not actually count towards the total (i.e.
          #       it contains no actual tests).
          #
          incr total -1
        }

1318
1319
1320
1321
1322
1323
1324






1325
1326
1327
1328
1329
1330
1331
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370







+
+
+
+
+
+







        #       test failure with the stop-on-failure flag enabled),
        #       break out of the test loop now.
        #
        if {$stop} then {
          break
        }
      } else {
        #
        # NOTE: This entire file has been skipped.  Record that fact in the
        #       test suite log file.
        #
        tputs $channel [appendArgs "==== \"" $fileName "\" SKIPPED\n"]

        #
        # NOTE: This file does not actually count towards the total (i.e.
        #       it is part of the test suite infrastructure).
        #
        incr total -1
      }

1352
1353
1354
1355
1356
1357
1358
1359


1360
1361
1362
1363


1364
1365
1366
1367
1368
1369
1370
1391
1392
1393
1394
1395
1396
1397

1398
1399
1400
1401
1402

1403
1404
1405
1406
1407
1408
1409
1410
1411







-
+
+



-
+
+







    tputs $channel [appendArgs "---- sourced " $count " test " \
        [expr {$count > 1 ? "files" : "file"}] \n]

    #
    # NOTE: Show the files that had failing and/or leaking tests.
    #
    if {[llength $failed] > 0} then {
      tputs $channel [appendArgs "---- files with failing tests: " $failed \n]
      tputs $channel [appendArgs "---- files with failing tests: " \
          [formatList $failed] \n]
    }

    if {[llength $leaked] > 0} then {
      tputs $channel [appendArgs "---- files with leaking tests: " $leaked \n]
      tputs $channel [appendArgs "---- files with leaking tests: " \
          [formatList $leaked] \n]
    }
  }

  proc configureTcltest { constraints imports force } {
    if {[isEagle]} then {
      #
      # HACK: Flag the "test" and "runTest" script library procedures so
1712
1713
1714
1715
1716
1717
1718






1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730



































































1731
1732
1733
1734
1735
1736
1737
1738
1739

1740
1741
1742
1743


1744
1745
1746
1747
1748


1749
1750
1751
1752
1753
1754



1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852

1853

1854


1855
1856





1857
1858






1859
1860
1861




1862
1863
1864
1865
1866
1867
1868







+
+
+
+
+
+












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








-
+
-

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







          # NOTE: Delete the temporary file we used to query the machine
          #       type for the native Tcl shell.
          #
          catch {file delete $fileName}
        }
      }
    }

    proc getCommandsForTclShell {} {
      return [testExecTclScript {
        puts -nonewline stdout [info commands]
      }]
    }

    proc getMachineForTclShell {} {
      return [testExecTclScript {
        puts -nonewline stdout $tcl_platform(machine)
      }]
    }

    proc getTkVersion {} {
      return [testExecTclScript {
        puts -nonewline stdout [package require Tk]; exit
      }]
    }

    proc getTestConfiguration {} {
      #
      # NOTE: Determine the effective test configuration and return it.  If
      #       the test configuration cannot be determined, return an empty
      #       string.
      #
      if {[info exists ::test_flags(-configuration)] && \
          [string length $::test_flags(-configuration)] > 0} then {
        #
        # NOTE: The test configuration has been manually overridden via the
        #       test flags; therefore, use it.
        #
        return $::test_flags(-configuration)
      } elseif {[info exists ::test_configuration]} then {
        #
        # NOTE: Use the test configuration.  The default value is "Release",
        #       as set by the test suite prologue; however, this may have
        #       been overridden.
        #
        return $::test_configuration
      } elseif {[info exists ::eagle_platform(configuration)]} then {
        #
        # NOTE: Use the build configuration of Eagle itself.  This value will
        #       always be "Debug" or "Release".
        #
        return $::eagle_platform(configuration)
      } else {
        #
        # NOTE: We are missing the configuration, return nothing.
        #
        return ""
      }
    }

    proc getTestSuffix {} {
      #
      # NOTE: Determine the effective test suffix and return it.  If
      #       the test suffix cannot be determined, return an empty
      #       string.
      #
      if {[info exists ::test_flags(-suffix)] && \
          [string length $::test_flags(-suffix)] > 0} then {
        #
        # NOTE: The test suffix has been manually overridden via the
        #       test flags; therefore, use it.
        #
        return $::test_flags(-suffix)
      } elseif {[info exists ::test_suffix]} then {
        #
        # NOTE: Use the test suffix.  There is no default value for
        #       this variable (i.e. by default, it does not exist).
        #
        return $::test_suffix
      } elseif {[info exists ::eagle_platform(text)]} then {
        #
        # NOTE: Use the build text of Eagle itself.  This value will
        #       typically be "NetFx20" or "NetFx40".
        #
        return $::eagle_platform(text)
      } else {
        #
        # NOTE: We are missing the suffix, return nothing.
        #
        return ""
      }
    }

    proc getGarudaDll {} {
      #
      # NOTE: Get the Garuda DLL of the same platform (i.e. machine type)
      #       as the native Tcl shell.
      #
      if {[info exists ::base_path]} then {
        #
        # NOTE: If the test configuration is available, use it.  Failing that,
        # NOTE: Get the effective test configuration.
        #       use the build configuration of Eagle itself.
        #
        if {[info exists ::test_configuration]} then {
          #
        set configuration [getTestConfiguration]

          # NOTE: Use the test configuration.  The default value is "Release",
          #       as set by the test suite prologue; however, this may have
          #       been overridden.
          #
          set configuration $::test_configuration
        #
        # NOTE: If there is no effective test configuration available, we
        } elseif {[info exists ::eagle_platform(configuration)]} then {
          #
          # NOTE: Use the build configuration of Eagle itself.  This value will
          #       always be "Debug" or "Release".
          #
          set configuration $::eagle_platform(configuration)
        #       cannot continue.
        #
        if {[string length $configuration] == 0} then {
        } else {
          #
          # NOTE: We are missing the configuration, return nothing.
          #
          return ""
        }

        #
        # NOTE: Build the full path and file name of the Garuda DLL, using
        #       the Eagle base path.  Currently, this will only work
        #       correctly if the test suite is being run from inside the
1967
1968
1969
1970
1971
1972
1973
1974
1975


1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
2070
2071
2072
2073
2074
2075
2076


2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091







-
-
+
+













    exportAndImportPackageCommands [namespace current] [list addConstraint \
        calculateRelativePerformance haveConstraint haveOrAddConstraint \
        processTestArguments getTemporaryPath getTestLog getTestLogId getFiles \
        getConstraints getTestFiles getTestRunId execTestShell runTestPrologue \
        runTestEpilogue runTest runAllTests fixConstraints sourceIfValid \
        isExitOnComplete getPassPercentage getSkipPercentage testExec tlog \
        returnInfoScript tputs formatDecimal formatList configureTcltest \
        calculateBogoCops removeConstraint machineToPlatform tsource testShim] \
        false false
        calculateBogoCops removeConstraint machineToPlatform tsource testShim \
        getTestConfiguration getTestSuffix getTclShellFileName] false false

    ###########################################################################
    ############################## END Tcl ONLY ###############################
    ###########################################################################
  }

  #
  # NOTE: Provide the Eagle test package to the interpreter.
  #
  package provide Eagle.Test \
    [expr {[isEagle] ? [info engine PatchLevel] : "1.0"}]
}

Changes to Externals/Eagle/lib/Eagle1.0/vendor.eagle.
40
41
42
43
44
45
46

47
48




49
50
51
52
53
54
55
40
41
42
43
44
45
46
47


48
49
50
51
52
53
54
55
56
57
58







+
-
-
+
+
+
+







        if {![uplevel 1 [list info exists $varName]]} then {
          continue
        }

        incr result

        if {!$quiet} then {
          catch {
          tqputs $channel [appendArgs \
              "---- found vendor-specific test override \"" $varName "\".\n"]
            tqputs $channel [appendArgs \
                "---- found vendor-specific test override \"" $varName \
                "\" with value \"" [uplevel 1 [list set $varName]] \"\n]
          }
        }
      }

      #
      # NOTE: Keep track of the list of test override variables, for later
      #       use by the test suite.  This needs to be done after the loop
      #       above because the variable used to keep track is listed with
105
106
107
108
109
110
111

112
113
114




115
116
117
118
119
120
121
108
109
110
111
112
113
114
115



116
117
118
119
120
121
122
123
124
125
126







+
-
-
-
+
+
+
+







          #
          if {![info exists ::env(EAGLELIBPATH)] || \
              [lsearch -exact $::env(EAGLELIBPATH) $dir2] == -1} then {
            #
            # NOTE: If we have NOT been instructed to be quiet, report now.
            #
            if {!$quiet} then {
              catch {
              tqputs $channel [appendArgs \
                  "---- found vendor-specific test package directory \"" \
                  $dir2 "\", adding...\n"]
                tqputs $channel [appendArgs \
                    "---- found vendor-specific test package directory \"" \
                    $dir2 "\", adding...\n"]
              }
            }

            #
            # NOTE: Append the directory to the necessary environment variable
            #       so that it will get picked up when Eagle actually rebuilds
            #       the auto-path list (below).
            #
140
141
142
143
144
145
146

147
148



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

165
166



167
168
169
170
171
172
173
174
175
176
177
178
179
180


181
182
183
184
185
186
187
145
146
147
148
149
150
151
152


153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172


173
174
175
176
177
178
179
180
181
182
183
184
185
186
187


188
189
190
191
192
193
194
195
196







+
-
-
+
+
+
















+
-
-
+
+
+












-
-
+
+







        set dir [file dirname $dir]
      }

      #
      # NOTE: If we have NOT been instructed to be quiet, report now.
      #
      if {!$quiet} then {
        catch {
        tqputs $channel \
            "---- could not find vendor-specific test package directory.\n"
          tqputs $channel \
              "---- could not find vendor-specific test package directory\n"
        }
      }

      #
      # NOTE: Directory not found, return failure.
      #
      return false
    }

    proc setupInterpreterTestPath { channel dir quiet } {
      set testPath [object invoke -flags +NonPublic Interpreter.GetActive \
          TestPath]

      if {$dir ne $testPath} then {
        object invoke -flags +NonPublic Interpreter.GetActive TestPath $dir

        if {!$quiet} then {
          catch {
          tqputs $channel [appendArgs \
              "---- set interpreter test path to \"" $dir \".\n]
            tqputs $channel [appendArgs \
                "---- set interpreter test path to \"" $dir \"\n]
          }
        }
      }
    }

    #
    # NOTE: Check for any overridden settings that may have been specified via
    #       the command line, etc.
    #
    checkForTestOverrides stdout [expr {[info exists test_overrides] ? \
        $test_overrides : [list binary_directory build_base_directory \
        build_directory common_directory connection_flags database_directory \
        datetime_format scratch_directory temporary_directory \
        test_configuration test_overrides test_year test_year_clr_v2 \
        test_year_clr_v4 vendor_directory]}] false
        test_configuration test_constraints test_overrides test_year \
        test_year_clr_v2 test_year_clr_v4 vendor_directory]}] false

    #
    # NOTE: This variable will contain the name of the directory containing the
    #       vendor-specific testing infrastructure.  If the variable does not
    #       already exist, create it; otherwise, it has been overridden and the
    #       existing value should be left intact.
    #
Changes to Externals/Eagle/lib/Test1.0/constraints.eagle.
24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
24
25
26
27
28
29
30

31
32
33
34
35
36
37
38







-
+







    tputs $channel "---- checking for platform... "

    if {[info exists ::tcl_platform(platform)]} then {
      addConstraint $::tcl_platform(platform)

      tputs $channel [appendArgs $::tcl_platform(platform) \n]
    } else {
      tputs $channel [appendArgs unknown \n]
      tputs $channel unknown\n
    }

    ###########################################################################

    if {![isEagle]} then {
      #
      # BUGFIX: We do not normally want to skip any Mono bugs in native Tcl.
56
57
58
59
60
61
62














































63
64
65
66
67
68
69
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
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







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







        #
        foreach constraint $constraints {
          addConstraint $constraint
        }
      }
    }
  }

  proc checkForScriptLibrary { channel } {
    tputs $channel "---- checking for script library... "

    #
    # NOTE: See if the variable containing the script library location
    #       exists.
    #
    if {[info exists ::tcl_library] && \
        [string length $::tcl_library] > 0} then {
      #
      # NOTE: Now see if the script library is external or embedded.
      #
      if {[file isdirectory $::tcl_library]} then {
        #
        # NOTE: Yes, it appears to be a directory name, which should
        #       mean that the necessary files are physically contained
        #       within it.
        #
        addConstraint tcl_library_external

        tputs $channel "yes (external)\n"

        #
        # NOTE: We are done here, return now.
        #
        return
      } elseif {[file isfile $::tcl_library]} then {
        #
        # NOTE: Yes, it appears to be a file name, which should mean
        #       that the necessary files are physically embedded within
        #       it.
        #
        addConstraint tcl_library_embedded

        tputs $channel "yes (embedded)\n"

        #
        # NOTE: We are done here, return now.
        #
        return
      }
    }

    tputs $channel no\n
  }

  proc checkForVariable { channel name {notEmpty true} {constraint ""} } {
    tputs $channel [appendArgs "---- checking for variable \"" $name \
        "\"... "]

    #
    # NOTE: First, normalize the variable name to be in the global scope.
548
549
550
551
552
553
554
555

556
557
558
559
560
561
562











563



564
565
566
567
568
569
570
594
595
596
597
598
599
600

601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619

620
621
622
623
624
625
626
627
628
629







-
+







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







      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForTestConfiguration { channel } {
    tputs $channel [appendArgs "---- checking for test configuration... "]
    tputs $channel "---- checking for test configuration... "

    if {[info exists ::test_configuration] && \
        [string length $::test_configuration] > 0} then {
      addConstraint [appendArgs configuration. $::test_configuration]

      tputs $channel [appendArgs $::test_configuration \n]
    } else {
      tputs $channel unknown\n
    }
  }

  proc checkForTestSuffix { channel } {
    tputs $channel "---- checking for test suffix... "

    if {[info exists ::test_suffix] && \
        [string length $::test_suffix] > 0} then {
      addConstraint [appendArgs suffix. $::test_suffix]

      tputs $channel [appendArgs unknown \n]
      tputs $channel [appendArgs $::test_suffix \n]
    } else {
      tputs $channel unknown\n
    }
  }

  proc checkForFile { channel name {constraint ""} } {
    tputs $channel [appendArgs "---- checking for file \"" $name \
        "\"... "]

771
772
773
774
775
776
777

















778
779
780
781
782
783
784
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860







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







      addConstraint tip285

      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForTip405 { channel } {
    tputs $channel "---- checking for TIP #405... "

    #
    # NOTE: Does the interpreter have TIP #405 (i.e. [lmap])?
    #
    catch {lmap} error

    if {$error ne "invalid command name \"lmap\""} then {
      addConstraint tip405

      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForTiming {
          channel threshold {constraint ""} {tries 1} {delay 1000}
          {asynchronous false} } {
    tputs $channel [appendArgs \
        "---- checking for precision timing (threshold of " $threshold \
        " milliseconds, delay of " $delay " milliseconds)... "]
863
864
865
866
867
868
869















870
871
872
873
874
875
876
877
878
879
880
881
882
883
884































885
886
887
888
889
890
891
939
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
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013







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















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







      addConstraint performance

      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForStackIntensive { channel } {
    tputs $channel "---- checking for stack intensive testing... "

    #
    # NOTE: Are we allowed to do stack intensive testing?
    #
    if {![info exists ::no(stackIntensive)]} then {
      addConstraint stackIntensive

      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForInteractive { channel } {
    tputs $channel "---- checking for interactive user... "

    #
    # NOTE: Is there an interactive user?
    #
    if {[info exists ::tcl_interactive] && $::tcl_interactive} then {
      addConstraint interactive

      tputs $channel yes\n
    } else {
      tputs $channel no\n
    }
  }

  proc checkForInteractiveCommand { channel name } {
    tputs $channel [appendArgs "---- checking for interactive command \"" \
        $name "\"... "]

    #
    # NOTE: Currently, only Eagle has "interactive commands".
    #
    if {[isEagle]} then {
      #
      # NOTE: Attempt to query the interactive command names from Eagle.
      #
      if {[catch {object invoke Utility GetInteractiveCommandNames $name \
              false} names] == 0 && \
          [llength $names] > 0} then {
        #
        # NOTE: Yes, it appears that it is available.
        #
        addConstraint [appendArgs interactiveCommand. $name]

        tputs $channel yes\n

        #
        # NOTE: We are done here, return now.
        #
        return
      }
    }

    tputs $channel no\n
  }

  proc checkForUserInteraction { channel } {
    tputs $channel "---- checking for user interaction... "

    #
    # HACK: For now, do the exact same check as checkForInteractive; however,
    #       this is still useful as a separate constraint because it can be
1007
1008
1009
1010
1011
1012
1013
























































































1014
1015
1016
1017
1018
1019
1020
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
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
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
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230







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







        addConstraint softwareUpdate

        tputs $channel trusted\n
      } else {
        tputs $channel untrusted\n
      }
    }

    proc checkForManagedDebuggingAssistants { channel } {
      set fileName [file normalize [appendArgs [info nameofexecutable] \
          .mda.config]]

      tputs $channel [appendArgs \
          "---- checking for managed debugging assistants enabled via \"" \
          $fileName "\"... "]

      if {[file exists $fileName]} then {
        #
        # NOTE: Since the System.Xml assembly may not be loaded, wrap the
        #       detection in a [catch] block.
        #
        if {[catch {
          #
          # NOTE: Create and load an XML document based on the data from the
          #       MDA configuration file associated with the executable that
          #       started this process.
          #
          set document [object create -alias System.Xml.XmlDocument]
          $document LoadXml [readFile $fileName]

          #
          # NOTE: Setup the XML namespace manager for use when using XPath
          #       to query the XML document.
          #
          set nameTable [$document NameTable]

          set namespaceManager [object create \
              -alias System.Xml.XmlNamespaceManager $nameTable]

          $namespaceManager AddNamespace mda \
              http://schemas.microsoft.com/CLR/2004/10/mda

          #
          # NOTE: Select all nodes underneath the location where they should
          #       reside in the MDA configuration XML document.
          #
          set nodes [$document SelectNodes \
              /mda:mdaConfig/mda:assistants/* $namespaceManager]

          #
          # NOTE: Populate the local result variable with the names of
          #       all the XML nodes found.
          #
          set names [object lmap -alias node $nodes {
            $node Name
          }]
        }] == 0} then {
          #
          # NOTE: Ok, the XML configuration file was loaded and parsed
          #       correctly, see if any managed debugging assistants were
          #       found enabled within it.
          #
          if {[info exists names] && [llength $names] > 0} then {
            #
            # NOTE: Add a test constraint for each managed debugging
            #       assistant that appears to be enabled.
            #
            addConstraint mda

            foreach name $names {
              addConstraint [appendArgs mda. $name]
            }

            #
            # NOTE: Save the list of managed debugging assistants for
            #       later use by the test suite.
            #
            set ::test_mdas $names

            #
            # NOTE: Yes, it appears that at least one managed debugging
            #       assistant is enabled.
            #
            tputs $channel [appendArgs "yes (" $names ")\n"]

            #
            # NOTE: We are done here, return now.
            #
            return
          }
        }
      }

      tputs $channel no\n
    }

    proc checkForStrongName { channel } {
      tputs $channel "---- checking for strong name... "

      if {[catch {object invoke Interpreter.GetActive GetStrongName} \
              strongName] == 0 && \
          [string length $strongName] > 0} then {
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175






2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2374
2375
2376
2377
2378
2379
2380





2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399







-
-
-
-
-
+
+
+
+
+
+













    # NOTE: We need several of our test constraint related commands in the
    #       global namespace.
    #
    exportAndImportPackageCommands [namespace current] [list checkForPlatform \
        checkForEagle checkForGaruda checkForShell checkForDebug checkForTk \
        checkForVersion checkForCommand checkForFile checkForNativeCode \
        checkForTip127 checkForTip194 checkForTip241 checkForTip285 \
        checkForPerformance checkForTiming checkForInteractive checkForSymbols \
        checkForLogFile checkForNetwork checkForCompileOption \
        checkForWindowsCommandProcessor checkForUserInteraction \
        checkForTclOptions checkForTestConfiguration checkForVariable \
        checkForFossil] false false
        checkForTip405 checkForPerformance checkForTiming checkForInteractive \
        checkForSymbols checkForLogFile checkForNetwork checkForCompileOption \
        checkForInteractiveCommand checkForWindowsCommandProcessor \
        checkForUserInteraction checkForTclOptions checkForTestConfiguration \
        checkForTestSuffix checkForVariable checkForScriptLibrary \
        checkForStackIntensive checkForFossil] false false

    ###########################################################################
    ############################## END Tcl ONLY ###############################
    ###########################################################################
  }

  #
  # NOTE: Provide the Eagle test constraints package to the interpreter.
  #
  package provide Eagle.Test.Constraints \
    [expr {[isEagle] ? [info engine PatchLevel] : "1.0"}]
}

Changes to Externals/Eagle/lib/Test1.0/prologue.eagle.
18
19
20
21
22
23
24
25
26
27



28
29
30
31
32
33
34
18
19
20
21
22
23
24



25
26
27
28
29
30
31
32
33
34







-
-
-
+
+
+







  if {[info level] > 0} then {
    error "cannot run, current level is not global"
  }

  #
  # NOTE: Make sure all the variables used by this prologue are unset.
  #
  unset -nocomplain pkg_dir pattern exec dummy directory name value \
      expr publicKeyToken encoding memory stack drive server database \
      timeout user password percent checkout timeStamp
  unset -nocomplain pkg_dir pattern exec dummy directory name value expr \
      publicKeyToken encoding memory stack drive server database timeout \
      user password percent checkout timeStamp

  #
  # NOTE: Set the location of the test suite, if necessary.
  #
  if {![info exists test_path]} then {
    set test_path [file normalize [file dirname [info script]]]
  }
249
250
251
252
253
254
255

256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282







+


















-
+







  set test_flags(-constraints) [list]; # default to no manual constraints.
  set test_flags(-logFile) ""; # default to using standard log file naming.
  set test_flags(-threshold) ""; # default to requiring all tests to pass.
  set test_flags(-stopOnFailure) ""; # default to continue on failure.
  set test_flags(-exitOnComplete) ""; # default to not exit after complete.
  set test_flags(-preTest) ""; # default to not evaluating anything.
  set test_flags(-postTest) ""; # default to not evaluating anything.
  set test_flags(-tclsh) ""; # Tcl shell, default to empty.

  #
  # NOTE: Check for and process any command line arguments.
  #
  if {[info exists argv]} then {
    eval processTestArguments test_flags $argv

    if {[info exists test_flags(-no)] && \
        [string length $test_flags(-no)] > 0} then {
      #
      # NOTE: Set the test run restrictions based on the provided command line
      #       argument value (which is assumed to be a "dictionary-style" list
      #       containing name/value pairs to add to the global "no" array).
      #
      foreach {name value} $test_flags(-no) {
        set no($name) $value
      }

      unset name value
      unset -nocomplain name value
    }

    if {[info exists test_flags(-logFile)] && \
        [string length $test_flags(-logFile)] > 0} then {
      #
      # NOTE: Set the log file name to the one provided by the command line.
      #
331
332
333
334
335
336
337
338
339


340
341






342





343







344
345
346
347
348
349
350
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
361
362
363
364
365
366
367
368







-
-
+
+


+
+
+
+
+
+

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







  #       necessary.
  #
  if {![info exists test_configuration]} then {
    set test_configuration [getPlatformInfo configuration Release]
  }

  #
  # NOTE: Set the Tcl shell executable to use for those specialized
  #       tests that may require it, if necessary.
  # NOTE: Set the Tcl shell executable to use for those specialized tests that
  #       may require it, if necessary.
  #
  if {![info exists test_tclsh]} then {
    #
    # NOTE: When running in Eagle, more complex logic is required to determine
    #       the Tcl shell to use for the various tests that require it.  Also,
    #       this same logic is used with Tcl when it is not running from an
    #       instance of the Tcl shell executable.
    #
    if {[isEagle] || ![string match tclsh* $bin_file]} then {
      if {[info exists test_flags(-tclsh)] && \
          [string length $test_flags(-tclsh)] > 0} then {
        #
        # NOTE: Use the Tcl shell specified via the command line.
        #
      set test_tclsh tclsh
        set test_tclsh $test_flags(-tclsh)
      } else {
        #
        # NOTE: Check for a Tcl shell specified via the environment.
        #
        set test_tclsh [getTclShellFileName]
      }
    } else {
      set test_tclsh $bin_file
    }
  }

  #
  # NOTE: Has automatic log file naming been disabled?
426
427
428
429
430
431
432




433
434
435
436
437
438
439
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461







+
+
+
+








  tputs $test_channel [appendArgs "---- test channel: " \
      $test_channel \n]

  tputs $test_channel [appendArgs "---- test configuration: " \
      [expr {[info exists test_configuration] ? \
          $test_configuration : "<none>"}] \n]

  tputs $test_channel [appendArgs "---- test suffix: " \
      [expr {[info exists test_suffix] ? \
          $test_suffix : "<none>"}] \n]

  if {[isEagle]} then {
    catch {info engine PublicKeyToken} publicKeyToken

    if {[string length $publicKeyToken] == 0} then {
      #
      # NOTE: The Eagle core library is not strong name signed.  This is not an
855
856
857
858
859
860
861











862
863
864
865
866
867
868
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901







+
+
+
+
+
+
+
+
+
+
+







        #
        # NOTE: For tests "debug-1.1", "debug-2.1", "debug-3.1" and
        #       "debug-4.1".
        #
        checkForCompileOption $test_channel DEBUGGER
      }

      #
      # NOTE: Has application domain management support been enabled (at
      #       compile-time)?
      #
      if {![info exists no(compileAppDomains)]} then {
        #
        # NOTE: For test "interp-1.27".
        #
        checkForCompileOption $test_channel APPDOMAINS
      }

      #
      # NOTE: Has isolated interpreter support been enabled (at compile-time)?
      #
      if {![info exists no(compileIsolatedInterpreters)]} then {
        #
        # NOTE: For test "xaml-1.2".
        #
1149
1150
1151
1152
1153
1154
1155
1156

1157
1158
1159






1160
1161
1162
1163
1164
1165
1166
1182
1183
1184
1185
1186
1187
1188

1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205







-
+



+
+
+
+
+
+







        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestAddNamedFunction*

        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestRemoveNamedFunction*

        #
        # NOTE: For test "interp-1.18".
        # NOTE: For test "interp-1.19".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestAddNamedFunction2*

        #
        # NOTE: For tests "function-5.*".
        #
        checkForObjectMember $test_channel Eagle._Tests.Default \
            *TestAddNamedFunction3*
      }

      #
      # NOTE: Has write-box testing support been disabled?
      #
      if {![info exists no(testWriteBox)]} then {
        #
1506
1507
1508
1509
1510
1511
1512








1513
1514
1515
1516
1517
1518
1519
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566







+
+
+
+
+
+
+
+







    #
    # NOTE: Has managed debugger testing support been disabled?
    #
    if {![info exists no(managedDebugger)]} then {
      checkForManagedDebugger $test_channel
    }

    #
    # NOTE: Has managed debugging assistants testing support been
    #       disabled?
    #
    if {![info exists no(managedDebuggingAssistants)]} then {
      checkForManagedDebuggingAssistants $test_channel
    }

    #
    # NOTE: Has script debugger testing support been disabled?
    #
    if {![info exists no(scriptDebugger)]} then {
      #
      # NOTE: For tests "debug-1.1", "debug-2.1", "debug-3.1", and
      #       "debug-4.1".
1621
1622
1623
1624
1625
1626
1627







1628
1629
1630
1631
1632
1633
1634
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688







+
+
+
+
+
+
+








  #
  # NOTE: Has checking for the test configuration been disabled?
  #
  if {![info exists no(testConfiguration)]} then {
    checkForTestConfiguration $test_channel
  }

  #
  # NOTE: Has checking for the test suffix been disabled?
  #
  if {![info exists no(testSuffix)]} then {
    checkForTestSuffix $test_channel
  }

  #
  # NOTE: Has checking for the extra files needed by various tests been
  #       disabled?
  #
  if {![info exists no(checkForFile)]} then {
    #
1740
1741
1742
1743
1744
1745
1746







1747
1748
1749
1750
1751
1752
1753
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814







+
+
+
+
+
+
+







    #
    # NOTE: For tests "excel-2.*".
    #
    if {![info exists no(test.xls)]} then {
      checkForFile $test_channel [file join $test_path test.xls]
    }

    #
    # NOTE: For test "proc-1.9".
    #
    if {![info exists no(testProcs.tcl)]} then {
      checkForFile $test_channel [file join $test_path testProcs.tcl]
    }

    #
    # NOTE: For test "interp-1.10".
    #
    if {![info exists no(settings.xml)]} then {
      checkForFile $test_channel [file join $test_path settings.xml]
    }

1832
1833
1834
1835
1836
1837
1838




1839
1840
1841
1842




1843
1844
1845
1846
1847
1848
1849
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918







+
+
+
+




+
+
+
+







  #
  # NOTE: Check the core test constraints unless they have been
  #       explicitly disabled.
  #
  if {![info exists no(platform)]} then {
    checkForPlatform $test_channel
  }

  if {![info exists no(scriptLibrary)]} then {
    checkForScriptLibrary $test_channel
  }

  if {![info exists no(tclOptions)]} then {
    checkForTclOptions $test_channel
  }

  if {![info exists no(stackIntensive)]} then {
    checkForStackIntensive $test_channel
  }

  if {![info exists no(windowsCommandProcessor)]} then {
    checkForWindowsCommandProcessor $test_channel cmd.exe
  }

  if {![info exists no(fossil)]} then {
    checkForFossil $test_channel
1938
1939
1940
1941
1942
1943
1944




1945
1946
1947
1948
1949
1950
1951
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024







+
+
+
+







    checkForTip241 $test_channel
  }

  if {![info exists no(tip285)]} then {
    checkForTip285 $test_channel
  }

  if {![info exists no(tip405)]} then {
    checkForTip405 $test_channel
  }

  #
  # NOTE: Has performance testing been disabled?
  #
  if {![info exists no(performance)]} then {
    checkForPerformance $test_channel
  }

1965
1966
1967
1968
1969
1970
1971















1972
1973
1974
1975
1976
1977
1978
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066







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








  #
  # NOTE: Has interactive testing been disabled?
  #
  if {![info exists no(interactive)]} then {
    checkForInteractive $test_channel
  }

  #
  # NOTE: Has interactive command testing been disabled?
  #
  if {![info exists no(interactiveCommand)]} then {
    #
    # NOTE: For test "debug-1.8".
    #
    checkForInteractiveCommand $test_channel go

    #
    # NOTE: For test "debug-1.9".
    #
    checkForInteractiveCommand $test_channel done
  }

  if {![info exists no(userInteraction)]} then {
    checkForUserInteraction $test_channel
  }

  #
  # NOTE: Check for network connectivity to our test host (i.e.
Changes to Membership/Properties/AssemblyInfo.cs.
29
30
31
32
33
34
35
36
37


29
30
31
32
33
34
35


36
37







-
-
+
+
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Revision and Build Numbers 
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.83.0")]
[assembly: AssemblyFileVersion("1.0.83.0")]
[assembly: AssemblyVersion("1.0.85.0")]
[assembly: AssemblyFileVersion("1.0.85.0")]
Added SQLite.Beta.nuspec.







































1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.Beta.nuspec -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<package>
  <metadata>
    <id>System.Data.SQLite.Beta</id>
    <title>System.Data.SQLite (x86/x64) Beta</title>
    <version>1.0.85.0</version>
    <authors>SQLite Development Team</authors>
    <description>The official SQLite database engine for both x86 and x64 along with the ADO.NET provider.</description>
    <language>en-US</language>
    <projectUrl>http://system.data.sqlite.org/</projectUrl>
    <iconUrl>http://system.data.sqlite.org/images/sqlite32.png</iconUrl>
    <licenseUrl>http://www.sqlite.org/copyright.html</licenseUrl>
    <tags>sqlite database ado.net provider interop</tags>
    <copyright>Public Domain</copyright>
  </metadata>
  <files>
    <file src="bin\2008\Release\bin\System.Data.SQLite.dll" target="lib\net20" />
    <file src="bin\2010\Release\bin\System.Data.SQLite.dll" target="lib\net40" />
    <file src="bin\2012\Release\bin\System.Data.SQLite.dll" target="lib\net45" />
    <file src="bin\2008\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net20" />
    <file src="bin\2010\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net40" />
    <file src="bin\2012\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net45" />
    <file src="bin\2008\Win32\ReleaseNativeOnlyStatic\SQLite.Interop.dll" target="content\net20\x86" />
    <file src="bin\2008\x64\ReleaseNativeOnlyStatic\SQLite.Interop.dll" target="content\net20\x64" />
    <file src="bin\2010\Win32\ReleaseNativeOnlyStatic\SQLite.Interop.dll" target="content\net40\x86" />
    <file src="bin\2010\x64\ReleaseNativeOnlyStatic\SQLite.Interop.dll" target="content\net40\x64" />
    <file src="bin\2012\Win32\ReleaseNativeOnlyStatic\SQLite.Interop.dll" target="content\net45\x86" />
    <file src="bin\2012\x64\ReleaseNativeOnlyStatic\SQLite.Interop.dll" target="content\net45\x64" />
    <file src="install.ps1" target="tools\install.ps1" />
  </files>
</package>
Changes to SQLite.Designer/AssemblyInfo.cs.
39
40
41
42
43
44
45
46
47


39
40
41
42
43
44
45


46
47







-
-
+
+
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Revision and Build Numbers 
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.83.0")]
[assembly: AssemblyFileVersion("1.0.83.0")]
[assembly: AssemblyVersion("1.0.85.0")]
[assembly: AssemblyFileVersion("1.0.85.0")]
Changes to SQLite.Designer/source.extension.vsixmanifest.
1
2
3
4
5
6

7
8
9
10
11
12
13
1
2
3
4
5

6
7
8
9
10
11
12
13





-
+







<?xml version="1.0" encoding="utf-8"?>
<Vsix Version="1.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2010">
  <Identifier Id="67b5f3a9-cde1-430f-a12b-af95bb064851">
    <Name>System.Data.SQLite Designer</Name>
    <Author>http://system.data.sqlite.org/</Author>
    <Version>1.0.83.0</Version>
    <Version>1.0.85.0</Version>
    <Description>ADO.NET Data Designer for SQLite</Description>
    <Locale>1033</Locale>
    <InstalledByMsi>false</InstalledByMsi>
    <SupportedProducts>
      <VisualStudio Version="10.0">
        <Edition>Pro</Edition>
      </VisualStudio>
Changes to SQLite.Interop/SQLite.Interop.2010.vcxproj.
1
2
3
4
5
6
7
8
9
10




11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21










+
+
+
+







<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.Interop.2010.vcxproj -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..</SQLiteNetDir>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="DebugNativeOnly|x64">
      <Configuration>DebugNativeOnly</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
Changes to SQLite.Interop/SQLite.Interop.2012.vcxproj.
1
2
3
4
5
6
7
8
9
10




11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21










+
+
+
+







<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.Interop.2012.vcxproj -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..</SQLiteNetDir>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="DebugNativeOnly|x64">
      <Configuration>DebugNativeOnly</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
Changes to SQLite.Interop/SQLite.Interop.Static.2010.vcxproj.
1
2
3
4
5
6
7
8
9
10




11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21










+
+
+
+







<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.Interop.Static.2010.vcxproj -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..</SQLiteNetDir>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="DebugNativeOnly|x64">
      <Configuration>DebugNativeOnly</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
Changes to SQLite.Interop/SQLite.Interop.Static.2012.vcxproj.
1
2
3
4
5
6
7
8
9
10




11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21










+
+
+
+







<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.Interop.Static.2012.vcxproj -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup>
    <SQLiteNetDir>$(MSBuildProjectDirectory)\..</SQLiteNetDir>
  </PropertyGroup>
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets" />
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="DebugNativeOnly|x64">
      <Configuration>DebugNativeOnly</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
Changes to SQLite.Interop/props/SQLite.Interop.2005.vsprops.
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
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







-
+









-
+




-
+




-
+







	<UserMacro
		Name="ConfigurationYear"
		Value="2005"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_BUILD_NUMBER"
		Value="083"
		Value="085"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_LINKER_VERSION"
		Value="1.0"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_MANIFEST_VERSION"
		Value="1.0.83.0"
		Value="1.0.85.0"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_RC_VERSION"
		Value="1,0,83,0"
		Value="1,0,85,0"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_DEBUG_DEFINES"
		Value="INTEROP_DEBUG=0x307;INTEROP_TEST_EXTENSION=1"
		Value="INTEROP_DEBUG=0x31F;INTEROP_LOG=1;INTEROP_TEST_EXTENSION=1"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_EXTRA_DEFINES"
		Value="INTEROP_EXTENSION_FUNCTIONS=1;INTEROP_CODEC=1"
		PerformEnvironmentSet="true"
	/>
Changes to SQLite.Interop/props/SQLite.Interop.2008.vsprops.
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
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







-
+









-
+




-
+




-
+







	<UserMacro
		Name="ConfigurationYear"
		Value="2008"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_BUILD_NUMBER"
		Value="083"
		Value="085"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_LINKER_VERSION"
		Value="1.0"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_MANIFEST_VERSION"
		Value="1.0.83.0"
		Value="1.0.85.0"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_RC_VERSION"
		Value="1,0,83,0"
		Value="1,0,85,0"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_DEBUG_DEFINES"
		Value="INTEROP_DEBUG=0x307;INTEROP_TEST_EXTENSION=1"
		Value="INTEROP_DEBUG=0x31F;INTEROP_LOG=1;INTEROP_TEST_EXTENSION=1"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="INTEROP_EXTRA_DEFINES"
		Value="INTEROP_EXTENSION_FUNCTIONS=1;INTEROP_CODEC=1"
		PerformEnvironmentSet="true"
	/>
Changes to SQLite.Interop/props/SQLite.Interop.2010.props.
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17



18
19
20
21
22
23
24
1
2
3
4
5
6
7
8
9
10
11
12

13
14



15
16
17
18
19
20
21
22
23
24












-
+

-
-
-
+
+
+







<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.Interop.2010.props -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup Label="UserMacros">
    <ConfigurationYear>2010</ConfigurationYear>
    <INTEROP_BUILD_NUMBER>083</INTEROP_BUILD_NUMBER>
    <INTEROP_BUILD_NUMBER>085</INTEROP_BUILD_NUMBER>
    <INTEROP_LINKER_VERSION>1.0</INTEROP_LINKER_VERSION>
    <INTEROP_MANIFEST_VERSION>1.0.83.0</INTEROP_MANIFEST_VERSION>
    <INTEROP_RC_VERSION>1,0,83,0</INTEROP_RC_VERSION>
    <INTEROP_DEBUG_DEFINES>INTEROP_DEBUG=0x307;INTEROP_TEST_EXTENSION=1</INTEROP_DEBUG_DEFINES>
    <INTEROP_MANIFEST_VERSION>1.0.85.0</INTEROP_MANIFEST_VERSION>
    <INTEROP_RC_VERSION>1,0,85,0</INTEROP_RC_VERSION>
    <INTEROP_DEBUG_DEFINES>INTEROP_DEBUG=0x31F;INTEROP_LOG=1;INTEROP_TEST_EXTENSION=1</INTEROP_DEBUG_DEFINES>
    <INTEROP_EXTRA_DEFINES>INTEROP_EXTENSION_FUNCTIONS=1;INTEROP_CODEC=1</INTEROP_EXTRA_DEFINES>
    <INTEROP_ASSEMBLY_RESOURCES>/ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteCommand.bmp,System.Data.SQLite.SQLiteCommand.bmp /ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteConnection.bmp,System.Data.SQLite.SQLiteConnection.bmp /ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteDataAdapter.bmp,System.Data.SQLite.SQLiteDataAdapter.bmp</INTEROP_ASSEMBLY_RESOURCES>
    <INTEROP_KEY_FILE>$(ProjectDir)..\System.Data.SQLite\System.Data.SQLite.snk</INTEROP_KEY_FILE>
    <INTEROP_NATIVE_NAME>SQLite.Interop</INTEROP_NATIVE_NAME>
    <INTEROP_MIXED_NAME>System.Data.SQLite</INTEROP_MIXED_NAME>
  </PropertyGroup>
  <ItemGroup>
Changes to SQLite.Interop/props/SQLite.Interop.2012.props.
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17



18
19
20
21
22
23
24
1
2
3
4
5
6
7
8
9
10
11
12

13
14



15
16
17
18
19
20
21
22
23
24












-
+

-
-
-
+
+
+







<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.Interop.2012.props -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup Label="UserMacros">
    <ConfigurationYear>2012</ConfigurationYear>
    <INTEROP_BUILD_NUMBER>083</INTEROP_BUILD_NUMBER>
    <INTEROP_BUILD_NUMBER>085</INTEROP_BUILD_NUMBER>
    <INTEROP_LINKER_VERSION>1.0</INTEROP_LINKER_VERSION>
    <INTEROP_MANIFEST_VERSION>1.0.83.0</INTEROP_MANIFEST_VERSION>
    <INTEROP_RC_VERSION>1,0,83,0</INTEROP_RC_VERSION>
    <INTEROP_DEBUG_DEFINES>INTEROP_DEBUG=0x307;INTEROP_TEST_EXTENSION=1</INTEROP_DEBUG_DEFINES>
    <INTEROP_MANIFEST_VERSION>1.0.85.0</INTEROP_MANIFEST_VERSION>
    <INTEROP_RC_VERSION>1,0,85,0</INTEROP_RC_VERSION>
    <INTEROP_DEBUG_DEFINES>INTEROP_DEBUG=0x31F;INTEROP_LOG=1;INTEROP_TEST_EXTENSION=1</INTEROP_DEBUG_DEFINES>
    <INTEROP_EXTRA_DEFINES>INTEROP_EXTENSION_FUNCTIONS=1;INTEROP_CODEC=1</INTEROP_EXTRA_DEFINES>
    <INTEROP_ASSEMBLY_RESOURCES>/ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteCommand.bmp,System.Data.SQLite.SQLiteCommand.bmp /ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteConnection.bmp,System.Data.SQLite.SQLiteConnection.bmp /ASSEMBLYRESOURCE:..\System.Data.SQLite\SQLiteDataAdapter.bmp,System.Data.SQLite.SQLiteDataAdapter.bmp</INTEROP_ASSEMBLY_RESOURCES>
    <INTEROP_KEY_FILE>$(ProjectDir)..\System.Data.SQLite\System.Data.SQLite.snk</INTEROP_KEY_FILE>
    <INTEROP_NATIVE_NAME>SQLite.Interop</INTEROP_NATIVE_NAME>
    <INTEROP_MIXED_NAME>System.Data.SQLite</INTEROP_MIXED_NAME>
  </PropertyGroup>
  <ItemGroup>
Changes to SQLite.Interop/props/sqlite3.props.
1
2
3
4
5
6
7
8
9
10
11
12
13


14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11


12
13
14
15
16
17
18
19
20











-
-
+
+







<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * sqlite3.props -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup Label="UserMacros">
    <SQLITE_MANIFEST_VERSION>3.7.15</SQLITE_MANIFEST_VERSION>
    <SQLITE_RC_VERSION>3,7,15</SQLITE_RC_VERSION>
    <SQLITE_MANIFEST_VERSION>3.7.15.2</SQLITE_MANIFEST_VERSION>
    <SQLITE_RC_VERSION>3,7,15,2</SQLITE_RC_VERSION>
    <SQLITE_COMMON_DEFINES>_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;SQLITE_THREADSAFE=1;SQLITE_USE_URI=1;SQLITE_ENABLE_COLUMN_METADATA=1;SQLITE_ENABLE_STAT3=1;SQLITE_ENABLE_FTS3=1;SQLITE_ENABLE_LOAD_EXTENSION=1;SQLITE_ENABLE_RTREE=1;SQLITE_SOUNDEX=1</SQLITE_COMMON_DEFINES>
    <SQLITE_EXTRA_DEFINES>SQLITE_HAS_CODEC=1</SQLITE_EXTRA_DEFINES>
    <SQLITE_WINCE_DEFINES>SQLITE_OMIT_WAL=1</SQLITE_WINCE_DEFINES>
    <SQLITE_DEBUG_DEFINES>SQLITE_DEBUG=1;SQLITE_MEMDEBUG=1;SQLITE_ENABLE_EXPENSIVE_ASSERT=1</SQLITE_DEBUG_DEFINES>
    <SQLITE_RELEASE_DEFINES>SQLITE_WIN32_MALLOC=1</SQLITE_RELEASE_DEFINES>
    <SQLITE_DISABLE_WARNINGS>4055;4100;4127;4146;4210;4232;4244;4245;4267;4306;4389;4701;4703;4706</SQLITE_DISABLE_WARNINGS>
    <SQLITE_DISABLE_X64_WARNINGS></SQLITE_DISABLE_X64_WARNINGS>
Changes to SQLite.Interop/props/sqlite3.vsprops.
10
11
12
13
14
15
16
17

18
19
20
21
22

23
24
25
26
27
28
29
10
11
12
13
14
15
16

17
18
19
20
21

22
23
24
25
26
27
28
29







-
+




-
+







<VisualStudioPropertySheet
	ProjectType="Visual C++"
	Version="8.00"
	Name="sqlite3"
	>
	<UserMacro
		Name="SQLITE_MANIFEST_VERSION"
		Value="3.7.15"
		Value="3.7.15.2"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="SQLITE_RC_VERSION"
		Value="3,7,15"
		Value="3,7,15,2"
		PerformEnvironmentSet="true"
	/>
	<UserMacro
		Name="SQLITE_COMMON_DEFINES"
		Value="_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;SQLITE_THREADSAFE=1;SQLITE_USE_URI=1;SQLITE_ENABLE_COLUMN_METADATA=1;SQLITE_ENABLE_STAT3=1;SQLITE_ENABLE_FTS3=1;SQLITE_ENABLE_LOAD_EXTENSION=1;SQLITE_ENABLE_RTREE=1;SQLITE_SOUNDEX=1"
		PerformEnvironmentSet="true"
	/>
Changes to SQLite.Interop/src/core/sqlite3.c.
1
2
3

4
5
6
7
8
9
10
1
2

3
4
5
6
7
8
9
10


-
+







/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
** version 3.7.15.  By combining all the individual C code files into this 
** version 3.7.15.2.  By combining all the individual C code files into this 
** single large file, the entire code can be compiled as a single translation
** unit.  This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately.  Performance improvements
** of 5% or more are commonly seen when SQLite is compiled as a single
** translation unit.
**
** This file is all you need to compile SQLite.  To use SQLite in other
669
670
671
672
673
674
675
676

677
678

679
680
681
682
683
684
685
669
670
671
672
673
674
675

676
677

678
679
680
681
682
683
684
685







-
+

-
+







** string contains the date and time of the check-in (UTC) and an SHA1
** hash of the entire source tree.
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.7.15"
#define SQLITE_VERSION        "3.7.15.2"
#define SQLITE_VERSION_NUMBER 3007015
#define SQLITE_SOURCE_ID      "2012-10-12 18:06:07 de784399ed1f0e27fc875e32719643d19819c8fb"
#define SQLITE_SOURCE_ID      "2013-01-09 11:53:05 c0e09560d26f0a6456be9dd3447f5311eb4f238f"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
1036
1037
1038
1039
1040
1041
1042

1043
1044
1045
1046
1047
1048
1049
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050







+







#define SQLITE_IOERR_CLOSE             (SQLITE_IOERR | (16<<8))
#define SQLITE_IOERR_DIR_CLOSE         (SQLITE_IOERR | (17<<8))
#define SQLITE_IOERR_SHMOPEN           (SQLITE_IOERR | (18<<8))
#define SQLITE_IOERR_SHMSIZE           (SQLITE_IOERR | (19<<8))
#define SQLITE_IOERR_SHMLOCK           (SQLITE_IOERR | (20<<8))
#define SQLITE_IOERR_SHMMAP            (SQLITE_IOERR | (21<<8))
#define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))
#define SQLITE_IOERR_DELETE_NOENT      (SQLITE_IOERR | (23<<8))
#define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
#define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))
#define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
#define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436










1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452

1453
1454
1455
1456
1457
1458
1459
1419
1420
1421
1422
1423
1424
1425

1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
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
1467
1468
1469
1470







-











+
+
+
+
+
+
+
+
+
+
















+







** VFS has handled the PRAGMA itself and the parser generates a no-op
** prepared statement.  ^If the [SQLITE_FCNTL_PRAGMA] file control returns
** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means
** that the VFS encountered an error while handling the [PRAGMA] and the
** compilation of the PRAGMA fails with an error.  ^The [SQLITE_FCNTL_PRAGMA]
** file control occurs at the beginning of pragma statement analysis and so
** it is able to override built-in [PRAGMA] statements.
** </ul>
**
** <li>[[SQLITE_FCNTL_BUSYHANDLER]]
** ^This file-control may be invoked by SQLite on the database file handle
** shortly after it is opened in order to provide a custom VFS with access
** to the connections busy-handler callback. The argument is of type (void **)
** - an array of two (void *) values. The first (void *) actually points
** to a function of type (int (*)(void *)). In order to invoke the connections
** busy-handler, this function should be invoked with the second (void *) in
** the array as the only argument. If it returns non-zero, then the operation
** should be retried. If it returns zero, the custom VFS should abandon the
** current operation.
**
** <li>[[SQLITE_FCNTL_TEMPFILENAME]]
** ^Application can invoke this file-control to have SQLite generate a
** temporary filename using the same algorithm that is followed to generate
** temporary filenames for TEMP tables and other internal uses.  The
** argument should be a char** which will be filled with the filename
** written into memory obtained from [sqlite3_malloc()].  The caller should
** invoke [sqlite3_free()] on the result to avoid a memory leak.
**
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE               1
#define SQLITE_GET_LOCKPROXYFILE             2
#define SQLITE_SET_LOCKPROXYFILE             3
#define SQLITE_LAST_ERRNO                    4
#define SQLITE_FCNTL_SIZE_HINT               5
#define SQLITE_FCNTL_CHUNK_SIZE              6
#define SQLITE_FCNTL_FILE_POINTER            7
#define SQLITE_FCNTL_SYNC_OMITTED            8
#define SQLITE_FCNTL_WIN32_AV_RETRY          9
#define SQLITE_FCNTL_PERSIST_WAL            10
#define SQLITE_FCNTL_OVERWRITE              11
#define SQLITE_FCNTL_VFSNAME                12
#define SQLITE_FCNTL_POWERSAFE_OVERWRITE    13
#define SQLITE_FCNTL_PRAGMA                 14
#define SQLITE_FCNTL_BUSYHANDLER            15
#define SQLITE_FCNTL_TEMPFILENAME           16

/*
** CAPI3REF: Mutex Handle
**
** The mutex module within SQLite defines [sqlite3_mutex] to be an
** abstract type for a mutex object.  The SQLite core never looks
** at the internal representation of an [sqlite3_mutex].  It only
2143
2144
2145
2146
2147
2148
2149
2150

2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
















2166
2167
2168
2169
2170
2171
2172
2154
2155
2156
2157
2158
2159
2160

2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199







-
+















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







** connection is opened. If it is globally disabled, filenames are
** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the
** database connection is opened. By default, URI handling is globally
** disabled. The default value may be changed by compiling with the
** [SQLITE_USE_URI] symbol defined.
**
** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
** <dd> This option taks a single integer argument which is interpreted as
** <dd> This option takes a single integer argument which is interpreted as
** a boolean in order to enable or disable the use of covering indices for
** full table scans in the query optimizer.  The default setting is determined
** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
** if that compile-time option is omitted.
** The ability to disable the use of covering indices for full table scans
** is because some incorrectly coded legacy applications might malfunction
** malfunction when the optimization is enabled.  Providing the ability to
** disable the optimization allows the older, buggy application code to work
** without change even with newer versions of SQLite.
**
** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]]
** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE
** <dd> These options are obsolete and should not be used by new code.
** They are retained for backwards compatibility but are now no-ops.
** </dl>
**
** [[SQLITE_CONFIG_SQLLOG]]
** <dt>SQLITE_CONFIG_SQLLOG
** <dd>This option is only available if sqlite is compiled with the
** SQLITE_ENABLE_SQLLOG pre-processor macro defined. The first argument should
** be a pointer to a function of type void(*)(void*,sqlite3*,const char*, int).
** The second should be of type (void*). The callback is invoked by the library
** in three separate circumstances, identified by the value passed as the
** fourth parameter. If the fourth parameter is 0, then the database connection
** passed as the second argument has just been opened. The third argument
** points to a buffer containing the name of the main database file. If the
** fourth parameter is 1, then the SQL statement that the third parameter
** points to has just been executed. Or, if the fourth parameter is 2, then
** the connection being passed as the second parameter is being closed. The
** third parameter is passed NULL In this case.
** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
#define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
#define SQLITE_CONFIG_SERIALIZED    3  /* nil */
#define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_SCRATCH       6  /* void*, int sz, int N */
2180
2181
2182
2183
2184
2185
2186

2187
2188
2189
2190
2191
2192
2193
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221







+







#define SQLITE_CONFIG_PCACHE       14  /* no-op */
#define SQLITE_CONFIG_GETPCACHE    15  /* no-op */
#define SQLITE_CONFIG_LOG          16  /* xFunc, void* */
#define SQLITE_CONFIG_URI          17  /* int */
#define SQLITE_CONFIG_PCACHE2      18  /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20  /* int */
#define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */

/*
** CAPI3REF: Database Connection Configuration Options
**
** These constants are the available integer configuration options that
** can be passed as the second argument to the [sqlite3_db_config()] interface.
**
8437
8438
8439
8440
8441
8442
8443


8444
8445
8446
8447
8448
8449
8450
8465
8466
8467
8468
8469
8470
8471
8472
8473
8474
8475
8476
8477
8478
8479
8480







+
+







SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*);
SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, int*);
SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree*, int);

SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);

SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p);

/*
** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta
** should be one of the following values. The integer values are assigned 
** to constants so that the offset of the corresponding field in an
** SQLite database header may be found using the following formula:
**
**   offset = 36 + (idx * 4)
8951
8952
8953
8954
8955
8956
8957
8958

8959
8960
8961
8962
8963
8964
8965
8981
8982
8983
8984
8985
8986
8987

8988
8989
8990
8991
8992
8993
8994
8995







-
+







SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe*, int addr);
SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int);
SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3*,Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3*,Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*);
SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int);
SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*);
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE   int sqlite3VdbeAssertMayAbort(Vdbe *, int);
SQLITE_PRIVATE   void sqlite3VdbeTrace(Vdbe*,FILE*);
9864
9865
9866
9867
9868
9869
9870
9871

9872
9873
9874
9875
9876
9877
9878
9894
9895
9896
9897
9898
9899
9900

9901
9902
9903
9904
9905
9906
9907
9908







-
+







  Db *aDb;                      /* All backends */
  int nDb;                      /* Number of backends currently in use */
  int flags;                    /* Miscellaneous flags. See below */
  i64 lastRowid;                /* ROWID of most recent insert (see above) */
  unsigned int openFlags;       /* Flags passed to sqlite3_vfs.xOpen() */
  int errCode;                  /* Most recent error code (SQLITE_*) */
  int errMask;                  /* & result codes with this before returning */
  u8 dbOptFlags;                /* Flags to enable/disable optimizations */
  u16 dbOptFlags;               /* Flags to enable/disable optimizations */
  u8 autoCommit;                /* The auto-commit flag. */
  u8 temp_store;                /* 1: file 2: memory 0: default */
  u8 mallocFailed;              /* True if we have seen a malloc failure */
  u8 dfltLockMode;              /* Default locking-mode for attached dbs */
  signed char nextAutovac;      /* Autovac setting after VACUUM if >=0 */
  u8 suppressErr;               /* Do not issue error messages if true */
  u8 vtabOnConflict;            /* Value to return for s3_vtab_on_conflict() */
10009
10010
10011
10012
10013
10014
10015

10016

10017
10018
10019
10020
10021
10022
10023
10039
10040
10041
10042
10043
10044
10045
10046

10047
10048
10049
10050
10051
10052
10053
10054







+
-
+







#define SQLITE_ColumnCache    0x0002   /* Column cache */
#define SQLITE_GroupByOrder   0x0004   /* GROUPBY cover of ORDERBY */
#define SQLITE_FactorOutConst 0x0008   /* Constant factoring */
#define SQLITE_IdxRealAsInt   0x0010   /* Store REAL as INT in indices */
#define SQLITE_DistinctOpt    0x0020   /* DISTINCT using indexes */
#define SQLITE_CoverIdxScan   0x0040   /* Covering index scans */
#define SQLITE_OrderByIdxJoin 0x0080   /* ORDER BY of joins via index */
#define SQLITE_SubqCoroutine  0x0100   /* Evaluate subqueries as coroutines */
#define SQLITE_AllOpts        0x00ff   /* All optimizations */
#define SQLITE_AllOpts        0xffff   /* All optimizations */

/*
** Macros for testing whether or not optimizations are enabled or disabled.
*/
#ifndef SQLITE_OMIT_BUILTIN_TEST
#define OptimizationDisabled(db, mask)  (((db)->dbOptFlags&(mask))!=0)
#define OptimizationEnabled(db, mask)   (((db)->dbOptFlags&(mask))==0)
10186
10187
10188
10189
10190
10191
10192
10193
10194
10195
10196
10197
10198
10199
10200
10201
10202
10203
10204
10205

10206
10207
10208
10209
10210
10211
10212
10217
10218
10219
10220
10221
10222
10223













10224
10225
10226
10227
10228
10229
10230
10231







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







#define COLFLAG_HIDDEN   0x0002    /* A hidden column in a virtual table */

/*
** A "Collating Sequence" is defined by an instance of the following
** structure. Conceptually, a collating sequence consists of a name and
** a comparison routine that defines the order of that sequence.
**
** There may two separate implementations of the collation function, one
** that processes text in UTF-8 encoding (CollSeq.xCmp) and another that
** processes text encoded in UTF-16 (CollSeq.xCmp16), using the machine
** native byte order. When a collation sequence is invoked, SQLite selects
** the version that will require the least expensive encoding
** translations, if any.
**
** The CollSeq.pUser member variable is an extra parameter that passed in
** as the first argument to the UTF-8 comparison function, xCmp.
** CollSeq.pUser16 is the equivalent for the UTF-16 comparison function,
** xCmp16.
**
** If both CollSeq.xCmp and CollSeq.xCmp16 are NULL, it means that the
** If CollSeq.xCmp is NULL, it means that the
** collating sequence is undefined.  Indices built on an undefined
** collating sequence may not be read or written.
*/
struct CollSeq {
  char *zName;          /* Name of the collating sequence, UTF-8 encoded */
  u8 enc;               /* Text encoding handled by xCmp() */
  void *pUser;          /* First argument to xCmp() */
10726
10727
10728
10729
10730
10731
10732
10733
10734
10735
10736
10737
10738
10739
10740
10745
10746
10747
10748
10749
10750
10751

10752
10753
10754
10755
10756
10757
10758







-








  Expr *pLeft;           /* Left subnode */
  Expr *pRight;          /* Right subnode */
  union {
    ExprList *pList;     /* Function arguments or in "<expr> IN (<expr-list)" */
    Select *pSelect;     /* Used for sub-selects and "<expr> IN (<select>)" */
  } x;
  CollSeq *pColl;        /* The collation type of the column or 0 */

  /* If the EP_Reduced flag is set in the Expr.flags mask, then no
  ** space is allocated for the fields below this point. An attempt to
  ** access them will result in a segfault or malfunction.
  *********************************************************************/

#if SQLITE_MAX_EXPR_DEPTH>0
10762
10763
10764
10765
10766
10767
10768
10769

10770
10771
10772
10773
10774
10775
10776
10780
10781
10782
10783
10784
10785
10786

10787
10788
10789
10790
10791
10792
10793
10794







-
+







#define EP_Agg        0x0002  /* Contains one or more aggregate functions */
#define EP_Resolved   0x0004  /* IDs have been resolved to COLUMNs */
#define EP_Error      0x0008  /* Expression contains one or more errors */
#define EP_Distinct   0x0010  /* Aggregate function with DISTINCT keyword */
#define EP_VarSelect  0x0020  /* pSelect is correlated, not constant */
#define EP_DblQuoted  0x0040  /* token.z was originally in "..." */
#define EP_InfixFunc  0x0080  /* True for an infix function: LIKE, GLOB, etc */
#define EP_ExpCollate 0x0100  /* Collating sequence specified explicitly */
#define EP_Collate    0x0100  /* Tree contains a TK_COLLATE opeartor */
#define EP_FixedDest  0x0200  /* Result needed in a specific register */
#define EP_IntValue   0x0400  /* Integer value contained in u.iValue */
#define EP_xIsSelect  0x0800  /* x.pSelect is valid (otherwise x.pList is) */
#define EP_Hint       0x1000  /* Not used */
#define EP_Reduced    0x2000  /* Expr struct is EXPR_REDUCEDSIZE bytes only */
#define EP_TokenOnly  0x4000  /* Expr struct is EXPR_TOKENONLYSIZE bytes only */
#define EP_Static     0x8000  /* Held in memory not obtained from malloc() */
10915
10916
10917
10918
10919
10920
10921
10922
10923



10924
10925
10926
10927
10928
10929
10930
10933
10934
10935
10936
10937
10938
10939


10940
10941
10942
10943
10944
10945
10946
10947
10948
10949







-
-
+
+
+







    char *zName;      /* Name of the table */
    char *zAlias;     /* The "B" part of a "A AS B" phrase.  zName is the "A" */
    Table *pTab;      /* An SQL table corresponding to zName */
    Select *pSelect;  /* A SELECT statement used in place of a table name */
    int addrFillSub;  /* Address of subroutine to manifest a subquery */
    int regReturn;    /* Register holding return address of addrFillSub */
    u8 jointype;      /* Type of join between this able and the previous */
    u8 notIndexed;    /* True if there is a NOT INDEXED clause */
    u8 isCorrelated;  /* True if sub-query is correlated */
    unsigned notIndexed :1;    /* True if there is a NOT INDEXED clause */
    unsigned isCorrelated :1;  /* True if sub-query is correlated */
    unsigned viaCoroutine :1;  /* Implemented as a co-routine */
#ifndef SQLITE_OMIT_EXPLAIN
    u8 iSelectId;     /* If pSelect!=0, the id of the sub-select in EQP */
#endif
    int iCursor;      /* The VDBE cursor number used to access this table */
    Expr *pOn;        /* The ON clause of a join */
    IdList *pUsing;   /* The USING clause of a join */
    Bitmask colUsed;  /* Bit N (1<<N) set if column N of pTab is used */
11002
11003
11004
11005
11006
11007
11008

11009
11010
11011
11012
11013
11014
11015
11021
11022
11023
11024
11025
11026
11027
11028
11029
11030
11031
11032
11033
11034
11035







+







      struct InLoop {
        int iCur;              /* The VDBE cursor used by this IN operator */
        int addrInTop;         /* Top of the IN loop */
      } *aInLoop;           /* Information about each nested IN operator */
    } in;                 /* Used when plan.wsFlags&WHERE_IN_ABLE */
    Index *pCovidx;       /* Possible covering index for WHERE_MULTI_OR */
  } u;
  double rOptCost;      /* "Optimal" cost for this level */

  /* The following field is really not part of the current level.  But
  ** we need a place to cache virtual table index information for each
  ** virtual table in the FROM clause and the WhereLevel structure is
  ** a convenient place since there is one WhereLevel for each FROM clause
  ** element.
  */
11140
11141
11142
11143
11144
11145
11146
11147
11148
11149
11150
11151
11152
11153
11154









11155
11156
11157
11158
11159
11160
11161
11160
11161
11162
11163
11164
11165
11166








11167
11168
11169
11170
11171
11172
11173
11174
11175
11176
11177
11178
11179
11180
11181
11182







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







  Expr *pOffset;         /* OFFSET expression. NULL means not used. */
};

/*
** Allowed values for Select.selFlags.  The "SF" prefix stands for
** "Select Flag".
*/
#define SF_Distinct        0x01  /* Output should be DISTINCT */
#define SF_Resolved        0x02  /* Identifiers have been resolved */
#define SF_Aggregate       0x04  /* Contains aggregate functions */
#define SF_UsesEphemeral   0x08  /* Uses the OpenEphemeral opcode */
#define SF_Expanded        0x10  /* sqlite3SelectExpand() called on this */
#define SF_HasTypeInfo     0x20  /* FROM subqueries have Table metadata */
#define SF_UseSorter       0x40  /* Sort using a sorter */
#define SF_Values          0x80  /* Synthesized from VALUES clause */
#define SF_Distinct        0x0001  /* Output should be DISTINCT */
#define SF_Resolved        0x0002  /* Identifiers have been resolved */
#define SF_Aggregate       0x0004  /* Contains aggregate functions */
#define SF_UsesEphemeral   0x0008  /* Uses the OpenEphemeral opcode */
#define SF_Expanded        0x0010  /* sqlite3SelectExpand() called on this */
#define SF_HasTypeInfo     0x0020  /* FROM subqueries have Table metadata */
#define SF_UseSorter       0x0040  /* Sort using a sorter */
#define SF_Values          0x0080  /* Synthesized from VALUES clause */
#define SF_Materialize     0x0100  /* Force materialization of views */


/*
** The results of a select can be distributed in several ways.  The
** "SRT" prefix means "SELECT Result Type".
*/
#define SRT_Union        1  /* Store result as keys in an index */
11376
11377
11378
11379
11380
11381
11382

11383
11384
11385
11386
11387
11388
11389
11397
11398
11399
11400
11401
11402
11403
11404
11405
11406
11407
11408
11409
11410
11411







+







#define OPFLAG_APPEND        0x08    /* This is likely to be an append */
#define OPFLAG_USESEEKRESULT 0x10    /* Try to avoid a seek in BtreeInsert() */
#define OPFLAG_CLEARCACHE    0x20    /* Clear pseudo-table cache in OP_Column */
#define OPFLAG_LENGTHARG     0x40    /* OP_Column only used for length() */
#define OPFLAG_TYPEOFARG     0x80    /* OP_Column only used for typeof() */
#define OPFLAG_BULKCSR       0x01    /* OP_Open** used to open bulk cursor */
#define OPFLAG_P2ISREG       0x02    /* P2 to OP_Open** is a register number */
#define OPFLAG_PERMUTE       0x01    /* OP_Compare: use the permutation */

/*
 * Each trigger present in the database schema is stored as an instance of
 * struct Trigger. 
 *
 * Pointers to instances of struct Trigger are stored in two ways.
 * 1. In the "trigHash" hash table (part of the sqlite3* that represents the 
11548
11549
11550
11551
11552
11553
11554




11555
11556
11557
11558
11559
11560
11561
11570
11571
11572
11573
11574
11575
11576
11577
11578
11579
11580
11581
11582
11583
11584
11585
11586
11587







+
+
+
+







  int isMallocInit;                 /* True after malloc is initialized */
  int isPCacheInit;                 /* True after malloc is initialized */
  sqlite3_mutex *pInitMutex;        /* Mutex used by sqlite3_initialize() */
  int nRefInitMutex;                /* Number of users of pInitMutex */
  void (*xLog)(void*,int,const char*); /* Function for logging */
  void *pLogArg;                       /* First argument to xLog() */
  int bLocaltimeFault;              /* True to fail localtime() calls */
#ifdef SQLITE_ENABLE_SQLLOG
  void(*xSqllog)(void*,sqlite3*,const char*, int);
  void *pSqllogArg;
#endif
};

/*
** Context pointer passed down through the tree-walk.
*/
struct Walker {
  int (*xExprCallback)(Walker*, Expr*);     /* Callback for expressions */
12063
12064
12065
12066
12067
12068
12069

12070
12071


12072
12073
12074
12075
12076
12077
12078
12089
12090
12091
12092
12093
12094
12095
12096


12097
12098
12099
12100
12101
12102
12103
12104
12105







+
-
-
+
+







SQLITE_PRIVATE u8 sqlite3HexToInt(int h);
SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
SQLITE_PRIVATE const char *sqlite3ErrStr(int);
SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, Token*);
SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Expr*, CollSeq*);
SQLITE_PRIVATE Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr*, Token*);
SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*);
SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *);
SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int);
SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64);
SQLITE_PRIVATE int sqlite3SubInt64(i64*,i64);
SQLITE_PRIVATE int sqlite3MulInt64(i64*,i64);
SQLITE_PRIVATE int sqlite3AbsInt32(int);
12282
12283
12284
12285
12286
12287
12288

12289
12290

12291
12292
12293
12294
12295
12296
12297
12309
12310
12311
12312
12313
12314
12315
12316
12317
12318
12319
12320
12321
12322
12323
12324
12325
12326







+


+







#define IN_INDEX_INDEX           3
SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, int*);

#ifdef SQLITE_ENABLE_ATOMIC_WRITE
SQLITE_PRIVATE   int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
SQLITE_PRIVATE   int sqlite3JournalSize(sqlite3_vfs *);
SQLITE_PRIVATE   int sqlite3JournalCreate(sqlite3_file *);
SQLITE_PRIVATE   int sqlite3JournalExists(sqlite3_file *p);
#else
  #define sqlite3JournalSize(pVfs) ((pVfs)->szOsFile)
  #define sqlite3JournalExists(p) 1
#endif

SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *);
SQLITE_PRIVATE int sqlite3MemJournalSize(void);
SQLITE_PRIVATE int sqlite3IsMemJournal(sqlite3_file *);

#if SQLITE_MAX_EXPR_DEPTH>0
12554
12555
12556
12557
12558
12559
12560




12561
12562
12563
12564
12565
12566
12567
12583
12584
12585
12586
12587
12588
12589
12590
12591
12592
12593
12594
12595
12596
12597
12598
12599
12600







+
+
+
+







   0,                         /* isMallocInit */
   0,                         /* isPCacheInit */
   0,                         /* pInitMutex */
   0,                         /* nRefInitMutex */
   0,                         /* xLog */
   0,                         /* pLogArg */
   0,                         /* bLocaltimeFault */
#ifdef SQLITE_ENABLE_SQLLOG
   0,                         /* xSqllog */
   0                          /* pSqllogArg */
#endif
};


/*
** Hash table for global functions - functions common to all
** database connections.  After initialization, this table is
** read-only.
13094
13095
13096
13097
13098
13099
13100

13101
13102
13103
13104
13105
13106
13107
13127
13128
13129
13130
13131
13132
13133
13134
13135
13136
13137
13138
13139
13140
13141







+







  Bool useRandomRowid;  /* Generate new record numbers semi-randomly */
  Bool nullRow;         /* True if pointing to a row with no data */
  Bool deferredMoveto;  /* A call to sqlite3BtreeMoveto() is needed */
  Bool isTable;         /* True if a table requiring integer keys */
  Bool isIndex;         /* True if an index containing keys only - no data */
  Bool isOrdered;       /* True if the underlying table is BTREE_UNORDERED */
  Bool isSorter;        /* True if a new-style sorter */
  Bool multiPseudo;     /* Multi-register pseudo-cursor */
  sqlite3_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
  const sqlite3_module *pModule;     /* Module for cursor pVtabCursor */
  i64 seqCount;         /* Sequence counter */
  i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
  i64 lastRowid;        /* Last rowid from a Next or NextIdx operation */
  VdbeSorter *pSorter;  /* Sorter object for OP_SorterOpen cursors */

13707
13708
13709
13710
13711
13712
13713
13714


13715
13716
13717
13718
13719
13720
13721
13741
13742
13743
13744
13745
13746
13747

13748
13749
13750
13751
13752
13753
13754
13755
13756







-
+
+







    */
    case SQLITE_DBSTATUS_STMT_USED: {
      struct Vdbe *pVdbe;         /* Used to iterate through VMs */
      int nByte = 0;              /* Used to accumulate return value */

      db->pnBytesFreed = &nByte;
      for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
        sqlite3VdbeDeleteObject(db, pVdbe);
        sqlite3VdbeClearObject(db, pVdbe);
        sqlite3DbFree(db, pVdbe);
      }
      db->pnBytesFreed = 0;

      *pHighwater = 0;
      *pCurrent = nByte;

      break;
22377
22378
22379
22380
22381
22382
22383
22384

22385
22386
22387
22388
22389
22390
22391
22412
22413
22414
22415
22416
22417
22418

22419
22420
22421
22422
22423
22424
22425
22426







-
+







      pEntry->chain = elem->next;
    }
    pEntry->count--;
    assert( pEntry->count>=0 );
  }
  sqlite3_free( elem );
  pH->count--;
  if( pH->count<=0 ){
  if( pH->count==0 ){
    assert( pH->first==0 );
    assert( pH->count==0 );
    sqlite3HashClear(pH);
  }
}

/* Attempt to locate an element of the hash table pH with a key
22675
22676
22677
22678
22679
22680
22681







22682
22683
22684
22685
22686
22687
22688
22710
22711
22712
22713
22714
22715
22716
22717
22718
22719
22720
22721
22722
22723
22724
22725
22726
22727
22728
22729
22730







+
+
+
+
+
+
+







**   *  sqlite3_vfs method implementations.
**   *  Locking primitives for the proxy uber-locking-method. (MacOSX only)
**   *  Definitions of sqlite3_vfs objects for all locking methods
**      plus implementations of sqlite3_os_init() and sqlite3_os_end().
*/
#if SQLITE_OS_UNIX              /* This file is used on unix only */

/* Use posix_fallocate() if it is available
*/
#if !defined(HAVE_POSIX_FALLOCATE) \
      && (_XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L)
# define HAVE_POSIX_FALLOCATE 1
#endif

/*
** There are various methods for file locking used for concurrency
** control:
**
**   1. POSIX locking (the default),
**   2. No locking,
**   3. Dot-file locking,
22847
22848
22849
22850
22851
22852
22853




22854
22855
22856
22857
22858
22859
22860
22889
22890
22891
22892
22893
22894
22895
22896
22897
22898
22899
22900
22901
22902
22903
22904
22905
22906







+
+
+
+







  unsigned short int ctrlFlags;       /* Behavioral bits.  UNIXFILE_* flags */
  int lastErrno;                      /* The unix errno from last I/O error */
  void *lockingContext;               /* Locking style specific state */
  UnixUnusedFd *pUnused;              /* Pre-allocated UnixUnusedFd */
  const char *zPath;                  /* Name of the file */
  unixShm *pShm;                      /* Shared memory segment information */
  int szChunk;                        /* Configured by FCNTL_CHUNK_SIZE */
#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
26407
26408
26409
26410
26411
26412
26413



26414
26415
26416
26417
26418
26419
26420
26453
26454
26455
26456
26457
26458
26459
26460
26461
26462
26463
26464
26465
26466
26467
26468
26469







+
+
+







  }else if( (*pArg)==0 ){
    pFile->ctrlFlags &= ~mask;
  }else{
    pFile->ctrlFlags |= mask;
  }
}

/* Forward declaration */
static int unixGetTempname(int nBuf, char *zBuf);

/*
** Information and control of an open file handle.
*/
static int unixFileControl(sqlite3_file *id, int op, void *pArg){
  unixFile *pFile = (unixFile*)id;
  switch( op ){
    case SQLITE_FCNTL_LOCKSTATE: {
26444
26445
26446
26447
26448
26449
26450








26451
26452
26453
26454
26455
26456
26457
26493
26494
26495
26496
26497
26498
26499
26500
26501
26502
26503
26504
26505
26506
26507
26508
26509
26510
26511
26512
26513
26514







+
+
+
+
+
+
+
+







      unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg);
      return SQLITE_OK;
    }
    case SQLITE_FCNTL_VFSNAME: {
      *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
      return SQLITE_OK;
    }
    case SQLITE_FCNTL_TEMPFILENAME: {
      char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
      if( zTFile ){
        unixGetTempname(pFile->pVfs->mxPathname, zTFile);
        *(char**)pArg = zTFile;
      }
      return SQLITE_OK;
    }
#ifdef SQLITE_DEBUG
    /* The pager calls this method to signal that it has done
    ** a rollback and that the database is therefore unchanged and
    ** it hence it is OK for the transaction change counter to be
    ** unchanged.
    */
    case SQLITE_FCNTL_DB_UNCHANGED: {
26475
26476
26477
26478
26479
26480
26481

26482
26483


26484
26485

















































































26486
26487
26488
26489
26490
26491
26492
26493
26494
26495
26496
26497
26498
26499
26500
26501





26502
26503

26504
26505
26506

26507
26508
26509
26510
26511
26512
26513
26532
26533
26534
26535
26536
26537
26538
26539


26540
26541
26542
26543
26544
26545
26546
26547
26548
26549
26550
26551
26552
26553
26554
26555
26556
26557
26558
26559
26560
26561
26562
26563
26564
26565
26566
26567
26568
26569
26570
26571
26572
26573
26574
26575
26576
26577
26578
26579
26580
26581
26582
26583
26584
26585
26586
26587
26588
26589
26590
26591
26592
26593
26594
26595
26596
26597
26598
26599
26600
26601
26602
26603
26604
26605
26606
26607
26608
26609
26610
26611
26612
26613
26614
26615
26616
26617
26618
26619
26620
26621
26622
26623
26624
26625
26626
26627
26628
26629
26630
26631
26632
26633
26634
26635
26636
26637
26638
26639
26640
26641
26642
26643
26644
26645
26646

26647


26648
26649
26650
26651
26652
26653
26654
26655
26656







+
-
-
+
+


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
















+
+
+
+
+

-
+
-
-

+







** larger for some devices.
**
** SQLite code assumes this function cannot fail. It also assumes that
** if two files are created in the same file-system directory (i.e.
** a database and its journal file) that the sector size will be the
** same for both.
*/
#ifndef __QNXNTO__ 
static int unixSectorSize(sqlite3_file *pFile){
  (void)pFile;
static int unixSectorSize(sqlite3_file *NotUsed){
  UNUSED_PARAMETER(NotUsed);
  return SQLITE_DEFAULT_SECTOR_SIZE;
}
#endif

/*
** The following version of unixSectorSize() is optimized for QNX.
*/
#ifdef __QNXNTO__
#include <sys/dcmd_blk.h>
#include <sys/statvfs.h>
static int unixSectorSize(sqlite3_file *id){
  unixFile *pFile = (unixFile*)id;
  if( pFile->sectorSize == 0 ){
    struct statvfs fsInfo;
       
    /* Set defaults for non-supported filesystems */
    pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
    pFile->deviceCharacteristics = 0;
    if( fstatvfs(pFile->h, &fsInfo) == -1 ) {
      return pFile->sectorSize;
    }

    if( !strcmp(fsInfo.f_basetype, "tmp") ) {
      pFile->sectorSize = fsInfo.f_bsize;
      pFile->deviceCharacteristics =
        SQLITE_IOCAP_ATOMIC4K |       /* All ram filesystem writes are atomic */
        SQLITE_IOCAP_SAFE_APPEND |    /* growing the file does not occur until
                                      ** the write succeeds */
        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
                                      ** so it is ordered */
        0;
    }else if( strstr(fsInfo.f_basetype, "etfs") ){
      pFile->sectorSize = fsInfo.f_bsize;
      pFile->deviceCharacteristics =
        /* etfs cluster size writes are atomic */
        (pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) |
        SQLITE_IOCAP_SAFE_APPEND |    /* growing the file does not occur until
                                      ** the write succeeds */
        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
                                      ** so it is ordered */
        0;
    }else if( !strcmp(fsInfo.f_basetype, "qnx6") ){
      pFile->sectorSize = fsInfo.f_bsize;
      pFile->deviceCharacteristics =
        SQLITE_IOCAP_ATOMIC |         /* All filesystem writes are atomic */
        SQLITE_IOCAP_SAFE_APPEND |    /* growing the file does not occur until
                                      ** the write succeeds */
        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
                                      ** so it is ordered */
        0;
    }else if( !strcmp(fsInfo.f_basetype, "qnx4") ){
      pFile->sectorSize = fsInfo.f_bsize;
      pFile->deviceCharacteristics =
        /* full bitset of atomics from max sector size and smaller */
        ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 |
        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
                                      ** so it is ordered */
        0;
    }else if( strstr(fsInfo.f_basetype, "dos") ){
      pFile->sectorSize = fsInfo.f_bsize;
      pFile->deviceCharacteristics =
        /* full bitset of atomics from max sector size and smaller */
        ((pFile->sectorSize / 512 * SQLITE_IOCAP_ATOMIC512) << 1) - 2 |
        SQLITE_IOCAP_SEQUENTIAL |     /* The ram filesystem has no write behind
                                      ** so it is ordered */
        0;
    }else{
      pFile->deviceCharacteristics =
        SQLITE_IOCAP_ATOMIC512 |      /* blocks are atomic */
        SQLITE_IOCAP_SAFE_APPEND |    /* growing the file does not occur until
                                      ** the write succeeds */
        0;
    }
  }
  /* Last chance verification.  If the sector size isn't a multiple of 512
  ** then it isn't valid.*/
  if( pFile->sectorSize % 512 != 0 ){
    pFile->deviceCharacteristics = 0;
    pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
  }
  return pFile->sectorSize;
}
#endif /* __QNXNTO__ */

/*
** Return the device characteristics for the file.
**
** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default.
** However, that choice is contraversial since technically the underlying
** file system does not always provide powersafe overwrites.  (In other
** words, after a power-loss event, parts of the file that were never
** written might end up being altered.)  However, non-PSOW behavior is very,
** very rare.  And asserting PSOW makes a large reduction in the amount
** of required I/O for journaling, since a lot of padding is eliminated.
**  Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control
** available to turn it off and URI query parameter available to turn it off.
*/
static int unixDeviceCharacteristics(sqlite3_file *id){
  unixFile *p = (unixFile*)id;
  int rc = 0;
#ifdef __QNXNTO__
  if( p->sectorSize==0 ) unixSectorSize(id);
  rc = p->deviceCharacteristics;
#endif
  if( p->ctrlFlags & UNIXFILE_PSOW ){
    return SQLITE_IOCAP_POWERSAFE_OVERWRITE;
    rc |= SQLITE_IOCAP_POWERSAFE_OVERWRITE;
  }else{
    return 0;
  }
  return rc;
}

#ifndef SQLITE_OMIT_WAL


/*
** Object used to represent an shared memory buffer.  
26915
26916
26917
26918
26919
26920
26921







26922
26923
26924
26925
26926

26927
26928
26929
26930
26931
26932
26933
27058
27059
27060
27061
27062
27063
27064
27065
27066
27067
27068
27069
27070
27071
27072
27073
27074
27075
27076
27077
27078
27079
27080
27081
27082
27083
27084







+
+
+
+
+
+
+





+







        /* The requested memory region does not exist. If bExtend is set to
        ** false, exit early. *pp will be set to NULL and SQLITE_OK returned.
        **
        ** Alternatively, if bExtend is true, use ftruncate() to allocate
        ** the requested memory region.
        */
        if( !bExtend ) goto shmpage_out;
#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
        if( osFallocate(pShmNode->h, sStat.st_size, nByte)!=0 ){
          rc = unixLogError(SQLITE_IOERR_SHMSIZE, "fallocate",
                            pShmNode->zFilename);
          goto shmpage_out;
        }
#else
        if( robust_ftruncate(pShmNode->h, nByte) ){
          rc = unixLogError(SQLITE_IOERR_SHMSIZE, "ftruncate",
                            pShmNode->zFilename);
          goto shmpage_out;
        }
#endif
      }
    }

    /* Map the requested memory region into this processes address space. */
    apNew = (char **)sqlite3_realloc(
        pShmNode->apRegion, (iRegion+1)*sizeof(char *)
    );
28121
28122
28123
28124
28125
28126
28127
28128
28129







28130
28131
28132
28133
28134
28135
28136
28272
28273
28274
28275
28276
28277
28278


28279
28280
28281
28282
28283
28284
28285
28286
28287
28288
28289
28290
28291
28292







-
-
+
+
+
+
+
+
+







  sqlite3_vfs *NotUsed,     /* VFS containing this as the xDelete method */
  const char *zPath,        /* Name of file to be deleted */
  int dirSync               /* If true, fsync() directory after deleting file */
){
  int rc = SQLITE_OK;
  UNUSED_PARAMETER(NotUsed);
  SimulateIOError(return SQLITE_IOERR_DELETE);
  if( osUnlink(zPath)==(-1) && errno!=ENOENT ){
    return unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
  if( osUnlink(zPath)==(-1) ){
    if( errno==ENOENT ){
      rc = SQLITE_IOERR_DELETE_NOENT;
    }else{
      rc = unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
    }
    return rc;
  }
#ifndef SQLITE_DISABLE_DIRSYNC
  if( (dirSync & 1)!=0 ){
    int fd;
    rc = osOpenDirectory(zPath, &fd);
    if( rc==SQLITE_OK ){
#if OS_VXWORKS
32135
32136
32137
32138
32139
32140
32141

32142

32143
32144
32145
32146
32147
32148
32149
32291
32292
32293
32294
32295
32296
32297
32298

32299
32300
32301
32302
32303
32304
32305
32306







+
-
+







      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
#else
      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
#endif
        if( retryIoerr(&nRetry, &lastErrno) ) continue;
        break;
      }
      assert( nWrite==0 || nWrite<=(DWORD)nRem );
      if( nWrite<=0 ){
      if( nWrite==0 || nWrite>(DWORD)nRem ){
        lastErrno = osGetLastError();
        break;
      }
#if !SQLITE_OS_WINCE
      offset += nWrite;
      overlapped.Offset = (LONG)(offset & 0xffffffff);
      overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
32633
32634
32635
32636
32637
32638
32639



32640
32641
32642
32643
32644
32645
32646
32790
32791
32792
32793
32794
32795
32796
32797
32798
32799
32800
32801
32802
32803
32804
32805
32806







+
+
+







  }else if( (*pArg)==0 ){
    pFile->ctrlFlags &= ~mask;
  }else{
    pFile->ctrlFlags |= mask;
  }
}

/* Forward declaration */
static int getTempname(int nBuf, char *zBuf);

/*
** Control and query of the open file handle.
*/
static int winFileControl(sqlite3_file *id, int op, void *pArg){
  winFile *pFile = (winFile*)id;
  switch( op ){
    case SQLITE_FCNTL_LOCKSTATE: {
32692
32693
32694
32695
32696
32697
32698








32699
32700
32701
32702
32703
32704
32705
32852
32853
32854
32855
32856
32857
32858
32859
32860
32861
32862
32863
32864
32865
32866
32867
32868
32869
32870
32871
32872
32873







+
+
+
+
+
+
+
+







      }
      if( a[1]>0 ){
        win32IoerrRetryDelay = a[1];
      }else{
        a[1] = win32IoerrRetryDelay;
      }
      return SQLITE_OK;
    }
    case SQLITE_FCNTL_TEMPFILENAME: {
      char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
      if( zTFile ){
        getTempname(pFile->pVfs->mxPathname, zTFile);
        *(char**)pArg = zTFile;
      }
      return SQLITE_OK;
    }
  }
  return SQLITE_NOTFOUND;
}

/*
** Return the sector size in bytes of the underlying block device for
33830
33831
33832
33833
33834
33835
33836




33837


33838
33839
33840
33841
33842
33843




33844


33845
33846
33847
33848
33849
33850
33851
33998
33999
34000
34001
34002
34003
34004
34005
34006
34007
34008

34009
34010
34011
34012
34013
34014
34015
34016
34017
34018
34019
34020

34021
34022
34023
34024
34025
34026
34027
34028
34029







+
+
+
+
-
+
+






+
+
+
+
-
+
+







#if SQLITE_OS_WINRT
      WIN32_FILE_ATTRIBUTE_DATA sAttrData;
      memset(&sAttrData, 0, sizeof(sAttrData));
      if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard,
                                  &sAttrData) ){
        attr = sAttrData.dwFileAttributes;
      }else{
        lastErrno = osGetLastError();
        if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
          rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
        }else{
        rc = SQLITE_OK; /* Already gone? */
          rc = SQLITE_ERROR;
        }
        break;
      }
#else
      attr = osGetFileAttributesW(zConverted);
#endif
      if ( attr==INVALID_FILE_ATTRIBUTES ){
        lastErrno = osGetLastError();
        if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
          rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
        }else{
        rc = SQLITE_OK; /* Already gone? */
          rc = SQLITE_ERROR;
        }
        break;
      }
      if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
        rc = SQLITE_ERROR; /* Files only. */
        break;
      }
      if ( osDeleteFileW(zConverted) ){
33859
33860
33861
33862
33863
33864
33865




33866


33867
33868
33869
33870
33871
33872
33873
33874
33875
33876
33877
33878
33879
33880
33881
33882
33883
33884

33885
33886
33887
33888
33889
33890
33891
34037
34038
34039
34040
34041
34042
34043
34044
34045
34046
34047

34048
34049
34050
34051
34052
34053
34054
34055
34056
34057
34058
34059
34060
34061
34062
34063
34064
34065
34066

34067
34068
34069
34070
34071
34072
34073
34074







+
+
+
+
-
+
+

















-
+







    } while(1);
  }
#ifdef SQLITE_WIN32_HAS_ANSI
  else{
    do {
      attr = osGetFileAttributesA(zConverted);
      if ( attr==INVALID_FILE_ATTRIBUTES ){
        lastErrno = osGetLastError();
        if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
          rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
        }else{
        rc = SQLITE_OK; /* Already gone? */
          rc = SQLITE_ERROR;
        }
        break;
      }
      if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
        rc = SQLITE_ERROR; /* Files only. */
        break;
      }
      if ( osDeleteFileA(zConverted) ){
        rc = SQLITE_OK; /* Deleted OK. */
        break;
      }
      if ( !retryIoerr(&cnt, &lastErrno) ){
        rc = SQLITE_ERROR; /* No more retries. */
        break;
      }
    } while(1);
  }
#endif
  if( rc ){
  if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
    rc = winLogError(SQLITE_IOERR_DELETE, lastErrno,
             "winDelete", zFilename);
  }else{
    logIoerr(cnt);
  }
  sqlite3_free(zConverted);
  OSTRACE(("DELETE \"%s\" %s\n", zFilename, (rc ? "failed" : "ok" )));
39071
39072
39073
39074
39075
39076
39077

39078
39079
39080
39081
39082
39083

39084
39085
39086
39087
39088
39089
39090
39254
39255
39256
39257
39258
39259
39260
39261
39262
39263
39264
39265
39266

39267
39268
39269
39270
39271
39272
39273
39274







+





-
+







      pPager->journalOff = 0;
    }else{
      /* This branch may be executed with Pager.journalMode==MEMORY if
      ** a hot-journal was just rolled back. In this case the journal
      ** file should be closed and deleted. If this connection writes to
      ** the database file, it will do so using an in-memory journal. 
      */
      int bDelete = (!pPager->tempFile && sqlite3JournalExists(pPager->jfd));
      assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE 
           || pPager->journalMode==PAGER_JOURNALMODE_MEMORY 
           || pPager->journalMode==PAGER_JOURNALMODE_WAL 
      );
      sqlite3OsClose(pPager->jfd);
      if( !pPager->tempFile ){
      if( bDelete ){
        rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
      }
    }
  }

#ifdef SQLITE_CHECK_PAGES
  sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash);
40289
40290
40291
40292
40293
40294
40295

40296
40297
40298
40299
40300
40301
40302
40473
40474
40475
40476
40477
40478
40479
40480
40481
40482
40483
40484
40485
40486
40487







+







    int isWal;                    /* True if WAL file exists */
    Pgno nPage;                   /* Size of the database file */

    rc = pagerPagecount(pPager, &nPage);
    if( rc ) return rc;
    if( nPage==0 ){
      rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0);
      if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK;
      isWal = 0;
    }else{
      rc = sqlite3OsAccess(
          pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal
      );
    }
    if( rc==SQLITE_OK ){
40614
40615
40616
40617
40618
40619
40620
40621

40622
40623
40624
40625
40626
40627
40628
40799
40800
40801
40802
40803
40804
40805

40806
40807
40808
40809
40810
40811
40812
40813







-
+







  pPager->xBusyHandler = xBusyHandler;
  pPager->pBusyHandlerArg = pBusyHandlerArg;

  if( isOpen(pPager->fd) ){
    void **ap = (void **)&pPager->xBusyHandler;
    assert( ((int(*)(void *))(ap[0]))==xBusyHandler );
    assert( ap[1]==pBusyHandlerArg );
    sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap);
    sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap);
  }
}

/*
** Change the page size used by the Pager object. The new page size 
** is passed in *pPageSize.
**
42795
42796
42797
42798
42799
42800
42801
42802

42803
42804
42805
42806
42807
42808
42809
42980
42981
42982
42983
42984
42985
42986

42987
42988
42989
42990
42991
42992
42993
42994







-
+







# define DIRECT_MODE 0
  assert( isDirectMode==0 );
  UNUSED_PARAMETER(isDirectMode);
#else
# define DIRECT_MODE isDirectMode
#endif

  if( !pPager->changeCountDone && pPager->dbSize>0 ){
  if( !pPager->changeCountDone && ALWAYS(pPager->dbSize>0) ){
    PgHdr *pPgHdr;                /* Reference to page 1 */

    assert( !pPager->tempFile && isOpen(pPager->fd) );

    /* Open page 1 of the file for writing. */
    rc = sqlite3PagerGet(pPager, 1, &pPgHdr);
    assert( pPgHdr==0 || rc==SQLITE_OK );
43015
43016
43017
43018
43019
43020
43021
43022

43023
43024
43025
43026
43027
43028
43029
43030
43031
43032
43033
43034
43035
43036
43037
43038
43039
43040
43041
43042
43043
43044
43045
43046
43047
43048
43049
43050
43051
43052
43053
43054
43055
43056
43057
43200
43201
43202
43203
43204
43205
43206

43207
43208
43209
43210
43211
43212
43213
43214

43215
43216
43217
43218
43219
43220
43221
43222
43223
43224
43225
43226
43227
43228
43229
43230
43231
43232
43233

43234
43235
43236
43237
43238
43239
43240







-
+







-



















-







  #else
      rc = pager_incr_changecounter(pPager, 0);
  #endif
      if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
  
      /* If this transaction has made the database smaller, then all pages
      ** being discarded by the truncation must be written to the journal
      ** file. This can only happen in auto-vacuum mode.
      ** file.
      **
      ** Before reading the pages with page numbers larger than the 
      ** current value of Pager.dbSize, set dbSize back to the value
      ** that it took at the start of the transaction. Otherwise, the
      ** calls to sqlite3PagerGet() return zeroed pages instead of 
      ** reading data from the database file.
      */
  #ifndef SQLITE_OMIT_AUTOVACUUM
      if( pPager->dbSize<pPager->dbOrigSize 
       && pPager->journalMode!=PAGER_JOURNALMODE_OFF
      ){
        Pgno i;                                   /* Iterator variable */
        const Pgno iSkip = PAGER_MJ_PGNO(pPager); /* Pending lock page */
        const Pgno dbSize = pPager->dbSize;       /* Database image size */ 
        pPager->dbSize = pPager->dbOrigSize;
        for( i=dbSize+1; i<=pPager->dbOrigSize; i++ ){
          if( !sqlite3BitvecTest(pPager->pInJournal, i) && i!=iSkip ){
            PgHdr *pPage;             /* Page to journal */
            rc = sqlite3PagerGet(pPager, i, &pPage);
            if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
            rc = sqlite3PagerWrite(pPage);
            sqlite3PagerUnref(pPage);
            if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
          }
        }
        pPager->dbSize = dbSize;
      } 
  #endif
  
      /* Write the master journal name into the journal file. If a master 
      ** journal file name has already been written to the journal file, 
      ** or if zMaster is NULL (no master journal), then this call is a no-op.
      */
      rc = writeMasterJournal(pPager, zMaster);
      if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
46600
46601
46602
46603
46604
46605
46606
46607

46608
46609
46610
46611
46612
46613
46614
46783
46784
46785
46786
46787
46788
46789

46790
46791
46792
46793
46794
46795
46796
46797







-
+







      ** are no outstanding references to any page other than page 1. And
      ** page 1 is never written to the log until the transaction is
      ** committed. As a result, the call to xUndo may not fail.
      */
      assert( walFramePgno(pWal, iFrame)!=1 );
      rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame));
    }
    walCleanupHash(pWal);
    if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal);
  }
  assert( rc==SQLITE_OK );
  return rc;
}

/* 
** Argument aWalData must point to an array of WAL_SAVEPOINT_NDATA u32 
50653
50654
50655
50656
50657
50658
50659














50660
50661
50662
50663
50664
50665
50666
50836
50837
50838
50839
50840
50841
50842
50843
50844
50845
50846
50847
50848
50849
50850
50851
50852
50853
50854
50855
50856
50857
50858
50859
50860
50861
50862
50863







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







  put4byte(&data[36 + 4*4], pBt->autoVacuum);
  put4byte(&data[36 + 7*4], pBt->incrVacuum);
#endif
  pBt->nPage = 1;
  data[31] = 1;
  return SQLITE_OK;
}

/*
** Initialize the first page of the database file (creating a database
** consisting of a single page and no schema objects). Return SQLITE_OK
** if successful, or an SQLite error code otherwise.
*/
SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p){
  int rc;
  sqlite3BtreeEnter(p);
  p->pBt->nPage = 0;
  rc = newDatabase(p->pBt);
  sqlite3BtreeLeave(p);
  return rc;
}

/*
** Attempt to start a new transaction. A write-transaction
** is started if the second argument is nonzero, otherwise a read-
** transaction.  If the second argument is 2 or more and exclusive
** transaction is started, meaning that no other process is allowed
** to access the database.  A preexisting transaction may not be
53853
53854
53855
53856
53857
53858
53859
53860

53861
53862
53863
53864
53865
53866
53867
54050
54051
54052
54053
54054
54055
54056

54057
54058
54059
54060
54061
54062
54063
54064







-
+







  Pgno pgnoNew;                        /* Page number of pNew */

  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  assert( sqlite3PagerIswriteable(pParent->pDbPage) );
  assert( pPage->nOverflow==1 );

  /* This error condition is now caught prior to reaching this function */
  if( pPage->nCell<=0 ) return SQLITE_CORRUPT_BKPT;
  if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT;

  /* Allocate a new page. This page will become the right-sibling of 
  ** pPage. Make the parent page writable, so that the new divider cell
  ** may be inserted. If both these operations are successful, proceed.
  */
  rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);

56871
56872
56873
56874
56875
56876
56877





56878


56879
56880
56881
56882
56883
56884
56885
57068
57069
57070
57071
57072
57073
57074
57075
57076
57077
57078
57079

57080
57081
57082
57083
57084
57085
57086
57087
57088







+
+
+
+
+
-
+
+







  
    /* Update the schema version field in the destination database. This
    ** is to make sure that the schema-version really does change in
    ** the case where the source and destination databases have the
    ** same schema version.
    */
    if( rc==SQLITE_DONE ){
      if( nSrcPage==0 ){
        rc = sqlite3BtreeNewDb(p->pDest);
        nSrcPage = 1;
      }
      if( rc==SQLITE_OK || rc==SQLITE_DONE ){
      rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1);
        rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1);
      }
      if( rc==SQLITE_OK ){
        if( p->pDestDb ){
          sqlite3ResetAllSchemasOfConnection(p->pDestDb);
        }
        if( destMode==PAGER_JOURNALMODE_WAL ){
          rc = sqlite3BtreeSetVersion(p->pDest, 2);
        }
56905
56906
56907
56908
56909
56910
56911

56912
56913
56914
56915
56916
56917
56918
56919
56920
56921
56922
56923
56924
56925
56926
56927
56928
56929

56930

56931
56932
56933
56934
56935
56936
56937
57108
57109
57110
57111
57112
57113
57114
57115
57116
57117
57118
57119
57120
57121
57122
57123
57124
57125
57126
57127
57128
57129
57130
57131
57132
57133
57134

57135
57136
57137
57138
57139
57140
57141
57142







+


















+
-
+







          nDestTruncate = (nSrcPage+ratio-1)/ratio;
          if( nDestTruncate==(int)PENDING_BYTE_PAGE(p->pDest->pBt) ){
            nDestTruncate--;
          }
        }else{
          nDestTruncate = nSrcPage * (pgszSrc/pgszDest);
        }
        assert( nDestTruncate>0 );
        sqlite3PagerTruncateImage(pDestPager, nDestTruncate);

        if( pgszSrc<pgszDest ){
          /* If the source page-size is smaller than the destination page-size,
          ** two extra things may need to happen:
          **
          **   * The destination may need to be truncated, and
          **
          **   * Data stored on the pages immediately following the 
          **     pending-byte page in the source database may need to be
          **     copied into the destination database.
          */
          const i64 iSize = (i64)pgszSrc * (i64)nSrcPage;
          sqlite3_file * const pFile = sqlite3PagerFile(pDestPager);
          i64 iOff;
          i64 iEnd;

          assert( pFile );
          assert( nDestTruncate==0 
          assert( (i64)nDestTruncate*(i64)pgszDest >= iSize || (
              || (i64)nDestTruncate*(i64)pgszDest >= iSize || (
                nDestTruncate==(int)(PENDING_BYTE_PAGE(p->pDest->pBt)-1)
             && iSize>=PENDING_BYTE && iSize<=PENDING_BYTE+pgszDest
          ));

          /* This call ensures that all data required to recreate the original
          ** database has been stored in the journal for pDestPager and the
          ** journal synced to disk. So at this point we may safely modify
58393
58394
58395
58396
58397
58398
58399
58400

58401
58402
58403
58404
58405
58406
58407
58598
58599
58600
58601
58602
58603
58604

58605
58606
58607
58608
58609
58610
58611
58612







-
+








/*
** Remember the SQL string for a prepared statement.
*/
SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
  assert( isPrepareV2==1 || isPrepareV2==0 );
  if( p==0 ) return;
#ifdef SQLITE_OMIT_TRACE
#if defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_ENABLE_SQLLOG)
  if( !isPrepareV2 ) return;
#endif
  assert( p->zSql==0 );
  p->zSql = sqlite3DbStrNDup(p->db, z, n);
  p->isPrepareV2 = (u8)isPrepareV2;
}

59063
59064
59065
59066
59067
59068
59069

59070
59071
59072
59073
59074
59075
59076
59268
59269
59270
59271
59272
59273
59274
59275
59276
59277
59278
59279
59280
59281
59282







+







  }
  assert( p->nOp>0 );
  assert( addr<p->nOp );
  if( addr<0 ){
    addr = p->nOp - 1;
  }
  pOp = &p->aOp[addr];
  assert( pOp->p4type==P4_NOTUSED || pOp->p4type==P4_INT32 );
  freeP4(db, pOp->p4type, pOp->p4.p);
  pOp->p4.p = 0;
  if( n==P4_INT32 ){
    /* Note: this cast is safe, because the origin data point was an int
    ** that was cast to a (const char *). */
    pOp->p4.i = SQLITE_PTR_TO_INT(zP4);
    pOp->p4type = P4_INT32;
59205
59206
59207
59208
59209
59210
59211
59212
59213
59214
59215
59216
59217
59218
59219
59220
59221
59222
59223












59224
59225
59226
59227
59228
59229
59230
59231
59232
59233
59234
59411
59412
59413
59414
59415
59416
59417












59418
59419
59420
59421
59422
59423
59424
59425
59426
59427
59428
59429




59430
59431
59432
59433
59434
59435
59436







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







      int i, j;
      KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
      assert( pKeyInfo->aSortOrder!=0 );
      sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField);
      i = sqlite3Strlen30(zTemp);
      for(j=0; j<pKeyInfo->nField; j++){
        CollSeq *pColl = pKeyInfo->aColl[j];
        if( pColl ){
          int n = sqlite3Strlen30(pColl->zName);
          if( i+n>nTemp-6 ){
            memcpy(&zTemp[i],",...",4);
            break;
          }
          zTemp[i++] = ',';
          if( pKeyInfo->aSortOrder[j] ){
            zTemp[i++] = '-';
          }
          memcpy(&zTemp[i], pColl->zName,n+1);
          i += n;
        const char *zColl = pColl ? pColl->zName : "nil";
        int n = sqlite3Strlen30(zColl);
        if( i+n>nTemp-6 ){
          memcpy(&zTemp[i],",...",4);
          break;
        }
        zTemp[i++] = ',';
        if( pKeyInfo->aSortOrder[j] ){
          zTemp[i++] = '-';
        }
        memcpy(&zTemp[i], zColl, n+1);
        i += n;
        }else if( i+4<nTemp-6 ){
          memcpy(&zTemp[i],",nil",4);
          i += 4;
        }
      }
      zTemp[i++] = ')';
      zTemp[i] = 0;
      assert( i<nTemp );
      break;
    }
    case P4_COLLSEQ: {
60666
60667
60668
60669
60670
60671
60672





















60673
60674
60675
60676
60677
60678
60679
60868
60869
60870
60871
60872
60873
60874
60875
60876
60877
60878
60879
60880
60881
60882
60883
60884
60885
60886
60887
60888
60889
60890
60891
60892
60893
60894
60895
60896
60897
60898
60899
60900
60901
60902







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







    db->errCode = rc;
  }else{
    sqlite3Error(db, rc, 0);
  }
  return rc;
}

#ifdef SQLITE_ENABLE_SQLLOG
/*
** If an SQLITE_CONFIG_SQLLOG hook is registered and the VM has been run, 
** invoke it.
*/
static void vdbeInvokeSqllog(Vdbe *v){
  if( sqlite3GlobalConfig.xSqllog && v->rc==SQLITE_OK && v->zSql && v->pc>=0 ){
    char *zExpanded = sqlite3VdbeExpandSql(v, v->zSql);
    assert( v->db->init.busy==0 );
    if( zExpanded ){
      sqlite3GlobalConfig.xSqllog(
          sqlite3GlobalConfig.pSqllogArg, v->db, zExpanded, 1
      );
      sqlite3DbFree(v->db, zExpanded);
    }
  }
}
#else
# define vdbeInvokeSqllog(x)
#endif

/*
** Clean up a VDBE after execution but do not delete the VDBE just yet.
** Write any error messages into *pzErrMsg.  Return the result code.
**
** After this routine is run, the VDBE should be ready to be executed
** again.
**
60693
60694
60695
60696
60697
60698
60699

60700
60701
60702
60703
60704
60705
60706
60916
60917
60918
60919
60920
60921
60922
60923
60924
60925
60926
60927
60928
60929
60930







+








  /* If the VDBE has be run even partially, then transfer the error code
  ** and error message from the VDBE into the main database structure.  But
  ** if the VDBE has just been set to run but has not actually executed any
  ** instructions yet, leave the main database error information unchanged.
  */
  if( p->pc>=0 ){
    vdbeInvokeSqllog(p);
    sqlite3VdbeTransferError(p);
    sqlite3DbFree(db, p->zErrMsg);
    p->zErrMsg = 0;
    if( p->runOnlyOnce ) p->expired = 1;
  }else if( p->rc && p->expired ){
    /* The expired flag was set on the VDBE before the first call
    ** to sqlite3_step(). For consistency (since sqlite3_step() was
60774
60775
60776
60777
60778
60779
60780
60781



60782
60783
60784

60785
60786

60787
60788
60789
60790
60791
60792
60793
60794
60795
60796
60797
60798
60799
60800
60801
60802
60803
60804

60805
60806
60807
60808
60809
60810
60811
60812
60813
60814
60815
60816
60817
60818

60819
60820
60821
60822
60823
60824
60825
60826
60827
60828
60829
60830

60831
60832
60833
60834
60835
60836
60837
60998
60999
61000
61001
61002
61003
61004

61005
61006
61007
61008
61009

61010
61011

61012
61013
61014
61015
61016
61017
61018
61019
61020
61021
61022
61023
61024
61025
61026
61027
61028
61029

61030
61031
61032

61033
61034
61035
61036
61037
61038
61039
61040
61041
61042
61043
61044
61045
61046
61047
61048
61049
61050
61051
61052
61053
61054
61055

61056
61057
61058
61059
61060
61061
61062
61063







-
+
+
+


-
+

-
+

















-
+


-











+











-
+







      }
      pAux->pAux = 0;
    }
  }
}

/*
** Free all memory associated with the Vdbe passed as the second argument.
** Free all memory associated with the Vdbe passed as the second argument,
** except for object itself, which is preserved.
**
** The difference between this function and sqlite3VdbeDelete() is that
** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with
** the database connection.
** the database connection and frees the object itself.
*/
SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){
SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
  SubProgram *pSub, *pNext;
  int i;
  assert( p->db==0 || p->db==db );
  releaseMemArray(p->aVar, p->nVar);
  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
  for(pSub=p->pProgram; pSub; pSub=pNext){
    pNext = pSub->pNext;
    vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
    sqlite3DbFree(db, pSub);
  }
  for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
  vdbeFreeOpArray(db, p->aOp, p->nOp);
  sqlite3DbFree(db, p->aLabel);
  sqlite3DbFree(db, p->aColName);
  sqlite3DbFree(db, p->zSql);
  sqlite3DbFree(db, p->pFree);
#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
  sqlite3DbFree(db, p->zExplain);
  sqlite3_free(p->zExplain);
  sqlite3DbFree(db, p->pExplain);
#endif
  sqlite3DbFree(db, p);
}

/*
** Delete an entire VDBE.
*/
SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
  sqlite3 *db;

  if( NEVER(p==0) ) return;
  db = p->db;
  assert( sqlite3_mutex_held(db->mutex) );
  sqlite3VdbeClearObject(db, p);
  if( p->pPrev ){
    p->pPrev->pNext = p->pNext;
  }else{
    assert( db->pVdbe==p );
    db->pVdbe = p->pNext;
  }
  if( p->pNext ){
    p->pNext->pPrev = p->pPrev;
  }
  p->magic = VDBE_MAGIC_DEAD;
  p->db = 0;
  sqlite3VdbeDeleteObject(db, p);
  sqlite3DbFree(db, p);
}

/*
** Make sure the cursor p is ready to read or write the row to which it
** was last positioned.  Return an error code if an OOM fault or I/O error
** prevents us from positioning the cursor to its correct position.
**
63586
63587
63588
63589
63590
63591
63592
63593



63594
63595
63596
63597
63598
63599
63600
63812
63813
63814
63815
63816
63817
63818

63819
63820
63821
63822
63823
63824
63825
63826
63827
63828







-
+
+
+







#endif

#ifdef SQLITE_DEBUG
/*
** Print the value of a register for tracing purposes:
*/
static void memTracePrint(FILE *out, Mem *p){
  if( p->flags & MEM_Null ){
  if( p->flags & MEM_Invalid ){
    fprintf(out, " undefined");
  }else if( p->flags & MEM_Null ){
    fprintf(out, " NULL");
  }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
    fprintf(out, " si:%lld", p->u.i);
  }else if( p->flags & MEM_Int ){
    fprintf(out, " i:%lld", p->u.i);
#ifndef SQLITE_OMIT_FLOATING_POINT
  }else if( p->flags & MEM_Real ){
63859
63860
63861
63862
63863
63864
63865

63866
63867
63868
63869
63870
63871
63872
64087
64088
64089
64090
64091
64092
64093
64094
64095
64096
64097
64098
64099
64100
64101







+







      Mem *pMem;
      int i;
    } af;
    struct OP_Concat_stack_vars {
      i64 nByte;
    } ag;
    struct OP_Remainder_stack_vars {
      char bIntint;   /* Started out as two integer operands */
      int flags;      /* Combined MEM_* flags from both inputs */
      i64 iA;         /* Integer value of left operand */
      i64 iB;         /* Integer value of right operand */
      double rA;      /* Real value of left operand */
      double rB;      /* Real value of right operand */
    } ah;
    struct OP_Function_stack_vars {
64768
64769
64770
64771
64772
64773
64774



64775
64776
64777
64778
64779
64780
64781
64997
64998
64999
65000
65001
65002
65003
65004
65005
65006
65007
65008
65009
65010
65011
65012
65013







+
+
+







  u.ae.n = pOp->p3;
  pIn1 = &aMem[pOp->p1];
  pOut = &aMem[pOp->p2];
  assert( pOut!=pIn1 );
  while( 1 ){
    sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
    Deephemeralize(pOut);
#ifdef SQLITE_DEBUG
    pOut->pScopyFrom = 0;
#endif
    REGISTER_TRACE(pOp->p2+pOp->p3-u.ae.n, pOut);
    if( (u.ae.n--)==0 ) break;
    pOut++;
    pIn1++;
  }
  break;
}
64961
64962
64963
64964
64965
64966
64967

64968
64969
64970
64971
64972
64973
64974
64975
64976
64977
64978
64979
64980
64981
64982
64983
64984

64985
64986
64987
64988
64989
64990
64991
64992
64993
64994
64995
64996
64997
64998
64999
65000
65001
65002
65003
65004

65005
65006
65007
65008
65009
65010
65011
65193
65194
65195
65196
65197
65198
65199
65200
65201
65202
65203
65204
65205
65206
65207
65208
65209
65210
65211
65212
65213
65214
65215
65216
65217
65218
65219
65220
65221
65222
65223
65224
65225
65226
65227
65228
65229
65230
65231
65232
65233
65234
65235
65236
65237
65238
65239
65240
65241
65242
65243
65244
65245
65246







+

















+




















+







*/
case OP_Add:                   /* same as TK_PLUS, in1, in2, out3 */
case OP_Subtract:              /* same as TK_MINUS, in1, in2, out3 */
case OP_Multiply:              /* same as TK_STAR, in1, in2, out3 */
case OP_Divide:                /* same as TK_SLASH, in1, in2, out3 */
case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
#if 0  /* local variables moved into u.ah */
  char bIntint;   /* Started out as two integer operands */
  int flags;      /* Combined MEM_* flags from both inputs */
  i64 iA;         /* Integer value of left operand */
  i64 iB;         /* Integer value of right operand */
  double rA;      /* Real value of left operand */
  double rB;      /* Real value of right operand */
#endif /* local variables moved into u.ah */

  pIn1 = &aMem[pOp->p1];
  applyNumericAffinity(pIn1);
  pIn2 = &aMem[pOp->p2];
  applyNumericAffinity(pIn2);
  pOut = &aMem[pOp->p3];
  u.ah.flags = pIn1->flags | pIn2->flags;
  if( (u.ah.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
  if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
    u.ah.iA = pIn1->u.i;
    u.ah.iB = pIn2->u.i;
    u.ah.bIntint = 1;
    switch( pOp->opcode ){
      case OP_Add:       if( sqlite3AddInt64(&u.ah.iB,u.ah.iA) ) goto fp_math;  break;
      case OP_Subtract:  if( sqlite3SubInt64(&u.ah.iB,u.ah.iA) ) goto fp_math;  break;
      case OP_Multiply:  if( sqlite3MulInt64(&u.ah.iB,u.ah.iA) ) goto fp_math;  break;
      case OP_Divide: {
        if( u.ah.iA==0 ) goto arithmetic_result_is_null;
        if( u.ah.iA==-1 && u.ah.iB==SMALLEST_INT64 ) goto fp_math;
        u.ah.iB /= u.ah.iA;
        break;
      }
      default: {
        if( u.ah.iA==0 ) goto arithmetic_result_is_null;
        if( u.ah.iA==-1 ) u.ah.iA = 1;
        u.ah.iB %= u.ah.iA;
        break;
      }
    }
    pOut->u.i = u.ah.iB;
    MemSetTypeFlag(pOut, MEM_Int);
  }else{
    u.ah.bIntint = 0;
fp_math:
    u.ah.rA = sqlite3VdbeRealValue(pIn1);
    u.ah.rB = sqlite3VdbeRealValue(pIn2);
    switch( pOp->opcode ){
      case OP_Add:         u.ah.rB += u.ah.rA;       break;
      case OP_Subtract:    u.ah.rB -= u.ah.rA;       break;
      case OP_Multiply:    u.ah.rB *= u.ah.rA;       break;
65029
65030
65031
65032
65033
65034
65035
65036

65037
65038
65039
65040
65041
65042
65043
65264
65265
65266
65267
65268
65269
65270

65271
65272
65273
65274
65275
65276
65277
65278







-
+







    MemSetTypeFlag(pOut, MEM_Int);
#else
    if( sqlite3IsNaN(u.ah.rB) ){
      goto arithmetic_result_is_null;
    }
    pOut->r = u.ah.rB;
    MemSetTypeFlag(pOut, MEM_Real);
    if( (u.ah.flags & MEM_Real)==0 ){
    if( (u.ah.flags & MEM_Real)==0 && !u.ah.bIntint ){
      sqlite3VdbeIntegerAffinity(pOut);
    }
#endif
  }
  break;

arithmetic_result_is_null:
65590
65591
65592
65593
65594
65595
65596
65597
65598
65599



65600
65601
65602
65603
65604
65605
65606
65607
65608

65609
65610
65611
65612





65613
65614
65615
65616
65617
65618
65619
65825
65826
65827
65828
65829
65830
65831



65832
65833
65834
65835
65836
65837
65838
65839
65840
65841
65842

65843
65844
65845
65846
65847
65848
65849
65850
65851
65852
65853
65854
65855
65856
65857
65858
65859







-
-
-
+
+
+








-
+




+
+
+
+
+







}

/* Opcode: Permutation * * * P4 *
**
** Set the permutation used by the OP_Compare operator to be the array
** of integers in P4.
**
** The permutation is only valid until the next OP_Permutation, OP_Compare,
** OP_Halt, or OP_ResultRow.  Typically the OP_Permutation should occur
** immediately prior to the OP_Compare.
** The permutation is only valid until the next OP_Compare that has
** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should 
** occur immediately prior to the OP_Compare.
*/
case OP_Permutation: {
  assert( pOp->p4type==P4_INTARRAY );
  assert( pOp->p4.ai );
  aPermute = pOp->p4.ai;
  break;
}

/* Opcode: Compare P1 P2 P3 P4 *
/* Opcode: Compare P1 P2 P3 P4 P5
**
** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this
** vector "A") and in reg(P2)..reg(P2+P3-1) ("B").  Save the result of
** the comparison for use by the next OP_Jump instruct.
**
** If P5 has the OPFLAG_PERMUTE bit set, then the order of comparison is
** determined by the most recent OP_Permutation operator.  If the
** OPFLAG_PERMUTE bit is clear, then register are compared in sequential
** order.
**
** P4 is a KeyInfo structure that defines collating sequences and sort
** orders for the comparison.  The permutation applies to registers
** only.  The KeyInfo elements are used sequentially.
**
** The comparison is a sort comparison, so NULLs compare equal,
** NULLs are less than numbers, numbers are less than strings,
65627
65628
65629
65630
65631
65632
65633

65634
65635
65636
65637
65638
65639
65640
65867
65868
65869
65870
65871
65872
65873
65874
65875
65876
65877
65878
65879
65880
65881







+







  int p2;
  const KeyInfo *pKeyInfo;
  int idx;
  CollSeq *pColl;    /* Collating sequence to use on this term */
  int bRev;          /* True for DESCENDING sort order */
#endif /* local variables moved into u.al */

  if( (pOp->p5 & OPFLAG_PERMUTE)==0 ) aPermute = 0;
  u.al.n = pOp->p3;
  u.al.pKeyInfo = pOp->p4.pKeyInfo;
  assert( u.al.n>0 );
  assert( u.al.pKeyInfo!=0 );
  u.al.p1 = pOp->p1;
  u.al.p2 = pOp->p2;
#if SQLITE_DEBUG
65772
65773
65774
65775
65776
65777
65778
65779
65780
65781
65782
65783
65784
65785
65786
65787
66013
66014
66015
66016
66017
66018
66019


66020
66021
66022
66023
66024
66025
66026







-
-







  break;
}

/* Opcode: Once P1 P2 * * *
**
** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise,
** set the flag and fall through to the next instruction.
**
** See also: JumpOnce
*/
case OP_Once: {             /* jump */
  assert( pOp->p1<p->nOnceFlag );
  if( p->aOnceFlag[pOp->p1] ){
    pc = pOp->p2-1;
  }else{
    p->aOnceFlag[pOp->p1] = 1;
65948
65949
65950
65951
65952
65953
65954





65955
65956
65957
65958
65959
65960
65961
66187
66188
66189
66190
66191
66192
66193
66194
66195
66196
66197
66198
66199
66200
66201
66202
66203
66204
66205







+
+
+
+
+







    }else{
      assert( sqlite3BtreeCursorIsValid(u.ao.pCrsr) );
      VVA_ONLY(rc =) sqlite3BtreeDataSize(u.ao.pCrsr, &u.ao.payloadSize);
      assert( rc==SQLITE_OK );   /* DataSize() cannot fail */
    }
  }else if( ALWAYS(u.ao.pC->pseudoTableReg>0) ){
    u.ao.pReg = &aMem[u.ao.pC->pseudoTableReg];
    if( u.ao.pC->multiPseudo ){
      sqlite3VdbeMemShallowCopy(u.ao.pDest, u.ao.pReg+u.ao.p2, MEM_Ephem);
      Deephemeralize(u.ao.pDest);
      goto op_column_out;
    }
    assert( u.ao.pReg->flags & MEM_Blob );
    assert( memIsValid(u.ao.pReg) );
    u.ao.payloadSize = u.ao.pReg->n;
    u.ao.zRec = u.ao.pReg->z;
    u.ao.pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr;
    assert( u.ao.payloadSize==0 || u.ao.zRec!=0 );
  }else{
67028
67029
67030
67031
67032
67033
67034
67035

67036
67037
67038
67039
67040
67041
67042
67272
67273
67274
67275
67276
67277
67278

67279
67280
67281
67282
67283
67284
67285
67286







-
+







    }
  }
  u.az.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
  u.az.pCx->isIndex = !u.az.pCx->isTable;
  break;
}

/* Opcode: OpenSorter P1 P2 * P4 *
/* Opcode: SorterOpen P1 P2 * P4 *
**
** This opcode works like OP_OpenEphemeral except that it opens
** a transient index that is specifically designed to sort large
** tables using an external merge-sort algorithm.
*/
case OP_SorterOpen: {
#if 0  /* local variables moved into u.ba */
67053
67054
67055
67056
67057
67058
67059
67060

67061
67062
67063
67064
67065



67066
67067
67068
67069
67070
67071
67072
67297
67298
67299
67300
67301
67302
67303

67304
67305
67306
67307


67308
67309
67310
67311
67312
67313
67314
67315
67316
67317







-
+



-
-
+
+
+







#else
  pOp->opcode = OP_OpenEphemeral;
  pc--;
#endif
  break;
}

/* Opcode: OpenPseudo P1 P2 P3 * *
/* Opcode: OpenPseudo P1 P2 P3 * P5
**
** Open a new cursor that points to a fake table that contains a single
** row of data.  The content of that one row in the content of memory
** register P2.  In other words, cursor P1 becomes an alias for the 
** MEM_Blob content contained in register P2.
** register P2 when P5==0.  In other words, cursor P1 becomes an alias for the 
** MEM_Blob content contained in register P2.  When P5==1, then the
** row is represented by P3 consecutive registers beginning with P2.
**
** A pseudo-table created by this opcode is used to hold a single
** row output from the sorter so that the row can be decomposed into
** individual columns using the OP_Column opcode.  The OP_Column opcode
** is the only cursor opcode that works with a pseudo-table.
**
** P3 is the number of fields in the records that will be stored by
67080
67081
67082
67083
67084
67085
67086

67087
67088
67089
67090
67091
67092
67093
67325
67326
67327
67328
67329
67330
67331
67332
67333
67334
67335
67336
67337
67338
67339







+







  assert( pOp->p1>=0 );
  u.bb.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0);
  if( u.bb.pCx==0 ) goto no_mem;
  u.bb.pCx->nullRow = 1;
  u.bb.pCx->pseudoTableReg = pOp->p2;
  u.bb.pCx->isTable = 1;
  u.bb.pCx->isIndex = 0;
  u.bb.pCx->multiPseudo = pOp->p5;
  break;
}

/* Opcode: Close P1 * * * *
**
** Close a cursor previously opened as P1.  If P1 is not
** currently open, this instruction is a no-op.
68068
68069
68070
68071
68072
68073
68074
68075

68076
68077
68078
68079
68080
68081
68082
68314
68315
68316
68317
68318
68319
68320

68321
68322
68323
68324
68325
68326
68327
68328







-
+







  sqlite3_vtab *pVtab;
  const sqlite3_module *pModule;
#endif /* local variables moved into u.bn */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  u.bn.pC = p->apCsr[pOp->p1];
  assert( u.bn.pC!=0 );
  assert( u.bn.pC->pseudoTableReg==0 );
  assert( u.bn.pC->pseudoTableReg==0 || u.bn.pC->nullRow );
  if( u.bn.pC->nullRow ){
    pOut->flags = MEM_Null;
    break;
  }else if( u.bn.pC->deferredMoveto ){
    u.bn.v = u.bn.pC->movetoTarget;
#ifndef SQLITE_OMIT_VIRTUALTABLE
  }else if( u.bn.pC->pVtabCursor ){
70735
70736
70737
70738
70739
70740
70741
70742
70743





70744
70745
70746
70747
70748
70749
70750
70981
70982
70983
70984
70985
70986
70987


70988
70989
70990
70991
70992
70993
70994
70995
70996
70997
70998
70999







-
-
+
+
+
+
+







  ** than p->nBuffer bytes remaining in the PMA, read all remaining data.  */
  iBuf = p->iReadOff % p->nBuffer;
  if( iBuf==0 ){
    int nRead;                    /* Bytes to read from disk */
    int rc;                       /* sqlite3OsRead() return code */

    /* Determine how many bytes of data to read. */
    nRead = (int)(p->iEof - p->iReadOff);
    if( nRead>p->nBuffer ) nRead = p->nBuffer;
    if( (p->iEof - p->iReadOff) > (i64)p->nBuffer ){
      nRead = p->nBuffer;
    }else{
      nRead = (int)(p->iEof - p->iReadOff);
    }
    assert( nRead>0 );

    /* Read data from the file. Return early if an error occurs. */
    rc = sqlite3OsRead(p->pFile, p->aBuffer, nRead, p->iReadOff);
    assert( rc!=SQLITE_IOERR_SHORT_READ );
    if( rc!=SQLITE_OK ) return rc;
  }
71807
71808
71809
71810
71811
71812
71813










71814
71815
71816
71817
71818
71819
71820
72056
72057
72058
72059
72060
72061
72062
72063
72064
72065
72066
72067
72068
72069
72070
72071
72072
72073
72074
72075
72076
72077
72078
72079







+
+
+
+
+
+
+
+
+
+







*/
SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *p){
  if( p->pMethods!=&JournalFileMethods ){
    return SQLITE_OK;
  }
  return createFile((JournalFile *)p);
}

/*
** The file-handle passed as the only argument is guaranteed to be an open
** file. It may or may not be of class JournalFile. If the file is a
** JournalFile, and the underlying file on disk has not yet been opened,
** return 0. Otherwise, return 1.
*/
SQLITE_PRIVATE int sqlite3JournalExists(sqlite3_file *p){
  return (p->pMethods!=&JournalFileMethods || ((JournalFile *)p)->pReal!=0);
}

/* 
** Return the number of bytes required to store a JournalFile that uses vfs
** pVfs to create the underlying on-disk files.
*/
SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){
  return (pVfs->szOsFile+sizeof(JournalFile));
72292
72293
72294
72295
72296
72297
72298









72299
72300
72301
72302
72303
72304
72305
72551
72552
72553
72554
72555
72556
72557
72558
72559
72560
72561
72562
72563
72564
72565
72566
72567
72568
72569
72570
72571
72572
72573







+
+
+
+
+
+
+
+
+







** Is equivalent to:
**
**     SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5
**
** The result of random()%5 in the GROUP BY clause is probably different
** from the result in the result-set.  We might fix this someday.  Or
** then again, we might not...
**
** If the reference is followed by a COLLATE operator, then make sure
** the COLLATE operator is preserved.  For example:
**
**     SELECT a+b, c+d FROM t1 ORDER BY 1 COLLATE nocase;
**
** Should be transformed into:
**
**     SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase;
**
** The nSubquery parameter specifies how many levels of subquery the
** alias is removed from the original expression.  The usually value is
** zero but it might be more if the alias is contained within a subquery
** of the original expression.  The Expr.op2 field of TK_AGG_FUNCTION
** structures must be increased by the nSubquery amount.
*/
72316
72317
72318
72319
72320
72321
72322
72323
72324



72325
72326
72327
72328
72329
72330
72331
72332
72333
72334
72335
72336
72337
72338
72339
72340
72341
72342
72343
72344
72345
72346

72347
72348

72349
72350
72351
72352
72353



72354
72355
72356
72357





72358
72359
72360
72361
72362
72363
72364
72584
72585
72586
72587
72588
72589
72590


72591
72592
72593
72594
72595
72596
72597
72598
72599
72600













72601

72602


72603
72604
72605
72606
72607
72608
72609
72610
72611
72612
72613
72614
72615
72616
72617
72618
72619
72620
72621
72622
72623
72624
72625
72626
72627







-
-
+
+
+







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

-
+
-
-
+





+
+
+




+
+
+
+
+







  sqlite3 *db;           /* The database connection */

  assert( iCol>=0 && iCol<pEList->nExpr );
  pOrig = pEList->a[iCol].pExpr;
  assert( pOrig!=0 );
  assert( pOrig->flags & EP_Resolved );
  db = pParse->db;
  if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
    pDup = sqlite3ExprDup(db, pOrig, 0);
  pDup = sqlite3ExprDup(db, pOrig, 0);
  if( pDup==0 ) return;
  if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
    incrAggFunctionDepth(pDup, nSubquery);
    pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
    if( pDup==0 ) return;
    if( pEList->a[iCol].iAlias==0 ){
      pEList->a[iCol].iAlias = (u16)(++pParse->nAlias);
    }
    pDup->iTable = pEList->a[iCol].iAlias;
  }else if( ExprHasProperty(pOrig, EP_IntValue) || pOrig->u.zToken==0 ){
    pDup = sqlite3ExprDup(db, pOrig, 0);
    if( pDup==0 ) return;
  }else{
    char *zToken = pOrig->u.zToken;
    assert( zToken!=0 );
    pOrig->u.zToken = 0;
    pDup = sqlite3ExprDup(db, pOrig, 0);
    pOrig->u.zToken = zToken;
    if( pDup==0 ) return;
    assert( (pDup->flags & (EP_Reduced|EP_TokenOnly))==0 );
    pDup->flags2 |= EP2_MallocedToken;
    pDup->u.zToken = sqlite3DbStrDup(db, zToken);
  }
  if( pExpr->flags & EP_ExpCollate ){
  if( pExpr->op==TK_COLLATE ){
    pDup->pColl = pExpr->pColl;
    pDup->flags |= EP_ExpCollate;
    pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
  }

  /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This 
  ** prevents ExprDelete() from deleting the Expr structure itself,
  ** allowing it to be repopulated by the memcpy() on the following line.
  ** The pExpr->u.zToken might point into memory that will be freed by the
  ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to
  ** make a copy of the token before doing the sqlite3DbFree().
  */
  ExprSetProperty(pExpr, EP_Static);
  sqlite3ExprDelete(db, pExpr);
  memcpy(pExpr, pDup, sizeof(*pExpr));
  if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
    assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
    pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
    pExpr->flags2 |= EP2_MallocedToken;
  }
  sqlite3DbFree(db, pDup);
}


/*
** Return TRUE if the name zCol occurs anywhere in the USING clause.
**
73037
73038
73039
73040
73041
73042
73043
73044

73045
73046
73047
73048
73049
73050
73051
73052
73053
73054
73055
73056
73057
73058
73059
73060
73061
73062
73063


73064
73065
73066


73067
73068
73069










73070
73071
73072
73073
73074
73075
73076
73300
73301
73302
73303
73304
73305
73306

73307
73308
73309
73310
73311
73312
73313
73314
73315
73316
73317
73318
73319
73320
73321
73322
73323
73324


73325
73326



73327
73328



73329
73330
73331
73332
73333
73334
73335
73336
73337
73338
73339
73340
73341
73342
73343
73344
73345







-
+

















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







    moreToDo = 0;
    pEList = pSelect->pEList;
    assert( pEList!=0 );
    for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
      int iCol = -1;
      Expr *pE, *pDup;
      if( pItem->done ) continue;
      pE = pItem->pExpr;
      pE = sqlite3ExprSkipCollate(pItem->pExpr);
      if( sqlite3ExprIsInteger(pE, &iCol) ){
        if( iCol<=0 || iCol>pEList->nExpr ){
          resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr);
          return 1;
        }
      }else{
        iCol = resolveAsName(pParse, pEList, pE);
        if( iCol==0 ){
          pDup = sqlite3ExprDup(db, pE, 0);
          if( !db->mallocFailed ){
            assert(pDup);
            iCol = resolveOrderByTermToExprList(pParse, pSelect, pDup);
          }
          sqlite3ExprDelete(db, pDup);
        }
      }
      if( iCol>0 ){
        CollSeq *pColl = pE->pColl;
        int flags = pE->flags & EP_ExpCollate;
        /* Convert the ORDER BY term into an integer column number iCol,
        ** taking care to preserve the COLLATE clause if it exists */
        sqlite3ExprDelete(db, pE);
        pItem->pExpr = pE = sqlite3Expr(db, TK_INTEGER, 0);
        if( pE==0 ) return 1;
        Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
        if( pNew==0 ) return 1;
        pE->pColl = pColl;
        pE->flags |= EP_IntValue | flags;
        pE->u.iValue = iCol;
        pNew->flags |= EP_IntValue;
        pNew->u.iValue = iCol;
        if( pItem->pExpr==pE ){
          pItem->pExpr = pNew;
        }else{
          assert( pItem->pExpr->op==TK_COLLATE );
          assert( pItem->pExpr->pLeft==pE );
          pItem->pExpr->pLeft = pNew;
        }
        sqlite3ExprDelete(db, pE);
        pItem->iOrderByCol = (u16)iCol;
        pItem->done = 1;
      }else{
        moreToDo = 1;
      }
    }
    pSelect = pSelect->pNext;
73167
73168
73169
73170
73171
73172
73173
73174

73175
73176
73177
73178

73179
73180
73181
73182
73183
73184
73185
73436
73437
73438
73439
73440
73441
73442

73443
73444
73445
73446

73447
73448
73449
73450
73451
73452
73453
73454







-
+



-
+







      /* If an AS-name match is found, mark this ORDER BY column as being
      ** a copy of the iCol-th result-set column.  The subsequent call to
      ** sqlite3ResolveOrderGroupBy() will convert the expression to a
      ** copy of the iCol-th result-set expression. */
      pItem->iOrderByCol = (u16)iCol;
      continue;
    }
    if( sqlite3ExprIsInteger(pE, &iCol) ){
    if( sqlite3ExprIsInteger(sqlite3ExprSkipCollate(pE), &iCol) ){
      /* The ORDER BY term is an integer constant.  Again, set the column
      ** number so that sqlite3ResolveOrderGroupBy() will convert the
      ** order-by term to a copy of the result-set expression */
      if( iCol<1 ){
      if( iCol<1 || iCol>0xffff ){
        resolveOutOfRangeError(pParse, zType, i+1, nResult);
        return 1;
      }
      pItem->iOrderByCol = (u16)iCol;
      continue;
    }

73525
73526
73527
73528
73529
73530
73531


73532

73533
73534
73535
73536
73537
73538
73539
73794
73795
73796
73797
73798
73799
73800
73801
73802

73803
73804
73805
73806
73807
73808
73809
73810







+
+
-
+







**
** CREATE TABLE t1(a);
** SELECT * FROM t1 WHERE a;
** SELECT a AS b FROM t1 WHERE b;
** SELECT * FROM t1 WHERE (select a from t1);
*/
SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
  int op;
  pExpr = sqlite3ExprSkipCollate(pExpr);
  int op = pExpr->op;
  op = pExpr->op;
  if( op==TK_SELECT ){
    assert( pExpr->flags&EP_xIsSelect );
    return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
  }
#ifndef SQLITE_OMIT_CAST
  if( op==TK_CAST ){
    assert( !ExprHasProperty(pExpr, EP_IntValue) );
73550
73551
73552
73553
73554
73555
73556
73557
73558






73559
73560
73561
73562
73563


























73564
73565
73566
73567
73568
73569

73570
73571
73572
73573






73574
73575

73576
73577
73578
73579
73580

73581
73582
73583
73584
73585















73586
73587
73588
73589
73590
73591
73592
73593
73594
73595
73596

73597
73598
73599
73600





73601
73602
73603
73604
73605
73606
73607

73608
73609
73610
73611
73612
73613







73614
73615
73616
73617
73618
73619
73620
73621
73622
73623
73821
73822
73823
73824
73825
73826
73827


73828
73829
73830
73831
73832
73833
73834




73835
73836
73837
73838
73839
73840
73841
73842
73843
73844
73845
73846
73847
73848
73849
73850
73851
73852
73853
73854
73855
73856
73857
73858
73859
73860
73861
73862
73863
73864
73865

73866




73867
73868
73869
73870
73871
73872
73873

73874


73875


73876





73877
73878
73879
73880
73881
73882
73883
73884
73885
73886
73887
73888
73889
73890
73891











73892




73893
73894
73895
73896
73897
73898
73899

73900
73901


73902
73903

73904
73905
73906

73907
73908
73909
73910
73911
73912
73913
73914
73915

73916
73917
73918
73919
73920
73921
73922







-
-
+
+
+
+
+
+

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





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

-
+
-
-

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


-


-
-
+

-



-
+
+
+
+
+
+
+


-







    assert( pExpr->pTab && j<pExpr->pTab->nCol );
    return pExpr->pTab->aCol[j].affinity;
  }
  return pExpr->affinity;
}

/*
** Set the explicit collating sequence for an expression to the
** collating sequence supplied in the second argument.
** Set the collating sequence for expression pExpr to be the collating
** sequence named by pToken.   Return a pointer to a new Expr node that
** implements the COLLATE operator.
**
** If a memory allocation error occurs, that fact is recorded in pParse->db
** and the pExpr parameter is returned unchanged.
*/
SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Expr *pExpr, CollSeq *pColl){
  if( pExpr && pColl ){
    pExpr->pColl = pColl;
    pExpr->flags |= EP_ExpCollate;
SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr *pExpr, Token *pCollName){
  if( pCollName->n>0 ){
    Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1);
    if( pNew ){
      pNew->pLeft = pExpr;
      pNew->flags |= EP_Collate;
      pExpr = pNew;
    }
  }
  return pExpr;
}
SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
  Token s;
  assert( zC!=0 );
  s.z = zC;
  s.n = sqlite3Strlen30(s.z);
  return sqlite3ExprAddCollateToken(pParse, pExpr, &s);
}

/*
** Skip over any TK_COLLATE and/or TK_AS operators at the root of
** an expression.
*/
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){
  while( pExpr && (pExpr->op==TK_COLLATE || pExpr->op==TK_AS) ){
    pExpr = pExpr->pLeft;
  }
  return pExpr;
}

/*
** Set the collating sequence for expression pExpr to be the collating
** Return the collation sequence for the expression pExpr. If
** sequence named by pToken.   Return a pointer to the revised expression.
** The collating sequence is marked as "explicit" using the EP_ExpCollate
** flag.  An explicit collating sequence will override implicit
** collating sequences.
** there is no defined collating sequence, return NULL.
**
** The collating sequence might be determined by a COLLATE operator
** or by the presence of a column with a defined collating sequence.
** COLLATE operators take first precedence.  Left operands take
** precedence over right operands.
*/
SQLITE_PRIVATE Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr *pExpr, Token *pCollName){
SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
  char *zColl = 0;            /* Dequoted name of collation sequence */
  CollSeq *pColl;
  sqlite3 *db = pParse->db;
  zColl = sqlite3NameFromToken(db, pCollName);
  pColl = sqlite3LocateCollSeq(pParse, zColl);
  CollSeq *pColl = 0;
  sqlite3ExprSetColl(pExpr, pColl);
  sqlite3DbFree(db, zColl);
  return pExpr;
}

  Expr *p = pExpr;
  while( p ){
    int op = p->op;
    if( op==TK_CAST || op==TK_UPLUS ){
      p = p->pLeft;
      continue;
    }
    assert( op!=TK_REGISTER || p->op2!=TK_COLLATE );
    if( op==TK_COLLATE ){
      if( db->init.busy ){
        /* Do not report errors when parsing while the schema */
        pColl = sqlite3FindCollSeq(db, ENC(db), p->u.zToken, 0);
      }else{
        pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
      }
/*
** Return the default collation sequence for the expression pExpr. If
** there is no default collation type, return 0.
*/
SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
  CollSeq *pColl = 0;
  Expr *p = pExpr;
  while( p ){
    int op;
    pColl = p->pColl;
    if( pColl ) break;
      break;
    op = p->op;
    if( p->pTab!=0 && (
        op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER || op==TK_TRIGGER
    )){
    }
    if( p->pTab!=0
     && (op==TK_AGG_COLUMN || op==TK_COLUMN
          || op==TK_REGISTER || op==TK_TRIGGER)
    ){
      /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
      ** a TK_COLUMN but was previously evaluated and cached in a register */
      const char *zColl;
      int j = p->iColumn;
      if( j>=0 ){
        sqlite3 *db = pParse->db;
        zColl = p->pTab->aCol[j].zColl;
        const char *zColl = p->pTab->aCol[j].zColl;
        pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
        pExpr->pColl = pColl;
      }
      break;
    }
    if( op!=TK_CAST && op!=TK_UPLUS ){
    if( p->flags & EP_Collate ){
      if( ALWAYS(p->pLeft) && (p->pLeft->flags & EP_Collate)!=0 ){
        p = p->pLeft;
      }else{
        p = p->pRight;
      }
    }else{
      break;
    }
    p = p->pLeft;
  }
  if( sqlite3CheckCollSeq(pParse, pColl) ){ 
    pColl = 0;
  }
  return pColl;
}

73713
73714
73715
73716
73717
73718
73719
73720

73721
73722
73723


73724
73725

73726
73727
73728
73729
73730
73731
73732
74012
74013
74014
74015
74016
74017
74018

74019



74020
74021


74022
74023
74024
74025
74026
74027
74028
74029







-
+
-
-
-
+
+
-
-
+







SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(
  Parse *pParse, 
  Expr *pLeft, 
  Expr *pRight
){
  CollSeq *pColl;
  assert( pLeft );
  if( pLeft->flags & EP_ExpCollate ){
  if( pLeft->flags & EP_Collate ){
    assert( pLeft->pColl );
    pColl = pLeft->pColl;
  }else if( pRight && pRight->flags & EP_ExpCollate ){
    pColl = sqlite3ExprCollSeq(pParse, pLeft);
  }else if( pRight && (pRight->flags & EP_Collate)!=0 ){
    assert( pRight->pColl );
    pColl = pRight->pColl;
    pColl = sqlite3ExprCollSeq(pParse, pRight);
  }else{
    pColl = sqlite3ExprCollSeq(pParse, pLeft);
    if( !pColl ){
      pColl = sqlite3ExprCollSeq(pParse, pRight);
    }
  }
  return pColl;
73948
73949
73950
73951
73952
73953
73954
73955
73956

73957
73958
73959
73960
73961
73962
73963

73964
73965
73966
73967
73968
73969
73970
73971
73972
74245
74246
74247
74248
74249
74250
74251


74252


74253
74254
74255


74256


74257
74258
74259
74260
74261
74262
74263







-
-
+
-
-



-
-
+
-
-







  if( pRoot==0 ){
    assert( db->mallocFailed );
    sqlite3ExprDelete(db, pLeft);
    sqlite3ExprDelete(db, pRight);
  }else{
    if( pRight ){
      pRoot->pRight = pRight;
      if( pRight->flags & EP_ExpCollate ){
        pRoot->flags |= EP_ExpCollate;
      pRoot->flags |= EP_Collate & pRight->flags;
        pRoot->pColl = pRight->pColl;
      }
    }
    if( pLeft ){
      pRoot->pLeft = pLeft;
      if( pLeft->flags & EP_ExpCollate ){
        pRoot->flags |= EP_ExpCollate;
      pRoot->flags |= EP_Collate & pLeft->flags;
        pRoot->pColl = pLeft->pColl;
      }
    }
    exprSetHeight(pRoot);
  }
}

/*
** Allocate a Expr node which joins as many as two subtrees.
74216
74217
74218
74219
74220
74221
74222
74223

74224
74225
74226
74227
74228
74229
74230
74507
74508
74509
74510
74511
74512
74513

74514
74515
74516
74517
74518
74519
74520
74521







-
+







  if( 0==(flags&EXPRDUP_REDUCE) ){
    nSize = EXPR_FULLSIZE;
  }else{
    assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
    assert( !ExprHasProperty(p, EP_FromJoin) ); 
    assert( (p->flags2 & EP2_MallocedToken)==0 );
    assert( (p->flags2 & EP2_Irreducible)==0 );
    if( p->pLeft || p->pRight || p->pColl || p->x.pList ){
    if( p->pLeft || p->pRight || p->x.pList ){
      nSize = EXPR_REDUCEDSIZE | EP_Reduced;
    }else{
      nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
    }
  }
  return nSize;
}
74433
74434
74435
74436
74437
74438
74439

74440
74441
74442
74443
74444
74445
74446
74724
74725
74726
74727
74728
74729
74730
74731
74732
74733
74734
74735
74736
74737
74738







+







    pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
    pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
    pNewItem->jointype = pOldItem->jointype;
    pNewItem->iCursor = pOldItem->iCursor;
    pNewItem->addrFillSub = pOldItem->addrFillSub;
    pNewItem->regReturn = pOldItem->regReturn;
    pNewItem->isCorrelated = pOldItem->isCorrelated;
    pNewItem->viaCoroutine = pOldItem->viaCoroutine;
    pNewItem->zIndex = sqlite3DbStrDup(db, pOldItem->zIndex);
    pNewItem->notIndexed = pOldItem->notIndexed;
    pNewItem->pIndex = pOldItem->pIndex;
    pTab = pNewItem->pTab = pOldItem->pTab;
    if( pTab ){
      pTab->nRef++;
    }
76239
76240
76241
76242
76243
76244
76245

76246
76247
76248
76249
76250
76251
76252
76531
76532
76533
76534
76535
76536
76537
76538
76539
76540
76541
76542
76543
76544
76545







+







      testcase( regFree2==0 );
      codeCompare(pParse, pLeft, pRight, OP_Le, r1, r2, r4, SQLITE_STOREP2);
      sqlite3VdbeAddOp3(v, OP_And, r3, r4, target);
      sqlite3ReleaseTempReg(pParse, r3);
      sqlite3ReleaseTempReg(pParse, r4);
      break;
    }
    case TK_COLLATE: 
    case TK_UPLUS: {
      inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
      break;
    }

    case TK_TRIGGER: {
      /* If the opcode is TK_TRIGGER, then the expression is a reference
76607
76608
76609
76610
76611
76612
76613






76614
76615
76616
76617
76618
76619
76620
76900
76901
76902
76903
76904
76905
76906
76907
76908
76909
76910
76911
76912
76913
76914
76915
76916
76917
76918
76919







+
+
+
+
+
+








    case TK_UMINUS:  zUniOp = "UMINUS"; break;
    case TK_UPLUS:   zUniOp = "UPLUS";  break;
    case TK_BITNOT:  zUniOp = "BITNOT"; break;
    case TK_NOT:     zUniOp = "NOT";    break;
    case TK_ISNULL:  zUniOp = "ISNULL"; break;
    case TK_NOTNULL: zUniOp = "NOTNULL"; break;

    case TK_COLLATE: {
      sqlite3ExplainExpr(pOut, pExpr->pLeft);
      sqlite3ExplainPrintf(pOut,".COLLATE(%s)",pExpr->u.zToken);
      break;
    }

    case TK_AGG_FUNCTION:
    case TK_CONST_FUNC:
    case TK_FUNCTION: {
      ExprList *pFarg;       /* List of function arguments */
      if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ){
        pFarg = 0;
76826
76827
76828
76829
76830
76831
76832



76833
76834
76835
76836
76837
76838
76839
77125
77126
77127
77128
77129
77130
77131
77132
77133
77134
77135
77136
77137
77138
77139
77140
77141







+
+
+







static int evalConstExpr(Walker *pWalker, Expr *pExpr){
  Parse *pParse = pWalker->pParse;
  switch( pExpr->op ){
    case TK_IN:
    case TK_REGISTER: {
      return WRC_Prune;
    }
    case TK_COLLATE: {
      return WRC_Continue;
    }
    case TK_FUNCTION:
    case TK_AGG_FUNCTION:
    case TK_CONST_FUNC: {
      /* The arguments to a function have a fixed destination.
      ** Mark them this way to avoid generated unneeded OP_SCopy
      ** instructions. 
      */
76847
76848
76849
76850
76851
76852
76853
76854
76855
76856





76857
76858
76859
76860
76861
76862
76863
77149
77150
77151
77152
77153
77154
77155



77156
77157
77158
77159
77160
77161
77162
77163
77164
77165
77166
77167







-
-
-
+
+
+
+
+







        }
      }
      break;
    }
  }
  if( isAppropriateForFactoring(pExpr) ){
    int r1 = ++pParse->nMem;
    int r2;
    r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
    if( NEVER(r1!=r2) ) sqlite3ReleaseTempReg(pParse, r1);
    int r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
    /* If r2!=r1, it means that register r1 is never used.  That is harmless
    ** but suboptimal, so we want to know about the situation to fix it.
    ** Hence the following assert: */
    assert( r2==r1 );
    pExpr->op2 = pExpr->op;
    pExpr->op = TK_REGISTER;
    pExpr->iTable = r2;
    return WRC_Prune;
  }
  return WRC_Continue;
}
77266
77267
77268
77269
77270
77271
77272
77273









77274
77275
77276
77277
77278
77279
77280
77281
77282
77283
77284
77285

77286
77287
77288
77289
77290
77291
77292
77293
77294
77295
77296
77570
77571
77572
77573
77574
77575
77576

77577
77578
77579
77580
77581
77582
77583
77584
77585
77586
77587
77588
77589
77590
77591
77592
77593
77594
77595
77596

77597
77598
77599


77600
77601
77602
77603
77604
77605
77606







-
+
+
+
+
+
+
+
+
+











-
+


-
-







  }
  assert( !ExprHasAnyProperty(pA, EP_TokenOnly|EP_Reduced) );
  assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) );
  if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
    return 2;
  }
  if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
  if( pA->op!=pB->op ) return 2;
  if( pA->op!=pB->op ){
    if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB)<2 ){
      return 1;
    }
    if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft)<2 ){
      return 1;
    }
    return 2;
  }
  if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2;
  if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2;
  if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;
  if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2;
  if( ExprHasProperty(pA, EP_IntValue) ){
    if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
      return 2;
    }
  }else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
    if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
    if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
      return 2;
      return pA->op==TK_COLLATE ? 1 : 2;
    }
  }
  if( (pA->flags & EP_ExpCollate)!=(pB->flags & EP_ExpCollate) ) return 1;
  if( (pA->flags & EP_ExpCollate)!=0 && pA->pColl!=pB->pColl ) return 2;
  return 0;
}

/*
** Compare two ExprList objects.  Return 0 if they are identical and 
** non-zero if they differ in any way.
**
77523
77524
77525
77526
77527
77528
77529

77530
77531



77532
77533
77534
77535
77536
77537
77538
77539
77540
77541
77542
77543
77544
77545




77546
77547
77548
77549
77550
77551
77552
77833
77834
77835
77836
77837
77838
77839
77840


77841
77842
77843
77844
77845
77846
77847
77848
77849
77850
77851
77852
77853
77854



77855
77856
77857
77858
77859
77860
77861
77862
77863
77864
77865







+
-
-
+
+
+











-
-
-
+
+
+
+







        }
        /* Make pExpr point to the appropriate pAggInfo->aFunc[] entry
        */
        assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
        ExprSetIrreducible(pExpr);
        pExpr->iAgg = (i16)i;
        pExpr->pAggInfo = pAggInfo;
        return WRC_Prune;
      }
      return WRC_Prune;
      }else{
        return WRC_Continue;
      }
    }
  }
  return WRC_Continue;
}
static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){
  UNUSED_PARAMETER(pWalker);
  UNUSED_PARAMETER(pSelect);
  return WRC_Continue;
}

/*
** Analyze the given expression looking for aggregate functions and
** for variables that need to be added to the pParse->aAgg[] array.
** Make additional entries to the pParse->aAgg[] array as necessary.
** Analyze the pExpr expression looking for aggregate functions and
** for variables that need to be added to AggInfo object that pNC->pAggInfo
** points to.  Additional entries are made on the AggInfo object as
** necessary.
**
** This routine should only be called after the expression has been
** analyzed by sqlite3ResolveExprNames().
*/
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
  Walker w;
  memset(&w, 0, sizeof(w));
80062
80063
80064
80065
80066
80067
80068
80069

80070
80071
80072
80073
80074
80075
80076
80375
80376
80377
80378
80379
80380
80381

80382
80383
80384
80385
80386
80387
80388
80389







-
+







  for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
    if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){
      sqlite3ErrorMsg(pFix->pParse,
         "%s %T cannot reference objects in database %s",
         pFix->zType, pFix->pName, pItem->zDatabase);
      return 1;
    }
    sqlite3_free(pItem->zDatabase);
    sqlite3DbFree(pFix->pParse->db, pItem->zDatabase);
    pItem->zDatabase = 0;
    pItem->pSchema = pFix->pSchema;
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
    if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
    if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
#endif
  }
80530
80531
80532
80533
80534
80535
80536

80537
80538
80539
80540
80541
80542
80543
80843
80844
80845
80846
80847
80848
80849
80850
80851
80852
80853
80854
80855
80856
80857







+







** Note that if an error occurred, it might be the case that
** no VDBE code was generated.
*/
SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
  sqlite3 *db;
  Vdbe *v;

  assert( pParse->pToplevel==0 );
  db = pParse->db;
  if( db->mallocFailed ) return;
  if( pParse->nested ) return;
  if( pParse->nErr ) return;

  /* Begin by generating some termination code at the end of the
  ** vdbe program
83093
83094
83095
83096
83097
83098
83099
83100

83101
83102
83103

83104
83105
83106
83107
83108
83109
83110
83407
83408
83409
83410
83411
83412
83413

83414



83415
83416
83417
83418
83419
83420
83421
83422







-
+
-
-
-
+








  /* Figure out how many bytes of space are required to store explicitly
  ** specified collation sequence names.
  */
  for(i=0; i<pList->nExpr; i++){
    Expr *pExpr = pList->a[i].pExpr;
    if( pExpr ){
      CollSeq *pColl = pExpr->pColl;
      CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr);
      /* Either pColl!=0 or there was an OOM failure.  But if an OOM
      ** failure we have quit before reaching this point. */
      if( ALWAYS(pColl) ){
      if( pColl ){
        nExtra += (1 + sqlite3Strlen30(pColl->zName));
      }
    }
  }

  /* 
  ** Allocate the index structure. 
83159
83160
83161
83162
83163
83164
83165

83166
83167
83168
83169
83170
83171
83172
83173
83174
83175
83176
83177
83178
83179
83180
83181
83182
83183



83184
83185

83186
83187
83188
83189
83190
83191
83192
83471
83472
83473
83474
83475
83476
83477
83478
83479
83480
83481
83482
83483
83484
83485
83486
83487
83488
83489
83490






83491
83492
83493
83494

83495
83496
83497
83498
83499
83500
83501
83502







+












-
-
-
-
-
-
+
+
+

-
+







  ** same column more than once cannot be an error because that would 
  ** break backwards compatibility - it needs to be a warning.
  */
  for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
    const char *zColName = pListItem->zName;
    Column *pTabCol;
    int requestedSortOrder;
    CollSeq *pColl;                /* Collating sequence */
    char *zColl;                   /* Collation sequence name */

    for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){
      if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break;
    }
    if( j>=pTab->nCol ){
      sqlite3ErrorMsg(pParse, "table %s has no column named %s",
        pTab->zName, zColName);
      pParse->checkSchema = 1;
      goto exit_create_index;
    }
    pIndex->aiColumn[i] = j;
    /* Justification of the ALWAYS(pListItem->pExpr->pColl):  Because of
    ** the way the "idxlist" non-terminal is constructed by the parser,
    ** if pListItem->pExpr is not null then either pListItem->pExpr->pColl
    ** must exist or else there must have been an OOM error.  But if there
    ** was an OOM error, we would never reach this point. */
    if( pListItem->pExpr && ALWAYS(pListItem->pExpr->pColl) ){
    if( pListItem->pExpr
     && (pColl = sqlite3ExprCollSeq(pParse, pListItem->pExpr))!=0
    ){
      int nColl;
      zColl = pListItem->pExpr->pColl->zName;
      zColl = pColl->zName;
      nColl = sqlite3Strlen30(zColl) + 1;
      assert( nExtra>=nColl );
      memcpy(zExtra, zColl, nColl);
      zColl = zExtra;
      zExtra += nColl;
      nExtra -= nColl;
    }else{
83992
83993
83994
83995
83996
83997
83998









83999
84000
84001
84002
84003
84004
84005
84302
84303
84304
84305
84306
84307
84308
84309
84310
84311
84312
84313
84314
84315
84316
84317
84318
84319
84320
84321
84322
84323
84324







+
+
+
+
+
+
+
+
+







** If iDb<0 then code the OP_Goto only - don't set flag to verify the
** schema on any databases.  This can be used to position the OP_Goto
** early in the code, before we know if any database tables will be used.
*/
SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
  Parse *pToplevel = sqlite3ParseToplevel(pParse);

#ifndef SQLITE_OMIT_TRIGGER
  if( pToplevel!=pParse ){
    /* This branch is taken if a trigger is currently being coded. In this
    ** case, set cookieGoto to a non-zero value to show that this function
    ** has been called. This is used by the sqlite3ExprCodeConstants()
    ** function. */
    pParse->cookieGoto = -1;
  }
#endif
  if( pToplevel->cookieGoto==0 ){
    Vdbe *v = sqlite3GetVdbe(pToplevel);
    if( v==0 ) return;  /* This only happens if there was a prior error */
    pToplevel->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1;
  }
  if( iDb>=0 ){
    sqlite3 *db = pToplevel->db;
84858
84859
84860
84861
84862
84863
84864

84865
84866
84867
84868
84869
84870
84871
85177
85178
85179
85180
85181
85182
85183
85184
85185
85186
85187
85188
85189
85190
85191







+







      pFrom->a[0].pSelect = pDup;
      assert( pFrom->a[0].pOn==0 );
      assert( pFrom->a[0].pUsing==0 );
    }else{
      sqlite3SelectDelete(db, pDup);
    }
    pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0);
    if( pDup ) pDup->selFlags |= SF_Materialize;
  }
  sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
  sqlite3Select(pParse, pDup, &dest);
  sqlite3SelectDelete(db, pDup);
}
#endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */

85567
85568
85569
85570
85571
85572
85573


















































85574
85575
85576
85577
85578
85579
85580
85887
85888
85889
85890
85891
85892
85893
85894
85895
85896
85897
85898
85899
85900
85901
85902
85903
85904
85905
85906
85907
85908
85909
85910
85911
85912
85913
85914
85915
85916
85917
85918
85919
85920
85921
85922
85923
85924
85925
85926
85927
85928
85929
85930
85931
85932
85933
85934
85935
85936
85937
85938
85939
85940
85941
85942
85943
85944
85945
85946
85947
85948
85949
85950







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







      double rVal = sqlite3_value_double(argv[0]);
      if( rVal<0 ) rVal = -rVal;
      sqlite3_result_double(context, rVal);
      break;
    }
  }
}

/*
** Implementation of the instr() function.
**
** instr(haystack,needle) finds the first occurrence of needle
** in haystack and returns the number of previous characters plus 1,
** or 0 if needle does not occur within haystack.
**
** If both haystack and needle are BLOBs, then the result is one more than
** the number of bytes in haystack prior to the first occurrence of needle,
** or 0 if needle never occurs in haystack.
*/
static void instrFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const unsigned char *zHaystack;
  const unsigned char *zNeedle;
  int nHaystack;
  int nNeedle;
  int typeHaystack, typeNeedle;
  int N = 1;
  int isText;

  UNUSED_PARAMETER(argc);
  typeHaystack = sqlite3_value_type(argv[0]);
  typeNeedle = sqlite3_value_type(argv[1]);
  if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return;
  nHaystack = sqlite3_value_bytes(argv[0]);
  nNeedle = sqlite3_value_bytes(argv[1]);
  if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){
    zHaystack = sqlite3_value_blob(argv[0]);
    zNeedle = sqlite3_value_blob(argv[1]);
    isText = 0;
  }else{
    zHaystack = sqlite3_value_text(argv[0]);
    zNeedle = sqlite3_value_text(argv[1]);
    isText = 1;
  }
  while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){
    N++;
    do{
      nHaystack--;
      zHaystack++;
    }while( isText && (zHaystack[0]&0xc0)==0x80 );
  }
  if( nNeedle>nHaystack ) N = 0;
  sqlite3_result_int(context, N);
}

/*
** Implementation of the substr() function.
**
** substr(x,p1,p2)  returns p2 characters of x[] beginning with p1.
** p1 is 1-indexed.  So substr(x,1,1) returns the first character
** of x.  If x is text, then we actually count UTF-8 characters.
86936
86937
86938
86939
86940
86941
86942

86943
86944
86945
86946
86947
86948
86949
87306
87307
87308
87309
87310
87311
87312
87313
87314
87315
87316
87317
87318
87319
87320







+







    FUNCTION(min,                0, 0, 1, 0                ),
    AGGREGATE(min,               1, 0, 1, minmaxStep,      minMaxFinalize ),
    FUNCTION(max,               -1, 1, 1, minmaxFunc       ),
    FUNCTION(max,                0, 1, 1, 0                ),
    AGGREGATE(max,               1, 1, 1, minmaxStep,      minMaxFinalize ),
    FUNCTION2(typeof,            1, 0, 0, typeofFunc,  SQLITE_FUNC_TYPEOF),
    FUNCTION2(length,            1, 0, 0, lengthFunc,  SQLITE_FUNC_LENGTH),
    FUNCTION(instr,              2, 0, 0, instrFunc        ),
    FUNCTION(substr,             2, 0, 0, substrFunc       ),
    FUNCTION(substr,             3, 0, 0, substrFunc       ),
    FUNCTION(abs,                1, 0, 0, absFunc          ),
#ifndef SQLITE_OMIT_FLOATING_POINT
    FUNCTION(round,              1, 0, 0, roundFunc        ),
    FUNCTION(round,              2, 0, 0, roundFunc        ),
#endif
87519
87520
87521
87522
87523
87524
87525

87526
87527
87528
87529
87530
87531



87532
87533
87534
87535
87536
87537
87538
87890
87891
87892
87893
87894
87895
87896
87897
87898
87899
87900
87901
87902

87903
87904
87905
87906
87907
87908
87909
87910
87911
87912







+





-
+
+
+








    pLeft = sqlite3Expr(db, TK_REGISTER, 0);
    if( pLeft ){
      /* Set the collation sequence and affinity of the LHS of each TK_EQ
      ** expression to the parent key column defaults.  */
      if( pIdx ){
        Column *pCol;
        const char *zColl;
        iCol = pIdx->aiColumn[i];
        pCol = &pTab->aCol[iCol];
        if( pTab->iPKey==iCol ) iCol = -1;
        pLeft->iTable = regData+iCol+1;
        pLeft->affinity = pCol->affinity;
        pLeft->pColl = sqlite3LocateCollSeq(pParse, pCol->zColl);
        zColl = pCol->zColl;
        if( zColl==0 ) zColl = db->pDfltColl->zName;
        pLeft = sqlite3ExprAddCollateString(pParse, pLeft, zColl);
      }else{
        pLeft->iTable = regData;
        pLeft->affinity = SQLITE_AFF_INTEGER;
      }
    }
    iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
    assert( iCol>=0 );
88255
88256
88257
88258
88259
88260
88261
88262

88263
88264
88265
88266
88267
88268
88269
88629
88630
88631
88632
88633
88634
88635

88636
88637
88638
88639
88640
88641
88642
88643







-
+







  Parse *p,       /* Generate code into this VDBE */
  int iCur,       /* The cursor number of the table */
  int iDb,        /* The database index in sqlite3.aDb[] */
  Table *pTab,    /* The table to be opened */
  int opcode      /* OP_OpenRead or OP_OpenWrite */
){
  Vdbe *v;
  if( IsVirtual(pTab) ) return;
  assert( !IsVirtual(pTab) );
  v = sqlite3GetVdbe(p);
  assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
  sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName);
  sqlite3VdbeAddOp3(v, opcode, iCur, pTab->tnum, iDb);
  sqlite3VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(pTab->nCol), P4_INT32);
  VdbeComment((v, "%s", pTab->zName));
}
89504
89505
89506
89507
89508
89509
89510
89511
89512
89513
89514
89515
89516
89517
89518
89519
89520
89521
89522
89523
89524
89525
89526
89527














89528
89529
89530
89531
89532
89533
89534
89535
89536
89878
89879
89880
89881
89882
89883
89884

















89885
89886
89887
89888
89889
89890
89891
89892
89893
89894
89895
89896
89897
89898


89899
89900
89901
89902
89903
89904
89905







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







#ifndef SQLITE_OMIT_CHECK
  if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
    ExprList *pCheck = pTab->pCheck;
    pParse->ckBase = regData;
    onError = overrideError!=OE_Default ? overrideError : OE_Abort;
    for(i=0; i<pCheck->nExpr; i++){
      int allOk = sqlite3VdbeMakeLabel(v);
      Expr *pDup = sqlite3ExprDup(db, pCheck->a[i].pExpr, 0);
      if( !db->mallocFailed ){
        assert( pDup!=0 );
        sqlite3ExprIfTrue(pParse, pDup, allOk, SQLITE_JUMPIFNULL);
        if( onError==OE_Ignore ){
          sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
        }else{
          char *zConsName = pCheck->a[i].zName;
          if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
          if( zConsName ){
            zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
          }else{
            zConsName = 0;
          }
          sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
        }
        sqlite3VdbeResolveLabel(v, allOk);
      sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL);
      if( onError==OE_Ignore ){
        sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
      }else{
        char *zConsName = pCheck->a[i].zName;
        if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
        if( zConsName ){
          zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
        }else{
          zConsName = 0;
        }
        sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
      }
      sqlite3VdbeResolveLabel(v, allOk);
      }
      sqlite3ExprDelete(db, pDup);
    }
  }
#endif /* !defined(SQLITE_OMIT_CHECK) */

  /* If we have an INTEGER PRIMARY KEY, make sure the primary key
  ** of the new record does not previously exist.  Except, if this
  ** is an UPDATE and the primary key is not changing, that is OK.
95249
95250
95251
95252
95253
95254
95255
95256

95257
95258
95259
95260
95261
95262
95263
95618
95619
95620
95621
95622
95623
95624

95625
95626
95627
95628
95629
95630
95631
95632







-
+







  }
  *pnCol = nCol;
  *paCol = aCol;

  for(i=0, pCol=aCol; i<nCol; i++, pCol++){
    /* Get an appropriate name for the column
    */
    p = pEList->a[i].pExpr;
    p = sqlite3ExprSkipCollate(pEList->a[i].pExpr);
    assert( p->pRight==0 || ExprHasProperty(p->pRight, EP_IntValue)
               || p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 );
    if( (zName = pEList->a[i].zName)!=0 ){
      /* If the column contains an "AS <name>" phrase, use <name> as the name */
      zName = sqlite3DbStrDup(db, zName);
    }else{
      Expr *pColExpr = p;  /* The expression that is the result column name */
96247
96248
96249
96250
96251
96252
96253
96254
96255


96256
96257
96258
96259



96260
96261
96262
96263
96264
96265
96266
96616
96617
96618
96619
96620
96621
96622


96623
96624
96625
96626


96627
96628
96629
96630
96631
96632
96633
96634
96635
96636







-
-
+
+


-
-
+
+
+







    if( pKeyMerge ){
      pKeyMerge->aSortOrder = (u8*)&pKeyMerge->aColl[nOrderBy];
      pKeyMerge->nField = (u16)nOrderBy;
      pKeyMerge->enc = ENC(db);
      for(i=0; i<nOrderBy; i++){
        CollSeq *pColl;
        Expr *pTerm = pOrderBy->a[i].pExpr;
        if( pTerm->flags & EP_ExpCollate ){
          pColl = pTerm->pColl;
        if( pTerm->flags & EP_Collate ){
          pColl = sqlite3ExprCollSeq(pParse, pTerm);
        }else{
          pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
          pTerm->flags |= EP_ExpCollate;
          pTerm->pColl = pColl;
          if( pColl==0 ) pColl = db->pDfltColl;
          pOrderBy->a[i].pExpr =
             sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
        }
        pKeyMerge->aColl[i] = pColl;
        pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
      }
    }
  }else{
    pKeyMerge = 0;
96455
96456
96457
96458
96459
96460
96461

96462
96463
96464
96465
96466
96467
96468
96825
96826
96827
96828
96829
96830
96831
96832
96833
96834
96835
96836
96837
96838
96839







+








  /* Implement the main merge loop
  */
  sqlite3VdbeResolveLabel(v, labelCmpr);
  sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
  sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
                         (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
  sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
  sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);

  /* Release temporary registers
  */
  if( regPrev ){
    sqlite3ReleaseTempRange(pParse, regPrev, nOrderBy+1);
  }
96522
96523
96524
96525
96526
96527
96528
96529
96530
96531
96532
96533
96534
96535
96536
96537
96538
96893
96894
96895
96896
96897
96898
96899



96900
96901
96902
96903
96904
96905
96906







-
-
-







    if( pExpr->iColumn<0 ){
      pExpr->op = TK_NULL;
    }else{
      Expr *pNew;
      assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
      assert( pExpr->pLeft==0 && pExpr->pRight==0 );
      pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0);
      if( pNew && pExpr->pColl ){
        pNew->pColl = pExpr->pColl;
      }
      sqlite3ExprDelete(db, pExpr);
      pExpr = pNew;
    }
  }else{
    pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList);
    pExpr->pRight = substExpr(db, pExpr->pRight, iTable, pEList);
    if( ExprHasProperty(pExpr, EP_xIsSelect) ){
97012
97013
97014
97015
97016
97017
97018
97019
97020
97021



97022
97023
97024
97025
97026
97027
97028
97029
97380
97381
97382
97383
97384
97385
97386



97387
97388
97389

97390
97391
97392
97393
97394
97395
97396







-
-
-
+
+
+
-







    **
    ** We look at every expression in the outer query and every place we see
    ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
    */
    pList = pParent->pEList;
    for(i=0; i<pList->nExpr; i++){
      if( pList->a[i].zName==0 ){
        const char *zSpan = pList->a[i].zSpan;
        if( ALWAYS(zSpan) ){
          pList->a[i].zName = sqlite3DbStrDup(db, zSpan);
        char *zName = sqlite3DbStrDup(db, pList->a[i].zSpan);
        sqlite3Dequote(zName);
        pList->a[i].zName = zName;
        }
      }
    }
    substExprList(db, pParent->pEList, iParent, pSub->pEList);
    if( isAgg ){
      substExprList(db, pParent->pGroupBy, iParent, pSub->pEList);
      pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
    }
97824
97825
97826
97827
97828
97829
97830







97831

97832


97833
97834
97835
97836
97837
97838
97839
97840
97841
97842
97843
97844
97845
97846
97847
97848
97849
97850
97851
97852






































97853
97854
97855
97856
97857
97858
97859
98191
98192
98193
98194
98195
98196
98197
98198
98199
98200
98201
98202
98203
98204
98205
98206

98207
98208
98209
98210
98211
98212
98213
98214
98215
98216
98217
98218
98219
98220
98221
98222
98223
98224
98225
98226
98227
98228
98229
98230
98231
98232
98233
98234
98235
98236
98237
98238
98239
98240
98241
98242
98243
98244
98245
98246
98247
98248
98249
98250
98251
98252
98253
98254
98255
98256
98257
98258
98259
98260
98261
98262
98263
98264
98265
98266
98267
98268
98269
98270
98271
98272
98273







+
+
+
+
+
+
+

+
-
+
+




















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







  for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
    struct SrcList_item *pItem = &pTabList->a[i];
    SelectDest dest;
    Select *pSub = pItem->pSelect;
    int isAggSub;

    if( pSub==0 ) continue;

    /* Sometimes the code for a subquery will be generated more than
    ** once, if the subquery is part of the WHERE clause in a LEFT JOIN,
    ** for example.  In that case, do not regenerate the code to manifest
    ** a view or the co-routine to implement a view.  The first instance
    ** is sufficient, though the subroutine to manifest the view does need
    ** to be invoked again. */
    if( pItem->addrFillSub ){
      if( pItem->viaCoroutine==0 ){
      sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
        sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
      }
      continue;
    }

    /* Increment Parse.nHeight by the height of the largest expression
    ** tree refered to by this, the parent select. The child select
    ** may contain expression trees of at most
    ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit
    ** more conservative than necessary, but much easier than enforcing
    ** an exact limit.
    */
    pParse->nHeight += sqlite3SelectExprHeight(p);

    isAggSub = (pSub->selFlags & SF_Aggregate)!=0;
    if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){
      /* This subquery can be absorbed into its parent. */
      if( isAggSub ){
        isAgg = 1;
        p->selFlags |= SF_Aggregate;
      }
      i = -1;
    }else if( pTabList->nSrc==1 && (p->selFlags & SF_Materialize)==0
      && OptimizationEnabled(db, SQLITE_SubqCoroutine)
    ){
      /* Implement a co-routine that will return a single row of the result
      ** set on each invocation.
      */
      int addrTop;
      int addrEof;
      pItem->regReturn = ++pParse->nMem;
      addrEof = ++pParse->nMem;
      /* Before coding the OP_Goto to jump to the start of the main routine,
      ** ensure that the jump to the verify-schema routine has already
      ** been coded. Otherwise, the verify-schema would likely be coded as 
      ** part of the co-routine. If the main routine then accessed the 
      ** database before invoking the co-routine for the first time (for 
      ** example to initialize a LIMIT register from a sub-select), it would 
      ** be doing so without having verified the schema version and obtained 
      ** the required db locks. See ticket d6b36be38.  */
      sqlite3CodeVerifySchema(pParse, -1);
      sqlite3VdbeAddOp0(v, OP_Goto);
      addrTop = sqlite3VdbeAddOp1(v, OP_OpenPseudo, pItem->iCursor);
      sqlite3VdbeChangeP5(v, 1);
      VdbeComment((v, "coroutine for %s", pItem->pTab->zName));
      pItem->addrFillSub = addrTop;
      sqlite3VdbeAddOp2(v, OP_Integer, 0, addrEof);
      sqlite3VdbeChangeP5(v, 1);
      sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
      explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
      sqlite3Select(pParse, pSub, &dest);
      pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow;
      pItem->viaCoroutine = 1;
      sqlite3VdbeChangeP2(v, addrTop, dest.iSdst);
      sqlite3VdbeChangeP3(v, addrTop, dest.nSdst);
      sqlite3VdbeAddOp2(v, OP_Integer, 1, addrEof);
      sqlite3VdbeAddOp1(v, OP_Yield, pItem->regReturn);
      VdbeComment((v, "end %s", pItem->pTab->zName));
      sqlite3VdbeJumpHere(v, addrTop-1);
      sqlite3ClearTempRegCache(pParse);
    }else{
      /* Generate a subroutine that will fill an ephemeral table with
      ** the content of this subquery.  pItem->addrFillSub will point
      ** to the address of the generated subroutine.  pItem->regReturn
      ** is a register allocated to hold the subroutine return address
      */
      int topAddr;
99504
99505
99506
99507
99508
99509
99510









99511
99512
99513
99514
99515
99516
99517
99918
99919
99920
99921
99922
99923
99924
99925
99926
99927
99928
99929
99930
99931
99932
99933
99934
99935
99936
99937
99938
99939
99940







+
+
+
+
+
+
+
+
+







    **   END;
    **
    **   INSERT INTO t1 ... ;            -- insert into t2 uses REPLACE policy
    **   INSERT OR IGNORE INTO t1 ... ;  -- insert into t2 uses IGNORE policy
    */
    pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf;

    /* Clear the cookieGoto flag. When coding triggers, the cookieGoto 
    ** variable is used as a flag to indicate to sqlite3ExprCodeConstants()
    ** that it is not safe to refactor constants (this happens after the
    ** start of the first loop in the SQL statement is coded - at that 
    ** point code may be conditionally executed, so it is no longer safe to 
    ** initialize constant register values).  */
    assert( pParse->cookieGoto==0 || pParse->cookieGoto==-1 );
    pParse->cookieGoto = 0;

    switch( pStep->op ){
      case TK_UPDATE: {
        sqlite3Update(pParse, 
          targetSrcList(pParse, pStep),
          sqlite3ExprListDup(db, pStep->pExprList, 0), 
          sqlite3ExprDup(db, pStep->pWhere, 0), 
          pParse->eOrconf
100660
100661
100662
100663
100664
100665
100666

100667
100668
100669
100670
100671
100672
100673
101083
101084
101085
101086
101087
101088
101089
101090
101091
101092
101093
101094
101095
101096
101097







+







** with 2.0.0, SQLite no longer uses GDBM so this command has
** become a no-op.
*/
SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse){
  Vdbe *v = sqlite3GetVdbe(pParse);
  if( v ){
    sqlite3VdbeAddOp2(v, OP_Vacuum, 0, 0);
    sqlite3VdbeUsesBtree(v, 0);
  }
  return;
}

/*
** This routine implements the OP_Vacuum opcode of the VDBE.
*/
101419
101420
101421
101422
101423
101424
101425
101426
101427
101428
101429
101430
101431
101432
101433
101434
101435
101436
101437
101438
101439
101440
101441
101442
101443
101444
101445
101446
101447
101843
101844
101845
101846
101847
101848
101849

101850
101851
101852
101853
101854
101855
101856
101857
101858
101859
101860
101861
101862

101863
101864
101865
101866
101867
101868
101869







-













-







  if( !pVTable ){
    sqlite3DbFree(db, zModuleName);
    return SQLITE_NOMEM;
  }
  pVTable->db = db;
  pVTable->pMod = pMod;

  assert( pTab->azModuleArg[1]==0 );
  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  pTab->azModuleArg[1] = db->aDb[iDb].zName;

  /* Invoke the virtual table constructor */
  assert( &db->pVtabCtx );
  assert( xConstruct );
  sCtx.pTab = pTab;
  sCtx.pVTable = pVTable;
  pPriorCtx = db->pVtabCtx;
  db->pVtabCtx = &sCtx;
  rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
  db->pVtabCtx = pPriorCtx;
  if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
  pTab->azModuleArg[1] = 0;

  if( SQLITE_OK!=rc ){
    if( zErr==0 ){
      *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName);
    }else {
      *pzErr = sqlite3MPrintf(db, "%s", zErr);
      sqlite3_free(zErr);
102430
102431
102432
102433
102434
102435
102436
102437

102438
102439
102440
102441
102442
102443
102444
102852
102853
102854
102855
102856
102857
102858

102859
102860
102861
102862
102863
102864
102865
102866







-
+







    memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
    if( pOld!=pWC->aStatic ){
      sqlite3DbFree(db, pOld);
    }
    pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
  }
  pTerm = &pWC->a[idx = pWC->nTerm++];
  pTerm->pExpr = p;
  pTerm->pExpr = sqlite3ExprSkipCollate(p);
  pTerm->wtFlags = wtFlags;
  pTerm->pWC = pWC;
  pTerm->iParent = -1;
  return idx;
}

/*
102590
102591
102592
102593
102594
102595
102596

102597

102598
102599
102600

102601
102602

102603
102604
102605
102606
102607


102608





102609
102610


102611
102612
102613






102614
102615
102616
102617
102618
102619
102620
103012
103013
103014
103015
103016
103017
103018
103019

103020
103021
103022

103023
103024

103025
103026
103027
103028


103029
103030
103031
103032
103033
103034
103035
103036


103037
103038



103039
103040
103041
103042
103043
103044
103045
103046
103047
103048
103049
103050
103051







+
-
+


-
+

-
+



-
-
+
+

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







*/
#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}

/*
** Commute a comparison operator.  Expressions of the form "X op Y"
** are converted into "Y op X".
**
** If left/right precendence rules come into play when determining the
** If a collation sequence is associated with either the left or right
** collating
** side of the comparison, it remains associated with the same side after
** the commutation. So "Y collate NOCASE op X" becomes 
** "X collate NOCASE op Y". This is because any collation sequence on
** "X op Y". This is because any collation sequence on
** the left hand side of a comparison overrides any collation sequence 
** attached to the right. For the same reason the EP_ExpCollate flag
** attached to the right. For the same reason the EP_Collate flag
** is not commuted.
*/
static void exprCommute(Parse *pParse, Expr *pExpr){
  u16 expRight = (pExpr->pRight->flags & EP_ExpCollate);
  u16 expLeft = (pExpr->pLeft->flags & EP_ExpCollate);
  u16 expRight = (pExpr->pRight->flags & EP_Collate);
  u16 expLeft = (pExpr->pLeft->flags & EP_Collate);
  assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN );
  if( expRight==expLeft ){
    /* Either X and Y both have COLLATE operator or neither do */
    if( expRight ){
      /* Both X and Y have COLLATE operators.  Make sure X is always
      ** used by clearing the EP_Collate flag from Y. */
  pExpr->pRight->pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight);
  pExpr->pLeft->pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
      pExpr->pRight->flags &= ~EP_Collate;
    }else if( sqlite3ExprCollSeq(pParse, pExpr->pLeft)!=0 ){
  SWAP(CollSeq*,pExpr->pRight->pColl,pExpr->pLeft->pColl);
  pExpr->pRight->flags = (pExpr->pRight->flags & ~EP_ExpCollate) | expLeft;
  pExpr->pLeft->flags = (pExpr->pLeft->flags & ~EP_ExpCollate) | expRight;
      /* Neither X nor Y have COLLATE operators, but X has a non-default
      ** collating sequence.  So add the EP_Collate marker on X to cause
      ** it to be searched first. */
      pExpr->pLeft->flags |= EP_Collate;
    }
  }
  SWAP(Expr*,pExpr->pRight,pExpr->pLeft);
  if( pExpr->op>=TK_GT ){
    assert( TK_LT==TK_GT+2 );
    assert( TK_GE==TK_LE+2 );
    assert( TK_GT>TK_EQ );
    assert( TK_GT<TK_LE );
    assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE );
102683
102684
102685
102686
102687
102688
102689
102690

102691
102692
102693
102694
102695

102696
102697
102698
102699
102700
102701
102702
103114
103115
103116
103117
103118
103119
103120

103121
103122
103123
103124
103125

103126
103127
103128
103129
103130
103131
103132
103133







-
+




-
+







  
          /* Figure out the collation sequence required from an index for
          ** it to be useful for optimising expression pX. Store this
          ** value in variable pColl.
          */
          assert(pX->pLeft);
          pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
          assert(pColl || pParse->nErr);
          if( pColl==0 ) pColl = pParse->db->pDfltColl;
  
          for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
            if( NEVER(j>=pIdx->nColumn) ) return 0;
          }
          if( pColl && sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
          if( sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
        }
        return pTerm;
      }
    }
  }
  return 0;
}
103207
103208
103209
103210
103211
103212
103213

103214
103215
103216
103217
103218
103219
103220
103638
103639
103640
103641
103642
103643
103644
103645
103646
103647
103648
103649
103650
103651
103652







+








  if( db->mallocFailed ){
    return;
  }
  pTerm = &pWC->a[idxTerm];
  pMaskSet = pWC->pMaskSet;
  pExpr = pTerm->pExpr;
  assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE );
  prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
  op = pExpr->op;
  if( op==TK_IN ){
    assert( pExpr->pRight==0 );
    if( ExprHasProperty(pExpr, EP_xIsSelect) ){
      pTerm->prereqRight = exprSelectTableUsage(pMaskSet, pExpr->x.pSelect);
    }else{
103233
103234
103235
103236
103237
103238
103239
103240
103241


103242
103243
103244
103245
103246
103247
103248
103665
103666
103667
103668
103669
103670
103671


103672
103673
103674
103675
103676
103677
103678
103679
103680







-
-
+
+







                       ** on left table of a LEFT JOIN.  Ticket #3015 */
  }
  pTerm->prereqAll = prereqAll;
  pTerm->leftCursor = -1;
  pTerm->iParent = -1;
  pTerm->eOperator = 0;
  if( allowedOp(op) && (pTerm->prereqRight & prereqLeft)==0 ){
    Expr *pLeft = pExpr->pLeft;
    Expr *pRight = pExpr->pRight;
    Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
    Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
    if( pLeft->op==TK_COLUMN ){
      pTerm->leftCursor = pLeft->iTable;
      pTerm->u.leftColumn = pLeft->iColumn;
      pTerm->eOperator = operatorMask(op);
    }
    if( pRight && pRight->op==TK_COLUMN ){
      WhereTerm *pNew;
103262
103263
103264
103265
103266
103267
103268
103269

103270
103271
103272
103273
103274
103275
103276
103694
103695
103696
103697
103698
103699
103700

103701
103702
103703
103704
103705
103706
103707
103708







-
+







        pTerm->nChild = 1;
        pTerm->wtFlags |= TERM_COPIED;
      }else{
        pDup = pExpr;
        pNew = pTerm;
      }
      exprCommute(pParse, pDup);
      pLeft = pDup->pLeft;
      pLeft = sqlite3ExprSkipCollate(pDup->pLeft);
      pNew->leftCursor = pLeft->iTable;
      pNew->u.leftColumn = pLeft->iColumn;
      testcase( (prereqLeft | extraRight) != prereqLeft );
      pNew->prereqRight = prereqLeft | extraRight;
      pNew->prereqAll = prereqAll;
      pNew->eOperator = operatorMask(pDup->op);
    }
103341
103342
103343
103344
103345
103346
103347
103348

103349
103350
103351
103352
103353
103354
103355
103773
103774
103775
103776
103777
103778
103779

103780
103781
103782
103783
103784
103785
103786
103787







-
+







  ){
    Expr *pLeft;       /* LHS of LIKE/GLOB operator */
    Expr *pStr2;       /* Copy of pStr1 - RHS of LIKE/GLOB operator */
    Expr *pNewExpr1;
    Expr *pNewExpr2;
    int idxNew1;
    int idxNew2;
    CollSeq *pColl;    /* Collating sequence to use */
    Token sCollSeqName;  /* Name of collating sequence */

    pLeft = pExpr->x.pList->a[1].pExpr;
    pStr2 = sqlite3ExprDup(db, pStr1, 0);
    if( !db->mallocFailed ){
      u8 c, *pC;       /* Last character before the first wildcard */
      pC = (u8*)&pStr2->u.zToken[sqlite3Strlen30(pStr2->u.zToken)-1];
      c = *pC;
103363
103364
103365
103366
103367
103368
103369
103370



103371
103372
103373


103374
103375
103376

103377
103378
103379


103380
103381
103382
103383
103384
103385
103386
103795
103796
103797
103798
103799
103800
103801

103802
103803
103804
103805


103806
103807
103808
103809
103810
103811
103812


103813
103814
103815
103816
103817
103818
103819
103820
103821







-
+
+
+

-
-
+
+



+

-
-
+
+







        if( c=='A'-1 ) isComplete = 0;   /* EV: R-64339-08207 */


        c = sqlite3UpperToLower[c];
      }
      *pC = c + 1;
    }
    pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, noCase ? "NOCASE" : "BINARY",0);
    sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
    sCollSeqName.n = 6;
    pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
    pNewExpr1 = sqlite3PExpr(pParse, TK_GE, 
                     sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl),
                     pStr1, 0);
           sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName),
           pStr1, 0);
    idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
    testcase( idxNew1==0 );
    exprAnalyze(pSrc, pWC, idxNew1);
    pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
    pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
                     sqlite3ExprSetColl(sqlite3ExprDup(db,pLeft,0), pColl),
                     pStr2, 0);
           sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName),
           pStr2, 0);
    idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
    testcase( idxNew2==0 );
    exprAnalyze(pSrc, pWC, idxNew2);
    pTerm = &pWC->a[idxTerm];
    if( isComplete ){
      pWC->a[idxNew1].iParent = idxTerm;
      pWC->a[idxNew2].iParent = idxTerm;
103490
103491
103492
103493
103494
103495
103496
103497

103498
103499
103500
103501
103502

103503
103504
103505
103506
103507
103508
103509
103925
103926
103927
103928
103929
103930
103931

103932
103933
103934
103935
103936

103937
103938
103939
103940
103941
103942
103943
103944







-
+




-
+







  Index *pIdx,                    /* Index to match column of */
  int iCol                        /* Column of index to match */
){
  int i;
  const char *zColl = pIdx->azColl[iCol];

  for(i=0; i<pList->nExpr; i++){
    Expr *p = pList->a[i].pExpr;
    Expr *p = sqlite3ExprSkipCollate(pList->a[i].pExpr);
    if( p->op==TK_COLUMN
     && p->iColumn==pIdx->aiColumn[iCol]
     && p->iTable==iBase
    ){
      CollSeq *pColl = sqlite3ExprCollSeq(pParse, p);
      CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
      if( ALWAYS(pColl) && 0==sqlite3StrICmp(pColl->zName, zColl) ){
        return i;
      }
    }
  }

  return -1;
103542
103543
103544
103545
103546
103547
103548
103549

103550
103551
103552
103553
103554
103555
103556
103977
103978
103979
103980
103981
103982
103983

103984
103985
103986
103987
103988
103989
103990
103991







-
+







  ** can be ignored. If it does not, and the column does not belong to the
  ** same table as index pIdx, return early. Finally, if there is no
  ** matching "col=X" expression and the column is on the same table as pIdx,
  ** set the corresponding bit in variable mask.
  */
  for(i=0; i<pDistinct->nExpr; i++){
    WhereTerm *pTerm;
    Expr *p = pDistinct->a[i].pExpr;
    Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr);
    if( p->op!=TK_COLUMN ) return 0;
    pTerm = findTerm(pWC, p->iTable, p->iColumn, ~(Bitmask)0, WO_EQ, 0);
    if( pTerm ){
      Expr *pX = pTerm->pExpr;
      CollSeq *p1 = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
      CollSeq *p2 = sqlite3ExprCollSeq(pParse, p);
      if( p1==p2 ) continue;
103594
103595
103596
103597
103598
103599
103600
103601

103602
103603
103604
103605
103606
103607
103608
104029
104030
104031
104032
104033
104034
104035

104036
104037
104038
104039
104040
104041
104042
104043







-
+







  pTab = pTabList->a[0].pTab;

  /* If any of the expressions is an IPK column on table iBase, then return 
  ** true. Note: The (p->iTable==iBase) part of this test may be false if the
  ** current SELECT is a correlated sub-query.
  */
  for(i=0; i<pDistinct->nExpr; i++){
    Expr *p = pDistinct->a[i].pExpr;
    Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr);
    if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1;
  }

  /* Loop through all indices on the table, checking each to see if it makes
  ** the DISTINCT qualifier redundant. It does so if:
  **
  **   1. The index is itself UNIQUE, and
103842
103843
103844
103845
103846
103847
103848
103849



103850
103851




103852
103853
103854
103855
103856
103857
103858
104277
104278
104279
104280
104281
104282
104283

104284
104285
104286
104287
104288
104289
104290
104291
104292
104293
104294
104295
104296
104297
104298
104299







-
+
+
+


+
+
+
+







    /* There is no point in building an automatic index for a single scan */
    return;
  }
  if( (pParse->db->flags & SQLITE_AutoIndex)==0 ){
    /* Automatic indices are disabled at run-time */
    return;
  }
  if( (p->cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0 ){
  if( (p->cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0
   && (p->cost.plan.wsFlags & WHERE_COVER_SCAN)==0
  ){
    /* We already have some kind of index in use for this query. */
    return;
  }
  if( pSrc->viaCoroutine ){
    /* Cannot index a co-routine */
    return;
  }
  if( pSrc->notIndexed ){
    /* The NOT INDEXED clause appears in the SQL. */
    return;
  }
  if( pSrc->isCorrelated ){
    /* The source is a correlated sub-query. No point in indexing it. */
104874
104875
104876
104877
104878
104879
104880
104881

104882
104883
104884
104885
104886
104887
104888
105315
105316
105317
105318
105319
105320
105321

105322
105323
105324
105325
105326
105327
105328
105329







-
+







    int isMatch;            /* ORDER BY term matches the index term */
    const char *zColl;      /* Name of collating sequence for i-th index term */
    WhereTerm *pConstraint; /* A constraint in the WHERE clause */

    /* If the next term of the ORDER BY clause refers to anything other than
    ** a column in the "base" table, then this index will not be of any
    ** further use in handling the ORDER BY. */
    pOBExpr = pOBItem->pExpr;
    pOBExpr = sqlite3ExprSkipCollate(pOBItem->pExpr);
    if( pOBExpr->op!=TK_COLUMN || pOBExpr->iTable!=base ){
      break;
    }

    /* Find column number and collating sequence for the next entry
    ** in the index */
    if( pIdx->zName && i<pIdx->nColumn ){
104900
104901
104902
104903
104904
104905
104906
104907

104908
104909
104910
104911
104912
104913
104914
105341
105342
105343
105344
105345
105346
105347

105348
105349
105350
105351
105352
105353
105354
105355







-
+







    }

    /* Check to see if the column number and collating sequence of the
    ** index match the column number and collating sequence of the ORDER BY
    ** clause entry.  Set isMatch to 1 if they both match. */
    if( pOBExpr->iColumn==iColumn ){
      if( zColl ){
        pColl = sqlite3ExprCollSeq(pParse, pOBExpr);
        pColl = sqlite3ExprCollSeq(pParse, pOBItem->pExpr);
        if( !pColl ) pColl = db->pDfltColl;
        isMatch = sqlite3StrICmp(pColl->zName, zColl)==0;
      }else{
        isMatch = 1;
      }
    }else{
      isMatch = 0;
105023
105024
105025
105026
105027
105028
105029
105030

105031
105032
105033
105034
105035
105036
105037
105038
105039
105040
105041
105042
105043
105044
105045
105046
105047





105048
105049
105050
105051
105052
105053
105054
105464
105465
105466
105467
105468
105469
105470

105471
105472
105473
105474
105475
105476
105477
105478
105479
105480
105481
105482
105483
105484
105485
105486
105487
105488
105489
105490
105491
105492
105493
105494
105495
105496
105497
105498
105499
105500







-
+

















+
+
+
+
+







**
** If there was an INDEXED BY clause (pSrc->pIndex) attached to the table in
** the SQL statement, then this function only considers plans using the 
** named index. If no such plan is found, then the returned cost is
** SQLITE_BIG_DBL. If a plan is found that uses the named index, 
** then the cost is calculated in the usual way.
**
** If a NOT INDEXED clause (pSrc->notIndexed!=0) was attached to the table 
** If a NOT INDEXED clause was attached to the table 
** in the SELECT statement, then no indexes are considered. However, the 
** selected plan may still take advantage of the built-in rowid primary key
** index.
*/
static void bestBtreeIndex(WhereBestIdx *p){
  Parse *pParse = p->pParse;  /* The parsing context */
  WhereClause *pWC = p->pWC;  /* The WHERE clause */
  struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */
  int iCur = pSrc->iCursor;   /* The cursor of the table to be accessed */
  Index *pProbe;              /* An index we are evaluating */
  Index *pIdx;                /* Copy of pProbe, or zero for IPK index */
  int eqTermMask;             /* Current mask of valid equality operators */
  int idxEqTermMask;          /* Index mask of valid equality operators */
  Index sPk;                  /* A fake index object for the primary key */
  tRowcnt aiRowEstPk[2];      /* The aiRowEst[] value for the sPk index */
  int aiColumnPk = -1;        /* The aColumn[] value for the sPk index */
  int wsFlagMask;             /* Allowed flags in p->cost.plan.wsFlag */
  int nPriorSat;              /* ORDER BY terms satisfied by outer loops */
  int nOrderBy;               /* Number of ORDER BY terms */
  char bSortInit;             /* Initializer for bSort in inner loop */
  char bDistInit;             /* Initializer for bDist in inner loop */


  /* Initialize the cost to a worst-case value */
  memset(&p->cost, 0, sizeof(p->cost));
  p->cost.rCost = SQLITE_BIG_DBL;

  /* If the pSrc table is the right table of a LEFT JOIN then we may not
  ** use an index to satisfy IS NULL constraints on that table.  This is
105089
105090
105091
105092
105093
105094
105095











105096
105097
105098
105099
105100
105101
105102
105535
105536
105537
105538
105539
105540
105541
105542
105543
105544
105545
105546
105547
105548
105549
105550
105551
105552
105553
105554
105555
105556
105557
105558
105559







+
+
+
+
+
+
+
+
+
+
+







    pProbe = &sPk;
    wsFlagMask = ~(
        WHERE_COLUMN_IN|WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_RANGE
    );
    eqTermMask = WO_EQ|WO_IN;
    pIdx = 0;
  }

  nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0;
  if( p->i ){
    nPriorSat = p->aLevel[p->i-1].plan.nOBSat;
    bSortInit = nPriorSat<nOrderBy;
    bDistInit = 0;
  }else{
    nPriorSat = 0;
    bSortInit = nOrderBy>0;
    bDistInit = p->pDistinct!=0;
  }

  /* Loop over all indices looking for the best one to use
  */
  for(; pProbe; pIdx=pProbe=pProbe->pNext){
    const tRowcnt * const aiRowEst = pProbe->aiRowEst;
    WhereCost pc;               /* Cost of using pProbe */
    double log10N = (double)1;  /* base-10 logarithm of nRow (inexact) */
105167
105168
105169
105170
105171
105172
105173
105174
105175
105176



105177
105178
105179
105180
105181
105182
105183
105184
105185
105186
105187
105188
105189
105190
105191
105192
105193
105194
105195

105196
105197
105198
105199
105200
105201
105202
105203
105204
105205
105624
105625
105626
105627
105628
105629
105630



105631
105632
105633


105634
105635
105636
105637
105638
105639
105640
105641
105642
105643







105644



105645
105646
105647
105648
105649
105650
105651







-
-
-
+
+
+
-
-










-
-
-
-
-
-
-
+
-
-
-







    **             SELECT a, b    FROM tbl WHERE a = 1;
    **             SELECT a, b, c FROM tbl WHERE a = 1;
    */
    int bInEst = 0;               /* True if "x IN (SELECT...)" seen */
    int nInMul = 1;               /* Number of distinct equalities to lookup */
    double rangeDiv = (double)1;  /* Estimated reduction in search space */
    int nBound = 0;               /* Number of range constraints seen */
    int bSort;                    /* True if external sort required */
    int bDist;                    /* True if index cannot help with DISTINCT */
    int bLookup = 0;              /* True if not a covering index */
    char bSort = bSortInit;       /* True if external sort required */
    char bDist = bDistInit;       /* True if index cannot help with DISTINCT */
    char bLookup = 0;             /* True if not a covering index */
    int nPriorSat;                /* ORDER BY terms satisfied by outer loops */
    int nOrderBy;                 /* Number of ORDER BY terms */
    WhereTerm *pTerm;             /* A single term of the WHERE clause */
#ifdef SQLITE_ENABLE_STAT3
    WhereTerm *pFirstTerm = 0;    /* First term matching the index */
#endif

    WHERETRACE((
      "   %s(%s):\n",
      pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk")
    ));
    memset(&pc, 0, sizeof(pc));
    nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0;
    if( p->i ){
      nPriorSat = pc.plan.nOBSat = p->aLevel[p->i-1].plan.nOBSat;
      bSort = nPriorSat<nOrderBy;
      bDist = 0;
    }else{
      nPriorSat = pc.plan.nOBSat = 0;
    pc.plan.nOBSat = nPriorSat;
      bSort = nOrderBy>0;
      bDist = p->pDistinct!=0;
    }

    /* Determine the values of pc.plan.nEq and nInMul */
    for(pc.plan.nEq=0; pc.plan.nEq<pProbe->nColumn; pc.plan.nEq++){
      int j = pProbe->aiColumn[pc.plan.nEq];
      pTerm = findTerm(pWC, iCur, j, p->notReady, eqTermMask, pIdx);
      if( pTerm==0 ) break;
      pc.plan.wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ);
105273
105274
105275
105276
105277
105278
105279
105280

105281
105282
105283
105284
105285
105286
105287
105719
105720
105721
105722
105723
105724
105725

105726
105727
105728
105729
105730
105731
105732
105733







-
+







    ** variable.  */
    if( bSort && (pSrc->jointype & JT_LEFT)==0 ){
      int bRev = 2;
      WHERETRACE(("      --> before isSortingIndex: nPriorSat=%d\n",nPriorSat));
      pc.plan.nOBSat = isSortingIndex(p, pProbe, iCur, &bRev);
      WHERETRACE(("      --> after  isSortingIndex: bRev=%d nOBSat=%d\n",
                  bRev, pc.plan.nOBSat));
      if( nPriorSat<pc.plan.nOBSat || (pc.plan.wsFlags & WHERE_UNIQUE)!=0 ){
      if( nPriorSat<pc.plan.nOBSat || (pc.plan.wsFlags & WHERE_ALL_UNIQUE)!=0 ){
        pc.plan.wsFlags |= WHERE_ORDERED;
      }
      if( nOrderBy==pc.plan.nOBSat ){
        bSort = 0;
        pc.plan.wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE;
      }
      if( bRev & 1 ) pc.plan.wsFlags |= WHERE_REVERSE;
106050
106051
106052
106053
106054
106055
106056










106057
106058
106059
106060
106061
106062
106063
106496
106497
106498
106499
106500
106501
106502
106503
106504
106505
106506
106507
106508
106509
106510
106511
106512
106513
106514
106515
106516
106517
106518
106519







+
+
+
+
+
+
+
+
+
+







  ** row of the left table of the join.
  */
  if( pLevel->iFrom>0 && (pTabItem[0].jointype & JT_LEFT)!=0 ){
    pLevel->iLeftJoin = ++pParse->nMem;
    sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin);
    VdbeComment((v, "init LEFT JOIN no-match flag"));
  }

  /* Special case of a FROM clause subquery implemented as a co-routine */
  if( pTabItem->viaCoroutine ){
    int regYield = pTabItem->regReturn;
    sqlite3VdbeAddOp2(v, OP_Integer, pTabItem->addrFillSub-1, regYield);
    pLevel->p2 =  sqlite3VdbeAddOp1(v, OP_Yield, regYield);
    VdbeComment((v, "next row of co-routine %s", pTabItem->pTab->zName));
    sqlite3VdbeAddOp2(v, OP_If, regYield+1, addrBrk);
    pLevel->op = OP_Goto;
  }else

#ifndef SQLITE_OMIT_VIRTUALTABLE
  if(  (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
    /* Case 0:  The table is a virtual-table.  Use the VFilter and VNext
    **          to access the data.
    */
    int iReg;   /* P3 Value for OP_VFilter */
107113
107114
107115
107116
107117
107118
107119













107120
107121
107122
107123
107124
107125
107126
107127
107128


107129
107130
107131
107132
107133
107134
107135
107136
107137
107138
107139
107140
107141
107142
107143
107144
107145
107146
107147
107148
107149
107150
107151
107152
107569
107570
107571
107572
107573
107574
107575
107576
107577
107578
107579
107580
107581
107582
107583
107584
107585
107586
107587
107588
107589
107590
107591
107592
107593
107594
107595


107596
107597
107598
107599
107600
107601
107602
107603
107604
107605
107606
107607
107608
107609
107610
107611



107612
107613
107614
107615
107616
107617
107618







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







-
-
+
+














-
-
-







        assert( sWBI.pSrc->pIndex==0 
                  || (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0
                  || sWBI.cost.plan.u.pIdx==sWBI.pSrc->pIndex );

        if( isOptimal && (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){
          notIndexed |= m;
        }
        if( isOptimal ){
          pWInfo->a[j].rOptCost = sWBI.cost.rCost;
        }else if( iFrom<nTabList-1 ){
          /* If two or more tables have nearly the same outer loop cost,
          ** very different inner loop (optimal) cost, we want to choose
          ** for the outer loop that table which benefits the least from
          ** being in the inner loop.  The following code scales the 
          ** outer loop cost estimate to accomplish that. */
          WHERETRACE(("   scaling cost from %.1f to %.1f\n",
                      sWBI.cost.rCost,
                      sWBI.cost.rCost/pWInfo->a[j].rOptCost));
          sWBI.cost.rCost /= pWInfo->a[j].rOptCost;
        }

        /* Conditions under which this table becomes the best so far:
        **
        **   (1) The table must not depend on other tables that have not
        **       yet run.  (In other words, it must not depend on tables
        **       in inner loops.)
        **
        **   (2) A full-table-scan plan cannot supercede indexed plan unless
        **       the full-table-scan is an "optimal" plan as defined above.
        **   (2) (This rule was removed on 2012-11-09.  The scaling of the
        **       cost using the optimal scan cost made this rule obsolete.)
        **
        **   (3) All tables have an INDEXED BY clause or this table lacks an
        **       INDEXED BY clause or this table uses the specific
        **       index specified by its INDEXED BY clause.  This rule ensures
        **       that a best-so-far is always selected even if an impossible
        **       combination of INDEXED BY clauses are given.  The error
        **       will be detected and relayed back to the application later.
        **       The NEVER() comes about because rule (2) above prevents
        **       An indexable full-table-scan from reaching rule (3).
        **
        **   (4) The plan cost must be lower than prior plans, where "cost"
        **       is defined by the compareCost() function above. 
        */
        if( (sWBI.cost.used&sWBI.notValid)==0                    /* (1) */
            && (bestJ<0 || (notIndexed&m)!=0                     /* (2) */
                || (bestPlan.plan.wsFlags & WHERE_NOT_FULLSCAN)==0
                || (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0)
            && (nUnconstrained==0 || sWBI.pSrc->pIndex==0        /* (3) */
                || NEVER((sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0))
            && (bestJ<0 || compareCost(&sWBI.cost, &bestPlan))   /* (4) */
        ){
          WHERETRACE(("   === table %d (%s) is best so far\n"
                      "       cost=%.1f, nRow=%.1f, nOBSat=%d, wsFlags=%08x\n",
                      j, sWBI.pSrc->pTab->zName,
107258
107259
107260
107261
107262
107263
107264


107265
107266
107267
107268
107269
107270
107271
107724
107725
107726
107727
107728
107729
107730
107731
107732
107733
107734
107735
107736
107737
107738
107739







+
+







      /* Do nothing */
    }else
#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
      const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
      int iCur = pTabItem->iCursor;
      sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB);
    }else if( IsVirtual(pTab) ){
      /* noop */
    }else
#endif
    if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
         && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){
      int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
      sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
      testcase( pTab->nCol==BMS-1 );
110203
110204
110205
110206
110207
110208
110209
110210

110211
110212
110213
110214
110215
110216
110217
110671
110672
110673
110674
110675
110676
110677

110678
110679
110680
110681
110682
110683
110684
110685







-
+







  spanExpr(&yygotominor.yy342, pParse, TK_VARIABLE, &yymsp[0].minor.yy0);
  sqlite3ExprAssignVarNumber(pParse, yygotominor.yy342.pExpr);
  spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
        break;
      case 194: /* expr ::= expr COLLATE ids */
{
  yygotominor.yy342.pExpr = sqlite3ExprSetCollByToken(pParse, yymsp[-2].minor.yy342.pExpr, &yymsp[0].minor.yy0);
  yygotominor.yy342.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy342.pExpr, &yymsp[0].minor.yy0);
  yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart;
  yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
        break;
      case 195: /* expr ::= CAST LP expr AS typetoken RP */
{
  yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy342.pExpr, 0, &yymsp[-1].minor.yy0);
110462
110463
110464
110465
110466
110467
110468
110469
110470

110471
110472
110473
110474
110475
110476
110477
110478
110479
110480
110481
110482
110483

110484
110485
110486
110487
110488
110489
110490
110491
110492
110493
110930
110931
110932
110933
110934
110935
110936


110937



110938
110939
110940
110941
110942
110943
110944
110945


110946



110947
110948
110949
110950
110951
110952
110953







-
-
+
-
-
-








-
-
+
-
-
-







{yygotominor.yy392 = OE_Abort;}
        break;
      case 244: /* uniqueflag ::= */
{yygotominor.yy392 = OE_None;}
        break;
      case 247: /* idxlist ::= idxlist COMMA nm collate sortorder */
{
  Expr *p = 0;
  if( yymsp[-1].minor.yy0.n>0 ){
  Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
    p = sqlite3Expr(pParse->db, TK_COLUMN, 0);
    sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0);
  }
  yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, p);
  sqlite3ExprListSetName(pParse,yygotominor.yy442,&yymsp[-2].minor.yy0,1);
  sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
  if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
}
        break;
      case 248: /* idxlist ::= nm collate sortorder */
{
  Expr *p = 0;
  if( yymsp[-1].minor.yy0.n>0 ){
  Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
    p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
    sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0);
  }
  yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, p);
  sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
  sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
  if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
}
        break;
      case 249: /* collate ::= */
112293
112294
112295
112296
112297
112298
112299







112300
112301
112302
112303
112304
112305
112306
112753
112754
112755
112756
112757
112758
112759
112760
112761
112762
112763
112764
112765
112766
112767
112768
112769
112770
112771
112772
112773







+
+
+
+
+
+
+








  /* If SQLite is already completely initialized, then this call
  ** to sqlite3_initialize() should be a no-op.  But the initialization
  ** must be complete.  So isInit must not be set until the very end
  ** of this routine.
  */
  if( sqlite3GlobalConfig.isInit ) return SQLITE_OK;

#ifdef SQLITE_ENABLE_SQLLOG
  {
    extern void sqlite3_init_sqllog(void);
    sqlite3_init_sqllog();
  }
#endif

  /* Make sure the mutex subsystem is initialized.  If unable to 
  ** initialize the mutex subsystem, return early with the error.
  ** If the system is so sick that we are unable to allocate a mutex,
  ** there is not much SQLite is going to be able to do.
  **
  ** The mutex subsystem must take care of serializing its own
112641
112642
112643
112644
112645
112646
112647









112648
112649
112650
112651
112652
112653
112654
113108
113109
113110
113111
113112
113113
113114
113115
113116
113117
113118
113119
113120
113121
113122
113123
113124
113125
113126
113127
113128
113129
113130







+
+
+
+
+
+
+
+
+







      break;
    }

    case SQLITE_CONFIG_COVERING_INDEX_SCAN: {
      sqlite3GlobalConfig.bUseCis = va_arg(ap, int);
      break;
    }

#ifdef SQLITE_ENABLE_SQLLOG
    case SQLITE_CONFIG_SQLLOG: {
      typedef void(*SQLLOGFUNC_t)(void*, sqlite3*, const char*, int);
      sqlite3GlobalConfig.xSqllog = va_arg(ap, SQLLOGFUNC_t);
      sqlite3GlobalConfig.pSqllogArg = va_arg(ap, void *);
      break;
    }
#endif

    default: {
      rc = SQLITE_ERROR;
      break;
    }
  }
  va_end(ap);
112980
112981
112982
112983
112984
112985
112986







112987
112988
112989
112990
112991
112992
112993
113456
113457
113458
113459
113460
113461
113462
113463
113464
113465
113466
113467
113468
113469
113470
113471
113472
113473
113474
113475
113476







+
+
+
+
+
+
+







  */
  if( !forceZombie && connectionIsBusy(db) ){
    sqlite3Error(db, SQLITE_BUSY, "unable to close due to unfinalized "
       "statements or unfinished backups");
    sqlite3_mutex_leave(db->mutex);
    return SQLITE_BUSY;
  }

#ifdef SQLITE_ENABLE_SQLLOG
  if( sqlite3GlobalConfig.xSqllog ){
    /* Closing the handle. Fourth parameter is passed the value 2. */
    sqlite3GlobalConfig.xSqllog(sqlite3GlobalConfig.pSqllogArg, db, 0, 2);
  }
#endif

  /* Convert the connection into a zombie and then close it.
  */
  db->magic = SQLITE_MAGIC_ZOMBIE;
  sqlite3LeaveMutexAndCloseZombie(db);
  return SQLITE_OK;
}
114613
114614
114615
114616
114617
114618
114619







114620
114621
114622
114623
114624
114625
114626
115096
115097
115098
115099
115100
115101
115102
115103
115104
115105
115106
115107
115108
115109
115110
115111
115112
115113
115114
115115
115116







+
+
+
+
+
+
+







  if( rc==SQLITE_NOMEM ){
    sqlite3_close(db);
    db = 0;
  }else if( rc!=SQLITE_OK ){
    db->magic = SQLITE_MAGIC_SICK;
  }
  *ppDb = db;
#ifdef SQLITE_ENABLE_SQLLOG
  if( sqlite3GlobalConfig.xSqllog ){
    /* Opening a db handle. Fourth parameter is passed 0. */
    void *pArg = sqlite3GlobalConfig.pSqllogArg;
    sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
  }
#endif
  return sqlite3ApiExit(0, rc);
}

/*
** Open a new database handle.
*/
SQLITE_API int sqlite3_open(
115181
115182
115183
115184
115185
115186
115187
115188

115189
115190
115191
115192
115193
115194
115195
115671
115672
115673
115674
115675
115676
115677

115678
115679
115680
115681
115682
115683
115684
115685







-
+







    ** operation N should be 0.  The idea is that a test program (like the
    ** SQL Logic Test or SLT test module) can run the same SQL multiple times
    ** with various optimizations disabled to verify that the same answer
    ** is obtained in every case.
    */
    case SQLITE_TESTCTRL_OPTIMIZATIONS: {
      sqlite3 *db = va_arg(ap, sqlite3*);
      db->dbOptFlags = (u8)(va_arg(ap, int) & 0xff);
      db->dbOptFlags = (u16)(va_arg(ap, int) & 0xffff);
      break;
    }

#ifdef SQLITE_N_KEYWORD
    /* sqlite3_test_control(SQLITE_TESTCTRL_ISKEYWORD, const char *zWord)
    **
    ** If zWord is a keyword recognized by the parser, then return the
121253
121254
121255
121256
121257
121258
121259



121260
121261
121262
121263
121264
121265
121266







121267
121268
121269
121270
121271
121272
121273
121274
121275
121276
121277
121278
121279
121280
121281
121282
121283
121284
121285
121286



















121287
121288


121289
121290
121291
121292
121293
121294
121295
121743
121744
121745
121746
121747
121748
121749
121750
121751
121752







121753
121754
121755
121756
121757
121758
121759
121760



















121761
121762
121763
121764
121765
121766
121767
121768
121769
121770
121771
121772
121773
121774
121775
121776
121777
121778
121779
121780

121781
121782
121783
121784
121785
121786
121787
121788
121789







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

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

-
+
+







    char *aTmp;                   /* Temp space for PoslistNearMerge() */

    /* Allocate temporary working space. */
    for(p=pExpr; p->pLeft; p=p->pLeft){
      nTmp += p->pRight->pPhrase->doclist.nList;
    }
    nTmp += p->pPhrase->doclist.nList;
    if( nTmp==0 ){
      res = 0;
    }else{
    aTmp = sqlite3_malloc(nTmp*2);
    if( !aTmp ){
      *pRc = SQLITE_NOMEM;
      res = 0;
    }else{
      char *aPoslist = p->pPhrase->doclist.pList;
      int nToken = p->pPhrase->nToken;
      aTmp = sqlite3_malloc(nTmp*2);
      if( !aTmp ){
        *pRc = SQLITE_NOMEM;
        res = 0;
      }else{
        char *aPoslist = p->pPhrase->doclist.pList;
        int nToken = p->pPhrase->nToken;

      for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){
        Fts3Phrase *pPhrase = p->pRight->pPhrase;
        int nNear = p->nNear;
        res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
      }
  
      aPoslist = pExpr->pRight->pPhrase->doclist.pList;
      nToken = pExpr->pRight->pPhrase->nToken;
      for(p=pExpr->pLeft; p && res; p=p->pLeft){
        int nNear;
        Fts3Phrase *pPhrase;
        assert( p->pParent && p->pParent->pLeft==p );
        nNear = p->pParent->nNear;
        pPhrase = (
            p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
        );
        res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
      }
    }
        for(p=p->pParent;res && p && p->eType==FTSQUERY_NEAR; p=p->pParent){
          Fts3Phrase *pPhrase = p->pRight->pPhrase;
          int nNear = p->nNear;
          res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
        }

        aPoslist = pExpr->pRight->pPhrase->doclist.pList;
        nToken = pExpr->pRight->pPhrase->nToken;
        for(p=pExpr->pLeft; p && res; p=p->pLeft){
          int nNear;
          Fts3Phrase *pPhrase;
          assert( p->pParent && p->pParent->pLeft==p );
          nNear = p->pParent->nNear;
          pPhrase = (
              p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
              );
          res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
        }
      }

    sqlite3_free(aTmp);
      sqlite3_free(aTmp);
    }
  }

  return res;
}

/*
** This function is a helper function for fts3EvalTestDeferredAndNear().
122519
122520
122521
122522
122523
122524
122525
122526

122527
122528
122529
122530
122531
122532
122533
123013
123014
123015
123016
123017
123018
123019

123020
123021
123022
123023
123024
123025
123026
123027







-
+







  sqlite3_tokenizer_cursor *pCursor;
  Fts3Expr *pRet = 0;
  int nConsumed = 0;

  rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, n, &pCursor);
  if( rc==SQLITE_OK ){
    const char *zToken;
    int nToken, iStart, iEnd, iPosition;
    int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0;
    int nByte;                               /* total space to allocate */

    rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition);
    if( rc==SQLITE_OK ){
      nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken;
      pRet = (Fts3Expr *)fts3MallocZero(nByte);
      if( !pRet ){
122634
122635
122636
122637
122638
122639
122640
122641

122642
122643
122644
122645
122646
122647
122648
123128
123129
123130
123131
123132
123133
123134

123135
123136
123137
123138
123139
123140
123141
123142







-
+







  */
  rc = sqlite3Fts3OpenTokenizer(
      pTokenizer, pParse->iLangid, zInput, nInput, &pCursor);
  if( rc==SQLITE_OK ){
    int ii;
    for(ii=0; rc==SQLITE_OK; ii++){
      const char *zByte;
      int nByte, iBegin, iEnd, iPos;
      int nByte = 0, iBegin = 0, iEnd = 0, iPos = 0;
      rc = pModule->xNext(pCursor, &zByte, &nByte, &iBegin, &iEnd, &iPos);
      if( rc==SQLITE_OK ){
        Fts3PhraseToken *pToken;

        p = fts3ReallocOrFree(p, nSpace + ii*sizeof(Fts3PhraseToken));
        if( !p ) goto no_mem;

124631
124632
124633
124634
124635
124636
124637
124638
124639
124640
124641




124642
124643
124644
124645
124646
124647
124648
125125
125126
125127
125128
125129
125130
125131




125132
125133
125134
125135
125136
125137
125138
125139
125140
125141
125142







-
-
-
-
+
+
+
+







  int nName;
  const char *zInput;
  int nInput;

  const char *azArg[64];

  const char *zToken;
  int nToken;
  int iStart;
  int iEnd;
  int iPos;
  int nToken = 0;
  int iStart = 0;
  int iEnd = 0;
  int iPos = 0;
  int i;

  Tcl_Obj *pRet;

  if( argc<2 ){
    sqlite3_result_error(context, "insufficient arguments", -1);
    return;
125881
125882
125883
125884
125885
125886
125887
125888

125889
125890
125891
125892
125893



125894
125895
125896
125897

125898
125899
125900
125901
125902
125903
125904
126375
126376
126377
126378
126379
126380
126381

126382
126383
126384



126385
126386
126387
126388
126389
126390

126391
126392
126393
126394
126395
126396
126397
126398







-
+


-
-
-
+
+
+



-
+







** If successful, SQLITE_OK is returned. Otherwise, an SQLite error code.
*/
static int fts3PendingTermsAdd(
  Fts3Table *p,                   /* Table into which text will be inserted */
  int iLangid,                    /* Language id to use */
  const char *zText,              /* Text of document to be inserted */
  int iCol,                       /* Column into which text is being inserted */
  u32 *pnWord                     /* OUT: Number of tokens inserted */
  u32 *pnWord                     /* IN/OUT: Incr. by number tokens inserted */
){
  int rc;
  int iStart;
  int iEnd;
  int iPos;
  int iStart = 0;
  int iEnd = 0;
  int iPos = 0;
  int nWord = 0;

  char const *zToken;
  int nToken;
  int nToken = 0;

  sqlite3_tokenizer *pTokenizer = p->pTokenizer;
  sqlite3_tokenizer_module const *pModule = pTokenizer->pModule;
  sqlite3_tokenizer_cursor *pCsr;
  int (*xNext)(sqlite3_tokenizer_cursor *pCursor,
      const char**,int*,int*,int*,int*);

125945
125946
125947
125948
125949
125950
125951
125952

125953
125954
125955
125956
125957
125958
125959
126439
126440
126441
126442
126443
126444
126445

126446
126447
126448
126449
126450
126451
126452
126453







-
+







      rc = fts3PendingTermsAddOne(
          p, iCol, iPos, &pIndex->hPending, zToken, pIndex->nPrefix
      );
    }
  }

  pModule->xClose(pCsr);
  *pnWord = nWord;
  *pnWord += nWord;
  return (rc==SQLITE_DONE ? SQLITE_OK : rc);
}

/* 
** Calling this function indicates that subsequent calls to 
** fts3PendingTermsAdd() are to add term/position-list pairs for the
** contents of the document with docid iDocid.
126149
126150
126151
126152
126153
126154
126155
126156


126157
126158
126159
126160

126161
126162
126163
126164
126165
126166
126167
126168
126169
126170
126171
126172
126173
126174
126175
126176
126177

126178
126179
126180
126181
126182
126183
126184
126643
126644
126645
126646
126647
126648
126649

126650
126651
126652
126653
126654
126655
126656
126657
126658
126659
126660
126661
126662
126663
126664
126665
126666
126667
126668
126669
126670
126671
126672
126673
126674
126675
126676
126677
126678
126679
126680
126681







-
+
+




+

















+







** (an integer) of a row about to be deleted. Remove all terms from the
** full-text index.
*/
static void fts3DeleteTerms( 
  int *pRC,               /* Result code */
  Fts3Table *p,           /* The FTS table to delete from */
  sqlite3_value *pRowid,  /* The docid to be deleted */
  u32 *aSz                /* Sizes of deleted document written here */
  u32 *aSz,               /* Sizes of deleted document written here */
  int *pbFound            /* OUT: Set to true if row really does exist */
){
  int rc;
  sqlite3_stmt *pSelect;

  assert( *pbFound==0 );
  if( *pRC ) return;
  rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pSelect, &pRowid);
  if( rc==SQLITE_OK ){
    if( SQLITE_ROW==sqlite3_step(pSelect) ){
      int i;
      int iLangid = langidFromSelect(p, pSelect);
      rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pSelect, 0));
      for(i=1; rc==SQLITE_OK && i<=p->nColumn; i++){
        const char *zText = (const char *)sqlite3_column_text(pSelect, i);
        rc = fts3PendingTermsAdd(p, iLangid, zText, -1, &aSz[i-1]);
        aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i);
      }
      if( rc!=SQLITE_OK ){
        sqlite3_reset(pSelect);
        *pRC = rc;
        return;
      }
      *pbFound = 1;
    }
    rc = sqlite3_reset(pSelect);
  }else{
    sqlite3_reset(pSelect);
  }
  *pRC = rc;
}
128395
128396
128397
128398
128399
128400
128401
128402

128403
128404
128405
128406
128407
128408
128409
128892
128893
128894
128895
128896
128897
128898

128899
128900
128901
128902
128903
128904
128905
128906







-
+







      }
    }

    while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
      int iCol;
      int iLangid = langidFromSelect(p, pStmt);
      rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pStmt, 0));
      aSz[p->nColumn] = 0;
      memset(aSz, 0, sizeof(aSz[0]) * (p->nColumn+1));
      for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){
        const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1);
        rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]);
        aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1);
      }
      if( p->bHasDocsize ){
        fts3InsertDocsize(&rc, p, aSz);
130039
130040
130041
130042
130043
130044
130045
130046
130047
130048



130049
130050
130051
130052
130053
130054
130055
130536
130537
130538
130539
130540
130541
130542



130543
130544
130545
130546
130547
130548
130549
130550
130551
130552







-
-
-
+
+
+







        const char *zText = (const char *)sqlite3_column_text(pStmt, iCol+1);
        int nText = sqlite3_column_bytes(pStmt, iCol+1);
        sqlite3_tokenizer_cursor *pT = 0;

        rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, nText, &pT);
        while( rc==SQLITE_OK ){
          char const *zToken;       /* Buffer containing token */
          int nToken;               /* Number of bytes in token */
          int iDum1, iDum2;         /* Dummy variables */
          int iPos;                 /* Position of token in zText */
          int nToken = 0;           /* Number of bytes in token */
          int iDum1 = 0, iDum2 = 0; /* Dummy variables */
          int iPos = 0;             /* Position of token in zText */

          rc = pModule->xNext(pT, &zToken, &nToken, &iDum1, &iDum2, &iPos);
          if( rc==SQLITE_OK ){
            int i;
            cksum2 = cksum2 ^ fts3ChecksumEntry(
                zToken, nToken, iLang, 0, iDocid, iCol, iPos
            );
130208
130209
130210
130211
130212
130213
130214
130215
130216
130217



130218
130219
130220
130221
130222
130223
130224
130705
130706
130707
130708
130709
130710
130711



130712
130713
130714
130715
130716
130717
130718
130719
130720
130721







-
-
-
+
+
+







    for(i=0; i<p->nColumn && rc==SQLITE_OK; i++){
      const char *zText = (const char *)sqlite3_column_text(pCsr->pStmt, i+1);
      sqlite3_tokenizer_cursor *pTC = 0;
  
      rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC);
      while( rc==SQLITE_OK ){
        char const *zToken;       /* Buffer containing token */
        int nToken;               /* Number of bytes in token */
        int iDum1, iDum2;         /* Dummy variables */
        int iPos;                 /* Position of token in zText */
        int nToken = 0;           /* Number of bytes in token */
        int iDum1 = 0, iDum2 = 0; /* Dummy variables */
        int iPos = 0;             /* Position of token in zText */
  
        rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos);
        for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
          Fts3PhraseToken *pPT = pDef->pToken;
          if( (pDef->iCol>=p->nColumn || pDef->iCol==i)
           && (pPT->bFirst==0 || iPos==0)
           && (pPT->n==nToken || (pPT->isPrefix && pPT->n<nToken))
130299
130300
130301
130302
130303
130304
130305
130306

130307
130308





130309
130310
130311
130312
130313
130314
130315
130316
130317
130318











130319
130320
130321



130322
130323
130324
130325
130326
130327




130328
130329
130330
130331
130332
130333
130334
130796
130797
130798
130799
130800
130801
130802

130803
130804
130805
130806
130807
130808
130809
130810










130811
130812
130813
130814
130815
130816
130817
130818
130819
130820
130821



130822
130823
130824






130825
130826
130827
130828
130829
130830
130831
130832
130833
130834
130835







-
+


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







** SQLite value pRowid contains the rowid of a row that may or may not be
** present in the FTS3 table. If it is, delete it and adjust the contents
** of subsiduary data structures accordingly.
*/
static int fts3DeleteByRowid(
  Fts3Table *p, 
  sqlite3_value *pRowid, 
  int *pnDoc,
  int *pnChng,                    /* IN/OUT: Decrement if row is deleted */
  u32 *aSzDel
){
  int rc = SQLITE_OK;             /* Return code */
  int bFound = 0;                 /* True if *pRowid really is in the table */

  fts3DeleteTerms(&rc, p, pRowid, aSzDel, &bFound);
  if( bFound && rc==SQLITE_OK ){
  int isEmpty = 0;
  int rc = fts3IsEmpty(p, pRowid, &isEmpty);
  if( rc==SQLITE_OK ){
    if( isEmpty ){
      /* Deleting this row means the whole table is empty. In this case
      ** delete the contents of all three tables and throw away any
      ** data in the pendingTerms hash table.  */
      rc = fts3DeleteAll(p, 1);
      *pnDoc = *pnDoc - 1;
    }else{
    int isEmpty = 0;              /* Deleting *pRowid leaves the table empty */
    rc = fts3IsEmpty(p, pRowid, &isEmpty);
    if( rc==SQLITE_OK ){
      if( isEmpty ){
        /* Deleting this row means the whole table is empty. In this case
        ** delete the contents of all three tables and throw away any
        ** data in the pendingTerms hash table.  */
        rc = fts3DeleteAll(p, 1);
        *pnChng = 0;
        memset(aSzDel, 0, sizeof(u32) * (p->nColumn+1) * 2);
      }else{
      fts3DeleteTerms(&rc, p, pRowid, aSzDel);
      if( p->zContentTbl==0 ){
        fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid);
        *pnChng = *pnChng - 1;
        if( p->zContentTbl==0 ){
          fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid);
        if( sqlite3_changes(p->db) ) *pnDoc = *pnDoc - 1;
      }else{
        *pnDoc = *pnDoc - 1;
      }
      if( p->bHasDocsize ){
        fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, &pRowid);
        }
        if( p->bHasDocsize ){
          fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, &pRowid);
        }
      }
    }
  }

  return rc;
}

130351
130352
130353
130354
130355
130356
130357
130358

130359
130360
130361
130362
130363
130364
130365
130852
130853
130854
130855
130856
130857
130858

130859
130860
130861
130862
130863
130864
130865
130866







-
+







  sqlite3_value **apVal,          /* Array of arguments */
  sqlite_int64 *pRowid            /* OUT: The affected (or effected) rowid */
){
  Fts3Table *p = (Fts3Table *)pVtab;
  int rc = SQLITE_OK;             /* Return Code */
  int isRemove = 0;               /* True for an UPDATE or DELETE */
  u32 *aSzIns = 0;                /* Sizes of inserted documents */
  u32 *aSzDel;                    /* Sizes of deleted documents */
  u32 *aSzDel = 0;                /* Sizes of deleted documents */
  int nChng = 0;                  /* Net change in number of documents */
  int bInsertDone = 0;

  assert( p->pSegments==0 );
  assert( 
      nArg==1                     /* DELETE operations */
   || nArg==(2 + p->nColumn + 3)  /* INSERT or UPDATE operations */
130379
130380
130381
130382
130383
130384
130385
130386
130387


130388
130389
130390
130391
130392


130393
130394
130395
130396
130397
130398
130399
130880
130881
130882
130883
130884
130885
130886


130887
130888
130889
130890
130891


130892
130893
130894
130895
130896
130897
130898
130899
130900







-
-
+
+



-
-
+
+








  if( nArg>1 && sqlite3_value_int(apVal[2 + p->nColumn + 2])<0 ){
    rc = SQLITE_CONSTRAINT;
    goto update_out;
  }

  /* Allocate space to hold the change in document sizes */
  aSzIns = sqlite3_malloc( sizeof(aSzIns[0])*(p->nColumn+1)*2 );
  if( aSzIns==0 ){
  aSzDel = sqlite3_malloc( sizeof(aSzDel[0])*(p->nColumn+1)*2 );
  if( aSzDel==0 ){
    rc = SQLITE_NOMEM;
    goto update_out;
  }
  aSzDel = &aSzIns[p->nColumn+1];
  memset(aSzIns, 0, sizeof(aSzIns[0])*(p->nColumn+1)*2);
  aSzIns = &aSzDel[p->nColumn+1];
  memset(aSzDel, 0, sizeof(aSzDel[0])*(p->nColumn+1)*2);

  /* If this is an INSERT operation, or an UPDATE that modifies the rowid
  ** value, then this operation requires constraint handling.
  **
  ** If the on-conflict mode is REPLACE, this means that the existing row
  ** should be deleted from the database before inserting the new row. Or,
  ** if the on-conflict mode is other than REPLACE, then this method must
130470
130471
130472
130473
130474
130475
130476
130477

130478
130479
130480
130481
130482
130483
130484
130971
130972
130973
130974
130975
130976
130977

130978
130979
130980
130981
130982
130983
130984
130985







-
+







  }

  if( p->bFts4 ){
    fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nChng);
  }

 update_out:
  sqlite3_free(aSzIns);
  sqlite3_free(aSzDel);
  sqlite3Fts3SegmentsClose(p);
  return rc;
}

/* 
** Flush any data in the pending-terms hash table to disk. If successful,
** merge all segments in the database (including the new segment, if 
131078
131079
131080
131081
131082
131083
131084
131085

131086
131087
131088
131089
131090
131091
131092
131579
131580
131581
131582
131583
131584
131585

131586
131587
131588
131589
131590
131591
131592
131593







-
+







      ** or more tokens in zDoc/nDoc.
      */
      rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, iLangid, zDoc, nDoc, &pC);
      if( rc!=SQLITE_OK ){
        return rc;
      }
      while( rc==SQLITE_OK && iCurrent<(nSnippet+nDesired) ){
        const char *ZDUMMY; int DUMMY1, DUMMY2, DUMMY3;
        const char *ZDUMMY; int DUMMY1 = 0, DUMMY2 = 0, DUMMY3 = 0;
        rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &DUMMY2, &DUMMY3, &iCurrent);
      }
      pMod->xClose(pC);
      if( rc!=SQLITE_OK && rc!=SQLITE_DONE ){ return rc; }

      nShift = (rc==SQLITE_DONE)+iCurrent-nSnippet;
      assert( nShift<=nDesired );
131122
131123
131124
131125
131126
131127
131128
131129
131130
131131
131132
131133
131134
131135
131136
131137
131138
131139
131140
131141
131142
131143
131144
131145
131146
131147
131148


131149
131150
131151



131152











131153
131154
131155
131156
131157
131158
131159
131623
131624
131625
131626
131627
131628
131629


131630
131631
131632
131633
131634
131635
131636
131637
131638
131639
131640
131641
131642
131643
131644
131645
131646
131647
131648
131649



131650
131651
131652
131653
131654
131655
131656
131657
131658
131659
131660
131661
131662
131663
131664
131665
131666
131667
131668
131669
131670
131671







-
-


















+
+
-
-
-
+
+
+

+
+
+
+
+
+
+
+
+
+
+







  int iEnd = 0;                   /* Byte offset of end of current token */
  int isShiftDone = 0;            /* True after snippet is shifted */
  int iPos = pFragment->iPos;     /* First token of snippet */
  u64 hlmask = pFragment->hlmask; /* Highlight-mask for snippet */
  int iCol = pFragment->iCol+1;   /* Query column to extract text from */
  sqlite3_tokenizer_module *pMod; /* Tokenizer module methods object */
  sqlite3_tokenizer_cursor *pC;   /* Tokenizer cursor open on zDoc/nDoc */
  const char *ZDUMMY;             /* Dummy argument used with tokenizer */
  int DUMMY1;                     /* Dummy argument used with tokenizer */
  
  zDoc = (const char *)sqlite3_column_text(pCsr->pStmt, iCol);
  if( zDoc==0 ){
    if( sqlite3_column_type(pCsr->pStmt, iCol)!=SQLITE_NULL ){
      return SQLITE_NOMEM;
    }
    return SQLITE_OK;
  }
  nDoc = sqlite3_column_bytes(pCsr->pStmt, iCol);

  /* Open a token cursor on the document. */
  pMod = (sqlite3_tokenizer_module *)pTab->pTokenizer->pModule;
  rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, pCsr->iLangid, zDoc,nDoc,&pC);
  if( rc!=SQLITE_OK ){
    return rc;
  }

  while( rc==SQLITE_OK ){
    const char *ZDUMMY;           /* Dummy argument used with tokenizer */
    int DUMMY1 = -1;              /* Dummy argument used with tokenizer */
    int iBegin;                   /* Offset in zDoc of start of token */
    int iFin;                     /* Offset in zDoc of end of token */
    int isHighlight;              /* True for highlighted terms */
    int iBegin = 0;               /* Offset in zDoc of start of token */
    int iFin = 0;                 /* Offset in zDoc of end of token */
    int isHighlight = 0;          /* True for highlighted terms */

    /* Variable DUMMY1 is initialized to a negative value above. Elsewhere
    ** in the FTS code the variable that the third argument to xNext points to
    ** is initialized to zero before the first (*but not necessarily
    ** subsequent*) call to xNext(). This is done for a particular application
    ** that needs to know whether or not the tokenizer is being used for
    ** snippet generation or for some other purpose.
    **
    ** Extreme care is required when writing code to depend on this
    ** initialization. It is not a documented part of the tokenizer interface.
    ** If a tokenizer is used directly by any code outside of FTS, this
    ** convention might not be respected.  */
    rc = pMod->xNext(pC, &ZDUMMY, &DUMMY1, &iBegin, &iFin, &iCurrent);
    if( rc!=SQLITE_OK ){
      if( rc==SQLITE_DONE ){
        /* Special case - the last token of the snippet is also the last token
        ** of the column. Append any punctuation that occurred between the end
        ** of the previous token and the end of the document to the output. 
        ** Then break out of the loop. */
131835
131836
131837
131838
131839
131840
131841
131842
131843
131844
131845
131846
131847
131848
131849
131850
132347
132348
132349
132350
132351
132352
132353


132354
132355
132356
132357
132358
132359
132360







-
-







*/
SQLITE_PRIVATE void sqlite3Fts3Offsets(
  sqlite3_context *pCtx,          /* SQLite function call context */
  Fts3Cursor *pCsr                /* Cursor object */
){
  Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
  sqlite3_tokenizer_module const *pMod = pTab->pTokenizer->pModule;
  const char *ZDUMMY;             /* Dummy argument used with xNext() */
  int NDUMMY;                     /* Dummy argument used with xNext() */
  int rc;                         /* Return Code */
  int nToken;                     /* Number of tokens in query */
  int iCol;                       /* Column currently being processed */
  StrBuffer res = {0, 0, 0};      /* Result string */
  TermOffsetCtx sCtx;             /* Context for fts3ExprTermOffsetInit() */

  if( !pCsr->pExpr ){
131869
131870
131871
131872
131873
131874
131875


131876
131877
131878



131879
131880
131881
131882
131883
131884
131885
132379
132380
132381
132382
132383
132384
132385
132386
132387



132388
132389
132390
132391
132392
132393
132394
132395
132396
132397







+
+
-
-
-
+
+
+







  sCtx.pCsr = pCsr;

  /* Loop through the table columns, appending offset information to 
  ** string-buffer res for each column.
  */
  for(iCol=0; iCol<pTab->nColumn; iCol++){
    sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor */
    const char *ZDUMMY;           /* Dummy argument used with xNext() */
    int NDUMMY = 0;               /* Dummy argument used with xNext() */
    int iStart;
    int iEnd;
    int iCurrent;
    int iStart = 0;
    int iEnd = 0;
    int iCurrent = 0;
    const char *zDoc;
    int nDoc;

    /* Initialize the contents of sCtx.aTerm[] for column iCol. There is 
    ** no way that this operation can fail, so the return code from
    ** fts3ExprIterate() can be discarded.
    */
136754
136755
136756
136757
136758
136759
136760
136761

136762
136763
136764
136765
136766
136767
136768
136769

136770
136771
136772
136773
136774
136775
136776
137266
137267
137268
137269
137270
137271
137272

137273
137274
137275
137276
137277
137278
137279
137280

137281
137282
137283
137284
137285
137286
137287
137288







-
+







-
+







    zInput = "";
  }else if( nInput<0 ){
    nInput = strlen(zInput);
  }
  nChar = nInput+1;
  pCsr = (IcuCursor *)sqlite3_malloc(
      sizeof(IcuCursor) +                /* IcuCursor */
      nChar * sizeof(UChar) +            /* IcuCursor.aChar[] */
      ((nChar+3)&~3) * sizeof(UChar) +   /* IcuCursor.aChar[] */
      (nChar+1) * sizeof(int)            /* IcuCursor.aOffset[] */
  );
  if( !pCsr ){
    return SQLITE_NOMEM;
  }
  memset(pCsr, 0, sizeof(IcuCursor));
  pCsr->aChar = (UChar *)&pCsr[1];
  pCsr->aOffset = (int *)&pCsr->aChar[nChar];
  pCsr->aOffset = (int *)&pCsr->aChar[(nChar+3)&~3];

  pCsr->aOffset[iOut] = iInput;
  U8_NEXT(zInput, iInput, nInput, c); 
  while( c>0 ){
    int isError = 0;
    c = u_foldCase(c, opt);
    U16_APPEND(pCsr->aChar, iOut, nChar, c, isError);
Changes to SQLite.Interop/src/core/sqlite3.h.
103
104
105
106
107
108
109
110

111
112

113
114
115
116
117
118
119
103
104
105
106
107
108
109

110
111

112
113
114
115
116
117
118
119







-
+

-
+







** string contains the date and time of the check-in (UTC) and an SHA1
** hash of the entire source tree.
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.7.15"
#define SQLITE_VERSION        "3.7.15.2"
#define SQLITE_VERSION_NUMBER 3007015
#define SQLITE_SOURCE_ID      "2012-10-12 18:06:07 de784399ed1f0e27fc875e32719643d19819c8fb"
#define SQLITE_SOURCE_ID      "2013-01-09 11:53:05 c0e09560d26f0a6456be9dd3447f5311eb4f238f"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
470
471
472
473
474
475
476

477
478
479
480
481
482
483
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484







+







#define SQLITE_IOERR_CLOSE             (SQLITE_IOERR | (16<<8))
#define SQLITE_IOERR_DIR_CLOSE         (SQLITE_IOERR | (17<<8))
#define SQLITE_IOERR_SHMOPEN           (SQLITE_IOERR | (18<<8))
#define SQLITE_IOERR_SHMSIZE           (SQLITE_IOERR | (19<<8))
#define SQLITE_IOERR_SHMLOCK           (SQLITE_IOERR | (20<<8))
#define SQLITE_IOERR_SHMMAP            (SQLITE_IOERR | (21<<8))
#define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))
#define SQLITE_IOERR_DELETE_NOENT      (SQLITE_IOERR | (23<<8))
#define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
#define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))
#define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
#define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870










871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886

887
888
889
890
891
892
893
853
854
855
856
857
858
859

860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904







-











+
+
+
+
+
+
+
+
+
+
















+







** VFS has handled the PRAGMA itself and the parser generates a no-op
** prepared statement.  ^If the [SQLITE_FCNTL_PRAGMA] file control returns
** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means
** that the VFS encountered an error while handling the [PRAGMA] and the
** compilation of the PRAGMA fails with an error.  ^The [SQLITE_FCNTL_PRAGMA]
** file control occurs at the beginning of pragma statement analysis and so
** it is able to override built-in [PRAGMA] statements.
** </ul>
**
** <li>[[SQLITE_FCNTL_BUSYHANDLER]]
** ^This file-control may be invoked by SQLite on the database file handle
** shortly after it is opened in order to provide a custom VFS with access
** to the connections busy-handler callback. The argument is of type (void **)
** - an array of two (void *) values. The first (void *) actually points
** to a function of type (int (*)(void *)). In order to invoke the connections
** busy-handler, this function should be invoked with the second (void *) in
** the array as the only argument. If it returns non-zero, then the operation
** should be retried. If it returns zero, the custom VFS should abandon the
** current operation.
**
** <li>[[SQLITE_FCNTL_TEMPFILENAME]]
** ^Application can invoke this file-control to have SQLite generate a
** temporary filename using the same algorithm that is followed to generate
** temporary filenames for TEMP tables and other internal uses.  The
** argument should be a char** which will be filled with the filename
** written into memory obtained from [sqlite3_malloc()].  The caller should
** invoke [sqlite3_free()] on the result to avoid a memory leak.
**
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE               1
#define SQLITE_GET_LOCKPROXYFILE             2
#define SQLITE_SET_LOCKPROXYFILE             3
#define SQLITE_LAST_ERRNO                    4
#define SQLITE_FCNTL_SIZE_HINT               5
#define SQLITE_FCNTL_CHUNK_SIZE              6
#define SQLITE_FCNTL_FILE_POINTER            7
#define SQLITE_FCNTL_SYNC_OMITTED            8
#define SQLITE_FCNTL_WIN32_AV_RETRY          9
#define SQLITE_FCNTL_PERSIST_WAL            10
#define SQLITE_FCNTL_OVERWRITE              11
#define SQLITE_FCNTL_VFSNAME                12
#define SQLITE_FCNTL_POWERSAFE_OVERWRITE    13
#define SQLITE_FCNTL_PRAGMA                 14
#define SQLITE_FCNTL_BUSYHANDLER            15
#define SQLITE_FCNTL_TEMPFILENAME           16

/*
** CAPI3REF: Mutex Handle
**
** The mutex module within SQLite defines [sqlite3_mutex] to be an
** abstract type for a mutex object.  The SQLite core never looks
** at the internal representation of an [sqlite3_mutex].  It only
1577
1578
1579
1580
1581
1582
1583
1584

1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
















1600
1601
1602
1603
1604
1605
1606
1588
1589
1590
1591
1592
1593
1594

1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633







-
+















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







** connection is opened. If it is globally disabled, filenames are
** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the
** database connection is opened. By default, URI handling is globally
** disabled. The default value may be changed by compiling with the
** [SQLITE_USE_URI] symbol defined.
**
** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
** <dd> This option taks a single integer argument which is interpreted as
** <dd> This option takes a single integer argument which is interpreted as
** a boolean in order to enable or disable the use of covering indices for
** full table scans in the query optimizer.  The default setting is determined
** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
** if that compile-time option is omitted.
** The ability to disable the use of covering indices for full table scans
** is because some incorrectly coded legacy applications might malfunction
** malfunction when the optimization is enabled.  Providing the ability to
** disable the optimization allows the older, buggy application code to work
** without change even with newer versions of SQLite.
**
** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]]
** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE
** <dd> These options are obsolete and should not be used by new code.
** They are retained for backwards compatibility but are now no-ops.
** </dl>
**
** [[SQLITE_CONFIG_SQLLOG]]
** <dt>SQLITE_CONFIG_SQLLOG
** <dd>This option is only available if sqlite is compiled with the
** SQLITE_ENABLE_SQLLOG pre-processor macro defined. The first argument should
** be a pointer to a function of type void(*)(void*,sqlite3*,const char*, int).
** The second should be of type (void*). The callback is invoked by the library
** in three separate circumstances, identified by the value passed as the
** fourth parameter. If the fourth parameter is 0, then the database connection
** passed as the second argument has just been opened. The third argument
** points to a buffer containing the name of the main database file. If the
** fourth parameter is 1, then the SQL statement that the third parameter
** points to has just been executed. Or, if the fourth parameter is 2, then
** the connection being passed as the second parameter is being closed. The
** third parameter is passed NULL In this case.
** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
#define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
#define SQLITE_CONFIG_SERIALIZED    3  /* nil */
#define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_SCRATCH       6  /* void*, int sz, int N */
1614
1615
1616
1617
1618
1619
1620

1621
1622
1623
1624
1625
1626
1627
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655







+







#define SQLITE_CONFIG_PCACHE       14  /* no-op */
#define SQLITE_CONFIG_GETPCACHE    15  /* no-op */
#define SQLITE_CONFIG_LOG          16  /* xFunc, void* */
#define SQLITE_CONFIG_URI          17  /* int */
#define SQLITE_CONFIG_PCACHE2      18  /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20  /* int */
#define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */

/*
** CAPI3REF: Database Connection Configuration Options
**
** These constants are the available integer configuration options that
** can be passed as the second argument to the [sqlite3_db_config()] interface.
**
Changes to SQLite.Interop/src/win/AssemblyInfo.cpp.
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22
8
9
10
11
12
13
14

15
16
17
18
19
20
21
22







-
+







using namespace System::Reflection;
using namespace System::Resources;
using namespace System::Runtime::InteropServices;

#include "interop.h"

[assembly:AssemblyTitleAttribute("SQLite.Interop")];
[assembly:AssemblyCompanyAttribute("Robert Simpson, et al.")];
[assembly:AssemblyCompanyAttribute("http://system.data.sqlite.org/")];
[assembly:AssemblyDescriptionAttribute("System.Data.SQLite Interop Assembly")];
[assembly:AssemblyProductAttribute("System.Data.SQLite")];
[assembly:AssemblyCopyrightAttribute("Public Domain")];
[assembly:AssemblyVersionAttribute(INTEROP_VERSION)];
[assembly:AssemblyFileVersionAttribute(INTEROP_VERSION)];

#if DEBUG
Changes to SQLite.Interop/src/win/interop.c.
37
38
39
40
41
42
43
44

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

44
45
46
47
48
49
50
51







-
+







#else
#define sqlite3InteropBreak(a)
#endif

typedef void (*SQLITEUSERFUNC)(sqlite3_context *, int, sqlite3_value **);
typedef void (*SQLITEFUNCFINAL)(sqlite3_context *);

#if defined(INTEROP_DEBUG)
#if defined(INTEROP_DEBUG) || defined(INTEROP_LOG)
SQLITE_PRIVATE void sqlite3InteropDebug(const char *zFormat, ...){
  va_list ap;                         /* Vararg list */
  StrAccum acc;                       /* String accumulator */
  char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */
  va_start(ap, zFormat);
  sqlite3StrAccumInit(&acc, zMsg, sizeof(zMsg), 0);
  acc.useMalloc = 0;
64
65
66
67
68
69
70








71
72
73
74
75
76
77
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85







+
+
+
+
+
+
+
+







    }
  }
#else
  fprintf(stderr, "%s", sqlite3StrAccumFinish(&acc));
#endif
}
#endif

#if defined(INTEROP_LOG)
SQLITE_PRIVATE int logConfigured = 0;

SQLITE_PRIVATE void sqlite3InteropLogCallback(void *pArg, int iCode, const char *zMsg){
  sqlite3InteropDebug("INTEROP_LOG (%d) %s\n", iCode, zMsg);
}
#endif

#if SQLITE_VERSION_NUMBER < 3007014
SQLITE_PRIVATE void * sqlite3DbMallocZero_interop(sqlite3 *db, int n)
{
  void *p;
  if (db) {
    sqlite3_mutex_enter(db->mutex);
179
180
181
182
183
184
185


















186

187
188
189
190
191
192
193
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211

212
213
214
215
216
217
218
219







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







    sqlite3_mutex_leave(db->mutex);
    ret = sqlite3_close(db);
  }
  return ret;
#endif
}

#if defined(INTEROP_LOG)
SQLITE_API int WINAPI sqlite3_config_log_interop()
{
  int ret;
  if( !logConfigured ){
    ret = sqlite3_config(SQLITE_CONFIG_LOG, sqlite3InteropLogCallback, 0);
    if( ret==SQLITE_OK ){
      logConfigured = 1;
    }else{
      sqlite3InteropDebug("sqlite3_config_log_interop(): sqlite3_config(SQLITE_CONFIG_LOG) returned %d.\n", ret);
    }
  }else{
    ret = SQLITE_OK;
  }
  return ret;
}
#endif

SQLITE_API int WINAPI sqlite3_open_interop(const char*filename, int flags, sqlite3 **ppdb)
SQLITE_API int WINAPI sqlite3_open_interop(const char *filename, int flags, sqlite3 **ppdb)
{
  int ret;

#if defined(INTEROP_DEBUG) && (INTEROP_DEBUG & INTEROP_DEBUG_OPEN)
  sqlite3InteropDebug("sqlite3_open_interop(): calling sqlite3_open_v2(\"%s\", %d, %p)...\n", filename, flags, ppdb);
#endif

239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
265
266
267
268
269
270
271



272
273
274
275
276
277
278







-
-
-







#if defined(INTEROP_DEBUG) && (INTEROP_DEBUG & INTEROP_DEBUG_CHANGES)
  sqlite3InteropDebug("sqlite3_changes_interop(): calling sqlite3_changes(%p)...\n", db);
#endif

#ifndef NDEBUG
  if (!db)
      sqlite3InteropBreak("null database handle for sqlite3_changes()");

  if (!sqlite3SafetyCheckOk(db))
      sqlite3InteropBreak("bad database handle for sqlite3_changes()");
#endif

  result = sqlite3_changes(db);

#if defined(INTEROP_DEBUG) && (INTEROP_DEBUG & INTEROP_DEBUG_CHANGES)
  sqlite3InteropDebug("sqlite3_changes_interop(): sqlite3_changes(%p) returned %d.\n", db, result);
#endif
733
734
735
736
737
738
739
740

741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756


















757
758
759
760
761
762
763
764
765
766
767

768
769

770



771



772
756
757
758
759
760
761
762

763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810

811
812
813
814
815

816
817
818
819







-
+
















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











+

-
+

+
+
+
-
+
+
+

#include "../core/sqlite3ext.h"
SQLITE_EXTENSION_INIT1

/*
** The interopTest() SQL function returns its first argument or raises an
** error if there are not enough arguments.
*/
static void interopTestFunc(
SQLITE_PRIVATE void interopTestFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const unsigned char *z;
  if( argc!=1 ){
    sqlite3_result_error(context, "need exactly one argument", -1);
    return;
  }
  z = sqlite3_value_text(argv[0]);
  if( z ){
    sqlite3_result_text(context, (char*)z, -1, SQLITE_STATIC);
  }else{
    sqlite3_result_null(context);
  }
}

/*
** The interopSleep() SQL function waits the specified number of milliseconds
** or raises an error if there are not enough arguments.
*/
SQLITE_PRIVATE void interopSleepFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int m;
  if( argc!=1 ){
    sqlite3_result_error(context, "need exactly one argument", -1);
    return;
  }
  m = sqlite3_value_int(argv[0]);
  sqlite3_result_int(context, SleepEx(m, TRUE));
}

/* SQLite invokes this routine once when it loads the extension.
** Create new functions, collating sequences, and virtual table
** modules here.  This is usually the only exported symbol in
** the shared library.
*/
SQLITE_API int interop_test_extension_init(
  sqlite3 *db,
  char **pzErrMsg,
  const sqlite3_api_routines *pApi
){
  int rc;
  SQLITE_EXTENSION_INIT2(pApi)
  return sqlite3_create_function(db, "interopTest", -1, SQLITE_ANY, 0,
  rc = sqlite3_create_function(db, "interopTest", -1, SQLITE_ANY, 0,
      interopTestFunc, 0, 0);
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_function(db, "interopSleep", 1, SQLITE_ANY, 0,
        interopSleepFunc, 0, 0);
}
  }
  return rc;
}
#endif
Changes to SQLite.Interop/src/win/interop.h.
1
2
3
4
5
6
7
8
9

10
1
2
3
4
5
6
7
8

9
10








-
+

/*
 * interop.h -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 */

#ifndef INTEROP_VERSION
#define INTEROP_VERSION       "1.0.83.0"
#define INTEROP_VERSION       "1.0.85.0"
#endif
Changes to SQLite.MSIL.nuspec.
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
23
24
25

26
27

28
29
1
2
3
4
5
6
7
8
9
10
11
12

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












-
+












+


+


<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.MSIL.nuspec -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<package>
  <metadata>
    <id>System.Data.SQLite.MSIL</id>
    <version>1.0.83.0</version>
    <version>1.0.85.0</version>
    <authors>SQLite Development Team</authors>
    <description>An ADO.NET provider for SQLite (managed-only).</description>
    <language>en-US</language>
    <projectUrl>http://system.data.sqlite.org/</projectUrl>
    <iconUrl>http://system.data.sqlite.org/images/sqlite32.png</iconUrl>
    <licenseUrl>http://www.sqlite.org/copyright.html</licenseUrl>
    <tags>sqlite database ado.net provider interop</tags>
    <copyright>Public Domain</copyright>
  </metadata>
  <files>
    <file src="bin\2008\Release\bin\System.Data.SQLite.dll" target="lib\net20" />
    <file src="bin\2010\Release\bin\System.Data.SQLite.dll" target="lib\net40" />
    <file src="bin\2012\Release\bin\System.Data.SQLite.dll" target="lib\net45" />
    <file src="bin\2008\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net20" />
    <file src="bin\2010\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net40" />
    <file src="bin\2012\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net45" />
  </files>
</package>
Changes to SQLite.NET.Settings.targets.
16
17
18
19
20
21
22



























23
24
25
26
27
28
29
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







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







  <!--
      NOTE: If the per-user settings file exists, import it now.  The contained
            settings, if any, will override the default ones provided below.
  -->
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets.user"
          Condition="Exists('$(SQLiteNetDir)\SQLite.NET.Settings.targets.user')" />

  <!--
  ******************************************************************************
  **                        Load Per-Framework Settings                       **
  ******************************************************************************
  -->

  <!--
      NOTE: If the per-framework settings files exist, import them now.  The
            contained settings, if any, will override the default ones provided
            below.
  -->
  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets.netFx20"
          Condition="'$(NetFx20)' != '' And '$(NetFx20)' != 'false' And
                     Exists('$(SQLiteNetDir)\SQLite.NET.Settings.targets.netFx20')" />

  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets.netFx35"
          Condition="'$(NetFx35)' != '' And '$(NetFx35)' != 'false' And
                     Exists('$(SQLiteNetDir)\SQLite.NET.Settings.targets.netFx35')" />

  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets.netFx40"
          Condition="'$(NetFx40)' != '' And '$(NetFx40)' != 'false' And
                     Exists('$(SQLiteNetDir)\SQLite.NET.Settings.targets.netFx40')" />

  <Import Project="$(SQLiteNetDir)\SQLite.NET.Settings.targets.netFx45"
          Condition="'$(NetFx45)' != '' And '$(NetFx45)' != 'false' And
                     Exists('$(SQLiteNetDir)\SQLite.NET.Settings.targets.netFx45')" />

  <!--
  ******************************************************************************
  **                       [Fairly] Generic Properties                        **
  ******************************************************************************
  -->

  <PropertyGroup>
110
111
112
113
114
115
116













117
118
119
120
121
122
123
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163







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







    <!--
        NOTE: Enable extra internal state checking for the public members of
              several key classes that use a connection.  By default, this is
              disabled.
    -->
    <CheckState Condition="'$(CheckState)' == ''">false</CheckState>

    <!--
        NOTE: Enable counting of all object instances for the CriticalHandle
              derived classes?  By default, this is disabled.  If this is
              enabled, this library will keep count of all non-disposed object
              instances for all the CriticalHandle derived classes.  Each
              counter will be incremented when an instance of the associated
              critical handle class is constructed and decremented when the
              ReleaseHandle method is completed successfully on an instance.
              These counts are intended to be used by the test suite to detect
              possible resource leaks.
    -->
    <CountHandle Condition="'$(CountHandle)' == ''">false</CountHandle>

    <!--
        NOTE: For interaction with the native SQLite implementation, use the
              custom built interop DLL (i.e. "SQLite.Interop.dll")?  By default,
              this is enabled.  This property is mutually exclusive with the
              "UseSqliteStandard" one, below.  This should always be disabled in
              the project file that builds the NetModule target.
    -->
236
237
238
239
240
241
242

















243
244
245
246
247
248
249
276
277
278
279
280
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
306







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







                  INTEROP_DEBUG_RESET          (0x0080)
                  INTEROP_DEBUG_CHANGES        (0x0100)
                  INTEROP_DEBUG_BREAK          (0x0200)
    -->
    <InteropDebug Condition="'$(InteropDebug)' == '' And '$(Configuration)' == 'Debug'">true</InteropDebug>
    <InteropDebug Condition="'$(InteropDebug)' == '' And '$(Configuration)' != 'Debug'">false</InteropDebug>

    <!--
        NOTE: Enable the logging callback in the custom built interop DLL (i.e.
              "SQLite.Interop.dll")?  By default, this is enabled in the Debug
              build configuration.  If this is disabled, the logging callback
              will be unavailable and diagnostic messages may not be seen if
              another native logging callback is not configured.  If this is
              enabled, it must also be enabled via the "INTEROP_LOG=1"
              preprocessor define being present in the "INTEROP_DEBUG_DEFINES"
              macro in the build properties file:

                  "SQLite.Interop\props\SQLite.Interop.20YY.[vs]props"

              for the corresponding version(s) of Visual Studio.
    -->
    <InteropLog Condition="'$(InteropLog)' == '' And '$(Configuration)' == 'Debug'">true</InteropLog>
    <InteropLog Condition="'$(InteropLog)' == '' And '$(Configuration)' != 'Debug'">false</InteropLog>

    <!--
        NOTE: Enable the use of native Windows APIs, when available?  By
              default, this is enabled.  If this is disabled, all features
              that require the use of native Windows APIs will be unavailable.
    -->
    <UseWindows Condition="'$(UseWindows)' == ''">true</UseWindows>
  </PropertyGroup>
Added SQLite.NET.Settings.targets.netFx35.






















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<!--
 *
 * SQLite.NET.Settings.targets.netFx35 -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup Condition="'$(ConfigurationYear)' != '' And
                            '$(ConfigurationYear)' != '2005' And
                            '$(ConfigurationYear)' != '2008'">
    <NetFx20>true</NetFx20>
    <NetFx35>true</NetFx35>
    <NetFx40>false</NetFx40>
    <NetFx45>false</NetFx45>
    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
    <TargetFrameworkProfile></TargetFrameworkProfile>
    <Prefer32Bit>false</Prefer32Bit>
    <PlatformToolset>v110</PlatformToolset>
  </PropertyGroup>
</Project>
Changes to SQLite.nuspec.
1
2
3
4
5
6
7
8
9
10
11
12
13
14

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

27
28

29
30
31
32


33
34
35
1
2
3
4
5
6
7
8
9
10
11
12
13

14
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













-
+












+


+




+
+



<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.nuspec -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<package>
  <metadata>
    <id>System.Data.SQLite</id>
    <title>System.Data.SQLite (x86/x64)</title>
    <version>1.0.83.0</version>
    <version>1.0.85.0</version>
    <authors>SQLite Development Team</authors>
    <description>The official SQLite database engine for both x86 and x64 along with the ADO.NET provider.</description>
    <language>en-US</language>
    <projectUrl>http://system.data.sqlite.org/</projectUrl>
    <iconUrl>http://system.data.sqlite.org/images/sqlite32.png</iconUrl>
    <licenseUrl>http://www.sqlite.org/copyright.html</licenseUrl>
    <tags>sqlite database ado.net provider interop</tags>
    <copyright>Public Domain</copyright>
  </metadata>
  <files>
    <file src="bin\2008\Release\bin\System.Data.SQLite.dll" target="lib\net20" />
    <file src="bin\2010\Release\bin\System.Data.SQLite.dll" target="lib\net40" />
    <file src="bin\2012\Release\bin\System.Data.SQLite.dll" target="lib\net45" />
    <file src="bin\2008\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net20" />
    <file src="bin\2010\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net40" />
    <file src="bin\2012\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net45" />
    <file src="bin\2008\Win32\ReleaseNativeOnlyStatic\SQLite.Interop.dll" target="content\net20\x86" />
    <file src="bin\2008\x64\ReleaseNativeOnlyStatic\SQLite.Interop.dll" target="content\net20\x64" />
    <file src="bin\2010\Win32\ReleaseNativeOnlyStatic\SQLite.Interop.dll" target="content\net40\x86" />
    <file src="bin\2010\x64\ReleaseNativeOnlyStatic\SQLite.Interop.dll" target="content\net40\x64" />
    <file src="bin\2012\Win32\ReleaseNativeOnlyStatic\SQLite.Interop.dll" target="content\net45\x86" />
    <file src="bin\2012\x64\ReleaseNativeOnlyStatic\SQLite.Interop.dll" target="content\net45\x64" />
    <file src="install.ps1" target="tools\install.ps1" />
  </files>
</package>
Changes to SQLite.x64.nuspec.
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
23
24
25

26
27

28
29
1
2
3
4
5
6
7
8
9
10
11
12

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












-
+












+


+


<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.x64.nuspec -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<package>
  <metadata>
    <id>System.Data.SQLite.x64</id>
    <version>1.0.83.0</version>
    <version>1.0.85.0</version>
    <authors>SQLite Development Team</authors>
    <description>The official SQLite database engine combined with a complete ADO.NET provider all rolled into a single mixed-mode assembly for x64.</description>
    <language>en-US</language>
    <projectUrl>http://system.data.sqlite.org/</projectUrl>
    <iconUrl>http://system.data.sqlite.org/images/sqlite32.png</iconUrl>
    <licenseUrl>http://www.sqlite.org/copyright.html</licenseUrl>
    <tags>sqlite database ado.net provider interop</tags>
    <copyright>Public Domain</copyright>
  </metadata>
  <files>
    <file src="bin\2008\x64\ReleaseStatic\System.Data.SQLite.dll" target="lib\net20" />
    <file src="bin\2010\x64\ReleaseStatic\System.Data.SQLite.dll" target="lib\net40" />
    <file src="bin\2012\x64\ReleaseStatic\System.Data.SQLite.dll" target="lib\net45" />
    <file src="bin\2008\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net20" />
    <file src="bin\2010\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net40" />
    <file src="bin\2012\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net45" />
  </files>
</package>
Changes to SQLite.x86.nuspec.
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
23
24
25

26
27

28
29
1
2
3
4
5
6
7
8
9
10
11
12

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












-
+












+


+


<?xml version="1.0" encoding="utf-8"?>
<!--
 *
 * SQLite.x86.nuspec -
 *
 * Written by Joe Mistachkin.
 * Released to the public domain, use at your own risk!
 *
-->
<package>
  <metadata>
    <id>System.Data.SQLite.x86</id>
    <version>1.0.83.0</version>
    <version>1.0.85.0</version>
    <authors>SQLite Development Team</authors>
    <description>The official SQLite database engine combined with a complete ADO.NET provider all rolled into a single mixed-mode assembly for x86.</description>
    <language>en-US</language>
    <projectUrl>http://system.data.sqlite.org/</projectUrl>
    <iconUrl>http://system.data.sqlite.org/images/sqlite32.png</iconUrl>
    <licenseUrl>http://www.sqlite.org/copyright.html</licenseUrl>
    <tags>sqlite database ado.net provider interop</tags>
    <copyright>Public Domain</copyright>
  </metadata>
  <files>
    <file src="bin\2008\Win32\ReleaseStatic\System.Data.SQLite.dll" target="lib\net20" />
    <file src="bin\2010\Win32\ReleaseStatic\System.Data.SQLite.dll" target="lib\net40" />
    <file src="bin\2012\Win32\ReleaseStatic\System.Data.SQLite.dll" target="lib\net45" />
    <file src="bin\2008\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net20" />
    <file src="bin\2010\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net40" />
    <file src="bin\2012\Release\bin\System.Data.SQLite.Linq.dll" target="lib\net45" />
  </files>
</package>
Changes to Setup/SQLite.iss.
79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93







-
+







#if Year == "2005"
Components: Application\Core\MSIL; Name: gac; Description: Install the assemblies into the global assembly cache.; Flags: unchecked; Check: CheckIsNetFx2Setup() or CheckIsNetFx4Setup()
#else
Components: Application\Core\MSIL Or Application\LINQ; Name: gac; Description: Install the assemblies into the global assembly cache.; Flags: unchecked; Check: CheckIsNetFx2Setup() or CheckIsNetFx4Setup()
#endif

#if AppProcessor == "x86"
#if Year == "2005" || Year == "2008"
#if Year == "2005"
Components: {#InstallerCondition}; Name: gac\vs2005; Description: Install the designer components for Visual Studio 2005.; Flags: unchecked; Check: CheckIsNetFx2Setup()
#endif
#if Year == "2008"
Components: {#InstallerCondition}; Name: gac\vs2008; Description: Install the designer components for Visual Studio 2008.; Flags: unchecked; Check: CheckIsNetFx2Setup()
#endif
#if Year == "2010"
Components: {#InstallerCondition}; Name: gac\vs2010; Description: Install the designer components for Visual Studio 2010.; Flags: unchecked; Check: CheckIsNetFx4Setup()
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
134
135
136
137
138

139
140
141
142
143
144
145
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
134
135
136
137

138
139
140
141
142
143
144
145







-
+










-
+






-
+








-
+








#if Year != "2005"
Components: Application\LINQ; Tasks: ngen; Filename: {code:GetNetFx2InstallRoot|Ngen.exe}; Parameters: "install ""{app}\bin\System.Data.SQLite.Linq.dll"" /nologo"; Flags: skipifdoesntexist; Check: CheckIsNetFx2Setup() and CheckForNetFx35(1)
Components: Application\LINQ; Tasks: ngen; Filename: {code:GetNetFx4InstallRoot|Ngen.exe}; Parameters: "install ""{app}\bin\System.Data.SQLite.Linq.dll"" /nologo"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup()
#endif

#if Pos("NativeOnly", AppConfiguration) == 0 && AppProcessor == "x86"
#if Year == "2005" || Year == "2008"
#if Year == "2005"
Components: {#InstallerCondition}; Tasks: gac\vs2005; Filename: {app}\bin\Installer.exe; Parameters: "-install true -wow64 true -installFlags AllExceptGlobalAssemblyCache -tracePriority Lowest -verbose true -noCompact true -noNetFx35 true -noNetFx40 true -noNetFx45 true -noVs2008 true -noVs2010 true -noVs2012 true -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx2Setup()
#endif
#if Year == "2008"
Components: {#InstallerCondition}; Tasks: gac\vs2008; Filename: {app}\bin\Installer.exe; Parameters: "-install true -wow64 true -installFlags AllExceptGlobalAssemblyCache -tracePriority Lowest -verbose true -noCompact true -noNetFx40 true -noNetFx45 true -noVs2005 true -noVs2010 true -noVs2012 true -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx2Setup()
#endif
#if Year == "2010"
Components: {#InstallerCondition}; Tasks: gac\vs2010; Filename: {app}\bin\Installer.exe; Parameters: "-install true -wow64 true -installFlags AllExceptGlobalAssemblyCache -tracePriority Lowest -verbose true -noCompact true -noNetFx20 true -noNetFx45 true -noVs2005 true -noVs2008 true -noVs2012 true -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup()
#endif
#if Year == "2012"
Components: {#InstallerCondition}; Tasks: gac\vs2012; Filename: {app}\bin\Installer.exe; Parameters: "-install true -wow64 true -installFlags AllExceptGlobalAssemblyCache -tracePriority Lowest -verbose true -noCompact true -noNetFx20 true -noNetFx40 true -noVs2005 true -noVs2008 true -noVs2010 true -configVersion 4.0.30319 -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup()
Components: {#InstallerCondition}; Tasks: gac\vs2012; Filename: {app}\bin\Installer.exe; Parameters: "-perUser true -install true -wow64 true -installFlags AllExceptGlobalAssemblyCache -tracePriority Lowest -verbose true -noCompact true -noNetFx20 true -noNetFx40 true -noVs2005 true -noVs2008 true -noVs2010 true -configVersion 4.0.30319 -vsVersionSuffix _Config -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup()
Components: {#InstallerCondition}; Tasks: gac\vs2012; Filename: {app}\bin\Installer.exe; Parameters: "-perUser true -install true -wow64 true -installFlags AllExceptGlobalAssemblyCache -tracePriority Lowest -verbose true -noCompact true -noNetFx20 true -noNetFx40 true -noNetFx45 true -noVs2005 true -noVs2008 true -noVs2010 true -configVersion 4.0.30319 -vsVersionSuffix _Config -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup()
#endif
#endif

[UninstallRun]
#if Pos("NativeOnly", AppConfiguration) == 0 && AppProcessor == "x86"
#if Year == "2012"
Components: {#InstallerCondition}; Tasks: gac\vs2012; Filename: {app}\bin\Installer.exe; Parameters: "-perUser true -install false -wow64 true -installFlags AllExceptGlobalAssemblyCache -tracePriority Lowest -verbose true -noCompact true -noNetFx20 true -noNetFx40 true -noVs2005 true -noVs2008 true -noVs2010 true -configVersion 4.0.30319 -vsVersionSuffix _Config -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup()
Components: {#InstallerCondition}; Tasks: gac\vs2012; Filename: {app}\bin\Installer.exe; Parameters: "-perUser true -install false -wow64 true -installFlags AllExceptGlobalAssemblyCache -tracePriority Lowest -verbose true -noCompact true -noNetFx20 true -noNetFx40 true -noNetFx45 true -noVs2005 true -noVs2008 true -noVs2010 true -configVersion 4.0.30319 -vsVersionSuffix _Config -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup()
Components: {#InstallerCondition}; Tasks: gac\vs2012; Filename: {app}\bin\Installer.exe; Parameters: "-install false -wow64 true -installFlags AllExceptGlobalAssemblyCache -tracePriority Lowest -verbose true -noCompact true -noNetFx20 true -noNetFx40 true -noVs2005 true -noVs2008 true -noVs2010 true -configVersion 4.0.30319 -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup()
#endif
#if Year == "2010"
Components: {#InstallerCondition}; Tasks: gac\vs2010; Filename: {app}\bin\Installer.exe; Parameters: "-install false -wow64 true -installFlags AllExceptGlobalAssemblyCache -tracePriority Lowest -verbose true -noCompact true -noNetFx20 true -noNetFx45 true -noVs2005 true -noVs2008 true -noVs2012 true -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup()
#endif
#if Year == "2008"
Components: {#InstallerCondition}; Tasks: gac\vs2008; Filename: {app}\bin\Installer.exe; Parameters: "-install false -wow64 true -installFlags AllExceptGlobalAssemblyCache -tracePriority Lowest -verbose true -noCompact true -noNetFx40 true -noNetFx45 true -noVs2005 true -noVs2010 true -noVs2012 true -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx2Setup()
#endif
#if Year == "2005" || Year == "2008"
#if Year == "2005"
Components: {#InstallerCondition}; Tasks: gac\vs2005; Filename: {app}\bin\Installer.exe; Parameters: "-install false -wow64 true -installFlags AllExceptGlobalAssemblyCache -tracePriority Lowest -verbose true -noCompact true -noNetFx35 true -noNetFx40 true -noNetFx45 true -noVs2008 true -noVs2010 true -noVs2012 true -whatIf false -confirm true"; Flags: skipifdoesntexist; Check: CheckIsNetFx2Setup()
#endif
#endif

#if Year != "2005"
Components: Application\LINQ; Tasks: ngen; Filename: {code:GetNetFx4InstallRoot|Ngen.exe}; Parameters: "uninstall ""{app}\bin\System.Data.SQLite.Linq.dll"" /nologo"; Flags: skipifdoesntexist; Check: CheckIsNetFx4Setup()
Components: Application\LINQ; Tasks: ngen; Filename: {code:GetNetFx2InstallRoot|Ngen.exe}; Parameters: "uninstall ""{app}\bin\System.Data.SQLite.Linq.dll"" /nologo"; Flags: skipifdoesntexist; Check: CheckIsNetFx2Setup() and CheckForNetFx35(1)
Changes to Setup/build_ce.bat.
26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40







-
+







)

SET TOOLS=%~dp0
SET TOOLS=%TOOLS:~0,-1%

%_VECHO% Tools = '%TOOLS%'

SET BUILD_CONFIGURATIONS=Release
SET BUILD_CONFIGURATIONS=Debug Release
SET BASE_CONFIGURATIONSUFFIX=Compact
SET PLATFORMS="Pocket PC 2003 (ARMV4)"
SET PROCESSORS=arm
SET YEARS=2008
SET BASE_PLATFORM=PocketPC

CALL :fn_ResetErrorLevel
Changes to Setup/set_common.bat.
16
17
18
19
20
21
22
23

24
25
26
27

28
29
30
31
32
33
34
16
17
18
19
20
21
22

23
24
25
26

27
28
29
30
31
32
33
34







-
+



-
+







)

IF NOT DEFINED PUBLICKEY (
  SET PUBLICKEY=db937bc2d44ff139
)

IF NOT DEFINED BUILD_CONFIGURATIONS (
  SET BUILD_CONFIGURATIONS=Release ReleaseNativeOnly
  SET BUILD_CONFIGURATIONS=Debug DebugNativeOnly Release ReleaseNativeOnly
)

IF NOT DEFINED TEST_CONFIGURATIONS (
  SET TEST_CONFIGURATIONS=Release
  SET TEST_CONFIGURATIONS=Debug Release
)

IF NOT DEFINED BAKE_CONFIGURATIONS (
  SET BAKE_CONFIGURATIONS=Release ReleaseNativeOnly
)

IF NOT DEFINED RELEASE_CONFIGURATIONS (
Changes to Setup/set_user_mistachkin_Debug.bat.
9
10
11
12
13
14
15

16
17
18
9
10
11
12
13
14
15
16
17
18
19







+



:: Released to the public domain, use at your own risk!
::

REM
REM NOTE: Enables the extra debug code helpful in troubleshooting issues.
REM
SET MSBUILD_ARGS=/p:CheckState=true
SET MSBUILD_ARGS=%MSBUILD_ARGS% /p:CountHandle=true
SET MSBUILD_ARGS=%MSBUILD_ARGS% /p:TraceConnection=true
SET MSBUILD_ARGS=%MSBUILD_ARGS% /p:TraceHandle=true
SET MSBUILD_ARGS=%MSBUILD_ARGS% /p:TraceStatement=true
Changes to Setup/test_all.bat.
96
97
98
99
100
101
102






103
104
105
106
107
108
109
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115







+
+
+
+
+
+







%__ECHO2% PUSHD "%ROOT%"

IF ERRORLEVEL 1 (
  ECHO Could not change directory to "%ROOT%".
  GOTO errors
)

REM
REM NOTE: Set an environment variable that can be used by the test suite to
REM       determine that testing is being performed in batch mode.
REM
SET TEST_ALL=1

FOR %%C IN (%TEST_CONFIGURATIONS%) DO (
  FOR %%Y IN (%YEARS%) DO (
    IF NOT DEFINED NOMANAGEDONLY (
      %__ECHO% Externals\Eagle\bin\EagleShell.exe -preInitialize "set test_year {%%Y}; set test_configuration {%%C}" -file "%TEST_FILE%"

      IF ERRORLEVEL 1 (
        ECHO Testing of "%%Y/%%C" managed-only assembly failed.
Changes to Setup/verify.lst.
78
79
80
81
82
83
84

85
86
87
88
89
90
91
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92







+







  Setup/bake.bat
  Setup/bake_all.bat
  Setup/build.bat
  Setup/build_all.bat
  Setup/build_ce.bat
  Setup/CheckForNetFx.pas
  Setup/clean.bat
  Setup/deployAndTestCe.eagle
  Setup/InitializeSetup.pas
  Setup/release.bat
  Setup/release_all.bat
  Setup/release_ce.bat
  Setup/release_static.bat
  Setup/set_2005.bat
  Setup/set_2008.bat
126
127
128
129
130
131
132

133
134
135
136

137
138
139
140
141
142
143
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146







+




+







  Setup/set_x64_2012.bat
  Setup/set_x86_2005.bat
  Setup/set_x86_2008.bat
  Setup/set_x86_2010.bat
  Setup/set_x86_2012.bat
  Setup/SQLite.iss
  Setup/test_all.bat
  Setup/test_ce.bat
  Setup/updateFileInfo.tcl
  Setup/verify.eagle
  Setup/verify.lst
  Setup/vsSp.bat
  SQLite.Beta.nuspec
  SQLite.Designer/
  SQLite.Designer/AssemblyInfo.cs
  SQLite.Designer/ChangePasswordDialog.cs
  SQLite.Designer/ChangePasswordDialog.Designer.cs
  SQLite.Designer/ChangePasswordDialog.resx
  SQLite.Designer/ChangeScriptDialog.cs
  SQLite.Designer/ChangeScriptDialog.Designer.cs
243
244
245
246
247
248
249

250
251
252
253
254
255
256
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260







+







  SQLite.NET.2008.MSBuild.sln
  SQLite.NET.2008.sln
  SQLite.NET.2010.MSBuild.sln
  SQLite.NET.2010.sln
  SQLite.NET.2012.MSBuild.sln
  SQLite.NET.2012.sln
  SQLite.NET.Settings.targets
  SQLite.NET.Settings.targets.netFx35
  SQLite.NET.targets
  SQLite.nuspec
  SQLite.x64.nuspec
  SQLite.x86.nuspec
  System.Data.SQLite/
  System.Data.SQLite/AssemblyInfo.cs
  System.Data.SQLite/DataTypes.xml
390
391
392
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
418
419
420
421
422
423
424

425
426
427
428
429
430
431
394
395
396
397
398
399
400
401
402
403
404
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







+









+











+
+








+







  testlinq/testlinq.2010.csproj
  testlinq/testlinq.2012.csproj
  Tests/
  Tests/all.eagle
  Tests/backup.eagle
  Tests/basic.eagle
  Tests/common.eagle
  Tests/empty.eagle
  Tests/installer.eagle
  Tests/Installer_Test_Vs2005.log
  Tests/Installer_Test_Vs2008.log
  Tests/Installer_Test_Vs2010.log
  Tests/Installer_Test_Vs2012.log
  Tests/nonWal.db
  Tests/pkgIndex.eagle
  Tests/stress.eagle
  Tests/testlinq.out
  Tests/thread.eagle
  Tests/tkt-00f86f9739.eagle
  Tests/tkt-0d5b1ef362.eagle
  Tests/tkt-17045010df.eagle
  Tests/tkt-201128cc88.eagle
  Tests/tkt-2c630bffa7.eagle
  Tests/tkt-2ce0870fad.eagle
  Tests/tkt-343d392b51.eagle
  Tests/tkt-3aa50d8413.eagle
  Tests/tkt-448d663d11.eagle
  Tests/tkt-544dba0a2f.eagle
  Tests/tkt-59edc1018b.eagle
  Tests/tkt-6434e23a0f.eagle
  Tests/tkt-6c6ecccc5f.eagle
  Tests/tkt-72905c9a77.eagle
  Tests/tkt-7e3fa93744.eagle
  Tests/tkt-84718e79fa.eagle
  Tests/tkt-8554170e09.eagle
  Tests/tkt-8b7d179c3c.eagle
  Tests/tkt-8c3bee31c8.eagle
  Tests/tkt-996d13cd87.eagle
  Tests/tkt-ac47dd230a.eagle
  Tests/tkt-ae5267b863.eagle
  Tests/tkt-b4a7ddc83f.eagle
  Tests/tkt-bb4b04d457.eagle
  Tests/tkt-ccfa69fc32.eagle
  Tests/tkt-e1b2e0f769.eagle
  Tests/tkt-e30b820248.eagle
  Tests/Uninstaller_Test_Vs2005.log
  Tests/Uninstaller_Test_Vs2008.log
Changes to System.Data.SQLite.Linq/AssemblyInfo.cs.
40
41
42
43
44
45
46
47
48


40
41
42
43
44
45
46


47
48







-
-
+
+
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.83.0")]
[assembly: AssemblyFileVersion("1.0.83.0")]
[assembly: AssemblyVersion("1.0.85.0")]
[assembly: AssemblyFileVersion("1.0.85.0")]
Changes to System.Data.SQLite.Linq/SQLiteProviderServices.cs.
98
99
100
101
102
103
104







105


106
107
108
109
110
111
112
98
99
100
101
102
103
104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119
120







+
+
+
+
+
+
+
-
+
+







    }

    protected override string GetDbProviderManifestToken(DbConnection connection)
    {
      if (String.IsNullOrEmpty(connection.ConnectionString))
        throw new ArgumentNullException("ConnectionString");

      bool parseViaFramework = false;

      if (connection is SQLiteConnection)
          parseViaFramework = ((SQLiteConnection)connection).ParseViaFramework;

      SortedList<string, string> opts = parseViaFramework ?
          SQLiteConnection.ParseConnectionStringViaFramework(connection.ConnectionString, false) :
      SortedList<string, string> opts = SQLiteConnection.ParseConnectionString(connection.ConnectionString);
          SQLiteConnection.ParseConnectionString(connection.ConnectionString);

      return SQLiteConnection.FindKey(opts, "DateTimeFormat", "ISO8601");
    }

    protected override DbProviderManifest GetDbProviderManifest(string versionHint)
    {
      return new SQLiteProviderManifest(versionHint);
    }
Changes to System.Data.SQLite/AssemblyInfo.cs.
60
61
62
63
64
65
66
67

68
69

70
60
61
62
63
64
65
66

67
68

69
70







-
+

-
+

//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Revision and Build Numbers 
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.83.0")]
[assembly: AssemblyVersion("1.0.85.0")]
#if !PLATFORM_COMPACTFRAMEWORK
[assembly: AssemblyFileVersion("1.0.83.0")]
[assembly: AssemblyFileVersion("1.0.85.0")]
#endif
Changes to System.Data.SQLite/LINQ/SQLiteFactory_Linq.cs.
24
25
26
27
28
29
30






31
32
33
34
35
36
37
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43







+
+
+
+
+
+







    {
#if (SQLITE_STANDARD || USE_INTEROP_DLL || PLATFORM_COMPACTFRAMEWORK) && PRELOAD_NATIVE_LIBRARY
        UnsafeNativeMethods.Initialize();
#endif

#if !PLATFORM_COMPACTFRAMEWORK
        SQLiteLog.Initialize();
#elif INTEROP_LOG
        if (UnsafeNativeMethods.sqlite3_config_log_interop() == SQLiteErrorCode.Ok)
        {
            UnsafeNativeMethods.sqlite3_log(
                SQLiteErrorCode.Ok, SQLiteConvert.ToUTF8("logging initialized."));
        }
#endif

        string version =
#if NET_40 || NET_45
            "4.0.0.0";
#else
            "3.5.0.0";
Changes to System.Data.SQLite/SQLite3.cs.
53
54
55
56
57
58
59
60

61
62
63
64
65
66
67
53
54
55
56
57
58
59

60
61
62
63
64
65
66
67







-
+







    internal const string PublicKey =
        "002400000480000094000000060200000024000052534131000400000100010005a288de5687c4e1" +
        "b621ddff5d844727418956997f475eb829429e411aff3e93f97b70de698b972640925bdd44280df0" +
        "a25a843266973704137cbb0e7441c1fe7cae4e2440ae91ab8cde3933febcb1ac48dd33b40e13c421" +
        "d8215c18a4349a436dd499e3c385cc683015f886f6c10bd90115eb2bd61b67750839e3a19941dc9c";

#if !PLATFORM_COMPACTFRAMEWORK
    internal const string DesignerVersion = "1.0.83.0";
    internal const string DesignerVersion = "1.0.85.0";
#endif

    /// <summary>
    /// The opaque pointer returned to us by the sqlite provider
    /// </summary>
    protected internal SQLiteConnectionHandle _sql;
    protected string _fileName;
170
171
172
173
174
175
176








177
178
179
180
181
182
183
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191







+
+
+
+
+
+
+
+







    internal override string Version
    {
      get
      {
        return SQLite3.SQLiteVersion;
      }
    }

    internal override int VersionNumber
    {
      get
      {
        return SQLite3.SQLiteVersionNumber;
      }
    }

    internal static string DefineConstants
    {
        get
        {
            StringBuilder result = new StringBuilder();
            IList<string> list = SQLiteDefineConstants.OptionList;
203
204
205
206
207
208
209








210
211
212
213
214
215
216
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232







+
+
+
+
+
+
+
+







    internal static string SQLiteVersion
    {
      get
      {
        return UTF8ToString(UnsafeNativeMethods.sqlite3_libversion(), -1);
      }
    }

    internal static int SQLiteVersionNumber
    {
      get
      {
        return UnsafeNativeMethods.sqlite3_libversion_number();
      }
    }

    internal static string SQLiteSourceId
    {
      get
      {
        return UTF8ToString(UnsafeNativeMethods.sqlite3_sourceid(), -1);
      }
1786
1787
1788
1789
1790
1791
1792




1793
1794
1795
1796
1797
1798
1799
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819







+
+
+
+








        if (handlePtr == IntPtr.Zero)
            throw new InvalidOperationException(
                "Backup object has an invalid handle pointer.");

        SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_backup_finish(handlePtr);
        handle.SetHandleAsInvalid();

#if COUNT_HANDLE
        if (n == SQLiteErrorCode.Ok) handle.WasReleasedOk();
#endif

        if ((n != SQLiteErrorCode.Ok) && (n != backup._stepResult))
            throw new SQLiteException(n, GetLastError());
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////

Changes to System.Data.SQLite/SQLiteBase.cs.
22
23
24
25
26
27
28




29
30
31
32
33
34
35
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39







+
+
+
+







    internal SQLiteBase(SQLiteDateFormats fmt, DateTimeKind kind)
      : base(fmt, kind) { }

    /// <summary>
    /// Returns a string representing the active version of SQLite
    /// </summary>
    internal abstract string Version { get; }
    /// <summary>
    /// Returns an integer representing the active version of SQLite
    /// </summary>
    internal abstract int VersionNumber { get; }
    /// <summary>
    /// Returns the rowid of the most recent successful INSERT into the database from this connection.
    /// </summary>
    internal abstract long LastInsertRowId { get; }
    /// <summary>
    /// Returns the number of changes the last executing insert/update caused.
    /// </summary>
573
574
575
576
577
578
579
580

581
582
583
584
585













586
587
588
589
590
591
















592
593
594
595
596
597
598
577
578
579
580
581
582
583

584
585




586
587
588
589
590
591
592
593
594
595
596
597
598






599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621







-
+

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







#else
            lock (hdl)
#endif
            {
#if !SQLITE_STANDARD
                SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_close_interop(db);
#else
                ResetConnection(hdl, db);
                ResetConnection(hdl, db, false);

                SQLiteErrorCode n;

                try
                {
                SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_close(db);
#endif
                if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError(hdl, db));
            }
        }
    }

    internal static void CloseConnectionV2(SQLiteConnectionHandle hdl, IntPtr db)
    {
        if ((hdl == null) || (db == IntPtr.Zero)) return;

        try
        {
                    n = UnsafeNativeMethods.sqlite3_close_v2(db);
                }
                catch (EntryPointNotFoundException)
                {
                    n = UnsafeNativeMethods.sqlite3_close(db);
                }
            // do nothing.
        }
        finally /* NOTE: Thread.Abort() protection. */
        {
#if PLATFORM_COMPACTFRAMEWORK
            lock (hdl.syncRoot)
#else
            lock (hdl)
#endif
            {
#if !SQLITE_STANDARD
                SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_close_interop(db);
#else
                ResetConnection(hdl, db, false);

                SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_close_v2(db);
#endif
                if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError(hdl, db));
            }
        }
    }

    internal static bool ResetConnection(SQLiteConnectionHandle hdl, IntPtr db, bool canThrow)
Changes to System.Data.SQLite/SQLiteCommand.cs.
18
19
20
21
22
23
24







25
26
27
28
29
30
31
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38







+
+
+
+
+
+
+







  /// SQLite implementation of DbCommand.
  /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
  [Designer("SQLite.Designer.SQLiteCommandDesigner, SQLite.Designer, Version=" + SQLite3.DesignerVersion + ", Culture=neutral, PublicKeyToken=db937bc2d44ff139"), ToolboxItem(true)]
#endif
  public sealed class SQLiteCommand : DbCommand, ICloneable
  {
    /// <summary>
    /// The default connection string to be used when creating a temporary
    /// connection to execute a command via the static <see cref="Execute" />
    /// method.
    /// </summary>
    private static readonly string DefaultConnectionString = "Data Source=:memory:;";

    /// <summary>
    /// The command text this command is based on
    /// </summary>
    private string _commandText;
    /// <summary>
    /// The connection the command is associated with
    /// </summary>
591
592
593
594
595
596
597



















































































598
599
600
601
602
603
604
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694







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







    /// </summary>
    /// <param name="behavior">The behavior the data reader should adopt</param>
    /// <returns>Returns a SQLiteDataReader object</returns>
    protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior)
    {
      return ExecuteReader(behavior);
    }

    /// <summary>
    /// This method creates a new connection, executes the query using the given
    /// execution type, closes the connection, and returns the results.  If the
    /// connection string is null, a temporary in-memory database connection will
    /// be used.
    /// </summary>
    /// <param name="commandText">
    /// The text of the command to be executed.
    /// </param>
    /// <param name="executeType">
    /// The execution type for the command.  This is used to determine which method
    /// of the command object to call, which then determines the type of results
    /// returned, if any.
    /// </param>
    /// <param name="connectionString">
    /// The connection string to the database to be opened, used, and closed.  If
    /// this parameter is null, a temporary in-memory databse will be used.
    /// </param>
    /// <param name="args">
    /// The SQL parameter values to be used when building the command object to be
    /// executed, if any.
    /// </param>
    /// <returns>
    /// The results of the query -OR- null if no results were produced from the
    /// given execution type.
    /// </returns>
    public static object Execute(
        string commandText,
        SQLiteExecuteType executeType,
        string connectionString,
        params object[] args
        )
    {
        if (connectionString == null)
            connectionString = DefaultConnectionString;

        using (SQLiteConnection connection = new SQLiteConnection(connectionString))
        {
            connection.Open();

            using (SQLiteCommand command = connection.CreateCommand())
            {
                command.CommandText = commandText;

                if (args != null)
                {
                    foreach (object arg in args)
                    {
                        if (arg is SQLiteParameter)
                            command.Parameters.Add((SQLiteParameter)arg);
                        else
                            command.Parameters.Add(new SQLiteParameter(DbType.Object, arg));
                    }
                }

                switch (executeType)
                {
                    case SQLiteExecuteType.None:
                        {
                            //
                            // NOTE: Do nothing.
                            //
                            break;
                        }
                    case SQLiteExecuteType.NonQuery:
                        {
                            return command.ExecuteNonQuery();
                        }
                    case SQLiteExecuteType.Scalar:
                        {
                            return command.ExecuteScalar();
                        }
                    case SQLiteExecuteType.Reader:
                        {
                            return command.ExecuteReader();
                        }
                }
            }
        }

        return null;
    }

    /// <summary>
    /// Overrides the default behavior to return a SQLiteDataReader specialization class
    /// </summary>
    /// <param name="behavior">The flags to be associated with the reader</param>
    /// <returns>A SQLiteDataReader</returns>
    public new SQLiteDataReader ExecuteReader(CommandBehavior behavior)
Changes to System.Data.SQLite/SQLiteConnection.cs.
330
331
332
333
334
335
336







337
338
339
340
341
342
343
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350







+
+
+
+
+
+
+







    /// </summary>
    private static object _syncRoot = new object();

    /// <summary>
    /// Static variable to store the connection event handlers to call.
    /// </summary>
    private static event SQLiteConnectionEventHandler _handlers;

#if SQLITE_STANDARD && !PLATFORM_COMPACTFRAMEWORK
    /// <summary>
    /// Used to hold the active library version number of SQLite.
    /// </summary>
    private static int _versionNumber;
#endif
    #endregion

    ///////////////////////////////////////////////////////////////////////////////////////////////

    #region Private Data
    /// <summary>
    /// State of the current connection
398
399
400
401
402
403
404






405
406
407
408
409
410
411
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424







+
+
+
+
+
+







    private SQLiteConnectionFlags _flags;

    /// <summary>
    /// Default command timeout
    /// </summary>
    private int _defaultTimeout = 30;

    /// <summary>
    /// Non-zero if the built-in (i.e. framework provided) connection string
    /// parser should be used when opening the connection.
    /// </summary>
    private bool _parseViaFramework;

    internal bool _binaryGuid;

    internal long _version;

    private event SQLiteUpdateEventHandler _updateHandler;
    private event SQLiteCommitHandler _commitHandler;
    private event SQLiteTraceEventHandler _traceHandler;
434
435
436
437
438
439
440
441

442
443

444
















445
446
447
448
449
450
451























452


453







454
455
456
457
458
459
460
461
462
463
464
465
466
467
468

469
470
471
472
473
474
475
447
448
449
450
451
452
453

454
455

456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506

507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527

528
529
530
531
532
533
534
535







-
+

-
+

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







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

+
+
-
+
+
+
+
+
+
+














-
+







    /// </summary>
    public SQLiteConnection()
      : this("")
    {
    }

    /// <summary>
    /// Initializes the connection with the specified connection string
    /// Initializes the connection with the specified connection string.
    /// </summary>
    /// <param name="connectionString">The connection string to use on the connection</param>
    /// <param name="connectionString">The connection string to use.</param>
    public SQLiteConnection(string connectionString)
        : this(connectionString, false)
    {
        // do nothing.
    }

    /// <summary>
    /// Initializes the connection with the specified connection string.
    /// </summary>
    /// <param name="connectionString">
    /// The connection string to use on.
    /// </param>
    /// <param name="parseViaFramework">
    /// Non-zero to parse the connection string using the built-in (i.e.
    /// framework provided) parser when opening the connection.
    /// </param>
    public SQLiteConnection(string connectionString, bool parseViaFramework)
    {
#if (SQLITE_STANDARD || USE_INTEROP_DLL || PLATFORM_COMPACTFRAMEWORK) && PRELOAD_NATIVE_LIBRARY
      UnsafeNativeMethods.Initialize();
#endif

#if !PLATFORM_COMPACTFRAMEWORK
      SQLiteLog.Initialize();

#if SQLITE_STANDARD
      //
      // NOTE: Check if the sqlite3_close_v2() native API should be available
      //       to use.  This must be done dynamically because the delegate set
      //       here is used by the SQLiteConnectionHandle class, which is a
      //       CriticalHandle derived class (i.e. protected by a constrained
      //       execution region).  Therefore, if the underlying native entry
      //       point is unavailable, an exception will be raised even if it is
      //       never actually called (i.e. because the runtime eagerly prepares
      //       all the methods in the call graph of the constrained execution
      //       region).
      //
      lock (_syncRoot)
      {
          if (_versionNumber == 0)
          {
              _versionNumber = SQLite3.SQLiteVersionNumber;

              if (_versionNumber >= 3007014)
                  SQLiteConnectionHandle.closeConnection = SQLiteBase.CloseConnectionV2;
          }
      }
#endif
#elif INTEROP_LOG
      if (UnsafeNativeMethods.sqlite3_config_log_interop() == SQLiteErrorCode.Ok)

      {
          UnsafeNativeMethods.sqlite3_log(
              SQLiteErrorCode.Ok, SQLiteConvert.ToUTF8("logging initialized."));
      }
#endif

      _parseViaFramework = parseViaFramework;
      _flags = SQLiteConnectionFlags.Default;
      _connectionState = ConnectionState.Closed;
      _connectionString = "";
      //_commandList = new List<WeakReference>();

      if (connectionString != null)
        ConnectionString = connectionString;
    }

    /// <summary>
    /// Clones the settings and connection string from an existing connection.  If the existing connection is already open, this
    /// function will open its own connection, enumerate any attached databases of the original connection, and automatically
    /// attach to them.
    /// </summary>
    /// <param name="connection"></param>
    /// <param name="connection">The connection to copy the settings from.</param>
    public SQLiteConnection(SQLiteConnection connection)
      : this(connection.ConnectionString)
    {
      string str;

      if (connection.State == ConnectionState.Open)
      {
1260
1261
1262
1263
1264
1265
1266
1267


1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279

1280
1281
1282
1283
1284








1285
1286
1287
1288

1289
1290

1291
1292
1293
































































1294
1295
1296
1297
1298
1299
1300
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
1354
1355
1356

1357
1358

1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
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
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433







-
+
+











-
+





+
+
+
+
+
+
+
+



-
+

-
+



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







      else if (path.StartsWith ("/", StringComparison.OrdinalIgnoreCase))
            return path;
      else
            throw new InvalidOperationException ("Invalid connection string: invalid URI");
    }

    /// <summary>
    /// Parses the connection string into component parts
    /// Parses the connection string into component parts using the custom
    /// connection string parser.
    /// </summary>
    /// <param name="connectionString">The connection string to parse</param>
    /// <returns>An array of key-value pairs representing each parameter of the connection string</returns>
    internal static SortedList<string, string> ParseConnectionString(string connectionString)
    {
      string s = connectionString;
      int n;
      SortedList<string, string> ls = new SortedList<string, string>(StringComparer.OrdinalIgnoreCase);

      // First split into semi-colon delimited values.  The Split() function of SQLiteBase accounts for and properly
      // skips semi-colons in quoted strings
      string[] arParts = SQLiteConvert.Split(s, ';');
      string[] arParts = s.Split(';');

      int x = arParts.Length;
      // For each semi-colon piece, split into key and value pairs by the presence of the = sign
      for (n = 0; n < x; n++)
      {
        if (arParts[n] == null)
          continue;

        arParts[n] = arParts[n].Trim();

        if (arParts[n].Length == 0)
          continue;

        int indexOf = arParts[n].IndexOf('=');

        if (indexOf != -1)
          ls.Add(arParts[n].Substring(0, indexOf), arParts[n].Substring(indexOf + 1));
          ls.Add(UnwrapString(arParts[n].Substring(0, indexOf).Trim()), UnwrapString(arParts[n].Substring(indexOf + 1).Trim()));
        else
          throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "Invalid ConnectionString format for part \"{0}\"", arParts[n]));
          throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "Invalid ConnectionString format for part \"{0}\", no equal sign found", arParts[n]));
      }
      return ls;
    }

    /// <summary>
    /// Parses a connection string using the built-in (i.e. framework provided)
    /// connection string parser class and returns the key/value pairs.  An
    /// exception may be thrown if the connection string is invalid or cannot be
    /// parsed.  When compiled for the .NET Compact Framework, the custom
    /// connection string parser is always used instead because the framework
    /// provided one is unavailable there.
    /// </summary>
    /// <param name="connectionString">
    /// The connection string to parse.
    /// </param>
    /// <param name="strict">
    /// Non-zero to throw an exception if any connection string values are not of
    /// the <see cref="String" /> type.
    /// </param>
    /// <returns>The list of key/value pairs.</returns>
    internal static SortedList<string, string> ParseConnectionStringViaFramework(
        string connectionString,
        bool strict
        )
    {
#if !PLATFORM_COMPACTFRAMEWORK
        DbConnectionStringBuilder connectionStringBuilder
            = new DbConnectionStringBuilder();

        connectionStringBuilder.ConnectionString = connectionString; /* throw */

        SortedList<string, string> result =
            new SortedList<string, string>(StringComparer.OrdinalIgnoreCase);

        foreach (string keyName in connectionStringBuilder.Keys)
        {
            object value = connectionStringBuilder[keyName];
            string keyValue = null;

            if (value is string)
            {
                keyValue = (string)value;
            }
            else if (strict)
            {
                throw new ArgumentException(
                    "connection property value is not a string",
                    keyName);
            }
            else if (value != null)
            {
                keyValue = value.ToString();
            }

            result.Add(keyName, keyValue);
        }

        return result;
#else
        //
        // NOTE: On the .NET Compact Framework, always use our custom connection
        //       string parser as the built-in (i.e. framework provided) one is
        //       unavailable.
        //
        return ParseConnectionString(connectionString);
#endif
    }

#if !PLATFORM_COMPACTFRAMEWORK
    /// <summary>
    /// Manual distributed transaction enlistment support
    /// </summary>
    /// <param name="transaction">The distributed transaction to enlist in</param>
    public override void EnlistTransaction(System.Transactions.Transaction transaction)
1429
1430
1431
1432
1433
1434
1435
1436






1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1562
1563
1564
1565
1566
1567
1568

1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587

1588
1589
1590
1591
1592
1593
1594







-
+
+
+
+
+
+













-







          SQLiteConnectionEventType.Opening, null, null, null, null, null));

      if (_connectionState != ConnectionState.Closed)
        throw new InvalidOperationException();

      Close();

      SortedList<string, string> opts = ParseConnectionString(_connectionString);
      SortedList<string, string> opts = _parseViaFramework ?
          ParseConnectionStringViaFramework(_connectionString, false) :
          ParseConnectionString(_connectionString);

      OnChanged(this, new ConnectionEventArgs(
          SQLiteConnectionEventType.ConnectionString, null, null, null, _connectionString, opts));

      object enumValue;

      enumValue = TryParseEnum(typeof(SQLiteConnectionFlags), FindKey(opts, "Flags", DefaultFlags.ToString()), true);
      _flags = (enumValue is SQLiteConnectionFlags) ? (SQLiteConnectionFlags)enumValue : DefaultFlags;

      bool fullUri = false;
      string fileName;

      if (Convert.ToInt32(FindKey(opts, "Version", DefaultVersion.ToString()), CultureInfo.InvariantCulture) != DefaultVersion)
        throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture, "Only SQLite Version {0} is supported at this time", DefaultVersion));

      fileName = FindKey(opts, "Data Source", DefaultDataSource);
      fileName = UnwrapFileName(fileName);

      if (String.IsNullOrEmpty(fileName))
      {
        fileName = FindKey(opts, "Uri", DefaultUri);
        if (String.IsNullOrEmpty(fileName))
        {
          fileName = FindKey(opts, "FullUri", DefaultFullUri);
1699
1700
1701
1702
1703
1704
1705










1706
1707
1708
1709
1710
1711
1712
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859







+
+
+
+
+
+
+
+
+
+







    /// This can also be set in the ConnectionString with "Default Timeout"
    /// </summary>
    public int DefaultTimeout
    {
      get { CheckDisposed(); return _defaultTimeout; }
      set { CheckDisposed(); _defaultTimeout = value; }
    }

    /// <summary>
    /// Non-zero if the built-in (i.e. framework provided) connection string
    /// parser should be used when opening the connection.
    /// </summary>
    public bool ParseViaFramework
    {
        get { CheckDisposed(); return _parseViaFramework; }
        set { CheckDisposed(); _parseViaFramework = value; }
    }

    /// <summary>
    /// Gets/sets the extra behavioral flags for this connection.  See the
    /// <see cref="SQLiteConnectionFlags" /> enumeration for a list of
    /// possible values.
    /// </summary>
    public SQLiteConnectionFlags Flags
1748
1749
1750
1751
1752
1753
1754



















1755
1756
1757
1758
1759
1760
1761
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927







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








        if (_sql == null)
          throw new InvalidOperationException("Database connection not valid for getting last insert rowid.");

        return _sql.LastInsertRowId;
      }
    }

    /// <summary>
    /// This method causes any pending database operation to abort and return at
    /// its earliest opportunity.  This routine is typically called in response
    /// to a user action such as pressing "Cancel" or Ctrl-C where the user wants
    /// a long query operation to halt immediately.  It is safe to call this
    /// routine from any thread.  However, it is not safe to call this routine
    /// with a database connection that is closed or might close before this method
    /// returns.
    /// </summary>
    public void Cancel()
    {
        CheckDisposed();

        if (_sql == null)
            throw new InvalidOperationException("Database connection not valid for query cancellation.");

        _sql.Cancel(); /* throw */
    }

    /// <summary>
    /// Returns the number of rows changed by the last INSERT, UPDATE, or DELETE statement executed on
    /// this connection.
    /// </summary>
#if !PLATFORM_COMPACTFRAMEWORK
    [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
1870
1871
1872
1873
1874
1875
1876
1877




1878
1879
1880
1881
1882
1883
1884
2036
2037
2038
2039
2040
2041
2042

2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053







-
+
+
+
+







    public SQLiteErrorCode Shutdown()
    {
        CheckDisposed();

        // make sure we have an instance of the base class
        if (_sql == null)
        {
            SortedList<string, string> opts = ParseConnectionString(_connectionString);
            SortedList<string, string> opts = _parseViaFramework ?
                ParseConnectionStringViaFramework(_connectionString, false) :
                ParseConnectionString(_connectionString);

            object enumValue;

            enumValue = TryParseEnum(typeof(SQLiteDateFormats), FindKey(opts,
                "DateTimeFormat", DefaultDateTimeFormat.ToString()), true);

            SQLiteDateFormats dateFormat = (enumValue is SQLiteDateFormats) ?
                (SQLiteDateFormats)enumValue : DefaultDateTimeFormat;
2063
2064
2065
2066
2067
2068
2069
2070
2071


2072
2073

2074
2075
2076
2077






2078
2079

2080
2081
2082
2083
2084

2085
2086
2087

2088
2089
2090


2091
2092
2093
2094
2095

2096
2097
2098
2099
2100
2101

2102
2103
2104
2105
2106
2107
2108
2232
2233
2234
2235
2236
2237
2238


2239
2240
2241

2242
2243



2244
2245
2246
2247
2248
2249
2250

2251
2252
2253
2254
2255

2256
2257
2258

2259
2260


2261
2262
2263
2264
2265
2266

2267
2268
2269
2270
2271
2272

2273
2274
2275
2276
2277
2278
2279
2280







-
-
+
+

-
+

-
-
-
+
+
+
+
+
+

-
+




-
+


-
+

-
-
+
+




-
+





-
+







                Marshal.FreeHGlobal(pArg);
        }

        return rc;
    }

    /// <summary>
    /// Removes one set of surrounding single -OR- double quotes from the file
    /// name and returns the resulting file name.  If the string is null, empty,
    /// Removes one set of surrounding single -OR- double quotes from the string
    /// value and returns the resulting string value.  If the string is null, empty,
    /// or contains quotes that are not balanced, nothing is done and the original
    /// string will be returned.
    /// string value will be returned.
    /// </summary>
    /// <param name="sourceFile">The database file name to process.</param>
    /// <returns>The modified database file name.</returns>
    private string UnwrapFileName(string sourceFile)
    /// <param name="value">The string value to process.</param>
    /// <returns>
    /// The string value, modified to remove one set of surrounding single -OR-
    /// double quotes, if applicable.
    /// </returns>
    private static string UnwrapString(string value)
    {
        if (String.IsNullOrEmpty(sourceFile))
        if (String.IsNullOrEmpty(value))
        {
            //
            // NOTE: The string is null or empty, return it verbatim.
            //
            return sourceFile;
            return value;
        }

        int length = sourceFile.Length;
        int length = value.Length;

        if (((sourceFile[0] == '\'') && (sourceFile[length - 1] == '\'')) ||
            ((sourceFile[0] == '"') && (sourceFile[length - 1] == '"')))
        if (((value[0] == '\'') && (value[length - 1] == '\'')) ||
            ((value[0] == '"') && (value[length - 1] == '"')))
        {
            //
            // NOTE: Remove the first and last character.
            //
            return sourceFile.Substring(1, length - 2);
            return value.Substring(1, length - 2);
        }

        //
        // NOTE: No match, return the input string verbatim.
        //
        return sourceFile;
        return value;
    }

    /// <summary>
    /// Expand the filename of the data source, resolving the |DataDirectory|
    /// macro as appropriate.
    /// </summary>
    /// <param name="sourceFile">The database filename to expand</param>
Changes to System.Data.SQLite/SQLiteConvert.cs.
1005
1006
1007
1008
1009
1010
1011





1012
1013
1014
1015

1016
1017
1018
1019
1020
1021

1022
1023
1024
1025
1026

1027
1028
1029
1030
1031

1032
1033
1034
1035
1036

1037
1038
1039
1040
1041

1042
1043
1044
1045
1046

1047
1048
1049
1050
1051
1052
1053
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019

1020
1021
1022
1023
1024
1025

1026
1027
1028
1029
1030

1031
1032
1033
1034
1035

1036
1037
1038
1039
1040

1041
1042
1043
1044
1045

1046
1047
1048
1049
1050

1051
1052
1053
1054
1055
1056
1057
1058







+
+
+
+
+



-
+





-
+




-
+




-
+




-
+




-
+




-
+







      Unknown = 0,

      /// <summary>
      /// The connection is being opened.
      /// </summary>
      Opening = 1,

      /// <summary>
      /// The connection string has been parsed.
      /// </summary>
      ConnectionString = 2,

      /// <summary>
      /// The connection was opened.
      /// </summary>
      Opened = 2,
      Opened = 3,

      /// <summary>
      /// The <see cref="ChangeDatabase" /> method was called on the
      /// connection.
      /// </summary>
      ChangeDatabase = 3,
      ChangeDatabase = 4,

      /// <summary>
      /// A transaction was created using the connection.
      /// </summary>
      NewTransaction = 4,
      NewTransaction = 5,

      /// <summary>
      /// The connection was enlisted into a transaction.
      /// </summary>
      EnlistTransaction = 5,
      EnlistTransaction = 6,

      /// <summary>
      /// A command was created using the connection.
      /// </summary>
      NewCommand = 6,
      NewCommand = 7,

      /// <summary>
      /// The connection is being closed.
      /// </summary>
      Closing = 7,
      Closing = 8,

      /// <summary>
      /// The connection was closed.
      /// </summary>
      Closed = 8
      Closed = 9
  }

  /// <summary>
  /// This implementation of SQLite for ADO.NET can process date/time fields in databases in only one of three formats.  Ticks, ISO8601
  /// and JulianDay.
  /// </summary>
  /// <remarks>
1175
1176
1177
1178
1179
1180
1181






































1182
1183
1184
1185
1186
1187
1188
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231







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







      /// all content is safely written to the disk surface prior to continuing.
      /// This ensures that an operating system crash or power failure will not
      /// corrupt the database.  FULL synchronous is very safe, but it is also
      /// slower.
      /// </summary>
      Full = 2
  }

  /// <summary>
  /// The requested command execution type.  This controls which method of the
  /// <see cref="SQLiteCommand" /> object will be called.
  /// </summary>
  public enum SQLiteExecuteType
  {
      /// <summary>
      /// Do nothing.  No method will be called.
      /// </summary>
      None = 0,

      /// <summary>
      /// The command is not expected to return a result -OR- the result is not
      /// needed.  The <see cref="SQLiteCommand.ExecuteNonQuery" /> method will
      /// be called.
      /// </summary>
      NonQuery = 1,

      /// <summary>
      /// The command is expected to return a scalar result -OR- the result should
      /// be limited to a scalar result.  The <see cref="SQLiteCommand.ExecuteScalar" />
      /// method will be called.
      /// </summary>
      Scalar = 2,

      /// <summary>
      /// The command is expected to return <see cref="SQLiteDataReader"/> result.
      /// The <see cref="SQLiteCommand.ExecuteReader()" /> method will be called.
      /// </summary>
      Reader = 3,

      /// <summary>
      /// Use the default command execution type.  Using this value is the same
      /// as using the <see cref="SQLiteExecuteType.None" /> value.
      /// </summary>
      Default = NonQuery /* TODO: Good default? */
  }

  /// <summary>
  /// Struct used internally to determine the datatype of a column in a resultset
  /// </summary>
  internal class SQLiteType
  {
    /// <summary>
Changes to System.Data.SQLite/SQLiteDataAdapter.cs.
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
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
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







+
+
+

-
+
+








+
+



+
-
+
+





+
+

-
+
+

+
-
-
+
+
+
+
+





+
+

-
+
+

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

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


+







  [Designer("Microsoft.VSDesigner.Data.VS.SqlDataAdapterDesigner, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
#endif
  public sealed class SQLiteDataAdapter : DbDataAdapter
  {
    private static object _updatingEventPH = new object();
    private static object _updatedEventPH = new object();

    ///////////////////////////////////////////////////////////////////////////////////////////////

    #region Public Constructors
    /// <overloads>
    /// This class is just a shell around the DbDataAdapter.  Nothing from DbDataAdapter is overridden here, just a few constructors are defined.
    /// This class is just a shell around the DbDataAdapter.  Nothing from
    /// DbDataAdapter is overridden here, just a few constructors are defined.
    /// </overloads>
    /// <summary>
    /// Default constructor.
    /// </summary>
    public SQLiteDataAdapter()
    {
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    /// Constructs a data adapter using the specified select command.
    /// </summary>
    /// <param name="cmd">
    /// <param name="cmd">The select command to associate with the adapter.</param>
    /// The select command to associate with the adapter.
    /// </param>
    public SQLiteDataAdapter(SQLiteCommand cmd)
    {
      SelectCommand = cmd;
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    /// Constructs a data adapter with the supplied select command text and associated with the specified connection.
    /// Constructs a data adapter with the supplied select command text and
    /// associated with the specified connection.
    /// </summary>
    /// <param name="commandText">
    /// <param name="commandText">The select command text to associate with the data adapter.</param>
    /// <param name="connection">The connection to associate with the select command.</param>
    /// The select command text to associate with the data adapter.
    /// </param>
    /// <param name="connection">
    /// The connection to associate with the select command.
    /// </param>
    public SQLiteDataAdapter(string commandText, SQLiteConnection connection)
    {
      SelectCommand = new SQLiteCommand(commandText, connection);
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    /// Constructs a data adapter with the specified select command text, and using the specified database connection string.
    /// Constructs a data adapter with the specified select command text,
    /// and using the specified database connection string.
    /// </summary>
    /// <param name="commandText">
    /// <param name="commandText">The select command text to use to construct a select command.</param>
    /// <param name="connectionString">A connection string suitable for passing to a new SQLiteConnection, which is associated with the select command.</param>
    public SQLiteDataAdapter(string commandText, string connectionString)
    /// The select command text to use to construct a select command.
    /// </param>
    /// <param name="connectionString">
    /// A connection string suitable for passing to a new SQLiteConnection,
    /// which is associated with the select command.
    /// </param>
    public SQLiteDataAdapter(
        string commandText,
        string connectionString
        )
        : this(commandText, connectionString, false)
    {
        // do nothing.
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    /// Constructs a data adapter with the specified select command text,
    /// and using the specified database connection string.
    /// </summary>
    /// <param name="commandText">
    /// The select command text to use to construct a select command.
    /// </param>
    /// <param name="connectionString">
    /// A connection string suitable for passing to a new SQLiteConnection,
    /// which is associated with the select command.
    /// </param>
    /// <param name="parseViaFramework">
    /// Non-zero to parse the connection string using the built-in (i.e.
    /// framework provided) parser when opening the connection.
    /// </param>
    public SQLiteDataAdapter(
        string commandText,
        string connectionString,
        bool parseViaFramework
        )
    {
      SQLiteConnection cnn = new SQLiteConnection(connectionString);
      SQLiteConnection cnn = new SQLiteConnection(
          connectionString, parseViaFramework);

      SelectCommand = new SQLiteCommand(commandText, cnn);
    }
    #endregion

    ///////////////////////////////////////////////////////////////////////////////////////////////

    #region IDisposable "Pattern" Members
    private bool disposed;
    private void CheckDisposed() /* throw */
    {
80
81
82
83
84
85
86
87

88
89
90
91
92





























93
94
95
96
97
98
99
136
137
138
139
140
141
142

143





144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179







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








    protected override void Dispose(bool disposing)
    {
        try
        {
            if (!disposed)
            {
                //if (disposing)
                if (disposing)
                //{
                //    ////////////////////////////////////
                //    // dispose managed resources here...
                //    ////////////////////////////////////
                //}
                {
                    ////////////////////////////////////
                    // dispose managed resources here...
                    ////////////////////////////////////

                    if (SelectCommand != null)
                    {
                        SelectCommand.Dispose();
                        SelectCommand = null;
                    }

                    if (InsertCommand != null)
                    {
                        InsertCommand.Dispose();
                        InsertCommand = null;
                    }

                    if (UpdateCommand != null)
                    {
                        UpdateCommand.Dispose();
                        UpdateCommand = null;
                    }

                    if (DeleteCommand != null)
                    {
                        DeleteCommand.Dispose();
                        DeleteCommand = null;
                    }
                }

                //////////////////////////////////////
                // release unmanaged resources here...
                //////////////////////////////////////

                disposed = true;
            }
Changes to System.Data.SQLite/SQLiteDataReader.cs.
642
643
644
645
646
647
648
649

650
651
652
653
654
655
656
642
643
644
645
646
647
648

649
650
651
652
653
654
655
656







-
+







    /// </summary>
    /// <param name="name">The name of the column to retrieve</param>
    /// <returns>The int i of the column</returns>
    public override int GetOrdinal(string name)
    {
      CheckDisposed();
      CheckClosed();
      SQLiteCommand.Check(_command);
      if (_throwOnDisposed) SQLiteCommand.Check(_command);

      //
      // NOTE: First, check if the column name cache has been initialized yet.
      //       If not, do it now.
      //
      if (_fieldIndexes == null)
          _fieldIndexes = new Dictionary<string, int>(new ColumnNameComparer());
850
851
852
853
854
855
856
857

858
859
860
861
862
863
864
850
851
852
853
854
855
856

857
858
859
860
861
862
863
864







-
+







            columnToParent.Add(n, value);
        }
    }

    internal DataTable GetSchemaTable(bool wantUniqueInfo, bool wantDefaultValue)
    {
      CheckClosed();
      SQLiteCommand.Check(_command);
      if (_throwOnDisposed) SQLiteCommand.Check(_command);

     //
     // BUGFIX: We need to quickly scan all the fields in the current
     //         "result set" to see how many distinct tables are actually
     //         involved.  This information is necessary so that some
     //         intelligent decisions can be made when constructing the
     //         metadata below.  For example, we need to be very careful
1217
1218
1219
1220
1221
1222
1223
1224

1225
1226
1227
1228
1229
1230
1231
1217
1218
1219
1220
1221
1222
1223

1224
1225
1226
1227
1228
1229
1230
1231







-
+







    /// Moves to the next resultset in multiple row-returning SQL command.
    /// </summary>
    /// <returns>True if the command was successful and a new resultset is available, False otherwise.</returns>
    public override bool NextResult()
    {
      CheckDisposed();
      CheckClosed();
      SQLiteCommand.Check(_command);
      if (_throwOnDisposed) SQLiteCommand.Check(_command);

      SQLiteStatement stmt = null;
      int fieldCount;

      while (true)
      {
        if (stmt == null && _activeStatement != null && _activeStatement._sql != null && _activeStatement._sql.IsOpen())
1343
1344
1345
1346
1347
1348
1349
1350

1351
1352
1353
1354
1355
1356
1357
1343
1344
1345
1346
1347
1348
1349

1350
1351
1352
1353
1354
1355
1356
1357







-
+







    /// Reads the next row from the resultset
    /// </summary>
    /// <returns>True if a new row was successfully loaded and is ready for processing</returns>
    public override bool Read()
    {
      CheckDisposed();
      CheckClosed();
      SQLiteCommand.Check(_command);
      if (_throwOnDisposed) SQLiteCommand.Check(_command);

      if (_readingState == -1) // First step was already done at the NextResult() level, so don't step again, just return true.
      {
        _readingState = 0;
        return true;
      }
      else if (_readingState == 0) // Actively reading rows
Changes to System.Data.SQLite/SQLiteDefineConstants.cs.
11
12
13
14
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
11
12
13
14
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







+
+
+
+
















+
+
+
+







{
    internal static class SQLiteDefineConstants
    {
        public static readonly IList<string> OptionList = new List<string>(new string[] {
#if CHECK_STATE
            "CHECK_STATE",
#endif

#if COUNT_HANDLE
            "COUNT_HANDLE",
#endif

#if DEBUG
            "DEBUG",
#endif

#if INTEROP_CODEC
            "INTEROP_CODEC",
#endif

#if INTEROP_DEBUG
            "INTEROP_DEBUG",
#endif

#if INTEROP_EXTENSION_FUNCTIONS
            "INTEROP_EXTENSION_FUNCTIONS",
#endif

#if INTEROP_LOG
            "INTEROP_LOG",
#endif

#if INTEROP_TEST_EXTENSION
            "INTEROP_TEST_EXTENSION",
#endif

#if NET_20
            "NET_20",
Changes to System.Data.SQLite/SQLiteException.cs.
1
2
3
4

5
6
7
8
9
10
11
1
2
3

4
5
6
7
8
9
10
11



-
+







/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 *
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace System.Data.SQLite
{
  using System;
  using System.Data.Common;
180
181
182
183
184
185
186

187



188
189
190
191
192
193
194
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198







+

+
+
+







    private static string GetStockErrorMessage(
        SQLiteErrorCode errorCode,
        string message
        )
    {
        return String.Format("{0}{1}{2}",
            GetErrorString(errorCode),
#if !NET_COMPACT_20
            Environment.NewLine, message).Trim();
#else
            "\r\n", message).Trim();
#endif
    }
  }

  /// <summary>
  /// SQLite error codes.  Actually, this enumeration represents a return code,
  /// which may also indicate success in one of several ways (e.g. SQLITE_OK,
  /// SQLITE_ROW, and SQLITE_DONE).  Therefore, the name of this enumeration is
Changes to System.Data.SQLite/SQLiteLog.cs.
354
355
356
357
358
359
360




361

362
363
364
365
366
367
368
354
355
356
357
358
359
360
361
362
363
364

365
366
367
368
369
370
371
372







+
+
+
+
-
+







        {
            bool enabled;
            SQLiteLogEventHandler handlers;

            lock (syncRoot)
            {
                enabled = _enabled;

                if (_handlers != null)
                    handlers = _handlers.Clone() as SQLiteLogEventHandler;
                else
                handlers = _handlers;
                    handlers = null;
            }

            if (enabled && (handlers != null))
                handlers(null, new LogEventArgs(
                    IntPtr.Zero, errorCode, message, null));
        }

Changes to System.Data.SQLite/System.Data.SQLite.Properties.targets.
66
67
68
69
70
71
72







73
74
75
76
77
78
79
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86







+
+
+
+
+
+
+







  <!--
      NOTE: Enable extra internal state checking?
  -->
  <PropertyGroup Condition="'$(CheckState)' != 'false'">
    <DefineConstants>$(DefineConstants);CHECK_STATE</DefineConstants>
  </PropertyGroup>

  <!--
      NOTE: Enable counting of the CriticalHandle derived object instances?
  -->
  <PropertyGroup Condition="'$(CountHandle)' != 'false'">
    <DefineConstants>$(DefineConstants);COUNT_HANDLE</DefineConstants>
  </PropertyGroup>

  <!--
      NOTE: For interaction with the native SQLite implementation, use the
            custom build interop DLL (i.e. "SQLite.Interop.DLL")?
  -->
  <PropertyGroup Condition="'$(UseInteropDll)' != 'false'">
    <DefineConstants>$(DefineConstants);USE_INTEROP_DLL</DefineConstants>
  </PropertyGroup>
142
143
144
145
146
147
148








149
150
151
152
153
154
155
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170







+
+
+
+
+
+
+
+







      NOTE: Enable extra diagnostics from the custom built interop DLL (see the
            "SQLite.NET.Settings.targets" file for more information)?
  -->
  <PropertyGroup Condition="'$(InteropDebug)' != 'false'">
    <DefineConstants>$(DefineConstants);INTEROP_DEBUG</DefineConstants>
  </PropertyGroup>

  <!--
      NOTE: Enable the logging callback in the custom built interop DLL (see
            the "SQLite.NET.Settings.targets" file for more information)?
  -->
  <PropertyGroup Condition="'$(InteropLog)' != 'false'">
    <DefineConstants>$(DefineConstants);INTEROP_LOG</DefineConstants>
  </PropertyGroup>

  <!--
      NOTE: Enable various Trace.WriteLine statements included in the code,
            based on several criteria (see the "SQLite.NET.Settings.targets"
            file for more information)?
  -->
  <PropertyGroup Condition="'$(TraceConnection)' != 'false'">
    <DefineConstants>$(DefineConstants);TRACE_CONNECTION</DefineConstants>
Changes to System.Data.SQLite/UnsafeNativeMethods.cs.
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
37



















38
39
40
41
42
43
44
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







-
+








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








#if !PLATFORM_COMPACTFRAMEWORK && !DEBUG
  using System.Security;
#endif

  using System.Runtime.InteropServices;

#if !PLATFORM_COMPACTFRAMEWORK
#if !PLATFORM_COMPACTFRAMEWORK || COUNT_HANDLE
  using System.Threading;
#endif

#if !PLATFORM_COMPACTFRAMEWORK && !DEBUG
  [SuppressUnmanagedCodeSecurity]
#endif
  internal static class UnsafeNativeMethods
  {
      #region Critical Handle Counts (Debug Build Only)
#if COUNT_HANDLE
      //
      // NOTE: These counts represent the total number of outstanding
      //       (non-disposed) CriticalHandle derived object instances
      //       created by this library and are primarily for use by
      //       the test suite.  These counts are incremented by the
      //       associated constructors and are decremented upon the
      //       successful completion of the associated ReleaseHandle
      //       methods.
      //
      internal static int connectionCount;
      internal static int statementCount;
      internal static int backupCount;
#endif
      #endregion

      /////////////////////////////////////////////////////////////////////////

      #region Optional Native SQLite Library Pre-Loading Code
      //
      // NOTE: If we are looking for the standard SQLite DLL ("sqlite3.dll"),
      //       the interop DLL ("SQLite.Interop.dll"), or we are running on the
      //       .NET Compact Framework, we should include this code (only if the
      //       feature has actually been enabled).  This code would be totally
      //       redundant if this module has been bundled into the mixed-mode
485
486
487
488
489
490
491
492

493
494
495
496
497
498
499
504
505
506
507
508
509
510

511
512
513
514
515
516
517
518







-
+







    //
    // NOTE: On the .NET Compact Framework, the native interop assembly must
    //       be used because it provides several workarounds to .NET Compact
    //       Framework limitations important for proper operation of the core
    //       System.Data.SQLite functionality (e.g. being able to bind
    //       parameters and handle column values of types Int64 and Double).
    //
    internal const string SQLITE_DLL = "SQLite.Interop.083.dll";
    internal const string SQLITE_DLL = "SQLite.Interop.085.dll";
#elif SQLITE_STANDARD
    //
    // NOTE: Otherwise, if the standard SQLite library is enabled, use it.
    //
    private const string SQLITE_DLL = "sqlite3";
#elif USE_INTEROP_DLL
    //
565
566
567
568
569
570
571




572
573
574
575
576
577
578
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601







+
+
+
+








    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_value_text_interop(IntPtr p, out int len);

    [DllImport(SQLITE_DLL)]
    internal static extern IntPtr sqlite3_value_text16_interop(IntPtr p, out int len);

#if INTEROP_LOG
    [DllImport(SQLITE_DLL)]
    internal static extern SQLiteErrorCode sqlite3_config_log_interop();
#endif
#endif
// !SQLITE_STANDARD

    #endregion

    // These functions add existing functionality on top of SQLite and require a little effort to
    // get working when using the standard SQLite library.
837
838
839
840
841
842
843







844
845
846
847
848
849
850
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880







+
+
+
+
+
+
+







#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_libversion();

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern int sqlite3_libversion_number();

#if !PLATFORM_COMPACTFRAMEWORK
    [DllImport(SQLITE_DLL, CallingConvention = CallingConvention.Cdecl)]
#else
    [DllImport(SQLITE_DLL)]
#endif
    internal static extern IntPtr sqlite3_sourceid();

1461
1462
1463
1464
1465
1466
1467
1468

1469










1470
1471
1472
1473
1474
1475
1476
1491
1492
1493
1494
1495
1496
1497

1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516







-
+

+
+
+
+
+
+
+
+
+
+







#endif

    ///////////////////////////////////////////////////////////////////////////

    #region SQLiteConnectionHandle Class
    // Handles the unmanaged database pointer, and provides finalization
    // support for it.
    internal class SQLiteConnectionHandle : CriticalHandle
    internal sealed class SQLiteConnectionHandle : CriticalHandle
    {
#if SQLITE_STANDARD && !PLATFORM_COMPACTFRAMEWORK
        internal delegate void CloseConnectionCallback(
            SQLiteConnectionHandle hdl, IntPtr db);

        internal static CloseConnectionCallback closeConnection =
            SQLiteBase.CloseConnection;
#endif

        ///////////////////////////////////////////////////////////////////////

#if PLATFORM_COMPACTFRAMEWORK
        internal readonly object syncRoot = new object();
#endif

        ///////////////////////////////////////////////////////////////////////

        public static implicit operator IntPtr(SQLiteConnectionHandle db)
1501
1502
1503
1504
1505
1506
1507




1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519

1520



1521

1522
1523
1524
1525
1526
1527
1528
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
1575
1576
1577







+
+
+
+












+

+
+
+

+







        }

        ///////////////////////////////////////////////////////////////////////

        private SQLiteConnectionHandle()
            : base(IntPtr.Zero)
        {
#if COUNT_HANDLE
            Interlocked.Increment(
                ref UnsafeNativeMethods.connectionCount);
#endif
        }

        ///////////////////////////////////////////////////////////////////////

        protected override bool ReleaseHandle()
        {
            try
            {
#if !PLATFORM_COMPACTFRAMEWORK
                IntPtr localHandle = Interlocked.Exchange(
                    ref handle, IntPtr.Zero);

#if SQLITE_STANDARD
                if (localHandle != IntPtr.Zero)
                    closeConnection(this, localHandle);
#else
                if (localHandle != IntPtr.Zero)
                    SQLiteBase.CloseConnection(this, localHandle);
#endif

#if !NET_COMPACT_20 && TRACE_HANDLE
                try
                {
                    Trace.WriteLine(String.Format(
                        "CloseConnection: {0}", localHandle));
                }
1536
1537
1538
1539
1540
1541
1542




1543
1544
1545
1546
1547
1548
1549
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602







+
+
+
+







                    if (handle != IntPtr.Zero)
                    {
                        SQLiteBase.CloseConnection(this, handle);
                        SetHandle(IntPtr.Zero);
                    }
                }
#endif
#if COUNT_HANDLE
                Interlocked.Decrement(
                    ref UnsafeNativeMethods.connectionCount);
#endif
#if DEBUG
                return true;
#endif
            }
#if !NET_COMPACT_20 && TRACE_HANDLE
            catch (SQLiteException e)
#else
1576
1577
1578
1579
1580
1581
1582










1583
1584
1585
1586
1587
1588
1589
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652







+
+
+
+
+
+
+
+
+
+







#else
            return true;
#endif
        }

        ///////////////////////////////////////////////////////////////////////

#if COUNT_HANDLE
        public int WasReleasedOk()
        {
            return Interlocked.Decrement(
                ref UnsafeNativeMethods.connectionCount);
        }
#endif

        ///////////////////////////////////////////////////////////////////////

        public override bool IsInvalid
        {
            get
            {
#if PLATFORM_COMPACTFRAMEWORK
                lock (syncRoot)
#endif
1609
1610
1611
1612
1613
1614
1615
1616

1617
1618
1619
1620
1621
1622
1623
1672
1673
1674
1675
1676
1677
1678

1679
1680
1681
1682
1683
1684
1685
1686







-
+







    }
    #endregion

    ///////////////////////////////////////////////////////////////////////////

    #region SQLiteStatementHandle Class
    // Provides finalization support for unmanaged SQLite statements.
    internal class SQLiteStatementHandle : CriticalHandle
    internal sealed class SQLiteStatementHandle : CriticalHandle
    {
#if PLATFORM_COMPACTFRAMEWORK
        internal readonly object syncRoot = new object();
#endif

        ///////////////////////////////////////////////////////////////////////

1654
1655
1656
1657
1658
1659
1660




1661
1662
1663
1664
1665
1666
1667
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734







+
+
+
+







        }

        ///////////////////////////////////////////////////////////////////////

        private SQLiteStatementHandle()
            : base(IntPtr.Zero)
        {
#if COUNT_HANDLE
            Interlocked.Increment(
                ref UnsafeNativeMethods.statementCount);
#endif
        }

        ///////////////////////////////////////////////////////////////////////

        protected override bool ReleaseHandle()
        {
            try
1689
1690
1691
1692
1693
1694
1695




1696
1697
1698
1699
1700
1701
1702
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773







+
+
+
+







                    if (handle != IntPtr.Zero)
                    {
                        SQLiteBase.FinalizeStatement(cnn, handle);
                        SetHandle(IntPtr.Zero);
                    }
                }
#endif
#if COUNT_HANDLE
                Interlocked.Decrement(
                    ref UnsafeNativeMethods.statementCount);
#endif
#if DEBUG
                return true;
#endif
            }
#if !NET_COMPACT_20 && TRACE_HANDLE
            catch (SQLiteException e)
#else
1729
1730
1731
1732
1733
1734
1735










1736
1737
1738
1739
1740
1741
1742
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823







+
+
+
+
+
+
+
+
+
+







#else
            return true;
#endif
        }

        ///////////////////////////////////////////////////////////////////////

#if COUNT_HANDLE
        public int WasReleasedOk()
        {
            return Interlocked.Decrement(
                ref UnsafeNativeMethods.statementCount);
        }
#endif

        ///////////////////////////////////////////////////////////////////////

        public override bool IsInvalid
        {
            get
            {
#if PLATFORM_COMPACTFRAMEWORK
                lock (syncRoot)
#endif
1762
1763
1764
1765
1766
1767
1768
1769

1770
1771
1772
1773
1774
1775
1776
1843
1844
1845
1846
1847
1848
1849

1850
1851
1852
1853
1854
1855
1856
1857







-
+







    }
    #endregion

    ///////////////////////////////////////////////////////////////////////////

    #region SQLiteBackupHandle Class
    // Provides finalization support for unmanaged SQLite backup objects.
    internal class SQLiteBackupHandle : CriticalHandle
    internal sealed class SQLiteBackupHandle : CriticalHandle
    {
#if PLATFORM_COMPACTFRAMEWORK
        internal readonly object syncRoot = new object();
#endif

        ///////////////////////////////////////////////////////////////////////

1807
1808
1809
1810
1811
1812
1813




1814
1815
1816
1817
1818
1819
1820
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905







+
+
+
+







        }

        ///////////////////////////////////////////////////////////////////////

        private SQLiteBackupHandle()
            : base(IntPtr.Zero)
        {
#if COUNT_HANDLE
            Interlocked.Increment(
                ref UnsafeNativeMethods.backupCount);
#endif
        }

        ///////////////////////////////////////////////////////////////////////

        protected override bool ReleaseHandle()
        {
            try
1842
1843
1844
1845
1846
1847
1848




1849
1850
1851
1852
1853
1854
1855
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944







+
+
+
+







                    if (handle != IntPtr.Zero)
                    {
                        SQLiteBase.FinishBackup(cnn, handle);
                        SetHandle(IntPtr.Zero);
                    }
                }
#endif
#if COUNT_HANDLE
                Interlocked.Decrement(
                    ref UnsafeNativeMethods.backupCount);
#endif
#if DEBUG
                return true;
#endif
            }
#if !NET_COMPACT_20 && TRACE_HANDLE
            catch (SQLiteException e)
#else
1879
1880
1881
1882
1883
1884
1885










1886
1887
1888
1889
1890
1891
1892
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991







+
+
+
+
+
+
+
+
+
+







            }
#if DEBUG
            return false;
#else
            return true;
#endif
        }

        ///////////////////////////////////////////////////////////////////////

#if COUNT_HANDLE
        public int WasReleasedOk()
        {
            return Interlocked.Decrement(
                ref UnsafeNativeMethods.backupCount);
        }
#endif

        ///////////////////////////////////////////////////////////////////////

        public override bool IsInvalid
        {
            get
            {
Changes to Tests/all.eagle.
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58







-
+







#
# NOTE: Run all the unit tests.
#
set test_time [time {
  runAllTests $test_channel $path \
      [getTestFiles [list $path] $test_flags(-file) $test_flags(-notFile)] \
      [list [file tail [info script]] *.tcl pkgIndex.eagle common.eagle \
      constraints.eagle epilogue.eagle prologue.eagle]
      constraints.eagle empty.eagle epilogue.eagle prologue.eagle]
}]

#
# NOTE: Run the local test epilogue, if any.
#
if {[file exists [file join $path epilogue.eagle]]} then {
  source [file join $path epilogue.eagle]
Changes to Tests/backup.eagle.
16
17
18
19
20
21
22






23
24
25
26
27
28
29
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35







+
+
+
+
+
+







###############################################################################

package require System.Data.SQLite.Test
runSQLiteTestPrologue

###############################################################################

checkForSQLiteDirectories $test_channel
getSQLiteHandleCounts $test_channel
reportSQLiteResources $test_channel

###############################################################################

set params(pages) [list -1 -1 0 0 1 1 2 2 1000 1000]

set params(callbacks) [list null "new SQLiteBackupCallback(BackupCallback)" \
                            null "new SQLiteBackupCallback(BackupCallback)" \
                            null "new SQLiteBackupCallback(BackupCallback)" \
                            null "new SQLiteBackupCallback(BackupCallback)" \
                            null "new SQLiteBackupCallback(BackupCallback)"]
223
224
225
226
227
228
229






230
231
232
233
234
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246







+
+
+
+
+
+





"^Ok System#CodeDom#Compiler#CompilerResults#\\d+ \\{\\} " \
[lindex $params(results) $i]]}
}

###############################################################################

unset -nocomplain i params pages callback

###############################################################################

checkForSQLiteDirectories $test_channel
getSQLiteHandleCounts $test_channel
reportSQLiteResources $test_channel

###############################################################################

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/basic.eagle.
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
310
311
312
313
314
315
316

317
318
319
320
321
322
323







-







} -body {
  set id [object invoke Interpreter.GetActive NextId]
  set dataSource [file join [getDatabaseDirectory] $fileName]

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System.Data;
    using System.Data.SQLite;

    namespace _Dynamic${id}
    {
      public static class Test${id}
      {
        public static bool TestSetAvRetry(
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
418
419
420
421
422
423
424

425
426
427
428
429
430
431







-







    INSERT INTO t1 (x) VALUES(1); \
    SELECT x FROM t1; \
  }

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System.Data;
    using System.Data.SQLite;

    namespace _Dynamic${id}
    {
      public static class Test${id}
      {
        public static void Main()
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
475
476
477
478
479
480
481

482
483
484
485
486
487
488







-







    INSERT INTO t1 (x) VALUES(1); \
    SELECT x FROM t1; \
  }

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System.Data;
    using System.Data.SQLite;

    namespace _Dynamic${id}
    {
      public static class Test${id}
      {
        public static void Main()
1688
1689
1690
1691
1692
1693
1694
1695

1696
1697
1698
1699
1700
1701
1702
1703
1704
1705

1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716

1717


1718
1719
1720
1721
1722
1723
1724
1685
1686
1687
1688
1689
1690
1691

1692
1693
1694
1695
1696
1697
1698
1699
1700
1701

1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714

1715
1716
1717
1718
1719
1720
1721
1722
1723







-
+









-
+











+
-
+
+








  set found(data) [expr \
      {[llength [file list $directory(data) $fileName]] == 1}]

  set t [object create -alias Thread threadStart]
  sql execute $db "BEGIN TRANSACTION;"; $t Start

  for {set i 1} {$i < 100} {incr i} {
  for {set i 1} {$i < 1000} {incr i} {
    #
    # NOTE: Execute a query that should force the creation of a temporary file
    #       for its statement journal.
    #
    sql execute $db "UPDATE t1 SET x = ?;" [list param1 String $i]

    #
    # NOTE: Give the other thread some time to notice the temporary file.
    #
    after 1000
    after [expr {int(rand() * 1000)}]

    #
    # NOTE: Stop when the other thread confirms that the temporary file was
    #       created in the correct directory.
    #
    if {[info exists found(temp)] && $found(temp)} then {
      break
    }
  }

  $t Join; sql execute $db "COMMIT TRANSACTION;"

  lappend result $found(data) $found(temp); set result
  lappend result $found(data) [expr {[info exists found(temp)] ? \
      $found(temp) : False}]; set result
} -cleanup {
  #
  # NOTE: Close the database; however, do not attempt to delete the file as
  #       it is not located in the database directory known to the cleanupDb
  #       procedure (i.e. the one returned by getDatabaseDirectory).
  #
  cleanupDb $fileName db true false false
1789
1790
1791
1792
1793
1794
1795
1796

1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815



1816
1817
1818
1819
1820
1821
1822
1823
1824
1825


1826
1827
1828
1829



1830
1831
1832
1833

1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
































































































































































































1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866













1867











































1868
1869





























1870
1871


1872
1873
1874
1875
1876
1877
1878
1788
1789
1790
1791
1792
1793
1794

1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825


1826
1827




1828
1829
1830
1831
1832
1833

1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
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
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
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
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053






2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141


2142
2143
2144
2145
2146
2147
2148
2149
2150







-
+



















+
+
+








-
-
+
+
-
-
-
-
+
+
+



-
+



















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








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

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


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







} -constraints {eagle SQLite System.Data.SQLite} -result \
[string map [list \n \r\n] {CantOpen {unable to open database file
this is a test} CantOpen {unable to open database file
this is a test} True True}]}

###############################################################################

runTest {test data-1.35 {open unencrypted database, with password} -setup {
runTest {test data-1.35 {unencrypted database, with password} -setup {
  setupDb [set fileName data-1.35.db]
} -body {
  sql execute $db "CREATE TABLE t1(x);"
  sql execute $db "INSERT INTO t1 (x) VALUES(1);"

  cleanupDb $fileName db true false false
  setupDb $fileName "" "" "" "" "Password=12345;" true false

  set result [list]

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  cleanupDb $fileName db true false false
  setupDb $fileName "" "" "" "" "" true false

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain error result db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
} -constraints {eagle defineConstant.System.Data.SQLite.INTEROP_CODEC monoBug28\
command.sql compile.DATA SQLite System.Data.SQLite} -match regexp -result {^1\
-match regexp -result {^1 \{System\.Data\.SQLite\.SQLiteException\
\(0x80004005\): file is encrypted or is not a database.*?\} 1\
\{System\.Data\.SQLite\.SQLiteException \(0x80004005\): file is encrypted or is\
not a database.*?\} 0 1$}}
\{System\.Data\.SQLite\.SQLiteException \(0x80004005\): file is encrypted or is\
not a database.*?\} 1 \{System\.Data\.SQLite\.SQLiteException \(0x80004005\):\
file is encrypted or is not a database.*?\} 0 1 0 2$}}

###############################################################################

runTest {test data-1.36 {open encrypted database, wrong password} -setup {
runTest {test data-1.36 {encrypted database, wrong password} -setup {
  setupDb [set fileName data-1.36.db] "" "" "" "" "Password=12345;"
} -body {
  sql execute $db "CREATE TABLE t1(x);"
  sql execute $db "INSERT INTO t1 (x) VALUES(1);"

  cleanupDb $fileName db true false false
  setupDb $fileName "" "" "" "" "Password=12346;" true false

  set result [list]

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  cleanupDb $fileName db true false false
  setupDb $fileName "" "" "" "" "Password=12345;" true false

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain error result db fileName
} -constraints {eagle defineConstant.System.Data.SQLite.INTEROP_CODEC monoBug28\
command.sql compile.DATA SQLite System.Data.SQLite} -match regexp -result {^1\
\{System\.Data\.SQLite\.SQLiteException \(0x80004005\): file is encrypted or is\
not a database.*?\} 1 \{System\.Data\.SQLite\.SQLiteException \(0x80004005\):\
file is encrypted or is not a database.*?\} 0 1 0 2$}}

###############################################################################

runTest {test data-1.37 {encrypted database, password w/start-space} -setup {
  setupDb [set fileName data-1.37.db] "" "" "" "" "Password= 1234;"
} -body {
  sql execute $db "CREATE TABLE t1(x);"
  sql execute $db "INSERT INTO t1 (x) VALUES(1);"

  cleanupDb $fileName db true false false
  setupDb $fileName "" "" "" "" "Password=1234;" true false

  set result [list]

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  cleanupDb $fileName db true false false
  setupDb $fileName "" "" "" "" "Password= 1234;" true false

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain error result db fileName
} -constraints {eagle defineConstant.System.Data.SQLite.INTEROP_CODEC monoBug28\
command.sql compile.DATA SQLite System.Data.SQLite} -result {0 1 0 1 0 1 0 3}}

###############################################################################

runTest {test data-1.38 {encrypted database, w/quoted-start-space} -setup {
  setupDb [set fileName data-1.38.db] "" "" "" "" "Password=\" 1234\";"
} -body {
  sql execute $db "CREATE TABLE t1(x);"
  sql execute $db "INSERT INTO t1 (x) VALUES(1);"

  cleanupDb $fileName db true false false
  setupDb $fileName "" "" "" "" "Password=1234;" true false

  set result [list]

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  cleanupDb $fileName db true false false
  setupDb $fileName "" "" "" "" "Password=\" 1234\";" true false

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain error result db fileName
} -constraints {eagle defineConstant.System.Data.SQLite.INTEROP_CODEC monoBug28\
command.sql compile.DATA SQLite System.Data.SQLite} -match regexp -result {^1\
\{System\.Data\.SQLite\.SQLiteException \(0x80004005\): file is encrypted or is\
not a database.*?\} 1 \{System\.Data\.SQLite\.SQLiteException \(0x80004005\):\
file is encrypted or is not a database.*?\} 0 1 0 2$}}

###############################################################################

runTest {test data-1.39 {encrypted database, password w/mid-space} -setup {
  setupDb [set fileName data-1.39.db] "" "" "" "" "Password=12 45;"
} -body {
  sql execute $db "CREATE TABLE t1(x);"
  sql execute $db "INSERT INTO t1 (x) VALUES(1);"

  cleanupDb $fileName db true false false
  setupDb $fileName "" "" "" "" "Password=1245;" true false

  set result [list]

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  cleanupDb $fileName db true false false
  setupDb $fileName "" "" "" "" "Password=12 45;" true false

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain error result db fileName
} -constraints {eagle defineConstant.System.Data.SQLite.INTEROP_CODEC monoBug28\
command.sql compile.DATA SQLite System.Data.SQLite} -match regexp -result {^1\
\{System\.Data\.SQLite\.SQLiteException \(0x80004005\): file is encrypted or is\
not a database.*?\} 1 \{System\.Data\.SQLite\.SQLiteException \(0x80004005\):\
file is encrypted or is not a database.*?\} 0 1 0 2$}}

###############################################################################

runTest {test data-1.40 {encrypted database, password w/end-space} -setup {
  setupDb [set fileName data-1.40.db] "" "" "" "" "Password=1234 ;"
} -body {
  sql execute $db "CREATE TABLE t1(x);"
  sql execute $db "INSERT INTO t1 (x) VALUES(1);"

  cleanupDb $fileName db true false false
  setupDb $fileName "" "" "" "" "Password=1234;" true false

  set result [list]

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  cleanupDb $fileName db true false false
  setupDb $fileName "" "" "" "" "Password=1234 ;" true false

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain error result db fileName
} -constraints {eagle defineConstant.System.Data.SQLite.INTEROP_CODEC monoBug28\
command.sql compile.DATA SQLite System.Data.SQLite} -result {0 1 0 1 0 1 0 3}}

###############################################################################

runTest {test data-1.41 {encrypted database, w/quoted-end-space} -setup {
  setupDb [set fileName data-1.41.db] "" "" "" "" "Password=\"1234 \";"
} -body {
  sql execute $db "CREATE TABLE t1(x);"
  sql execute $db "INSERT INTO t1 (x) VALUES(1);"

  cleanupDb $fileName db true false false
  setupDb $fileName "" "" "" "" "Password=1234;" true false

  set result [list]

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  cleanupDb $fileName db true false false
  setupDb $fileName "" "" "" "" "Password=\"1234 \";" true false

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error

  set result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain error result db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-match regexp -result {^1 \{System\.Data\.SQLite\.SQLiteException\
\(0x80004005\): file is encrypted or is not a database.*?\} 1\
\{System\.Data\.SQLite\.SQLiteException \(0x80004005\): file is encrypted or is\
not a database.*?\} 0 1$}}
} -constraints {eagle defineConstant.System.Data.SQLite.INTEROP_CODEC monoBug28\
command.sql compile.DATA SQLite System.Data.SQLite} -match regexp -result {^1\
\{System\.Data\.SQLite\.SQLiteException \(0x80004005\): file is encrypted or is\
not a database.*?\} 1 \{System\.Data\.SQLite\.SQLiteException \(0x80004005\):\
file is encrypted or is not a database.*?\} 0 1 0 2$}}

###############################################################################

runTest {test data-1.42 {encrypted database, password via builder} -setup {
  setupDb [set fileName data-1.42.db] "" "" "" "" "Password=67 89;"
} -body {
  sql execute $db "CREATE TABLE t1(x);"
  sql execute $db "INSERT INTO t1 (x) VALUES(1);"

  cleanupDb $fileName db true false false

  set connectionStringBuilder [object create -alias \
      System.Data.SQLite.SQLiteConnectionStringBuilder]

  $connectionStringBuilder DataSource \
      [file join [getDatabaseDirectory] $fileName]

  $connectionStringBuilder Password "67 89"

  set connection [object create -alias \
      System.Data.SQLite.SQLiteConnection \
      [$connectionStringBuilder ToString] true]

  $connection Open; addDbConnection $connection

  set result [list]

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  cleanupDb $fileName db true false false
  setupDb $fileName "" "" "" "" "Password=\"67 89\";" true false

  lappend result [catch {sql execute $db \
      "INSERT INTO t1 (x) VALUES(1);"} error] $error

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT COUNT(*) FROM t1;"} error] $error

  set result
} -cleanup {
  unset -nocomplain connection

  cleanupDb $fileName; # NOTE: After object disposal.

  unset -nocomplain connectionStringBuilder error result db fileName
} -constraints {eagle defineConstant.System.Data.SQLite.INTEROP_CODEC monoBug28\
command.sql compile.DATA SQLite System.Data.SQLite} -result {0 1 0 1 0 1 0 3}}

###############################################################################

runTest {test data-1.43 {quoted connection string properties} -setup {
  unset -nocomplain result list pair strings string
} -body {
  set result [list]

  set strings [list \
      "OneTwo=ThreeFour" "\"OneTwo\"=\"ThreeFour\"" \
      "One Two=Three Four" "\"One Two\"=\"Three Four\"" \
      "OneTwo=ThreeFour;" "\"OneTwo\"=\"ThreeFour\";" \
      "One Two=Three Four;" "\"One Two\"=\"Three Four\";"]

  foreach string $strings {
    set list [object invoke -flags +NonPublic \
        System.Data.SQLite.SQLiteConnection ParseConnectionString $string]

    object foreach -alias pair $list {
      lappend result [list [$pair Key] [$pair Value]]
    }
  }

  set result
} -cleanup {
  unset -nocomplain result list pair strings string
} -constraints {eagle System.Data.SQLite} -result {{OneTwo ThreeFour} {OneTwo\
ThreeFour} {{One Two} {Three Four}} {{One Two} {Three Four}} {OneTwo ThreeFour}\
{OneTwo ThreeFour} {{One Two} {Three Four}} {{One Two} {Three Four}}}}

###############################################################################

runTest {test data-1.37 {rollback to nested savepoint} -setup {
  setupDb [set fileName data-1.37.db]
runTest {test data-1.44 {rollback to nested savepoint} -setup {
  setupDb [set fileName data-1.44.db]
} -body {
  sql execute $db "BEGIN IMMEDIATE TRANSACTION;"
  sql execute $db "SAVEPOINT one;"

  sql execute $db "CREATE TABLE t1(x);"
  sql execute $db "SAVEPOINT two;"

1893
1894
1895
1896
1897
1898
1899
1900
1901


1902
1903
1904
1905
1906
1907
1908
2165
2166
2167
2168
2169
2170
2171


2172
2173
2174
2175
2176
2177
2178
2179
2180







-
-
+
+







  unset -nocomplain result db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{1 2 1}}

###############################################################################

runTest {test data-1.38 {NoExtensionFunctions connection flag} -setup {
  setupDb [set fileName data-1.38.db]
runTest {test data-1.45 {NoExtensionFunctions connection flag} -setup {
  setupDb [set fileName data-1.45.db]
} -body {
  set result [list]

  lappend result [catch {sql execute -execute scalar $db \
      "SELECT replicate('1234', 2);"} output] $output

  cleanupDb $fileName
1925
1926
1927
1928
1929
1930
1931
1932
1933


1934
1935
1936
1937
1938
1939
1940
2197
2198
2199
2200
2201
2202
2203


2204
2205
2206
2207
2208
2209
2210
2211
2212







-
-
+
+







} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^0 12341234 1 \{System\.Data\.SQLite\.SQLiteException\
\(0x80004005\): SQL logic error or missing database.*?\} 0 1234123412341234$}}

###############################################################################

runTest {test data-1.39 {column name and index lookup} -setup {
  setupDb [set fileName data-1.39.db]
runTest {test data-1.46 {column name and index lookup} -setup {
  setupDb [set fileName data-1.46.db]
} -body {
  sql execute $db {
    CREATE TABLE t1(x, y, z);
    INSERT INTO t1 (x, y, z) VALUES(1, 'foo', 1234);
  }

  set dataReader [sql execute -execute reader -format datareader \
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967



























































































1968
1969
1970
1971
1972
1973
1974
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337










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








  cleanupDb $fileName

  unset -nocomplain result db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \
{{x 0 1} {y 1 foo} {z 2 1234}}}

###############################################################################

runTest {test data-1.47 {nullable value types} -setup {
  setupDb [set fileName data-1.47.db]
} -body {
  sql execute $db {
    CREATE TABLE t1(x INTEGER);
    INSERT INTO t1 (x) VALUES(NULL);
    INSERT INTO t1 (x) VALUES(1);
  }

  set dataReader [sql execute -execute reader -format datareader \
      -alias $db "SELECT x FROM t1 ORDER BY x;"]

  set result [list]

  while {[$dataReader Read]} {
    foreach {a b c d e} [list "" "" "" "" ""] break

    set x [$dataReader GetOrdinal x]

    foreach {a b c e} [list \
        [$dataReader GetName $x] [$dataReader GetValue $x] \
        [catch {$dataReader GetInt64 $x} d] [$dataReader Item x]] break

    lappend result [list $x $a $b $c $d $e]
  }

  set result
} -cleanup {
  unset -nocomplain dataReader

  cleanupDb $fileName

  unset -nocomplain e d c b a x result db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^\{0 x System#DBNull#\d+ 1\
\{System\.Reflection\.TargetInvocationException: Exception has been thrown by\
the target of an invocation\. ---> System\.InvalidCastException:.*\}\
System#DBNull#\d+\} \{0 x 1 0 1 1\}$}}

###############################################################################

runTest {test data-1.48 {static SQLiteCommand.Execute method} -setup {
  unset -nocomplain result sql
} -body {
  set sql(1) { \
    CREATE TABLE t1(x); \
    INSERT INTO t1 (x) VALUES (NULL); \
    SELECT x FROM t1 ORDER BY x; \
  }

  set sql(2) { \
    CREATE TABLE t1(x); \
    INSERT INTO t1 (x) VALUES (?); \
    SELECT x FROM t1 ORDER BY x; \
  }

  set result(1) [object invoke System.Data.SQLite.SQLiteCommand Execute \
      "this will not execute" None null]

  set result(2) [object invoke System.Data.SQLite.SQLiteCommand Execute \
      $sql(1) NonQuery null]

  set result(3) [object invoke System.Data.SQLite.SQLiteCommand Execute \
      $sql(1) Scalar null]

  set result(4) [object invoke System.Data.SQLite.SQLiteCommand Execute \
      $sql(1) Reader null]

  set result(5) [object invoke System.Data.SQLite.SQLiteCommand Execute \
      "this will not execute" None null 1]

  set result(6) [object invoke System.Data.SQLite.SQLiteCommand Execute \
      $sql(2) NonQuery null 1]

  set result(7) [object invoke System.Data.SQLite.SQLiteCommand Execute \
      $sql(2) Scalar null 1]

  set result(8) [object invoke System.Data.SQLite.SQLiteCommand Execute \
      $sql(2) Reader null 1]

  list $result(1) $result(2) $result(3) $result(4) $result(5) $result(6) \
      $result(7) $result(8)
} -cleanup {
  unset -nocomplain result sql
} -constraints {eagle monoBug28 SQLite System.Data.SQLite} -match regexp \
-result {^\{\} 1 System#DBNull#\d+ System#Data#SQLite#SQLiteDataReader#\d+ \{\}\
1 1 System#Data#SQLite#SQLiteDataReader#\d+$}}

###############################################################################

unset -nocomplain systemDataSQLiteDllFile systemDataSQLiteLinqDllFile \
    testExeFile testLinqExeFile northwindEfDbFile testLinqOutFile

###############################################################################

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/common.eagle.
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
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
361
362
363
364
365
366
367
368
369
370
371
372

373
374
375
376
377
378
379

380
381
382
383
384
385
386
387







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













-
+






-
+

















-
+






-
+







        #
        # NOTE: Return the native-only interop assembly file name.
        #
        return [file nativename \
            [file join [getBinaryDirectory] SQLite.Interop.dll]]
      }
    }

    proc getCommonDirectory {} {
      #
      # NOTE: This procedure returns the directory where the test scripts
      #       should be located.  By default, this just returns the Eagle
      #       binary directory.
      #
      if {[info exists ::common_directory] && \
          [string length $::common_directory] > 0} then {
        #
        # NOTE: The location of the common directory has been set;
        #       therefore, use it.
        #
        return $::common_directory
      } elseif {[info exists ::vendor_directory] && \
          [string length $::vendor_directory] > 0} then {
        #
        # NOTE: The location of the vendor directory has been set;
        #       therefore, use it.
        #
        return $::vendor_directory
      } elseif {[info exists ::tcl_library] && \
          [string length $::tcl_library] > 0 && \
          [file isdirectory $::tcl_library]} then {
        #
        # NOTE: The variable with the location of the script library is
        #       set and appears to be a real directory (i.e. not embedded
        #       within a file); therefore, use it.
        #
        return $::tcl_library
      } else {
        #
        # NOTE: Fallback to the directory containing the executable.
        #
        return [info binary]
      }
    }

    proc getDatabaseDirectory {} {
      #
      # NOTE: This procedure returns the directory where the test databases
      #       should be located.  By default, this just uses the temporary
      #       directory configured for this system.
      #
      if {[info exists ::database_directory] && \
          [string length $::database_directory] > 0} then {
        #
        # NOTE: The location of the database directory has been overridden;
        #       therefore, use it.
        #
        return [file normalize $::database_directory]
        return $::database_directory
      } elseif {[info exists ::scratch_directory] && \
          [string length $::scratch_directory] > 0} then {
        #
        # NOTE: The location of the scratch directory has been overridden;
        #       therefore, use it.
        #
        return [file normalize $::scratch_directory]
        return $::scratch_directory
      } else {
        return [getTemporaryPath]
      }
    }

    proc getTemporaryDirectory {} {
      #
      # NOTE: This procedure returns the directory where the temporary files
      #       should be located.  By default, this just uses the temporary
      #       directory configured for this system.
      #
      if {[info exists ::temporary_directory] && \
          [string length $::temporary_directory] > 0} then {
        #
        # NOTE: The location of the temporary directory has been overridden;
        #       therefore, use it.
        #
        return [file normalize $::temporary_directory]
        return $::temporary_directory
      } elseif {[info exists ::scratch_directory] && \
          [string length $::scratch_directory] > 0} then {
        #
        # NOTE: The location of the scratch directory has been overridden;
        #       therefore, use it.
        #
        return [file normalize $::scratch_directory]
        return $::scratch_directory
      } else {
        return [getTemporaryPath]
      }
    }

    proc getTestOverridesPreamble { {extraVarNames ""} } {
      set varNames [list]
431
432
433
434
435
436
437
438
439
440
441






























442
443
444
445
446
447
448
449
450
451



452


453
454
455
456
457
458
459
468
469
470
471
472
473
474




475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517

518
519
520
521
522
523
524
525
526







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










+
+
+
-
+
+







      return [uplevel 1 [list subst [appendArgs $prefix {
        if {[hasRuntimeOption native]} then {
          object invoke Interpreter.GetActive AddRuntimeOption native
        }
      } [getTestOverridesPreamble [list path test_channel]] $suffix]]]
    }

    proc tryCopyBuildFile { fileName } {
      #
      # NOTE: If we cannot copy the assembly then it is probably already loaded.
      #
    proc tryCopyBinaryFile { fileName {newFileName ""} } {
      set sourceFileName [getBinaryFileName $fileName]

      if {![file exists $sourceFileName]} then {
        tputs $::test_channel [appendArgs \
            "---- skipped copying binary file \"" $sourceFileName \
            "\", it does not exist\n"]

        return
      }

      if {[string length $newFileName] > 0} then {
        set targetFileName [getBuildFileName $newFileName]
      } else {
        set targetFileName [getBuildFileName $fileName]
      }

      if {[catch {
              file copy -force $sourceFileName $targetFileName}] == 0} then {
        tputs $::test_channel [appendArgs \
            "---- copied binary file from \"" $sourceFileName "\" to \"" \
            $targetFileName \"\n]
      } else {
        tputs $::test_channel [appendArgs \
            "---- failed to copy binary file from \"" $sourceFileName \
            "\" to \"" $targetFileName \"\n]
      }
    }

    proc tryCopyBuildFile { fileName {newFileName ""} } {
      set sourceFileName [getBuildFileName $fileName]

      if {![file exists $sourceFileName]} then {
        tputs $::test_channel [appendArgs \
            "---- skipped copying build file \"" $sourceFileName \
            "\", it does not exist\n"]

        return
      }

      if {[string length $newFileName] > 0} then {
        set targetFileName [getBinaryFileName $newFileName]
      } else {
      set targetFileName [getBinaryFileName $fileName]
        set targetFileName [getBinaryFileName $fileName]
      }

      if {[catch {
              file copy -force $sourceFileName $targetFileName}] == 0} then {
        tputs $::test_channel [appendArgs \
            "---- copied build file from \"" $sourceFileName "\" to \"" \
            $targetFileName \"\n]
      } else {
478
479
480
481
482
483
484




















485
486
487
488
489
490
491
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578







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







        tputs $::test_channel [appendArgs \
            "---- deleted binary file \"" $fileName \"\n]
      } else {
        tputs $::test_channel [appendArgs \
            "---- failed to delete binary file \"" $fileName \"\n]
      }
    }

    proc tryDeleteBuildFile { fileName } {
      set fileName [getBuildFileName $fileName]

      if {![file exists $fileName]} then {
        tputs $::test_channel [appendArgs \
            "---- skipped deleting build file \"" $fileName \
            "\", it does not exist\n"]

        return
      }

      if {[catch {file delete $fileName}] == 0} then {
        tputs $::test_channel [appendArgs \
            "---- deleted build file \"" $fileName \"\n]
      } else {
        tputs $::test_channel [appendArgs \
            "---- failed to delete build file \"" $fileName \"\n]
      }
    }

    proc tryCopyAssembly { fileName {pdb true} } {
      tryCopyBuildFile $fileName

      if {$pdb} then {
        tryCopyBuildFile [appendArgs [file rootname $fileName] .pdb]
      }
520
521
522
523
524
525
526















527
528
529
530
531
532
533
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635







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







        # NOTE: Return the full path of the loaded file.
        #
        return $fileName
      }

      return ""
    }

    proc isSQLiteReady {} {
      #
      # NOTE: This procedure must return non-zero only if the SQLite native
      #       library and the System.Data.SQLite managed assembly are loaded
      #       and ready for use by the test suite.  Currently, this procedure
      #       should be called only after the [tryLoadAssembly] procedure has
      #       been called to probe for the System.Data.SQLite managed assembly
      #       and the [checkForSQLite] procedure has been called to probe for
      #       the SQLite native library; otherwise, this procedure will simply
      #       always return zero.
      #
      return [expr {[haveConstraint System.Data.SQLite] && \
          [haveConstraint SQLite]}]
    }

    proc checkForSQLite { channel } {
      tputs $channel "---- checking for core SQLite library... "

      if {[catch {
              object invoke -flags +NonPublic System.Data.SQLite.SQLite3 \
              SQLiteVersion} version] == 0} then {
915
916
917
918
919
920
921























922
923
924
925
926
927
928
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053







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







        # NOTE: We somehow failed to remove the handle, report why.
        #
        tputs $::test_channel [appendArgs \
            "==== WARNING: failed to remove connection handle \"" $connection \
            "\", error: " \n\t $error \n]
      }
    }

    proc addDbConnection { connection {varName db} } {
      #
      # NOTE: Refer to the specified variable (e.g. "db") in the context of our
      #       caller.
      #
      upvar 1 $varName db

      #
      # NOTE: Create a correctly formatted name for the database connection to
      #       be added to the list managed by the Eagle interpreter.
      #
      set db [object invoke -flags +NonPublic \
          Eagle._Components.Private.FormatOps DatabaseObjectName $connection \
          SQLiteConnection [object invoke Interpreter.GetActive NextId]]

      #
      # NOTE: Add the database connection provided by our caller to the list
      #       of those known to the Eagle interpreter.
      #
      object invoke -flags +NonPublic Interpreter.GetActive.connections Add \
          $db $connection
    }

    proc cleanupDb { fileName {varName db} {collect true} {qualify true}
                     {delete true} } {
      #
      # NOTE: Attempt to force all pending "garbage" objects to be collected,
      #       including SQLite statements and backup objects; this should allow
      #       the underlying database file to be deleted.
999
1000
1001
1002
1003
1004
1005






























































1006
1007
1008
1009
1010
1011
1012
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
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
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
1198
1199







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







        # NOTE: The file does not exist, success!
        #
        set code 0
      }

      return $code
    }

    proc setupDbInterruptCallback { channel log } {
      tputs $channel "---- setting up debugger interrupt callback... "

      if {[catch {
        #
        # NOTE: Make sure the script debugger and the isolated interpreter are
        #       setup and ready for use.
        #
        debug setup true true

        #
        # NOTE: Load the necessary packages into the isolated interpreter.
        #
        debug eval {
          package require Eagle
          package require Eagle.Library
          package require Eagle.Test
        }

        #
        # NOTE: Copy the necessary variables into the isolated interpreter.
        #
        debug invoke 0 set ::test_channel $channel; # NOTE: For [tputs].
        debug invoke 0 set ::test_log $log; # NOTE: For [tlog].

        #
        # NOTE: Install the callback script to be evaluated in the isolated
        #       interpreter when this interpreter is interrupted by script
        #       cancellation, etc.
        #
        debug callback apply {{sender e} {
          #
          # NOTE: Check if this callback is one that we care about.
          #
          if {"Canceled" in [split [$e InterruptType] ", "]} then {
            #
            # NOTE: Iterate through all database connections known to the
            #       parent interpreter.
            #
            object foreach -alias pair \
                [object invoke -flags +NonPublic $e Interpreter.connections] {
              #
              # NOTE: Attempt to cancel any SQL queries in progress on this
              #       database connection.
              #
              if {[catch {$pair Value.Cancel} error] != 0} then {
                tputs $::test_channel [appendArgs \n \
                    "==== WARNING: failed to cancel query for connection \"" \
                    [$pair Key] "\", error: " \n\t $error \n]
              }
            }
          }
        }}
      } error] == 0} then {
        addConstraint interruptCallback.sqlite3

        tputs $channel yes\n
      } else {
        tputs $channel [appendArgs "no, error: " \n\t $error \n]
      }
    }

    proc cleanupFile { fileName {collect true} {force false} } {
      #
      # NOTE: Attempt to force all pending "garbage" objects to be collected,
      #       including SQLite statements and backup objects; this should allow
      #       the underlying database file to be deleted.
      #
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
















































































1067
1068
1069
1070
1071
1072
1073
1074
1075


1076
1077







1078
1079
1080


1081
1082
1083
1084
1085
1086
1087
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
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
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
1349
1350
1351
1352







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









+
+

-
+
+
+
+
+
+
+

-
-
+
+







        #
        set code 0
      }

      return $code
    }

    proc collectGarbage { channel } {
      #
      # NOTE: Attempt to force a full garbage collection now.  Report any
      #       error that is encountered if we fail.
      #
      if {[catch {object invoke GC GetTotalMemory true} error]} then {
        tputs $channel [appendArgs \
            "==== WARNING: failed full garbage collection, error: " \
            \n\t $error \n]
      }
    proc collectGarbage { channel {milliseconds 1000} {quiet true} } {
      if {[catch {object invoke GC GetTotalMemory false} result] == 0} then {
        if {!$quiet} then {
          tputs $channel [appendArgs \
              "---- memory in use by the CLR before collection... " \
              $result " bytes\n"]
        }
      } else {
        tputs $channel [appendArgs \
            "==== WARNING: failed to get CLR memory usage, error: " \
            \n\t $result \n]
      }

      #########################################################################

      #
      # NOTE: Repeatedly attempt to collect garbage until the allotted number
      #       of milliseconds has elapsed.  Always attempt to collect garbage
      #       at least once.
      #
      set start [clock seconds]
      set stop [expr {$start + ($milliseconds / 1000)}]

      do {
        #
        # NOTE: Attempt to force a full garbage collection now.  Report any
        #       error that is encountered if we fail.
        #
        if {[catch {object invoke GC GetTotalMemory true} error]} then {
          tputs $channel [appendArgs \
              "==== WARNING: failed full garbage collection, error: " \
              \n\t $error \n]
        }

        set now [clock seconds]
      } while {$start <= $now && $now < $stop}

      #########################################################################

      if {[catch {object invoke GC GetTotalMemory false} result] == 0} then {
        if {!$quiet} then {
          tputs $channel [appendArgs \
              "---- memory in use by the CLR after collection... " \
              $result " bytes\n"]
        }
      } else {
        tputs $channel [appendArgs \
            "==== WARNING: failed to get CLR memory usage, error: " \
            \n\t $result \n]
      }
    }

    proc getSQLiteHandleCounts { channel {quiet false} } {
      set result [list]

      if {[haveConstraint \
              defineConstant.System.Data.SQLite.COUNT_HANDLE]} then {
        #
        # NOTE: Add each critical handle count to the resulting list.
        #
        foreach name [list connectionCount statementCount backupCount] {
          set value [object invoke -flags +NonPublic \
              System.Data.SQLite.UnsafeNativeMethods $name]

          if {!$quiet} then {
            tputs $channel [appendArgs \
                "---- critical handle count \"" $name "\" is " $value \n]
          }

          lappend result $value
        }
      } elseif {!$quiet} then {
        #
        # NOTE: The actual handle counts are not available; therefore, just
        #       return an empty list.
        #
        tputs $channel "---- critical handle counts unavailable\n"
      }

      return $result
    }

    proc shutdownSQLite { channel {force false} {quiet false} } {
      #
      # NOTE: Make sure that SQLite core library is completely shutdown.  This
      #       is used by tests that change configuration options and/or those
      #       that need to make sure logging is initialized (i.e. just in case
      #       the SQLite core library was initialized in the process prior to
      #       the SQLiteLog class being able to setup its logging callback).
      #       Normally, this should only be performed if SQLite is loaded and
      #       ready for use by the test suite.
      #
      if {$force || [haveConstraint SQLite]} then {
      if {$force || [isSQLiteReady]} then {
        #
        # BUGFIX: Before calling the native shutdown function, make sure both
        #         of the PRAGMA related directory names are freed.
        #
        checkForSQLiteDirectories $channel true

        if {[catch {object invoke -flags +NonPublic \
              System.Data.SQLite.UnsafeNativeMethods \
              sqlite3_shutdown} result] == 0} then {
                System.Data.SQLite.UnsafeNativeMethods \
                sqlite3_shutdown} result] == 0} then {
          if {!$quiet} then {
            tputs $channel [appendArgs \
                "---- call sqlite3_shutdown()... ok: " $result \n]
          }
        } else {
          if {!$quiet} then {
            tputs $channel [appendArgs \
1224
1225
1226
1227
1228
1229
1230
1231



1232
1233

1234
1235
1236
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






1279
1280
1281
1282
1283
1284
1285
1489
1490
1491
1492
1493
1494
1495

1496
1497
1498
1499

1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512


1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525

1526
1527
1528
1529


1530
1531
1532

1533
1534




1535
1536
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
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613

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







-
+
+
+

-
+












-
-
+
+











-
+
+

+
-
-
+
+

-
+

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






-
+
+


+
+
+
+
+
+







            }
          }
        }
      } else {
        tputs $channel no\n

        #
        # NOTE: Does our caller want to reset the directories?
        # NOTE: Does our caller want to reset the directories?  This can only
        #       be performed if SQLite is loaded and ready for use by the test
        #       suite.
        #
        if {$reset} then {
        if {$reset && [isSQLiteReady]} then {
          #
          # NOTE: Now make sure the database and temporary directories are
          #       reset their default values, which should be null for both.
          #       Since the sqlite3_win32_set_directory function does not
          #       appear to be available, use the associated PRAGMA commands
          #       instead.
          #
          foreach directory [list data_store_directory temp_store_directory] {
            set sql [appendArgs "PRAGMA " $directory " = \"\";"]

            if {[catch {executeSql $sql} result] == 0} then {
              tputs $channel [appendArgs \
                  "---- execute PRAGMA " $directory "... ok: " \
                  $result \n]
                  "---- execute PRAGMA " $directory "... ok: \"" \
                  $result \"\n]
            } else {
              tputs $channel [appendArgs \
                  "---- execute PRAGMA " $directory "... error: " \
                  \n\t $result \n]
            }
          }
        }
      }

      #
      # NOTE: Finally, show the current value of the database and temporary
      #       directories.
      #       directories.  This can only be performed if SQLite is loaded
      #       and ready for use by the test suite.
      #
      if {[isSQLiteReady]} then {
      foreach directory [list data_store_directory temp_store_directory] {
        tputs $channel [appendArgs "---- checking " $directory "... "]
        foreach directory [list data_store_directory temp_store_directory] {
          tputs $channel [appendArgs "---- checking " $directory "... "]

        set sql [appendArgs "PRAGMA " $directory \;]
          set sql [appendArgs "PRAGMA " $directory \;]

        if {[catch {executeSql $sql scalar} result] == 0} then {
          tputs $channel [appendArgs "ok: \"" $result \"\n]
        } else {
          tputs $channel [appendArgs "error: " \n\t $result \n]
          if {[catch {executeSql $sql scalar} result] == 0} then {
            tputs $channel [appendArgs "ok: \"" $result \"\n]
          } else {
            tputs $channel [appendArgs "error: " \n\t $result \n]
          }
        }
      }
    }

    proc loadSQLiteTestSettings { channel {suffix ""} {quiet false} } {
      #
      # NOTE: Skip loading the settings if their usage has been disabled.
      #
      if {![info exists ::no(sqliteTestSettings)]} then {
        #
        # NOTE: Load custom per-user and/or per-host test settings now.
        #
        if {[info exists ::tcl_platform(user)]} then {
          set userSettingsFileName [file join [getCommonDirectory] \
              [appendArgs settings $suffix . $::tcl_platform(user) .eagle]]

          if {[file exists $userSettingsFileName]} then {
            if {!$quiet} then {
              tputs $channel [appendArgs \
                  "---- loading per-user test settings file \"" \
                  $userSettingsFileName \"...\n]
            }

            if {[catch {uplevel 1 [list source $userSettingsFileName]} \
                    error]} then {
              if {!$quiet} then {
                tputs $channel [appendArgs \
                    "==== WARNING: failed to load per-user settings file \"" \
                    $userSettingsFileName "\", error: " \n\t $error \n]
              }
            }
          } else {
            if {!$quiet} then {
              tputs $channel [appendArgs \
                  "---- skipped loading per-user test settings file \"" \
                  $userSettingsFileName "\", it does not exist\n"]
            }
          }
        }

        #######################################################################

        if {[info exists ::tcl_platform(host)]} then {
          set hostSettingsFileName [file join [getCommonDirectory] \
              [appendArgs settings $suffix . $::tcl_platform(host) .eagle]]

          if {[file exists $hostSettingsFileName]} then {
            if {!$quiet} then {
              tputs $channel [appendArgs \
                  "---- loading per-host test settings file \"" \
                  $hostSettingsFileName \"...\n]
            }

            if {[catch {uplevel 1 [list source $hostSettingsFileName]} \
                    error]} then {
              if {!$quiet} then {
                tputs $channel [appendArgs \
                    "==== WARNING: failed to load per-host settings file \"" \
                    $hostSettingsFileName "\", error: " \n\t $error \n]
              }
            }
          } else {
            if {!$quiet} then {
              tputs $channel [appendArgs \
                  "---- skipped loading per-host test settings file \"" \
                  $hostSettingsFileName "\", it does not exist\n"]
            }
          }
        }
      }
    }

    proc runSQLiteTestPrologue {} {
      #
      # NOTE: Skip running our custom prologue if the main one has been skipped.
      # NOTE: Skip running our custom prologue if the main one has been
      #       skipped.
      #
      if {![info exists ::no(prologue.eagle)]} then {
        #
        # NOTE: Load the "before-constraints" custom per-user and/or per-host
        #       test settings now.
        #
        uplevel 1 [list loadSQLiteTestSettings $::test_channel .before]

        #
        # NOTE: Skip all System.Data.SQLite related file handling (deleting,
        #       copying, and loading) if we are so instructed.
        #
        if {![info exists ::no(sqliteFiles)]} then {
          #
          # NOTE: Skip trying to delete any files if we are so instructed.
1311
1312
1313
1314
1315
1316
1317
























1318
1319
1320
1321
1322
1323
1324
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693







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







          #
          # NOTE: Skip trying to load any files if we are so instructed.
          #
          if {![info exists ::no(loadSqliteFiles)]} then {
            tryLoadAssembly System.Data.SQLite.dll
            tryLoadAssembly System.Data.SQLite.Linq.dll
          }

          #
          # NOTE: Skip trying to delete external files if we are so instructed.
          #
          if {![info exists ::no(deleteSqliteExternalFiles)]} then {
            tryDeleteBuildFile Installer.exe.mda.config
            tryDeleteBuildFile test.exe.mda.config
            tryDeleteBuildFile testlinq.exe.mda.config
          }

          #
          # NOTE: Skip trying to copy external files if we are so instructed.
          #
          if {![info exists ::no(copySqliteExternalFiles)]} then {
            #
            # NOTE: Copy the MDA configuration file for the Eagle shell to the
            #       build output directory; however, use the name of the legacy
            #       test executable.  This will make sure that the legacy tests
            #       run with the same set of MDAs configured.
            #
            tryCopyBinaryFile EagleShell.exe.mda.config Installer.exe.mda.config
            tryCopyBinaryFile EagleShell.exe.mda.config test.exe.mda.config
            tryCopyBinaryFile EagleShell.exe.mda.config testlinq.exe.mda.config
          }
        }

        catch {
          tputs $::test_channel [appendArgs \
              "---- file version of \"sqlite3.dll\"... " \
              [file version [getBinaryFileName sqlite3.dll]] \n]
        }
1375
1376
1377
1378
1379
1380
1381
1382
1383






1384
1385
1386
1387



1388
1389
1390
1391





1392
1393
1394


1395
1396

1397
1398
1399
1400
1401
1402
1403
1404
1405
1744
1745
1746
1747
1748
1749
1750


1751
1752
1753
1754
1755
1756
1757



1758
1759
1760




1761
1762
1763
1764
1765



1766
1767


1768


1769
1770
1771
1772
1773
1774
1775







-
-
+
+
+
+
+
+

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








        #
        # NOTE: Check the SQLite database and temporary directories.
        #
        checkForSQLiteDirectories $::test_channel

        #
        # NOTE: Attempt to determine if the custom extension functions were
        #       compiled into the SQLite interop assembly.
        # NOTE: Attempt to determine if various compile-time options needed for
        #       test constraints were enabled for the managed assembly.  There
        #       are some compile-time options that must also have been enabled
        #       for the interop assembly in order to be effective.  For those
        #       options, it will be assumed that it was enabled for the interop
        #       assembly if it was enabled for the managed assembly.
        #
        checkForSQLiteDefineConstant $::test_channel \
            CHECK_STATE

        foreach defineConstant [list CHECK_STATE COUNT_HANDLE INTEROP_CODEC \
                                     INTEROP_DEBUG INTEROP_LOG \
                                     INTEROP_EXTENSION_FUNCTIONS \
        checkForSQLiteDefineConstant $::test_channel \
            USE_INTEROP_DLL

        checkForSQLiteDefineConstant $::test_channel \
                                     INTEROP_TEST_EXTENSION SQLITE_STANDARD \
                                     USE_INTEROP_DLL] {
          #
          # NOTE: Check if the compile-time option is listed in the list of
          #       "define constants" kept track of by the managed assembly.
            INTEROP_EXTENSION_FUNCTIONS

        checkForSQLiteDefineConstant $::test_channel \
          #
          checkForSQLiteDefineConstant $::test_channel $defineConstant
            INTEROP_TEST_EXTENSION

        }
        checkForSQLiteDefineConstant $::test_channel \
            SQLITE_STANDARD

        #
        # NOTE: Check the current build year.  Basically, this indicates
        #       which version of MSBuild and/or Visual Studio was used to
        #       compile the assembly binaries under test.
        #
        tputs $::test_channel \
1416
1417
1418
1419
1420
1421
1422









1423
1424
1425
1426
1427
1428












1429
1430
1431
1432
1433
1434
1435
1436
1437
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
1467
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856

1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880







+
+
+
+
+
+
+
+
+






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











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











-
+
+









+
+
+
+
+
+







        tputs $::test_channel \
            "---- checking for System.Data.SQLite build configuration... "

        set configuration [getBuildConfiguration]
        addConstraint [appendArgs buildConfiguration $configuration]
        tputs $::test_channel [appendArgs \" $configuration \"\n]

        #
        # NOTE: Try to setup an interrupt callback using the script debugger
        #       that will cancel all SQL queries in progress for all database
        #       connections known to this interpreter.
        #
        if {![info exists ::no(sqliteInterruptCallback)]} then {
          setupDbInterruptCallback $::test_channel $::test_log
        }

        #
        # NOTE: Check for the native runtime option, which would mean we are
        #       using the mixed-mode assembly.
        #
        checkForRuntimeOption $::test_channel native

        #
        # NOTE: Check if the test suite should count the number of connections
        #       "opened" and "closed" from the pool when determining if a test
        #       passed.  Disabling this behavior is sometimes necessary (e.g.
        #       during the release testing process) because there are several
        #       tests that rely on the "opened from pool" count being greater
        #       than zero.  These tests may fail due to the non-deterministic
        #       behavior of the CLR GC, even when there is no bug in the code
        #       being tested.
        #
        checkForRuntimeOption $::test_channel noPoolCounts

        #
        # NOTE: Report the resource usage prior to running any tests.
        #
        reportSQLiteResources $::test_channel

        #
        # NOTE: Show the active test constraints.
        #
        tputs $::test_channel [appendArgs "---- constraints: " \
            [formatList [lsort [getConstraints]]] \n]

        #
        # NOTE: Save the test constraints for use by threads created in this
        #       application domain.  This is necessary because all the Eagle
        #       "test context" information is per-thread.
        #
        if {![info exists ::test_constraints]} then {
          set ::test_constraints $::eagle_tests(constraints)
        }

        #
        # NOTE: Load the "after-constraints" custom per-user and/or per-host
        #       test settings now.
        #
        uplevel 1 [list loadSQLiteTestSettings $::test_channel .after]

        #
        # NOTE: Show when our tests actually began (now).
        #
        tputs $::test_channel [appendArgs \
            "---- System.Data.SQLite tests began at " \
            [clock format [clock seconds]] \n]
      }
    }

    proc runSQLiteTestEpilogue {} {
      #
      # NOTE: Skip running our custom epilogue if the main one has been skipped.
      # NOTE: Skip running our custom epilogue if the main one has been
      #       skipped.
      #
      if {![info exists ::no(epilogue.eagle)]} then {
        #
        # NOTE: Show when our tests actually ended (now).
        #
        tputs $::test_channel [appendArgs \
            "---- System.Data.SQLite tests ended at " \
            [clock format [clock seconds]] \n]

        #
        # BUGFIX: Before checking the final resources in use by SQLite, make
        #         sure both of the PRAGMA related directory names are freed.
        #
        checkForSQLiteDirectories $::test_channel true

        #
        # NOTE: Also report the resource usage after running the tests.
        #
        reportSQLiteResources $::test_channel
      }
    }

Added Tests/empty.eagle.






































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
###############################################################################
#
# empty.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require Eagle.Library
package require Eagle.Test

runTestPrologue

###############################################################################

package require System.Data.SQLite.Test
runSQLiteTestPrologue

###############################################################################

#
# NOTE: There are no unit tests in this file.  This file exists to serve two
#       purposes:
#
#       1. Provide a "template" script file that can be used when creating new
#          unit test files.
#
#       2. Provide a script file that can be evaluated to setup an interactive
#          environment for ad-hoc testing of System.Data.SQLite using the Eagle
#          Shell.
#

###############################################################################

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/stress.eagle.
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
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
87
88
89
90
91
92
93







+
+
+
+
+
+
+
+
+








+
+
+
+
+
+
+
+
+

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





+
+
+







###############################################################################

package require System.Data.SQLite.Test
runSQLiteTestPrologue

###############################################################################

#
# NOTE: Report before test, before shutdown.
#
checkForSQLiteDirectories $test_channel
getSQLiteHandleCounts $test_channel
reportSQLiteResources $test_channel

###############################################################################

#
# NOTE: Make sure that SQLite core library is completely shutdown prior to
#       starting any of the tests in this file.
#
shutdownSQLite $test_channel

###############################################################################

#
# NOTE: Report before test, after shutdown.
#
checkForSQLiteDirectories $test_channel
getSQLiteHandleCounts $test_channel
reportSQLiteResources $test_channel

###############################################################################

runTest {test stress-1.1 {multithreaded stress testing} -setup {
  unset -nocomplain result thread index workload noWorkload srcDb db \
      fileName compiled options count times logFileName logListener \
      connection indicators iterations exitOnFail failures
  unset -nocomplain result thread index workload priority noWorkload \
      priorities srcDb db fileName compiled options count times logFileName \
      logListener connection indicators iterations exitOnFail coTaskMem \
      noTrace failures status

  #############################################################################

  proc setupWorkloadMemDb { fileName {varName db} } {
    #
    # NOTE: This should be an in-memory database; therefore, skip attempting
    #       to delete the underlying database file as that would not make any
    #       sense.  Also, disable use of "PRAGMA temp_store_directory" when
    #       setting up the new connection because it is not thread-safe.
    #
    uplevel 1 [list setupDb $fileName "" "" "" "" "" false false true false \
        $varName]
  }

  #############################################################################

  proc setupWorkloadFileDb { fileName {varName db} } {
    #
    # NOTE: Skip attempting to delete the underlying database file.  Also,
    #       disable use of "PRAGMA temp_store_directory" when setting up
    #       the new connection because it is not thread-safe.
    #
    uplevel 1 [list setupDb $fileName "" "" "" "" "" true false false false \
        $varName]
  }

  #############################################################################

  proc formatWorkloadResult { index } {
    set result [appendArgs "---- iterations for workload (" $index "): "]

    append result [expr {[info exists ::iterations($index,total)] ? \
        $::iterations($index,total) : 0}] " total, "

    append result [expr {[info exists ::iterations($index,ok)] ? \
        $::iterations($index,ok) : 0}] " ok, "

    append result [expr {[info exists ::iterations($index,error)] ? \
        $::iterations($index,error) : 0}] " error, "

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
87
88

89





90
91
92
93
94
95
96
97

98



























































99
100
101
102
103
104
105
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151

152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174


175
176
177
178
179
180

181
182
183
184
185
186
187
188
189
190
191
192
193
194

195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
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







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


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







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









-
-
+

+



-
+

+
+
+
+
+







-
+

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







        $::failures($indicator) : 0}] " failed\n"

    return $result
  }

  #############################################################################

  proc formatWorkloadTime { index } {
    if {[info exists ::times($index)]} then {
      set length [llength $::times($index)]

      if {$length > 0} then {
        set sum [expr [join $::times($index) +]]

        return [appendArgs "---- average time for workload (" $index \
            ") is about " [expr {int($sum / $length / 1000.0)}] \
            " milliseconds (" [expr {int($sum / ([info exists \
            ::iterations($index,total)] ? $::iterations($index,total) : \
            $length) / 1000.0)}] " milliseconds per iteration)\n"]
      }
    }

    return [appendArgs "---- no times for workload (" $index )\n]
  }

  #############################################################################

  proc isExpectedError { error } {
    return [expr {[regexp -- {\sno such table: t1\s} $error] || \
        [regexp -- {\sdatabase is locked\s} $error]}]
        [regexp -- {\sdatabase is locked\s} $error] || \
        [regexp -- {\sdatabase table is locked\s} $error]}]
  }

  #############################################################################

  proc initTest { indicator } {
    set ::eagle_tests(constraints) $::test_constraints
  }

  #############################################################################

  proc delayTest { {extra 0} } {
    after [expr {int((rand() * 1000) + $extra)}]
  }

  #############################################################################

  proc showTest { indicator } {
    tputs $::test_channel $indicator
    append ::indicators $indicator
    after [expr {int(rand() * 1000 + $::count(2))}]
    delayTest $::count(2)
  }

  #############################################################################

  proc doneTest { {indicator ""} } {
    if {[string length $indicator] > 0} then {
      lappend ::status(done) $indicator
    }
    if {[info exists ::status(done)]} then {
      host title $::status(done)
    } else {
      host title ""
    }
  }

  #############################################################################

  proc failTest { indicator error } {
    #
    # NOTE: Halt all testing and exit the process now
    #       -OR- just record the failure and continue?
    #
    if {$::exitOnFail} then {
      set level [expr {[info level] - 1}]
    set level [expr {[info level] - 1}]

    if {$::exitOnFail} then {
      tputs $::test_channel [appendArgs \
          \n [info level $level] ": " \n\t $error \n]

      exit Failure
      exit failure
    } else {
      tlog [appendArgs \
          "\n---- BEGIN TEST FAILURE OUTPUT\n" \
          \n [info level $level] ": " \n\t $error \n \
          "\n---- END TEST FAILURE OUTPUT\n"]

      tputs $::test_channel $indicator

      if {![info exists ::failures($indicator)]} then {
        set ::failures($indicator) 0
      }

      incr ::failures($indicator)
      after [expr {int(rand() * 1000 + $::count(2))}]
      delayTest $::count(2)
    }
  }

  #############################################################################

  proc allocMem { size } {
    if {$::coTaskMem} then {
      return [object invoke -create \
          System.Runtime.InteropServices.Marshal \
          AllocCoTaskMem $size]; # throw
    } else {
      set ptr [object invoke -create -flags +NonPublic \
          System.Data.SQLite.UnsafeNativeMethods \
          sqlite3_malloc $size]

      if {[object invoke $ptr ToInt64] != 0} then {
        return $ptr
      } else {
        error [appendArgs "sqlite3_malloc(" $size ") failed"]
      }
    }
  }

  #############################################################################

  proc useMem { ptr size } {
    if {![isMono]} then {
      #
      # HACK: The type signature of the ZeroMemory method changed as of the
      #       .NET Framework 4.5.  The second argument went from being of
      #       type UInt to type UIntPtr.
      #
      if {[haveConstraint dotNet40] && [haveConstraint dotNet45]} then {
        set newSize [object create UIntPtr $size]
      } else {
        set newSize $size
      }

      object invoke -flags +NonPublic Microsoft.Win32.Win32Native \
          ZeroMemory $ptr $newSize
    }
  }

  #############################################################################

  proc freeMem { ptr } {
    if {$::coTaskMem} then {
      object invoke System.Runtime.InteropServices.Marshal \
          FreeCoTaskMem $ptr
    } else {
      object invoke -flags +NonPublic \
          System.Data.SQLite.UnsafeNativeMethods \
          sqlite3_free $ptr
    }

    #
    # NOTE: Free extra opaque object handle reference added by the
    #       [return] command in [allocMem].
    #
    object dispose $ptr
  }

  #############################################################################

  proc setupLogging { fileName } {
    if {![info exists ::logListener]} then {
      set ::logListener [object create -alias \
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166











167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182

183

184



185
186
187
188
189
190

191

192



























193
194
195
196
197
198

199
200
201

202
203
204


205
206
207

208
209
210

211


212
213
214
215








216
217

218
219


















220
221
222
223
224
225
226
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
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378

379
380
381

382
383
384

385
386
387
388

389
390
391

392
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
418
419
420
421
422
423
424
425
426
427
428
429
430
431







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




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
















+

+
-
+
+
+






+

+

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





-
+


-
+


-
+
+


-
+


-
+

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


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








    tputs $::test_channel [appendArgs \
        "---- disabled SQLite trace logging to file \"" $fileName \"\n]
  }

  #############################################################################

  #
  # NOTE: The trace listener used with the SQLiteLog class to capture output
  #       from the core SQLite library requires its own log file because the
  #       TextWriterTraceListener class opens and locks the log file it uses
  #       as the basis of the output stream.  Before this test is complete,
  #       the entire contents of this trace log file will be copied into the
  #       main test log file and then deleted.
  #
  set logFileName [appendArgs [file rootname $test_log] .trace.log]
  setupLogging $logFileName

  #############################################################################

  #
  # NOTE: Setup the default values for the tunable workload parameters.  Any,
  #       all, or none of these may be overriden via the command line.
  #
  set count(0) 1;        # Workload repeat count (i.e. total full runs).
  set count(1) 20;       # Workload iteration count (i.e. within a run).
  set count(2) 500;      # Workload iteration delay, in milliseconds.
  set count(3) 2000;     # Workload "small" data chunk size, in bytes.
  set count(4) 10000000; # Workload "big" data chunk size, in bytes.
  set noWorkload [list]; # Workloads to be omitted from the run, by index.
  set exitOnFail true;   # Halt testing and exit process on test failure?
  set count(0) 3;         # Workload repeat count (i.e. total full runs).
  set count(1) 5;         # Workload iteration count (i.e. within a run).
  set count(2) 200;       # Workload iteration delay, in milliseconds.
  set count(3) 57;        # Workload "small" data chunk size, in bytes.
  set count(4) 10000;     # Workload "big" data chunk size, in bytes.
  set count(5) 209715200; # Maximum heap memory to exclude at one time.
  set noWorkload [list];  # Workloads to be omitted from the run, by index.
  set priorities [list];  # Dictionary of workload thread priorities.
  set exitOnFail false;   # Halt testing and exit process on test failure?
  set coTaskMem true;     # Use AllocCoTaskMem/FreeCoTaskMem for memory?
  set noTrace false;      # Disable SQLite trace logging to a file?

  #############################################################################

  #
  # NOTE: If command line arguments to the test suite are available, process
  #       them for any options that are applicable to this test (i.e. any of
  #       the tunable workload parameters listed above).
  #
  if {[info exists argv] && [llength $argv] > 0} then {
    parse options -flags \
        {-StopOnUnknownOption +IgnoreOnUnknownOption SkipOnUnknownOption} -- \
        [list [list null MustHaveIntegerValue -1 -1 -count0 $count(0)] \
        [list null MustHaveIntegerValue -1 -1 -count1 $count(1)] \
        [list null MustHaveIntegerValue -1 -1 -count2 $count(2)] \
        [list null MustHaveIntegerValue -1 -1 -count3 $count(3)] \
        [list null MustHaveIntegerValue -1 -1 -count4 $count(4)] \
        [list null MustHaveIntegerValue -1 -1 -count5 $count(5)] \
        [list null MustHaveListValue -1 -1 -noWorkload $noWorkload] \
        [list null MustHaveListValue -1 -1 -priorities $priorities] \
        [list null MustHaveBooleanValue -1 -1 -exitOnFail $exitOnFail]] $argv
        [list null MustHaveBooleanValue -1 -1 -exitOnFail $exitOnFail] \
        [list null MustHaveBooleanValue -1 -1 -coTaskMem $coTaskMem] \
        [list null MustHaveBooleanValue -1 -1 -noTrace $noTrace]] $argv

    set count(0) $options(-count0,value)
    set count(1) $options(-count1,value)
    set count(2) $options(-count2,value)
    set count(3) $options(-count3,value)
    set count(4) $options(-count4,value)
    set count(5) $options(-count5,value)
    set noWorkload $options(-noWorkload,value)
    set priorities $options(-priorities,value)
    set exitOnFail $options(-exitOnFail,value)
    set coTaskMem $options(-coTaskMem,value)
    set noTrace $options(-noTrace,value)
  }

  #############################################################################

  #
  # NOTE: Load custom per-user and/or per-host test settings.  Currently, this
  #       is done after processing the command line options.  The settings file
  #       should take into account the existing workload parameters and avoid
  #       changing any that may have already been overridden.
  #
  loadSQLiteTestSettings $test_channel .stress

  #############################################################################

  #
  # NOTE: The trace listener used with the SQLiteLog class to capture output
  #       from the core SQLite library requires its own log file because the
  #       TextWriterTraceListener class opens and locks the log file it uses
  #       as the basis of the output stream.  Before this test is complete,
  #       the entire contents of this trace log file will be copied into the
  #       main test log file and then deleted.
  #
  if {!$noTrace} then {
    set logFileName [appendArgs [file rootname $test_log] .trace.log]
    setupLogging $logFileName
  }

  #############################################################################

  tputs $test_channel [appendArgs \
      "---- workloads will repeat " $count(0) " time(s)...\n"]
      "---- workloads will repeat " $count(0) " time(s)\n"]

  tputs $test_channel [appendArgs \
      "---- workloads will have " $count(1) " iteration(s)...\n"]
      "---- workloads will have " $count(1) " iteration(s)\n"]

  tputs $test_channel [appendArgs \
      "---- workloads will wait at least " $count(2) " millisecond(s)...\n"]
      "---- workloads will wait at least " $count(2) \
      " millisecond(s) after each iteration\n"]

  tputs $test_channel [appendArgs \
      "---- workload \"small\" chunk size is " $count(3) " byte(s)...\n"]
      "---- small chunk size is " $count(3) " byte(s)\n"]

  tputs $test_channel [appendArgs \
      "---- workload \"big\" chunk size is " $count(4) " byte(s)...\n"]
      "---- big chunk size is " $count(4) " byte(s)\n"]

  tputs $test_channel [appendArgs \
      "---- maximum excluded heap memory is " $count(5) " byte(s)\n"]
  if {[llength $noWorkload] > 0} then {
    tputs $test_channel [appendArgs \
        "---- workloads to be skipped... " $noWorkload \n]
  }

  tputs $test_channel [appendArgs \
      "---- workloads to be skipped... " \
      [expr {[llength $noWorkload] > 0 ? $noWorkload : "none"}] \n]

  tputs $test_channel [appendArgs \
      "---- workloads priority overrides... " \
      [expr {[llength $priorities] > 0 ? $priorities : "none"}] \n]

  tputs $test_channel [appendArgs \
      "---- unexpected errors " \
      "---- workload failures " [expr {$exitOnFail ? "will" : "will not"}] \
      " halt testing and exit the process...\n"]
      [expr {$exitOnFail ? "will" : "will not"}] \
      " halt testing and exit the process\n"]

  tputs $test_channel [appendArgs \
      "---- the " [expr {$coTaskMem ? "CoTaskMem" : "SQLite"}] \
      " allocator will be used to exclude heap memory\n"]

  tputs $test_channel [appendArgs \
      "---- trace logging to a file is " \
      [expr {$noTrace ? "disabled" : "enabled"}] \n]

  #############################################################################

  #
  # NOTE: Create the workload priority array based on the priority list seen
  #       on the command line, if any.
  #
  array set priority $priorities

  #############################################################################

  #
  # NOTE: Workloads #12 and #13 contain C# code that should be compiled, but
  #       only once.  These variables keep track of that state information.
  #       An integer value in one of these variables means the compilation was
245
246
247
248
249
250
251
252
253


254
255
256
257
258
259
260
450
451
452
453
454
455
456


457
458
459
460
461
462
463
464
465







-
-
+
+







  # NOTE: This is a normal on-disk database.
  #
  set fileName(2) [file join [getDatabaseDirectory] [appendArgs \
      stress- [pid] - [string trim [clock seconds] -] .db]]

  #############################################################################

  setupDb $fileName(1) "" "" "" "" "" false false true true srcDb
  setupDb $fileName(2)
  setupWorkloadMemDb $fileName(1) srcDb
  setupWorkloadFileDb $fileName(2)

  #############################################################################

  #
  # NOTE: This serves two purposes.  First, it allows us to verify the trace
  #       logging subsystem is working properly.  Second, it places the file
  #       name for the associated database file into the trace log file.
270
271
272
273
274
275
276

277

278
279
280
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

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
361
362
363
364
365
366
367
368
369

370

371
372
373
374
375
376


377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392

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
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

443
444
445
446
447
448
449
450
451
452
453

454
455
456
457
458
459
460
461
462
463
464
465
466

467

468
469
470
471
472
473
474
475
476
477
478
479
480
481
482

483
484
485
486
487
488
489
490
491
492
493
494
495

496

497
498
499
500

501
502

503
504
505
506
507
508
509
510
511
512

513
514
515
516
517
518
519
520
521
522
523
524
525

526

527
528
529
530
531
532
533
534
535
536
537
538
539
540

541
542
543
544
545
546
547
548
549
550
551
552
553

554

555
556
557
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
587
588
589
590
591
592
593
594
595

596
597
598
599
600
601
602
603
604
605
606
607
608

609
610
611
612
613
614
615
475
476
477
478
479
480
481
482

483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513

514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543

544
545
546


547

548
549
550
551
552
553
554
555
556
557
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
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617

618
619
620

621



622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649

650
651
652

653


654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680

681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711

712
713
714
715

716


717
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
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772

773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802

803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838







+
-
+















+













+
-
+














+













+
-
+


-
-

-
+
+
















+













+
-
+


-
-

-
+
+
















+













+
-
+


-
+
-
-
-
+
+











+













+
-
+


-
+
-
-
+











+













+
-
+















+













+
-
+



-
+
-
-
+










+













+
-
+














+













+
-
+














+













+
-
+













+













+








  set workload(1) [list \
      [list srcFileName dstFileName table count1 count2 count3] {
    #
    # NOTE: Workload #1, CREATE TABLE statements.
    #
    lappend ::times(1) [lindex [time {
      initTest A
      setupDb $dstFileName "" "" "" "" "" true false
      setupWorkloadFileDb $dstFileName
      for {set index 2} {$index <= $count1} {incr index} {
        if {[catch {
          sql execute $db [appendArgs \
              "CREATE TABLE IF NOT EXISTS t" \
              $index "(x PRIMARY KEY, y, z);"]
          showTest A
        } error]} then {
          if {[isExpectedError $error]} then {
            showTest a
          } else {
            failTest a $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
      doneTest A
    }] 0]
  }]

  #############################################################################
  #                              WORKLOAD #2 (B)                              #
  #############################################################################

  set workload(2) [list \
      [list srcFileName dstFileName table count1 count2 count3] {
    #
    # NOTE: Workload #2, DROP TABLE statements.
    #
    lappend ::times(2) [lindex [time {
      initTest B
      setupDb $dstFileName "" "" "" "" "" true false
      setupWorkloadFileDb $dstFileName
      for {set index 2} {$index <= $count1} {incr index} {
        if {[catch {
          sql execute $db [appendArgs \
              "DROP TABLE IF EXISTS t" $index \;]
          showTest B
        } error]} then {
          if {[isExpectedError $error]} then {
            showTest b
          } else {
            failTest b $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
      doneTest B
    }] 0]
  }]

  #############################################################################
  #                              WORKLOAD #3 (C)                              #
  #############################################################################

  set workload(3) [list \
      [list srcFileName dstFileName table count1 count2 count3] {
    #
    # NOTE: Workload #3, "small" SELECT statements.
    #
    lappend ::times(3) [lindex [time {
      initTest C
      setupDb $dstFileName "" "" "" "" "" true false
      setupWorkloadFileDb $dstFileName
      for {set index 1} {$index <= $count1} {incr index} {
        if {[catch {
          set sql [appendArgs \
              "SELECT x, y FROM " $table " WHERE z = 'small';"]
          set reader [sql execute -execute reader \
              -format dataReader -alias $db $sql]
              -format dataReader -alias $db [appendArgs \
              "SELECT x, y FROM " $table " WHERE z = 'small';"]]
          while {[$reader Read]} {
            #
            # NOTE: Do nothing.
            #
          }
          unset -nocomplain reader
          showTest C
        } error]} then {
          if {[isExpectedError $error]} then {
            showTest c
          } else {
            failTest c $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
      doneTest C
    }] 0]
  }]

  #############################################################################
  #                              WORKLOAD #4 (D)                              #
  #############################################################################

  set workload(4) [list \
      [list srcFileName dstFileName table count1 count2 count3] {
    #
    # NOTE: Workload #4, "big" SELECT statements.
    #
    lappend ::times(4) [lindex [time {
      initTest D
      setupDb $dstFileName "" "" "" "" "" true false
      setupWorkloadFileDb $dstFileName
      for {set index 1} {$index <= $count1} {incr index} {
        if {[catch {
          set sql [appendArgs \
              "SELECT x, y FROM " $table " WHERE z = 'big';"]
          set reader [sql execute -execute reader \
              -format dataReader -alias $db $sql]
              -format dataReader -alias $db [appendArgs \
              "SELECT x, y FROM " $table " WHERE z = 'big';"]]
          while {[$reader Read]} {
            #
            # NOTE: Do nothing.
            #
          }
          unset -nocomplain reader
          showTest D
        } error]} then {
          if {[isExpectedError $error]} then {
            showTest d
          } else {
            failTest d $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
      doneTest D
    }] 0]
  }]

  #############################################################################
  #                              WORKLOAD #5 (E)                              #
  #############################################################################

  set workload(5) [list \
      [list srcFileName dstFileName table count1 count2 count3] {
    #
    # NOTE: Workload #5, "small" INSERT statements.
    #
    lappend ::times(5) [lindex [time {
      initTest E
      setupDb $dstFileName "" "" "" "" "" true false
      setupWorkloadFileDb $dstFileName
      for {set index 1} {$index <= $count1} {incr index} {
        if {[catch {
          sql execute $db [appendArgs \
          sql execute $db [appendArgs "INSERT INTO " $table \
              "INSERT INTO " $table "(x, y, z) VALUES('" \
              [format %lX [expr {random()}]] "', '" \
              [base64 encode -- [expr {randstr($count2)}]] \
              "(x, y, z) VALUES('" [format %lX [expr {random()}]] \
              "', '" [base64 encode -- [expr {randstr($count2)}]] \
              "', 'small');"]
          showTest E
        } error]} then {
          if {[isExpectedError $error]} then {
            showTest e
          } else {
            failTest e $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
      doneTest E
    }] 0]
  }]

  #############################################################################
  #                              WORKLOAD #6 (F)                              #
  #############################################################################

  set workload(6) [list \
      [list srcFileName dstFileName table count1 count2 count3] {
    #
    # NOTE: Workload #6, "big" INSERT statements.
    #
    lappend ::times(6) [lindex [time {
      initTest F
      setupDb $dstFileName "" "" "" "" "" true false
      setupWorkloadFileDb $dstFileName
      for {set index 1} {$index <= $count1} {incr index} {
        if {[catch {
          sql execute $db [appendArgs \
          sql execute $db [appendArgs "INSERT INTO " $table \
              "INSERT INTO " $table "(x, y, z) VALUES('" \
              [format %lX [expr {random()}]] \
              "(x, y, z) VALUES('" [format %lX [expr {random()}]] \
              "', RANDOMBLOB(" $count3 "), 'big');"]
          showTest F
        } error]} then {
          if {[isExpectedError $error]} then {
            showTest f
          } else {
            failTest f $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
      doneTest F
    }] 0]
  }]

  #############################################################################
  #                              WORKLOAD #7 (G)                              #
  #############################################################################

  set workload(7) [list \
      [list srcFileName dstFileName table count1 count2 count3] {
    #
    # NOTE: Workload #7, "small" UPDATE statements.
    #
    lappend ::times(7) [lindex [time {
      initTest G
      setupDb $dstFileName "" "" "" "" "" true false
      setupWorkloadFileDb $dstFileName
      for {set index 1} {$index <= $count1} {incr index} {
        if {[catch {
          sql execute $db [appendArgs "UPDATE " $table \
              " SET y = '" [base64 encode -- [expr {randstr($count2)}]] \
              "' WHERE x LIKE '" [format %X $index] "%' AND z = 'small';"]
          showTest G
        } error]} then {
          if {[isExpectedError $error]} then {
            showTest g
          } else {
            failTest g $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
      doneTest G
    }] 0]
  }]

  #############################################################################
  #                              WORKLOAD #8 (H)                              #
  #############################################################################

  set workload(8) [list \
      [list srcFileName dstFileName table count1 count2 count3] {
    #
    # NOTE: Workload #8, "big" UPDATE statements.
    #
    lappend ::times(8) [lindex [time {
      initTest H
      setupDb $dstFileName "" "" "" "" "" true false
      setupWorkloadFileDb $dstFileName
      for {set index 1} {$index <= $count1} {incr index} {
        if {[catch {
          sql execute $db [appendArgs "UPDATE " $table \
              " SET y = RANDOMBLOB(" $count3 \
              " SET y = RANDOMBLOB(" $count3 ") WHERE x LIKE '" \
              ") WHERE x LIKE '" [format %X $index] \
              "%' AND z = 'big';"]
              [format %X $index] "%' AND z = 'big';"]
          showTest H
        } error]} then {
          if {[isExpectedError $error]} then {
            showTest h
          } else {
            failTest h $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
      doneTest H
    }] 0]
  }]

  #############################################################################
  #                              WORKLOAD #9 (I)                              #
  #############################################################################

  set workload(9) [list \
      [list srcFileName dstFileName table count1 count2 count3] {
    #
    # NOTE: Workload #9, "small" DELETE statements.
    #
    lappend ::times(9) [lindex [time {
      initTest I
      setupDb $dstFileName "" "" "" "" "" true false
      setupWorkloadFileDb $dstFileName
      for {set index 1} {$index <= $count1} {incr index} {
        if {[catch {
          sql execute $db [appendArgs "DELETE FROM " $table \
              " WHERE x LIKE '" [format %X $index] "%' AND z = 'small';"]
          showTest I
        } error]} then {
          if {[isExpectedError $error]} then {
            showTest i
          } else {
            failTest i $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
      doneTest I
    }] 0]
  }]

  #############################################################################
  #                              WORKLOAD #10 (J)                             #
  #############################################################################

  set workload(10) [list \
      [list srcFileName dstFileName table count1 count2 count3] {
    #
    # NOTE: Workload #10, "big" DELETE statements.
    #
    lappend ::times(10) [lindex [time {
      initTest J
      setupDb $dstFileName "" "" "" "" "" true false
      setupWorkloadFileDb $dstFileName
      for {set index 1} {$index <= $count1} {incr index} {
        if {[catch {
          sql execute $db [appendArgs "DELETE FROM " $table \
              " WHERE x LIKE '" [format %X $index] "%' AND z = 'big';"]
          showTest J
        } error]} then {
          if {[isExpectedError $error]} then {
            showTest j
          } else {
            failTest j $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
      doneTest J
    }] 0]
  }]

  #############################################################################
  #                              WORKLOAD #11 (K)                             #
  #############################################################################

  set workload(11) [list \
      [list srcFileName dstFileName table count1 count2 count3] {
    #
    # NOTE: Workload #11, VACUUM statement.
    #
    lappend ::times(11) [lindex [time {
      initTest K
      setupDb $dstFileName "" "" "" "" "" true false
      setupWorkloadFileDb $dstFileName
      for {set index 1} {$index <= $count1} {incr index} {
        if {[catch {
          sql execute $db "VACUUM;"
          showTest K
        } error]} then {
          if {[isExpectedError $error]} then {
            showTest k
          } else {
            failTest k $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
      doneTest K
    }] 0]
  }]

  #############################################################################
  #                              WORKLOAD #12 (L)                             #
  #############################################################################

  set workload(12) [list \
      [list srcFileName dstFileName table count1 count2 count3] {
    #
    # NOTE: Workload #12, backup to in-memory database.
    #
    lappend ::times(12) [lindex [time {
      initTest L
      for {set index 1} {$index <= $count1} {incr index} {
        if {[string is integer -strict $::compiled(12)]} then {
          set id $::compiled(12); # NOTE: Already compiled.
          if {[catch {
            object invoke _Dynamic${id}.Test${id} BackupAndGetData
            showTest L
          } error]} then {
669
670
671
672
673
674
675

676
677
678
679
680
681
682
683
684
685
686
687
688

689
690
691
692
693
694
695
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920







+













+







              }
            }
          } else {
            error $errors
          }
        }
      }
      doneTest L
    }] 0]
  }]

  #############################################################################
  #                              WORKLOAD #13 (M)                             #
  #############################################################################

  set workload(13) [list \
      [list srcFileName dstFileName table count1 count2 count3] {
    #
    # NOTE: Workload #13, backup from an in-memory database.
    #
    lappend ::times(13) [lindex [time {
      initTest M
      for {set index 1} {$index <= $count1} {incr index} {
        if {[string is integer -strict $::compiled(13)]} then {
          set id $::compiled(13); # NOTE: Already compiled.
          if {[catch {
            object invoke _Dynamic${id}.Test${id} BackupAndGetData
            showTest M
          } error]} then {
749
750
751
752
753
754
755

756
757
758
759
760
761
762
763
764
765
766
767
768

769

770
771
772
773
774

775
776
777
778

779
780
781
782
783
784
785
786
787

788
789
790
791
792
793
794
795
796
797
798
799
800

801
802
803
804
805
806
807
808
809
810
811
812

813
814








































































































































































815



816
817













818
819


820
821
822
823
824
825







826
827
828
829
830
831
832
833
834







835

836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856




857

858
859
860
861
862
863
864


865
866
867
868
869
870

871
872

873
874

875
876
877
878
879
880
881
882
883
884
885
886
887


888
889
890
891
892
893
894
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995

996
997
998
999
1000

1001


1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
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
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
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
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
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215


1216
1217
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
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
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293


1294
1295
1296
1297
1298
1299
1300

1301


1302


1303






1304
1305
1306
1307
1308


1309
1310
1311
1312
1313
1314
1315
1316
1317







+













+
-
+




-
+
-
-


+









+













+












+


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

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

-
+
+






+
+
+
+
+
+
+









+
+
+
+
+
+
+
-
+





















+
+
+
+

+





-
-
+
+





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





-
-
+
+







              }
            }
          } else {
            error $errors
          }
        }
      }
      doneTest M
    }] 0]
  }]

  #############################################################################
  #                              WORKLOAD #14 (N)                             #
  #############################################################################

  set workload(14) [list \
      [list srcFileName dstFileName table count1 count2 count3] {
    #
    # NOTE: Workload #14, PRAGMA integrity check statement.
    #
    lappend ::times(14) [lindex [time {
      initTest N
      setupDb $dstFileName "" "" "" "" "" true false
      setupWorkloadFileDb $dstFileName
      for {set index 1} {$index <= $count1} {incr index} {
        if {[catch {
          set result [sql execute -execute scalar $db \
              "PRAGMA integrity_check;"]
          if {$result eq "ok"} then {
          if {$result ne "ok"} then {
            showTest N
          } else {
            error [appendArgs "integrity check failed: " $result]
          }
          showTest N
        } error]} then {
          if {[isExpectedError $error]} then {
            showTest n
          } else {
            failTest n $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
      doneTest N
    }] 0]
  }]

  #############################################################################
  #                              WORKLOAD #15 (O)                             #
  #############################################################################

  set workload(15) [list \
      [list srcFileName dstFileName table count1 count2 count3] {
    #
    # NOTE: Workload #15, force managed garbage collection
    #
    lappend ::times(15) [lindex [time {
      initTest O
      for {set index 1} {$index <= $count1} {incr index} {
        if {[catch {
          collectGarbage $::test_channel
          showTest O
        } error]} then {
          if {[isExpectedError $error]} then {
            showTest o
          } else {
            failTest o $error
          }
        }
      }
      doneTest O
    }] 0]
  }]

  #############################################################################
  #                              WORKLOAD #16 (P)                             #
  #############################################################################

  set workload(16) [list \
      [list srcFileName dstFileName table count1 count2 count3] {
    #
    # NOTE: Workload #16, allocate (exclude) some native heap memory
    #
    lappend ::times(16) [lindex [time {
      initTest P
      set maxSize $::count(5)
      object invoke GC AddMemoryPressure $maxSize
      try {
        for {set index 1} {$index <= $count1} {incr index} {
          if {[catch {
            set size [expr {int(min($maxSize, abs($count3 * $index * 5.0)))}]
            set ptr [allocMem $size]; # throw
            useMem $ptr $size; delayTest $count2
            freeMem $ptr; unset -nocomplain ptr
            showTest P
          } error]} then {
            if {[isExpectedError $error]} then {
              showTest p
            } else {
              failTest p $error
            }
          }
        }
      } finally {
        if {[info exists ptr]} then {
          freeMem $ptr; unset -nocomplain ptr
        }
        object invoke GC RemoveMemoryPressure $maxSize
      }
      doneTest P
    }] 0]
  }]

  #############################################################################
  #                              WORKLOAD #17 (Q)                             #
  #############################################################################

  set workload(17) [list \
      [list srcFileName dstFileName table count1 count2 count3] {
    #
    # NOTE: Workload #17, change the database journal mode
    #
    lappend ::times(17) [lindex [time {
      initTest Q
      setupWorkloadFileDb $dstFileName
      for {set index 1} {$index <= $count1} {incr index} {
        if {[catch {
          sql execute $db [appendArgs "PRAGMA journal_mode = \"" \
              [expr {$index % 2 == 0 ? "delete" : "wal"}] \"\;]
          showTest Q
        } error]} then {
          if {[isExpectedError $error]} then {
            showTest q
          } else {
            failTest q $error
          }
        }
      }
      cleanupDb $dstFileName db false true false
      doneTest Q
    }] 0]
  }]

  #############################################################################
  #                              WORKLOAD #18 (R)                             #
  #############################################################################

  set workload(18) [list \
      [list srcFileName dstFileName table count1 count2 count3] {
    #
    # NOTE: Workload #18, execute queries against the in-memory database
    #
    lappend ::times(18) [lindex [time {
      initTest R
      setupWorkloadMemDb $srcFileName
      for {set index 1} {$index <= $count1} {incr index} {
        if {[catch {
          #
          # NOTE: Workload #18.3, "small" SELECT statements.
          #
          set reader [sql execute -execute reader \
              -format dataReader -alias $db [appendArgs \
              "SELECT x, y FROM " $table " WHERE z = 'small';"]]
          while {[$reader Read]} {
            #
            # NOTE: Do nothing.
            #
          }
          unset -nocomplain reader
          #
          # NOTE: Workload #18.4, "big" SELECT statements.
          #
          set reader [sql execute -execute reader \
              -format dataReader -alias $db [appendArgs \
              "SELECT x, y FROM " $table " WHERE z = 'big';"]]
          while {[$reader Read]} {
            #
            # NOTE: Do nothing.
            #
          }
          unset -nocomplain reader
          #
          # NOTE: Workload #18.5, "small" INSERT statements.
          #
          sql execute $db [appendArgs "INSERT INTO " $table \
              "(x, y, z) VALUES('" [format %lX [expr {random()}]] \
              "', '" [base64 encode -- [expr {randstr($count2)}]] \
              "', 'small');"]
          #
          # NOTE: Workload #18.6, "big" INSERT statements.
          #
          sql execute $db [appendArgs "INSERT INTO " $table \
              "(x, y, z) VALUES('" [format %lX [expr {random()}]] \
              "', RANDOMBLOB(" $count3 "), 'big');"]
          #
          # NOTE: Workload #18.7, "small" UPDATE statements.
          #
          sql execute $db [appendArgs "UPDATE " $table \
              " SET y = '" [base64 encode -- [expr {randstr($count2)}]] \
              "' WHERE x LIKE '" [format %X $index] "%' AND z = 'small';"]
          #
          # NOTE: Workload #18.8, "big" UPDATE statements.
          #
          sql execute $db [appendArgs "UPDATE " $table \
              " SET y = RANDOMBLOB(" $count3 ") WHERE x LIKE '" \
              [format %X $index] "%' AND z = 'big';"]
          #
          # NOTE: Workload #18.9, "small" DELETE statements.
          #
          sql execute $db [appendArgs "DELETE FROM " $table \
              " WHERE x LIKE '" [format %X $index] "%' AND z = 'small';"]
          #
          # NOTE: Workload #18.10, "big" DELETE statements.
          #
          sql execute $db [appendArgs "DELETE FROM " $table \
              " WHERE x LIKE '" [format %X $index] "%' AND z = 'big';"]
          #
          # NOTE: Workload #18.11, VACUUM statement.
          #
          sql execute $db "VACUUM;"
          #
          # NOTE: Workload #18.14, PRAGMA integrity check statement.
          #
          set result [sql execute -execute scalar $db \
              "PRAGMA integrity_check;"]
          if {$result ne "ok"} then {
            error [appendArgs "integrity check failed: " $result]
          }
          showTest R
        } error]} then {
          if {[isExpectedError $error]} then {
            showTest r
          } else {
            failTest r $error
          }
        }
      }
      cleanupDb $srcFileName db false true false
      doneTest R
    }] 0]
  }]
} -body {
  tputs $test_channel [appendArgs \
      "==== WARNING: this stress test may take several minutes...\n"]

  for {set index(0) 0} {$index(0) < $count(0)} {incr index(0)} {
    sql execute $db "CREATE TABLE IF NOT EXISTS t1(x PRIMARY KEY, y, z);"
  for {set index(0) 1} {$index(0) <= $count(0)} {incr index(0)} {
    if {$index(0) > 1} then {
      #
      # NOTE: Advance output to the next line due to the workload
      #       iteration progress indicators from the previous run.
      #
      tputs $test_channel \n
    }

    tputs $test_channel [appendArgs \
        "---- starting workload run #" $index(0) ...\n]

    unset -nocomplain thread status; doneTest

    unset -nocomplain thread
    sql execute $srcDb "CREATE TABLE IF NOT EXISTS t1(x PRIMARY KEY, y, z);"
    sql execute $db "CREATE TABLE IF NOT EXISTS t1(x PRIMARY KEY, y, z);"

    foreach index(1) [lsort -integer [array names workload]] {
      if {[lsearch -exact $noWorkload $index(1)] == -1} then {
        set thread($index(1)) [object create -alias System.Threading.Thread \
            [list apply $workload($index(1)) $fileName(1) $fileName(2) t1 \
            $count(1) $count(3) $count(4)] 1048576]

        $thread($index(1)) Name [appendArgs \
            [file rootname [file tail $fileName(2)]] " #" $index(1)]

        if {[info exists priority($index(1))]} then {
          $thread($index(1)) Priority $priority($index(1))
        }
      }
    }

    foreach index(1) [list Start Join] {
      foreach index(2) [array names thread] {
        $thread($index(2)) $index(1)
      }
    }

    foreach index(1) [array names thread] {
      if {[info exists thread($index(1))] && \
          [cleanupThread $thread($index(1))]} then {
        unset -nocomplain thread($index(1))
      }
    }

    unset -nocomplain thread
    unset -nocomplain thread status; doneTest
  }

  #############################################################################

  foreach index(0) [split $indicators ""] {
    #
    # NOTE: See if this workload iteration raised an error.  If so, the
    #       indicator letter will be in lower case; otherwise, it will
    #       be in upper case.
    #
    set index(1) [string is upper -strict $index(0)]

    set index(2) [expr {[string ordinal $index(0) 0] - \
        [string ordinal [expr {$index(1) ? "A" : "a"}] 0] + 1}]

    set index(3) [expr {$index(1) ? "ok" : "error"}]

    if {![info exists iterations($index(2),$index(3))]} then {
      set iterations($index(2),$index(3)) 0
    }

    if {![info exists iterations($index(2),total)]} then {
      set iterations($index(2),total) 0
    }

    incr iterations($index(2),$index(3))
    incr iterations($index(2),total)
  }

  #############################################################################

  #
  # NOTE: Advance output to the next line due to the workload iteration
  #       progress indicators.
  # NOTE: Advance output to the next line due to the workload
  #       iteration progress indicators from the final run.
  #
  tputs $test_channel \n

  #############################################################################

  foreach index(0) [lsort -integer [array names times]] {
  foreach index(0) [lsort -integer [array names workload]] {
    set times(length) [llength $times($index(0))]

    if {[lsearch -exact $noWorkload $index(0)] == -1} then {
    if {$times(length) > 0} then {
      tputs $test_channel [appendArgs \
      tputs $test_channel [formatWorkloadResult $index(0)]
          "---- average time for workload (" $index(0) ") is about " \
          [expr int(([join $times($index(0)) +])/$times(length)/1000.0)] \
          " milliseconds\n"]
    } else {
      tputs $test_channel [appendArgs \
          "---- no times for workload (" $index(0) ")\n"]
    }
  }

  #############################################################################

  foreach index(0) [lsort -integer [array names workload]] {
    tputs $test_channel [formatWorkloadResult $index(0)]
  foreach index(0) [lsort -integer [array names times]] {
    tputs $test_channel [formatWorkloadTime $index(0)]
  }

  #############################################################################

  set result [sql execute -execute scalar $srcDb "PRAGMA integrity_check;"]

  if {$result eq "ok"} then {
912
913
914
915
916
917
918










919

920


921

922


923
924
925
926
927
928
929
930
931
932
933
934
935

936


937
938
939
940
941
942
943
944
945
946















947
948
949
950
951
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375

1376
1377
1378
1379
1380
1381






1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401







+
+
+
+
+
+
+
+
+
+

+

+
+

+

+
+













+
-
+
+




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





  #
  # NOTE: The overall test result is the total number of failures (i.e.
  #       "unexpected errors") encountered during a workload iteration.
  #
  expr {[array size failures] > 0 ? \
      [expr [join [array values failures] +]] : 0}
} -cleanup {
  foreach index(0) [array names thread] {
    if {[info exists thread($index(0))] && \
        [cleanupThread $thread($index(0))]} then {
      unset -nocomplain thread($index(0))
    }
  }

  rename freeMem ""
  rename useMem ""
  rename allocMem ""
  rename failTest ""
  rename doneTest ""
  rename showTest ""
  rename delayTest ""
  rename initTest ""
  rename isExpectedError ""
  rename formatWorkloadTime ""
  rename formatWorkloadResult ""
  rename setupWorkloadFileDb ""
  rename setupWorkloadMemDb ""

  cleanupDb $fileName(2)
  cleanupDb $fileName(1) srcDb

  foreach index(0) [array names workload] {
    catch {
      object removecallback [list apply $workload($index(0)) $fileName(1) \
          $fileName(2) t1 $count(1) $count(3) $count(4)]
    }
  }

  freeDbConnection

  if {!$noTrace} then {
  cleanupLogging $logFileName
    cleanupLogging $logFileName
  }

  rename cleanupLogging ""
  rename setupLogging ""

  unset -nocomplain result thread index workload noWorkload srcDb db \
      fileName compiled options count times logFileName logListener \
      connection indicators iterations exitOnFail failures
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-result {0}}
  unset -nocomplain result thread index workload priority noWorkload \
      priorities srcDb db fileName compiled options count times logFileName \
      logListener connection indicators iterations exitOnFail coTaskMem \
      noTrace failures status
} -time true -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite} -result {0}}

###############################################################################

#
# NOTE: Report after test.
#
checkForSQLiteDirectories $test_channel
getSQLiteHandleCounts $test_channel
reportSQLiteResources $test_channel

###############################################################################

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/thread.eagle.
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
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
87
88
89
90
91
92


93
94
95

96
97
98
99
100
101
102
103
104
105







+
-
+





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

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







+
-
+
+
+
+
+
+
+
+
+

-
+

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


-
-
+
+
+
-


+








package require System.Data.SQLite.Test
runSQLiteTestPrologue

###############################################################################

checkForSQLiteDirectories $test_channel true
set handle_counts [getSQLiteHandleCounts $test_channel]
set memory_used [reportSQLiteResources $test_channel true]
set memory_used [reportSQLiteResources $test_channel]

###############################################################################

#
# NOTE: How many test threads should be created and used for these tests?  This
#       value must be at least two.  The first test thread (at index 0) just
#       repeatedly calls the Thread.Abort() method on the other test threads
#       that appear to be alive until all test threads appear to be dead.  All
#       other threads will attempt to open a connection, execute one or more
#       queries against it, and then close it.
#       value must be at least two.  The first test thread (at index 0) is
#       always the "master thread" and just repeatedly calls the Thread.Abort()
#       method on other random test threads that appear to be alive until all
#       test threads appear to have died.  All other test threads will attempt
#       to open a connection, execute one or more queries against it, and then
#       close it.
#
if {![info exists count(1)]} then {
  set count(1) 10
}

#
# NOTE: How many milliseconds should the master thread initially wait until it
#       starts to abort the other test threads?
#
if {![info exists count(2)]} then {
set count 10
  set count(2) 1000
}

#
# NOTE: How many milliseconds (maximum) should the master thread wait between
#       aborting other random test threads?
#
if {![info exists count(3)]} then {
  set count(3) 1000
}

#
# NOTE: How many bytes should be used for the five random data blobs contained
#       in the test database?
#
if {![info exists count(4)]} then {
  set count(4) 1000
}

###############################################################################

runTest {test thread-1.1 {Thread.Abort() impact on native resources} -setup {
  setupDb [set fileName thread-1.1.db]

  tputs $test_channel [appendArgs \
      "---- using " $count(1) " test threads (with one master thread)\n"]
      "---- using a total of " $count " threads...\n"]

  tputs $test_channel [appendArgs \
      "---- initial wait will be " $count(2) " milliseconds\n"]

  tputs $test_channel [appendArgs \
      "---- subsequent maximum wait will be " $count(3) " milliseconds\n"]

  tputs $test_channel [appendArgs \
      "---- random data blob size will be " $count(4) " bytes\n"]
} -body {
  sql execute $db {
  sql execute $db [subst {
    CREATE TABLE t1(x INTEGER PRIMARY KEY, y BLOB);
    INSERT INTO t1 (y) VALUES(RANDOMBLOB(1000));
    INSERT INTO t1 (y) VALUES(RANDOMBLOB(1000));
    INSERT INTO t1 (y) VALUES(RANDOMBLOB(1000));
    INSERT INTO t1 (y) VALUES(RANDOMBLOB(1000));
    INSERT INTO t1 (y) VALUES(RANDOMBLOB(1000));
  }
    INSERT INTO t1 (y) VALUES(RANDOMBLOB(${count(4)}));
    INSERT INTO t1 (y) VALUES(RANDOMBLOB(${count(4)}));
    INSERT INTO t1 (y) VALUES(RANDOMBLOB(${count(4)}));
    INSERT INTO t1 (y) VALUES(RANDOMBLOB(${count(4)}));
    INSERT INTO t1 (y) VALUES(RANDOMBLOB(${count(4)}));
  }]

  #
  # NOTE: The temporary directory must be reset here because it allocates
  #       some SQLite memory and this test requires an extremely accurate
  # NOTE: The data and temporary directories must be reset here (after the
  #       setupDb call above) because they allocate some SQLite memory and
  #       this test requires an extremely accurate reading.
  #       reading.
  #
  sql execute $db {
    PRAGMA data_store_directory = "";
    PRAGMA temp_store_directory = "";
  }

  #
  # NOTE: Close the database now, freeing any native SQLite memory and/or
  #       resources that it may be using at this point; however, do not
  #       actually delete the database file because it is needed in the C#
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
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142
143

144
145
146
147
148
149

150
151
152
153
154
155

156
157
158
159
160

161
162
163
164
165
166
167
168







-
+








-
+





-
+





-
+




-
+







    using System.Threading;
    using Eagle._Containers.Public;

    namespace _Dynamic${id}
    {
      public static class Test${id}
      {
        public static IntList RunTestThreads()
        public static LongList RunTestThreads()
        {
          //
          // NOTE: This is the total number of data bytes seen in the second
          //       column of the query result rows seen by all test threads.
          //       This value will vary greatly based upon how many loop
          //       iterations are performed prior to each test thread being
          //       aborted.
          //
          int sum = 0;
          long sum = 0;

          //
          // NOTE: This is the total number of query result rows seen by all
          //       the test threads.
          //
          int rows = 0;
          long rows = 0;

          //
          // NOTE: This is the total number of exceptions caught by all the
          //       test threads.
          //
          int errors = 0;
          long errors = 0;

          //
          // NOTE: This is the total number of test threads to create.
          //
          int count = ${count};
          int count = ${count(1)};

          //
          // NOTE: Create the array of thread objects.
          //
          Thread\[\] thread = new Thread\[count\];

          //
277
278
279
280
281
282
283
284

285
286
287
288
289
290
291
292
293
294
295

296
297
298
299
300
301
302
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







-
+










-
+







                goEvent.WaitOne();

                //
                // NOTE: Give the other test threads a slight head start to
                //       make sure that they are fully alive prior to trying
                //       to abort any of them.
                //
                Thread.Sleep(1000);
                Thread.Sleep(${count(2)});

                //
                // NOTE: Loop forever until all test threads appear to be dead.
                //
                while (true)
                {
                  //
                  // NOTE: Wait a random number of milliseconds, up to a full
                  //       second.
                  //
                  Thread.Sleep(random.Next(0, 1000));
                  Thread.Sleep(random.Next(0, ${count(3)}));

                  //
                  // NOTE: Select a random thread to abort.
                  //
                  int index = random.Next(1, count);

                  //
384
385
386
387
388
389
390
391

392
393
394
395
396
397
398
422
423
424
425
426
427
428

429
430
431
432
433
434
435
436







-
+







          }

          //
          // NOTE: Return a list of integers with total number of data bytes
          //       seen, total number of query result rows seen, and the total
          //       number of exceptions caught by all the test threads.
          //
          IntList counts = new IntList();
          LongList counts = new LongList();

          counts.Add(sum);
          counts.Add(rows);
          counts.Add(errors);

          return counts;
        }
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
446
447
448
449
450
451
452


453
454
455
456
457
458
459




460
461
462
463
464
465
466
467
468
469
470

471
472
473
474
475
476







-
-
+
+
+




-
-
-
-
+
+
+
+







-
+





  }] true true true results errors [list System.Data.SQLite.dll Eagle.dll]]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} RunTestThreads
      } result] : [set result ""]}] $result \
      [collectGarbage $test_channel] \
      [reportSQLiteResources $test_channel true]
      [collectGarbage $test_channel [expr {$count(1) * 1000}] false] \
      [getSQLiteHandleCounts $test_channel] \
      [reportSQLiteResources $test_channel]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result results errors code sql dataSource id db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result [appendArgs "^Ok System#CodeDom#Compiler#CompilerResults#\\d+\
\\{\\} 0 \\{\\d+ \\d+ " $count "\\} \\{\\} " $memory_used \$]}
} -time true -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
System.Data.SQLite} -match regexp -result [appendArgs "^Ok\
System#CodeDom#Compiler#CompilerResults#\\d+ \\{\\} 0 \\{\\d+ \\d+ " $count(1) \
"\\} \\{\\} \\{" $handle_counts "\\} " $memory_used \$]}

###############################################################################

unset -nocomplain count

###############################################################################

unset -nocomplain memory_used
unset -nocomplain memory_used handle_counts

###############################################################################

runSQLiteTestEpilogue
runTestEpilogue
Added Tests/tkt-6434e23a0f.eagle.






















































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
###############################################################################
#
# tkt-6434e23a0f.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require Eagle.Library
package require Eagle.Test

runTestPrologue

###############################################################################

package require System.Data.SQLite.Test
runSQLiteTestPrologue

###############################################################################

runTest {test tkt-6434e23a0f-1.1 {SQLiteDataAdapter command disposal} -setup {
  setupDb [set fileName tkt-6434e23a0f-1.1.db]
} -body {
  sql execute $db "CREATE TABLE t1(x);"
  sql execute $db "INSERT INTO t1 (x) VALUES(1);"
  sql execute $db "INSERT INTO t1 (x) VALUES(2);"

  cleanupDb $fileName db true false false

  set id [object invoke Interpreter.GetActive NextId]
  set dataSource [file join [getDatabaseDirectory] $fileName]

  set sql { \
    SELECT x FROM t1; \
  }

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System.Data;
    using System.Data.SQLite;
    using System.IO;

    namespace _Dynamic${id}
    {
      public static class Test${id}
      {
        public static void Main()
        {
          using (SQLiteConnection connection = new SQLiteConnection(
              "Data Source=${dataSource};"))
          {
            connection.Open();

            using (SQLiteDataAdapter dataAdapter = new SQLiteDataAdapter(
                "${sql}", connection))
            {
              dataAdapter.Fill(new DataSet());
            }
          }

          File.Delete("${dataSource}");
        }
      }
    }
  }] true true true results errors System.Data.SQLite.dll]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} Main
      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result results errors code sql dataSource id db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}

###############################################################################

runSQLiteTestEpilogue
runTestEpilogue
Added Tests/tkt-6c6ecccc5f.eagle.


















































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
###############################################################################
#
# tkt-6c6ecccc5f.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require Eagle.Library
package require Eagle.Test

runTestPrologue

###############################################################################

package require System.Data.SQLite.Test
runSQLiteTestPrologue

###############################################################################

runTest {test tkt-6c6ecccc5f-1.1 {CloseConnection with extensions} -setup {
  setupDb [set fileName tkt-6c6ecccc5f-1.1.db]
} -body {
  sql execute $db {
    CREATE VIRTUAL TABLE t1 USING fts4(x TEXT);
    INSERT INTO t1 (x) VALUES('one');
    INSERT INTO t1 (x) VALUES('two');
  }

  set id [object invoke Interpreter.GetActive NextId]
  set dataSource [file join [getDatabaseDirectory] $fileName]
  set sql "SELECT x FROM t1 WHERE x MATCH 'one';"

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System.Data;
    using System.Data.SQLite;

    namespace _Dynamic${id}
    {
      public static class Test${id}
      {
        public static void Main()
        {
          using (SQLiteConnection connection = new SQLiteConnection(
              "Data Source=${dataSource};"))
          {
            connection.Open();

            using (SQLiteCommand command = new SQLiteCommand("${sql}",
                connection))
            {
              /* IGNORED */
              command.ExecuteReader(CommandBehavior.CloseConnection);
            }
          }
        }
      }
    }
  }] true true true results errors System.Data.SQLite.dll]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} Main
      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result results errors code sql dataSource id db fileName
} -constraints \
{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
-match regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0\
\{\}$}}

###############################################################################

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/tkt-72905c9a77.eagle.
16
17
18
19
20
21
22








23
24
25
26
27
28
29
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37







+
+
+
+
+
+
+
+







###############################################################################

package require System.Data.SQLite.Test
runSQLiteTestPrologue

###############################################################################

#
# NOTE: Make sure that SQLite core library is completely shutdown prior to
#       starting any of the tests in this file.
#
shutdownSQLite $test_channel

###############################################################################

#
# NOTE: This value is needed as part of the test result; therefore, it must be
#       set outside of the test setup.
#
set id [object invoke Interpreter.GetActive NextId]

###############################################################################
260
261
262
263
264
265
266

267
268


269
270
271
272
273
274
275
276
277
278
279
280
268
269
270
271
272
273
274
275


276
277
278
279
280
281
282
283
284
285
286
287
288
289







+
-
-
+
+












      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} GetTraceOutput
      } result] : [set result ""]}] [string map [list \r\n \n] $result]
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors dataSource fileName
} -constraints [fixConstraints {eagle monoBug28 configuration.Release\
} -constraints {eagle configuration.Release monoBug28 command.sql compile.DATA\
SQLite System.Data.SQLite} -match regexp -result [appendArgs "^Ok\
!defineConstant.System.Data.SQLite.INTEROP_LOG command.sql compile.DATA\
SQLite System.Data.SQLite}] -match regexp -result [appendArgs "^Ok\
System#CodeDom#Compiler#CompilerResults#\\d+ \\{\\} 0 \\{" [string repeat \
"SQLite message \\(0\\): TEST $id
" [expr {4 * [info processors]}]] "\\}\$"]}

###############################################################################

unset -nocomplain id

###############################################################################

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/tkt-996d13cd87.eagle.
27
28
29
30
31
32
33
34

35
36
37
38
39
40
41
27
28
29
30
31
32
33

34
35
36
37
38
39
40
41







-
+







  runTest {test [appendArgs tkt-996d13cd87-1. $i] {SQLiteConnection stress} \
      -setup {
    set fileName [appendArgs tkt-996d13cd87-1. $i .db]

    tputs $test_channel [appendArgs \
        "---- using a total of " $count " threads...\n"]

    if {[catch {
    if {![haveConstraint runtime.noPoolCounts] && [catch {
        object invoke -flags +NonPublic \
            System.Data.SQLite.SQLiteConnectionPool _poolOpened 0

        object invoke -flags +NonPublic \
            System.Data.SQLite.SQLiteConnectionPool _poolClosed 0
    }] == 0} then {
      set havePoolCounts true
Added Tests/tkt-ae5267b863.eagle.




























































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
###############################################################################
#
# tkt-ae5267b863.eagle --
#
# Written by Joe Mistachkin.
# Released to the public domain, use at your own risk!
#
###############################################################################

package require Eagle
package require Eagle.Library
package require Eagle.Test

runTestPrologue

###############################################################################

package require System.Data.SQLite.Test
runSQLiteTestPrologue

###############################################################################

#
# NOTE: For some reason, this test does not play nicely when all the managed
#       debugging assistants are enabled.
#
runTest {test tkt-ae5267b863-1.1 {segfault during command GC} -setup {
  setupDb [set fileName tkt-ae5267b863-1.1.db]
} -body {
  set id [object invoke Interpreter.GetActive NextId]
  set dataSource [file join [getDatabaseDirectory] $fileName]

  set sql(1) { \
    CREATE TABLE t1( \
      __rowid INTEGER PRIMARY KEY AUTOINCREMENT, \
      z STRING \
    ); \
  }

  set sql(2) { \
    CREATE VIRTUAL TABLE t2 USING RTREE( \
      id, minx, maxx, miny, maxy \
    ); \
  }

  set sql(3) { \
    INSERT INTO t1 VALUES({0}, \"value {0}\"); \
  }

  set sql(4) { \
    INSERT INTO t2 VALUES({0}, {0}, {0}, {0}, {0}); \
  }

  set sql(5) { \
    SELECT COUNT(*) FROM t1, t2 \
    WHERE t1.__rowid = t2.id AND \
    (t2.minx <= :xmax and t2.miny <= :ymax and \
     t2.maxx >= :xmin and t2.maxy >= :ymin); \
  }

  unset -nocomplain results errors

  set code [compileCSharpWith [subst {
    using System;
    using System.Data.SQLite;

    namespace _Dynamic${id}
    {
      public static class Test${id}
      {
        public static void Main()
        {
          using (SQLiteConnection connection = new SQLiteConnection(
              "Data Source=${dataSource};"))
          {
            connection.Open();

            using (SQLiteCommand command = connection.CreateCommand())
            {
              command.CommandText = "${sql(1)}";
              command.ExecuteNonQuery();

              command.CommandText = "${sql(2)}";
              command.ExecuteNonQuery();
            }

            using (SQLiteCommand command = connection.CreateCommand())
            {
              using (SQLiteTransaction transaction =
                  connection.BeginTransaction())
              {
                for (int index = 0; index < 10; index++)
                {
                  command.CommandText = String.Format("${sql(3)}", index);
                  command.ExecuteNonQuery();

                  command.CommandText = String.Format("${sql(4)}", index);
                  command.ExecuteNonQuery();
                }

                transaction.Commit();
              }
            }

            //
            // NOTE: Perform a huge amount of command creation and execution
            //       cycles for a better chance to trigger the bug.
            //
            for (int index = 0; index < 100000; index++)
            {
              //
              // NOTE: Purposely omit the 'using' block here to test
              //       command disposal via the garbage collector.
              //
              SQLiteCommand command = connection.CreateCommand();

              command.CommandText = "${sql(5)}";
              command.Parameters.Add(new SQLiteParameter(":xmin", 2));
              command.Parameters.Add(new SQLiteParameter(":xmax", 8));
              command.Parameters.Add(new SQLiteParameter(":ymin", 2));
              command.Parameters.Add(new SQLiteParameter(":ymax", 8));

              using (SQLiteDataReader reader = command.ExecuteReader())
              {
                while (reader.Read()) {
                  //
                  // do nothing.
                  //
                }
              }
            }

            connection.Close();
          }
        }
      }
    }
  }] true true true results errors System.Data.SQLite.dll]

  list $code $results \
      [expr {[info exists errors] ? $errors : ""}] \
      [expr {$code eq "Ok" ? [catch {
        object invoke _Dynamic${id}.Test${id} Main
      } result] : [set result ""]}] $result
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result code results errors sql dataSource id db fileName
} -constraints [fixConstraints {eagle monoBug28 command.sql compile.DATA\
SQLite System.Data.SQLite !mda}] -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}

###############################################################################

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/tkt-bb4b04d457.eagle.
16
17
18
19
20
21
22
23

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

23
24
25
26
27
28
29
30







-
+







###############################################################################

package require System.Data.SQLite.Test
runSQLiteTestPrologue

###############################################################################

runTest {test tkt-bb4b04d457-1.1 {} -setup {
runTest {test tkt-bb4b04d457-1.1 {TIMESTAMP column with Ticks} -setup {
  setupDb [set fileName tkt-bb4b04d457-1.1.db] "" Ticks Utc
} -body {
  set dateTime [object invoke -alias DateTime Parse 2011-11-29T12:34:56Z]
  set dateTime [$dateTime -alias ToUniversalTime]

  sql execute $db "CREATE TABLE t1(x TIMESTAMP NOT NULL);"

Changes to Tests/tkt-e1b2e0f769.eagle.
120
121
122
123
124
125
126

127

128
129

130
131
132
133
134
135
120
121
122
123
124
125
126
127

128


129
130
131
132
133
134
135







+
-
+
-
-
+






  set result1
} -cleanup {
  cleanupDb $fileName

  unset -nocomplain result2 result1 code results errors sql table dataSource \
      id x db fileName
} -constraints \
[fixConstraints {eagle monoBug28 command.sql compile.DATA SQLite\
{eagle monoBug28 !defineConstant.System.Data.SQLite.CHECK_STATE command.sql\
!defineConstant.System.Data.SQLite.CHECK_STATE System.Data.SQLite}] -match \
compile.DATA SQLite System.Data.SQLite} -match regexp -result {^Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 3 Ok\
regexp -result {^Ok System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 3 Ok\
System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 0$}}

###############################################################################

runSQLiteTestEpilogue
runTestEpilogue
Changes to Tests/version.eagle.
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39







-
+







#
# NOTE: For these unit tests to be useful and accurate, the following version
#       numbers must be manually kept synchronized with the version numbers for
#       the source code files, the built binaries, and the release packages.
#
set version(major)             1
set version(minor)             0
set version(build)            83; # NOTE: Incremented with each release.
set version(build)            85; # NOTE: Incremented with each release.
set version(revision)          0

###############################################################################
# ********************* END VOLATILE VERSION INFORMATION **********************
###############################################################################

#
173
174
175
176
177
178
179


180
181
182
183
184
185
186
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188







+
+







    [appendArgs <version> [string map [list . \\.] $version(full)] \
        </version>] \
    [appendArgs <version> [string map [list . \\.] $version(full)] \
        </version>] \
    [appendArgs <version> [string map [list . \\.] $version(full)] \
        </version>] \
    [appendArgs <version> [string map [list . \\.] $version(full)] \
        </version>] \
    [appendArgs <version> [string map [list . \\.] $version(full)] \
        </version>] \
    [appendArgs Version= [string map [list . \\.] $version(full)] ,] \
    [appendArgs &quot\; [format %03d $version(build)] &quot\;] \
    [appendArgs AssemblyVersion\\(\" [string map [list . \\.] \
        $version(full)] \"\\)] \
    [appendArgs AssemblyFileVersion\\(\" [string map [list . \\.] \
        $version(full)] \"\\)] \
239
240
241
242
243
244
245

246
247
248
249
250
251
252
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255







+







        $version(full)] \"\\)] \
    [appendArgs AssemblyFileVersion\\(\" [string map [list . \\.] \
        $version(full)] \"\\)]]

set fileNames [list \
    readme.htm \
    SQLite.nuspec \
    SQLite.Beta.nuspec \
    SQLite.MSIL.nuspec \
    SQLite.x64.nuspec \
    SQLite.x86.nuspec \
    [file join Doc Extra dbfactorysupport.html] \
    [file join Doc Extra welcome.html] \
    [file join Membership Properties AssemblyInfo.cs] \
    [file join Membership Properties AssemblyInfo.cs] \
Changes to exclude_bin.txt.
1
2
3
4

5
6
1
2
3
4
5
6
7




+


*.done
*.exp
*.lib
*.map
*.mda.config
*EnvDTE.*
*Microsoft.*
Changes to exclude_src.txt.
1
2
3
4

5
6

7
8
9

10
11
12
13
14
15
16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19




+


+



+







*.cache
*.chw
*.docstates
*.fossil
*.mistachkin.eagle
*.ncb
*.nupkg
*.pdb
*.suo
*.user
*.zip
.fossil-settings/*
_FOSSIL_
bin/*
Doc/Output/*
Externals/Eagle/bin/Eagle.dll
Externals/Eagle/bin/EagleShell.exe
Externals/Eagle/bin/SQLite.Interop.*
Externals/Eagle/bin/sqlite3.*
31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48
49
50
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48
49
50
51
52
53







-

+











Externals/MSVCPP/*
Externals/NDoc3/*
Membership/*
Membership/obj/*
Membership/Profile/*
Membership/SiteMap/*
obj/*
Setup/set_user_*.bat
Setup/Output/*
Setup/set_user_*.bat
SQLite.Designer/obj/*
SQLite.Designer/Properties/*
SQLite.Designer/VSDesign/*
System.Data.SQLite.Linq/obj/*
System.Data.SQLite/obj/*
System.Data.SQLite/Properties/*
test/obj/*
testce/obj/*
testlinq/obj/*
tools/install/obj/*
www/*
Changes to readme.htm.
1
2
3
4
5
6
7
8
9


10
11
12
13
14
15
16
1
2
3
4
5
6
7


8
9
10
11
12
13
14
15
16







-
-
+
+







<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
</head>
<body>
ADO.NET SQLite Data Provider<br />
Version 1.0.83.0 December XX, 2012 <font color="red">(release scheduled)</font><br />
Using <a href="http://www.sqlite.org/src/info/trunk">SQLite 3.7.15</a><br />
Version 1.0.85.0 March XX, 2013 <font color="red">(release scheduled)</font><br />
Using <a href="http://www.sqlite.org/src/info/trunk">SQLite 3.7.16</a><br />
Originally written by Robert Simpson<br />
Released to the public domain, use at your own risk!<br />
Official provider website:&nbsp;<a href="http://system.data.sqlite.org/">http://system.data.sqlite.org/</a><br />
Legacy versions:&nbsp;<a href="http://sqlite.phxsoftware.com/">http://sqlite.phxsoftware.com/</a><br />
<br />
The current development version can be downloaded from <a href="http://system.data.sqlite.org/index.html/timeline?y=ci">
http://system.data.sqlite.org/index.html/timeline?y=ci</a>
142
143
144
145
146
147
148
149

150
151
152
153
154
155
156
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156







-
+







app.config file:<br />
<pre>
&lt;configuration&gt;
    &lt;system.data&gt;
        &lt;DbProviderFactories&gt;
            &lt;remove invariant="System.Data.SQLite" /&gt;
            &lt;add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite"
                 type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.83.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" /&gt;
                 type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.85.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" /&gt;
        &lt;/DbProviderFactories&gt;
    &lt;/system.data&gt;
&lt;/configuration&gt;
</pre>
<p>
See the help documentation for further details on implementing both version-specific
(GAC enabled) and version independent DBProviderFactories support.
183
184
185
186
187
188
189


















190

191
192
193

194
195
196
197



198
199
200
201
202
203
204
205
206
207
208
209
210
211

212
213
214

215



216
217
218
219
220
221
222
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207

208
209
210

211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247







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


-
+




+
+
+













-
+



+

+
+
+







it to extend its functionality, but the core engine's source is not changed.</p>
<p>
</p>

<h2><b>Version History</b></h2>

<p>
    <b>1.0.85.0 - March XX, 2013 <font color="red">(release scheduled)</font></b>
</p>
<ul>
    <li>Updated to <a href="http://www.sqlite.org/src/info/trunk">SQLite 3.7.16</a>.</li>
    <li>Add static Execute method to the SQLiteCommand class.</li>
    <li>Add public constructor to the SQLiteDataAdapter class that allows passing the parseViaFramework parameter to the SQLiteConnection constructor.</li>
    <li>When built with the CHECK_STATE compile-time option, skip throwing exceptions from the SQLiteDataReader class when the object is being disposed.</li>
</ul>
<p>
    <b>1.0.84.0 - January 9, 2013</b>
</p>
<ul>
    <li>Updated to <a href="http://www.sqlite.org/releaselog/3_7_15_2.html">SQLite 3.7.15.2</a>.</li>
    <li>Explicitly dispose of all SQLiteCommand objects managed by the DbDataAdapter class. Fix for [6434e23a0f].</li>
    <li>Add Cancel method to the SQLiteConnection class to interrupt a long running query.</li>
    <li>Improve thread safety of the SQLiteLog.LogMessage method.</li>
</ul>
<p>
    <b>1.0.83.0 - December XX, 2012</b>
    <b>1.0.83.0 - December 29, 2012</b>
</p>
<ul>
    <li>Updated to <a href="http://www.sqlite.org/src/info/trunk">SQLite 3.7.15</a>.</li>
    <li>Updated to <a href="http://www.sqlite.org/releaselog/3_7_15_1.html">SQLite 3.7.15.1</a>.</li>
    <li>Add Visual Studio 2012 support to all the applicable solution/project files, their associated supporting files, and the test suite.</li>
    <li>Add Visual Studio 2012 support to the redesigned designer support installer.</li>
    <li>Allow opened connections to skip adding the extension functions included in the interop assembly via the new NoExtensionFunctions connection flag.</li>
    <li>Support loading of SQLite extensions via the new EnableExtensions and LoadExtension methods of the SQLiteConnection class. Pursuant to [17045010df].</li>
    <li>Remove one set of surrounding single or double quotes from property names and values parsed from the connection string. Fix for [b4cc611998].</li>
    <li>Modify parsing of connection strings to allow property names and values to be quoted.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>Add ParseViaFramework property to the SQLiteConnection class to allow the built-in (i.e. framework provided) connection string parser to be used when opening a connection. Pursuant to [b4cc611998].</li>
    <li>Add notifications before and after any connection is opened and closed, as well as other related notifications, via the new static Changed event.</li>
    <li>Add an overload of the SQLiteLog.LogMessage method that takes a single string parameter.</li>
    <li>Add an overload of the SQLiteConnection.LogMessage method that takes a SQLiteErrorCode parameter.</li>
    <li>All applicable calls into the SQLite core library now return a SQLiteErrorCode instead of an integer error code.</li>
    <li>Make sure the error code of the SQLiteException class gets serialized.</li>
    <li>Make the test project for the .NET Compact Framework more flexible.</li>
    <li>When available, the new sqlite3_errstr function from the core library is used to get the error message for a specific return code.</li>
    <li>The SetMemoryStatus, Shutdown, ResultCode, ExtendedResultCode, and SetAvRetry methods of the SQLiteConnection class now return a SQLiteErrorCode instead of an integer error code.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>The public constructor for the SQLiteException now takes a SQLiteErrorCode instead of an integer error code.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>The ErrorCode property of the SQLiteException is now an Int32, to allow the property inherited from the base class to be properly overridden.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>The ErrorCode field of the LogEventArgs is now an object instead of an integer.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>The names and messages associated with the SQLiteErrorCode enumeration values have been normalized to match those in the SQLite core library.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>Implement more robust locking semantics for the CriticalHandle derived classes when compiled for the .NET Compact Framework.</li>
    <li>Cache column indexes are they are looked up when using the SQLiteDataReader to improve performance.</li>
    <li>Cache column indexes as they are looked up when using the SQLiteDataReader to improve performance.</li>
    <li>Prevent the SQLiteConnection.Close method from throwing non-fatal exceptions during its disposal.</li>
    <li>Rename the interop assembly functions sqlite3_cursor_rowid, sqlite3_context_collcompare, sqlite3_context_collseq, sqlite3_cursor_rowid, and sqlite3_table_cursor to include an &quot;_interop&quot; suffix.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>Prevent the LastInsertRowId, MemoryUsed, and MemoryHighwater connection properties from throwing NotSupportedException when running on the .NET Compact Framework. Fix for [dd45aba387].</li>
    <li>Improve automatic detection of the sqlite3_close_v2 function when compiled to use the standard SQLite library.</li>
    <li>Add protection against ThreadAbortException asynchronously interrupting native resource initialization and finalization.</li>
    <li>Add native logging callback for use with the sqlite3_log function to the interop assembly, enabled via the INTEROP_LOG preprocessor definition.</li>
    <li>Add various diagnostic messages to the interop assembly, enabled via flags in the INTEROP_DEBUG preprocessor definition.</li>
    <li>Further enhancements to the build and test automation.</li>
    <li>Add test automation for the Windows CE binaries.</li>
</ul>
<p>
    <b>1.0.82.0 - September 3, 2012</b>
</p>
<ul>
    <li>Updated to <a href="http://www.sqlite.org/releaselog/3_7_14.html">SQLite 3.7.14</a>.</li>
Changes to test/AssemblyInfo.cs.
34
35
36
37
38
39
40
41
42


34
35
36
37
38
39
40


41
42







-
-
+
+
// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
[assembly: AssemblyVersion("1.0.83.0")]
[assembly: AssemblyFileVersion("1.0.83.0")]
[assembly: AssemblyVersion("1.0.85.0")]
[assembly: AssemblyFileVersion("1.0.85.0")]
Changes to test/TestCases.cs.
18
19
20
21
22
23
24


25
26

27
28
29
30
31
32
33
18
19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35







+
+

-
+







  internal class TestCases : TestCaseBase
  {
    private const int NumThreads = 8;
    private const int ThreadTimeout = 60000;

    private List<string> droptables = new List<string>();
    private List<string> maydroptable = new List<string>();

#if !INTEROP_LOG
    private long logevents = 0;
    
#endif

    internal TestCases()
    {
    }

    internal TestCases(DbProviderFactory factory, string connectionString)
      : base(factory, connectionString)
1359
1360
1361
1362
1363
1364
1365
1366

1367
1368
1369
1370
1371
1372
1373
1361
1362
1363
1364
1365
1366
1367

1368
1369
1370
1371
1372
1373
1374
1375







-
+







      System.Threading.WaitHandle.WaitAll(events, ThreadTimeout);

      bool failed = false;
      Exception e = null;

      for (int n = 0; n < arr.Length; n++)
      {
        if (arr[n].t.Join(0) == false)
        if (!arr[n].t.Join(ThreadTimeout / arr.Length))
        {
          failed = true;
          arr[n].t.Abort();
          arr[n].t.Join();
        }
        if (arr[n].e != null) e = arr[n].e;
        arr[n].cnn.Dispose();
1625
1626
1627
1628
1629
1630
1631

1632
1633
1634
1635
1636
1637
1638
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641







+







        SQLiteErrorCode rc = cnn.ResultCode();
        SQLiteErrorCode xrc = cnn.ExtendedResultCode();

        cnn.Close();
      }
    }

#if !INTEROP_LOG
    //Logging EventHandler
    public void OnLogEvent(object sender, LogEventArgs logEvent)
    {
        object errorCode = logEvent.ErrorCode;
        string err_msg = logEvent.Message;
        logevents++;
    }
1666
1667
1668
1669
1670
1671
1672

1673
1674
1675
1676
1677
1678
1679
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683







+







            cnn.Close();

            // remove the log handler before the connection is closed.
            sqlite_fact.Log -= logHandler;

        }
    }
#endif

    /// <summary>
    /// Open a reader and then attempt to write to test the writer's command timeout property
    /// SQLite doesn't allow a write when a reader is active.
    /// *** NOTE AS OF 3.3.8 this test no longer blocks because SQLite now allows you to update table(s)
    /// while a reader is active on the same connection.  Therefore the timeout test is invalid
    /// </summary>
Changes to test/app.config.
1
2
3
4
5

6
7
8
1
2
3
4

5
6
7
8




-
+



<configuration>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SQLite" />
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.83.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.85.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
    </DbProviderFactories>
  </system.data>
</configuration>
Changes to test/test.2005.csproj.
78
79
80
81
82
83
84

85
86
87
88
89
90
91
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92







+







    <EmbeddedResource Include="TestCasesDialog.resx">
      <DependentUpon>TestCasesDialog.cs</DependentUpon>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <None Include="app.config" />
  </ItemGroup>
  <Import Project="$(SQLiteNetDir)\System.Data.SQLite\System.Data.SQLite.Properties.targets" />
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
Changes to test/test.2008.csproj.
79
80
81
82
83
84
85

86
87
88
89
90
91
92
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93







+







    <EmbeddedResource Include="TestCasesDialog.resx">
      <DependentUpon>TestCasesDialog.cs</DependentUpon>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <None Include="app.config" />
  </ItemGroup>
  <Import Project="$(SQLiteNetDir)\System.Data.SQLite\System.Data.SQLite.Properties.targets" />
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
Changes to test/test.2010.csproj.
80
81
82
83
84
85
86

87
88
89
90
91
92
93
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94







+







    <EmbeddedResource Include="TestCasesDialog.resx">
      <DependentUpon>TestCasesDialog.cs</DependentUpon>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <None Include="app.config" />
  </ItemGroup>
  <Import Project="$(SQLiteNetDir)\System.Data.SQLite\System.Data.SQLite.Properties.targets" />
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
Changes to test/test.2012.csproj.
79
80
81
82
83
84
85

86
87
88
89
90
91
92
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93







+







    <EmbeddedResource Include="TestCasesDialog.resx">
      <DependentUpon>TestCasesDialog.cs</DependentUpon>
    </EmbeddedResource>
  </ItemGroup>
  <ItemGroup>
    <None Include="app.config" />
  </ItemGroup>
  <Import Project="$(SQLiteNetDir)\System.Data.SQLite\System.Data.SQLite.Properties.targets" />
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
Changes to testce/AssemblyInfo.cs.
34
35
36
37
38
39
40
41
42


43
34
35
36
37
38
39
40


41
42
43







-
-
+
+

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
[assembly: AssemblyVersion("1.0.83.0")]
// [assembly: AssemblyFileVersion("1.0.83.0")]
[assembly: AssemblyVersion("1.0.85.0")]
// [assembly: AssemblyFileVersion("1.0.85.0")]

Changes to testlinq/2008/App.config.
1
2
3
4
5
6

7
8
9
10
11
12
1
2
3
4
5

6
7
8
9
10
11
12





-
+






<?xml version="1.0"?>
<configuration>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SQLite" />
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.83.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.85.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
    </DbProviderFactories>
  </system.data>
  <connectionStrings>
    <add name="northwindEFEntities" connectionString="metadata=res://*/NorthwindModel2008.csdl|res://*/NorthwindModel2008.ssdl|res://*/NorthwindModel2008.msl;provider=System.Data.SQLite;provider connection string=&quot;data source=.\northwindEF.db&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>
</configuration>
Changes to testlinq/2010/App.config.
1
2
3
4
5
6

7
8
9
10
11
12
1
2
3
4
5

6
7
8
9
10
11
12





-
+






<?xml version="1.0"?>
<configuration>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SQLite" />
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.83.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.85.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
    </DbProviderFactories>
  </system.data>
  <connectionStrings>
    <add name="northwindEFEntities" connectionString="metadata=res://*/NorthwindModel2010.csdl|res://*/NorthwindModel2010.ssdl|res://*/NorthwindModel2010.msl;provider=System.Data.SQLite;provider connection string=&quot;data source=.\northwindEF.db&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>
</configuration>
Changes to testlinq/2012/App.config.
1
2
3
4
5
6

7
8
9
10
11
12
1
2
3
4
5

6
7
8
9
10
11
12





-
+






<?xml version="1.0"?>
<configuration>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SQLite" />
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.83.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite, Version=1.0.85.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" />
    </DbProviderFactories>
  </system.data>
  <connectionStrings>
    <add name="northwindEFEntities" connectionString="metadata=res://*/NorthwindModel2012.csdl|res://*/NorthwindModel2012.ssdl|res://*/NorthwindModel2012.msl;provider=System.Data.SQLite;provider connection string=&quot;data source=.\northwindEF.db&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>
</configuration>
Changes to testlinq/Program.cs.
322
323
324
325
326
327
328
329

330
331
332
333
334
335
336
322
323
324
325
326
327
328

329
330
331
332
333
334
335
336







-
+







      }

    private static int OldTests()
    {
      using (northwindEFEntities db = new northwindEFEntities())
      {
        {
          string entitySQL = "SELECT VALUE o FROM Orders AS o WHERE SQLite.DatePart('yyyy', o.OrderDate) = 1997;";
          string entitySQL = "SELECT VALUE o FROM Orders AS o WHERE SQLite.DatePart('yyyy', o.OrderDate) = 1997 ORDER BY o.OrderID;";
          ObjectQuery<Orders> query = db.CreateQuery<Orders>(entitySQL);

          foreach (Orders o in query)
          {
            Console.WriteLine(o.ShipPostalCode);
          }
        }
355
356
357
358
359
360
361

362
363
364
365
366
367
368
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369







+







          Console.WriteLine(c.CompanyName);
        }

        {
          DateTime dt = new DateTime(1997, 1, 1);
          var query = from order in db.Orders
                      where order.OrderDate < dt
                      orderby order.OrderID
                      select order;

          foreach (Orders o in query)
          {
            Console.WriteLine(o.OrderDate.ToString());
          }
        }
396
397
398
399
400
401
402
403


404
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
443
444
445

446
447
448
449
450
451
452
397
398
399
400
401
402
403

404
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
443
444
445
446
447
448
449
450
451
452
453
454
455
456







-
+
+










+









-
+









-
+












+








          db.DeleteObject(cust);
          db.SaveChanges();
        }

        {
          var query = db.Customers.Where(cust => cust.Country == "Denmark")
                          .SelectMany(cust => cust.Orders.Where(o => o.Freight > 5));
                          .SelectMany(cust => cust.Orders.Where(o => o.Freight > 5))
                          .OrderBy(o => o.Customers.CustomerID);

          foreach (Orders c in query)
          {
            Console.WriteLine(c.Freight);
          }
        }

        {
          var query = from c in db.Customers
                      where c.Orders.Any(o => o.OrderDate.HasValue == true && o.OrderDate.Value.Year == 1997)
                      orderby c.CustomerID
                      select c;

          foreach (Customers c in query)
          {
            Console.WriteLine(c.CompanyName);
          }
        }

        {
          string entitySQL = "SELECT VALUE o FROM Orders AS o WHERE o.Customers.Country <> 'UK' AND o.Customers.Country <> 'Mexico' AND Year(o.OrderDate) = 1997;";
          string entitySQL = "SELECT VALUE o FROM Orders AS o WHERE o.Customers.Country <> 'UK' AND o.Customers.Country <> 'Mexico' AND Year(o.OrderDate) = 1997 ORDER BY o.OrderID;";
          ObjectQuery<Orders> query = db.CreateQuery<Orders>(entitySQL);

          foreach (Orders o in query)
          {
            Console.WriteLine(o.ShipPostalCode);
          }
        }

        {
          string entitySQL = "SELECT VALUE o FROM Orders AS o WHERE NewGuid() <> NewGuid();";
          string entitySQL = "SELECT VALUE o FROM Orders AS o WHERE NewGuid() <> NewGuid() ORDER BY o.OrderID;";
          ObjectQuery<Orders> query = db.CreateQuery<Orders>(entitySQL);

          foreach (Orders o in query)
          {
            Console.WriteLine(o.ShipPostalCode);
          }
        }

        // This query requires SQLite 3.6.2 to function correctly
        {
          var query = from p in db.Products
                      where p.OrderDetails.Count(od => od.Orders.Customers.Country == p.Suppliers.Country) > 2
                      orderby p.ProductID
                      select p;

          foreach (Products p in query)
          {
            Console.WriteLine(p.ProductName);
          }
        }
Changes to testlinq/Properties/AssemblyInfo.cs.
37
38
39
40
41
42
43
44
45


37
38
39
40
41
42
43


44
45







-
-
+
+
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.83.0")]
[assembly: AssemblyFileVersion("1.0.83.0")]
[assembly: AssemblyVersion("1.0.85.0")]
[assembly: AssemblyFileVersion("1.0.85.0")]
Changes to tools/install/Installer.cs.
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
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
87
88
89







+
















+















+







        string fileName,           /* in */
        string invariant,          /* in */
        string name,               /* in */
        string description,        /* in */
        string typeName,           /* in */
        AssemblyName assemblyName, /* in */
        object clientData,         /* in */
        bool perUser,              /* in */
        bool wow64,                /* in */
        bool throwOnMissing,       /* in */
        bool whatIf,               /* in */
        bool verbose,              /* in */
        ref bool saved,            /* out */
        ref string error           /* out */
    );

    ///////////////////////////////////////////////////////////////////////////

    internal delegate bool FrameworkRegistryCallback(
        Installer.MockRegistryKey rootKey, /* in */
        string frameworkName,              /* in */
        Version frameworkVersion,          /* in */
        string platformName,               /* in */
        object clientData,                 /* in */
        bool perUser,                      /* in */
        bool wow64,                        /* in */
        bool throwOnMissing,               /* in */
        bool whatIf,                       /* in */
        bool verbose,                      /* in */
        ref string error                   /* out */
    );

    ///////////////////////////////////////////////////////////////////////////

    internal delegate bool VisualStudioRegistryCallback(
        Installer.MockRegistryKey rootKey, /* in */
        Version vsVersion,                 /* in */
        string suffix,                     /* in, optional */
        Installer.Package package,         /* in */
        object clientData,                 /* in */
        bool perUser,                      /* in */
        bool wow64,                        /* in */
        bool throwOnMissing,               /* in */
        bool whatIf,                       /* in */
        bool verbose,                      /* in */
        ref string error                   /* out */
    );
    #endregion
3945
3946
3947
3948
3949
3950
3951

3952
3953
3954






3955
3956

3957
3958
3959
3960
3961
3962
3963
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965

3966
3967
3968
3969
3970
3971
3972
3973







+



+
+
+
+
+
+

-
+







            return Object.ReferenceEquals(rootKey, registry.CurrentUser) ||
                Object.ReferenceEquals(rootKey, registry.LocalMachine);
        }

        ///////////////////////////////////////////////////////////////////////

        private static string GetRootKeyName(
            bool perUser,
            bool wow64
            )
        {
            //
            // BUGFIX: Apparently, the per-user registry hive does not use
            //         the "Wow6432Node" node to store settings for 32-bit
            //         applications running on a 64-bit operating system.
            //         Ticket [a0677309f0] has further details.
            //
            return String.Format("{0}{1}", RootKeyName,
                wow64 && Is64BitProcess() ?
                !perUser && wow64 && Is64BitProcess() ?
                    "\\" + Wow64SubKeyName : String.Empty);
        }

        ///////////////////////////////////////////////////////////////////////

        private static string GetSystemDirectory(
            bool wow64
4089
4090
4091
4092
4093
4094
4095

4096
4097
4098
4099
4100

4101
4102
4103
4104
4105
4106
4107
4108

4109
4110
4111
4112
4113
4114
4115
4116

4117
4118
4119
4120
4121
4122
4123
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110

4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127

4128
4129
4130
4131
4132
4133
4134
4135







+




-
+








+







-
+







        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region .NET Framework Handling
        private static string GetFrameworkRootKeyName(
            bool perUser,
            bool wow64
            )
        {
            return String.Format("{0}\\Microsoft\\.NETFramework",
                GetRootKeyName(wow64));
                GetRootKeyName(perUser, wow64));
        }

        ///////////////////////////////////////////////////////////////////////

        private static string GetFrameworkKeyName(
            string frameworkName,
            Version frameworkVersion,
            string platformName,
            bool perUser,
            bool wow64
            )
        {
            string format = !String.IsNullOrEmpty(platformName) ?
                "{0}\\Microsoft\\{1}\\v{2}\\{3}" :
                "{0}\\Microsoft\\{1}\\v{2}";

            return String.Format(format, GetRootKeyName(wow64),
            return String.Format(format, GetRootKeyName(perUser, wow64),
                frameworkName, frameworkVersion, platformName);
        }

        ///////////////////////////////////////////////////////////////////////

        private static string GetImageRuntimeVersion(
            string fileName
4140
4141
4142
4143
4144
4145
4146

4147
4148
4149
4150
4151
4152
4153
4154


4155
4156
4157
4158
4159
4160
4161
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165


4166
4167
4168
4169
4170
4171
4172
4173
4174







+






-
-
+
+







        }

        ///////////////////////////////////////////////////////////////////////

        private static string GetFrameworkDirectory(
            MockRegistryKey rootKey,
            Version frameworkVersion,
            bool perUser,
            bool wow64,
            bool whatIf,
            bool verbose
            )
        {
            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, GetFrameworkRootKeyName(wow64), false,
                    whatIf, verbose))
                    rootKey, GetFrameworkRootKeyName(perUser, wow64),
                    false, whatIf, verbose))
            {
                if (key == null)
                    return null;

                object value = RegistryHelper.GetValue(
                    key, "InstallRoot", null, whatIf, verbose);

4253
4254
4255
4256
4257
4258
4259

4260
4261
4262
4263
4264
4265
4266


4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278


4279
4280
4281
4282
4283
4284
4285
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279

4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292

4293
4294
4295
4296
4297
4298
4299
4300
4301







+






-
+
+











-
+
+







        ///////////////////////////////////////////////////////////////////////

        private static bool HaveFrameworkDirectory(
            MockRegistryKey rootKey,
            string frameworkName,
            Version frameworkVersion,
            string platformName,
            bool perUser,
            bool wow64,
            bool whatIf,
            bool verbose
            )
        {
            string keyName = GetFrameworkKeyName(
                frameworkName, frameworkVersion, platformName, wow64);
                frameworkName, frameworkVersion, platformName, perUser,
                wow64);

            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                    return false;

                if (platformName != null) // NOTE: Skip non-desktop.
                    return true;

                string directory = GetFrameworkDirectory(
                    rootKey, frameworkVersion, wow64, whatIf, verbose);
                    rootKey, frameworkVersion, perUser, wow64, whatIf,
                    verbose);

                if (String.IsNullOrEmpty(directory))
                    return false;

                if (!Directory.Exists(directory))
                    return false;

4296
4297
4298
4299
4300
4301
4302

4303
4304
4305
4306
4307
4308
4309


4310
4311
4312
4313
4314
4315
4316
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325

4326
4327
4328
4329
4330
4331
4332
4333
4334







+






-
+
+







        ///////////////////////////////////////////////////////////////////////

        private static bool HaveFrameworkRegistry(
            MockRegistryKey rootKey,
            string frameworkName,
            Version frameworkVersion,
            string platformName,
            bool perUser,
            bool wow64,
            bool whatIf,
            bool verbose
            )
        {
            string keyName = GetFrameworkKeyName(
                frameworkName, frameworkVersion, platformName, wow64);
                frameworkName, frameworkVersion, platformName, perUser,
                wow64);

            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                    return false;

4337
4338
4339
4340
4341
4342
4343

4344
4345
4346
4347
4348
4349
4350
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369







+







            string version, /* NOTE: Optional. */
            string invariant,
            string name,
            string description,
            string typeName,
            AssemblyName assemblyName,
            object clientData,
            bool perUser,
            bool wow64,
            bool throwOnMissing,
            bool whatIf,
            bool verbose,
            ref bool saved,
            ref string error
            )
4450
4451
4452
4453
4454
4455
4456
4457

4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471


4472
4473
4474
4475
4476
4477
4478
4469
4470
4471
4472
4473
4474
4475

4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489

4490
4491
4492
4493
4494
4495
4496
4497
4498







-
+













-
+
+







                        "frameworkName = {0}, frameworkVersion = {1}, " +
                        "platformName = {2}", ForDisplay(frameworkName),
                        ForDisplay(frameworkVersion),
                        ForDisplay(platformName)), traceCategory);

                    if (!HaveFrameworkDirectory(
                            rootKey, frameworkName, frameworkVersion,
                            platformName, wow64, whatIf, verbose))
                            platformName, perUser, wow64, whatIf, verbose))
                    {
                        TraceOps.DebugAndTrace(TracePriority.Low,
                            debugCallback, traceCallback,
                            ".NET Framework directory not found, skipping...",
                            traceCategory);

                        continue;
                    }

                    if (callback == null)
                        continue;

                    string directory = GetFrameworkDirectory(
                        rootKey, frameworkVersion, wow64, whatIf, verbose);
                        rootKey, frameworkVersion, perUser, wow64, whatIf,
                        verbose);

                    if (String.IsNullOrEmpty(directory))
                    {
                        TraceOps.DebugAndTrace(TracePriority.Low,
                            debugCallback, traceCallback, String.Format(
                            ".NET Framework {0} directory is invalid, " +
                            "skipping...", ForDisplay(frameworkVersion)),
4507
4508
4509
4510
4511
4512
4513
4514
4515



4516
4517
4518
4519
4520
4521
4522
4527
4528
4529
4530
4531
4532
4533


4534
4535
4536
4537
4538
4539
4540
4541
4542
4543







-
-
+
+
+







                        continue;
                    }

                    bool localSaved = false;

                    if (!callback(
                            fileName, invariant, name, description, typeName,
                            assemblyName, clientData, wow64, throwOnMissing,
                            whatIf, verbose, ref localSaved, ref error))
                            assemblyName, clientData, perUser, wow64,
                            throwOnMissing, whatIf, verbose, ref localSaved,
                            ref error))
                    {
                        return false;
                    }
                    else
                    {
                        if (localSaved && !saved)
                            saved = true;
4539
4540
4541
4542
4543
4544
4545

4546
4547
4548
4549
4550
4551
4552
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574







+







        [MethodImpl(MethodImplOptions.NoInlining)]
        private static bool ForEachFrameworkRegistry(
            MockRegistry registry,
            FrameworkList frameworkList,
            FrameworkRegistryCallback callback,
            string version, /* NOTE: Optional. */
            object clientData,
            bool perUser,
            bool wow64,
            bool throwOnMissing,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
4644
4645
4646
4647
4648
4649
4650
4651

4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667


4668
4669
4670
4671
4672
4673
4674
4666
4667
4668
4669
4670
4671
4672

4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687


4688
4689
4690
4691
4692
4693
4694
4695
4696







-
+














-
-
+
+







                        "frameworkName = {0}, frameworkVersion = {1}, " +
                        "platformName = {2}", ForDisplay(frameworkName),
                        ForDisplay(frameworkVersion),
                        ForDisplay(platformName)), traceCategory);

                    if (!HaveFrameworkRegistry(
                            rootKey, frameworkName, frameworkVersion,
                            platformName, wow64, whatIf, verbose))
                            platformName, perUser, wow64, whatIf, verbose))
                    {
                        TraceOps.DebugAndTrace(TracePriority.Low,
                            debugCallback, traceCallback,
                            ".NET Framework registry not found, skipping...",
                            traceCategory);

                        continue;
                    }

                    if (callback == null)
                        continue;

                    if (!callback(
                            rootKey, frameworkName, frameworkVersion,
                            platformName, clientData, wow64, throwOnMissing,
                            whatIf, verbose, ref error))
                            platformName, clientData, perUser, wow64,
                            throwOnMissing, whatIf, verbose, ref error))
                    {
                        return false;
                    }
                }
            }

            return true;
4710
4711
4712
4713
4714
4715
4716

4717
4718
4719
4720
4721
4722
4723
4724
4725

4726
4727
4728
4729
4730
4731
4732
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747

4748
4749
4750
4751
4752
4753
4754
4755







+








-
+








        ///////////////////////////////////////////////////////////////////////

        private static bool HaveVsVersion(
            MockRegistryKey rootKey,
            Version vsVersion,
            string suffix,
            bool perUser,
            bool wow64,
            bool whatIf,
            bool verbose
            )
        {
            if (vsVersion == null)
                return false;

            string keyName = GetVsKeyName(vsVersion, suffix, wow64);
            string keyName = GetVsKeyName(vsVersion, suffix, perUser, wow64);

            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                    return false;

4760
4761
4762
4763
4764
4765
4766

4767
4768
4769
4770
4771
4772
4773
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797







+







        private static bool ForEachVsVersionRegistry(
            MockRegistry registry,
            VsList vsList,
            VisualStudioRegistryCallback callback,
            string suffix,
            Package package,
            object clientData,
            bool perUser,
            bool wow64,
            bool throwOnMissing,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
4807
4808
4809
4810
4811
4812
4813
4814


4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829


4830
4831
4832
4833
4834
4835
4836
4831
4832
4833
4834
4835
4836
4837

4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853

4854
4855
4856
4857
4858
4859
4860
4861
4862







-
+
+














-
+
+







            {
                TraceOps.DebugAndTrace(TracePriority.Lower,
                    debugCallback, traceCallback, String.Format(
                    "vsVersion = {0}", ForDisplay(vsVersion)),
                    traceCategory);

                if (!HaveVsVersion(
                        rootKey, vsVersion, suffix, wow64, whatIf, verbose))
                        rootKey, vsVersion, suffix, perUser, wow64, whatIf,
                        verbose))
                {
                    TraceOps.DebugAndTrace(TracePriority.Low,
                        debugCallback, traceCallback,
                        "Visual Studio version not found, skipping...",
                        traceCategory);

                    continue;
                }

                if (callback == null)
                    continue;

                if (!callback(
                        rootKey, vsVersion, suffix, package, clientData,
                        wow64, throwOnMissing, whatIf, verbose, ref error))
                        perUser, wow64, throwOnMissing, whatIf, verbose,
                        ref error))
                {
                    return false;
                }
            }

            return true;
        }
5007
5008
5009
5010
5011
5012
5013

5014
5015
5016
5017
5018
5019
5020
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047







+







            string fileName,
            string invariant,
            string name,
            string description,
            string typeName,
            AssemblyName assemblyName,
            object clientData,
            bool perUser,
            bool wow64,
            bool throwOnMissing,
            bool whatIf,
            bool verbose,
            ref bool saved,
            ref string error
            )
5048
5049
5050
5051
5052
5053
5054

5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067

5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079

5080
5081
5082
5083
5084
5085
5086
5087


5088
5089
5090
5091
5092
5093
5094
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094

5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115

5116
5117
5118
5119
5120
5121
5122
5123
5124







+












-
+












+







-
+
+







        ///////////////////////////////////////////////////////////////////////

        #region Assembly Folders Handling
        private static string GetAssemblyFoldersKeyName(
            string frameworkName,
            Version frameworkVersion,
            string platformName,
            bool perUser,
            bool wow64
            )
        {
            //
            // NOTE: This registry key appears to always be 32-bit only
            //       (i.e. probably because it is only used by Visual
            //       Studio, which is currently always 32-bit only).
            //
            string format = !String.IsNullOrEmpty(platformName) ?
                "{0}\\Microsoft\\{1}\\v{2}\\{3}\\AssemblyFoldersEx" :
                "{0}\\Microsoft\\{1}\\v{2}\\AssemblyFoldersEx";

            return String.Format(format, GetRootKeyName(wow64),
            return String.Format(format, GetRootKeyName(perUser, wow64),
                frameworkName, frameworkVersion, platformName);
        }

        ///////////////////////////////////////////////////////////////////////

        private static bool AddToAssemblyFolders(
            MockRegistryKey rootKey,
            string frameworkName,
            Version frameworkVersion,
            string platformName,
            string subKeyName,
            string directory,
            bool perUser,
            bool wow64,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            string keyName = GetAssemblyFoldersKeyName(
                frameworkName, frameworkVersion, platformName, wow64);
                frameworkName, frameworkVersion, platformName, perUser,
                wow64);

            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, true, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
5122
5123
5124
5125
5126
5127
5128

5129
5130
5131
5132
5133
5134
5135
5136
5137


5138
5139
5140
5141
5142
5143
5144
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167

5168
5169
5170
5171
5172
5173
5174
5175
5176







+








-
+
+








        private static bool RemoveFromAssemblyFolders(
            MockRegistryKey rootKey,
            string frameworkName,
            Version frameworkVersion,
            string platformName,
            string subKeyName,
            bool perUser,
            bool wow64,
            bool throwOnMissing,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            string keyName = GetAssemblyFoldersKeyName(
                frameworkName, frameworkVersion, platformName, wow64);
                frameworkName, frameworkVersion, platformName, perUser,
                wow64);

            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, true, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
5159
5160
5161
5162
5163
5164
5165

5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185

5186
5187
5188
5189


5190
5191
5192
5193
5194
5195
5196


5197
5198
5199
5200
5201
5202
5203
5204

5205
5206
5207
5208
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
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253

5254
5255
5256
5257
5258
5259
5260
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
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
5236
5237
5238
5239
5240
5241
5242
5243

5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259

5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290

5291
5292
5293
5294
5295
5296
5297
5298







+



















-
+



-
+
+





-
-
+
+








+




-
+







+







-
+
+










+


















-
+








        private static bool ProcessAssemblyFolders(
            MockRegistryKey rootKey,
            string frameworkName,
            Version frameworkVersion,
            string platformName,
            object clientData,
            bool perUser,
            bool wow64,
            bool throwOnMissing,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            AnyPair<string, bool> pair = clientData as AnyPair<string, bool>;

            if (pair == null)
            {
                error = "invalid framework callback data";
                return false;
            }

            if (pair.Y)
            {
                return RemoveFromAssemblyFolders(
                    rootKey, frameworkName, frameworkVersion, platformName,
                    LegacyProjectName, wow64, false, whatIf, verbose,
                    LegacyProjectName, perUser, wow64, false, whatIf, verbose,
                    ref error) &&
                AddToAssemblyFolders(
                    rootKey, frameworkName, frameworkVersion, platformName,
                    ProjectName, pair.X, wow64, whatIf, verbose, ref error);
                    ProjectName, pair.X, perUser, wow64, whatIf, verbose,
                    ref error);
            }
            else
            {
                return RemoveFromAssemblyFolders(
                    rootKey, frameworkName, frameworkVersion, platformName,
                    ProjectName, wow64, throwOnMissing, whatIf, verbose,
                    ref error);
                    ProjectName, perUser, wow64, throwOnMissing, whatIf,
                    verbose, ref error);
            }
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Visual Studio Handling
        private static string GetVsRootKeyName(
            bool perUser,
            bool wow64
            )
        {
            return String.Format("{0}\\Microsoft\\VisualStudio",
                GetRootKeyName(wow64));
                GetRootKeyName(perUser, wow64));
        }

        ///////////////////////////////////////////////////////////////////////

        private static string GetVsKeyName(
            Version vsVersion,
            string suffix,
            bool perUser,
            bool wow64
            )
        {
            if (vsVersion == null)
                return null;

            return String.Format(
                "{0}\\{1}{2}", GetVsRootKeyName(wow64), vsVersion, suffix);
                "{0}\\{1}{2}", GetVsRootKeyName(perUser, wow64), vsVersion,
                suffix);
        }

        ///////////////////////////////////////////////////////////////////////

        #region Visual Studio Data Source Handling
        private static bool AddVsDataSource(
            MockRegistryKey rootKey,
            Version vsVersion,
            string suffix,
            Package package,
            bool perUser,
            bool wow64,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            if (vsVersion == null)
            {
                error = "invalid VS version";
                return false;
            }

            if (package == null)
            {
                error = "invalid VS package";
                return false;
            }

            string keyName = GetVsKeyName(vsVersion, suffix, wow64);
            string keyName = GetVsKeyName(vsVersion, suffix, perUser, wow64);

            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
5317
5318
5319
5320
5321
5322
5323

5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342

5343
5344
5345
5346
5347
5348
5349
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380

5381
5382
5383
5384
5385
5386
5387
5388







+


















-
+







        ///////////////////////////////////////////////////////////////////////

        private static bool RemoveVsDataSource(
            MockRegistryKey rootKey,
            Version vsVersion,
            string suffix,
            Package package,
            bool perUser,
            bool wow64,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            if (vsVersion == null)
            {
                error = "invalid VS version";
                return false;
            }

            if (package == null)
            {
                error = "invalid VS package";
                return false;
            }

            string keyName = GetVsKeyName(vsVersion, suffix, wow64);
            string keyName = GetVsKeyName(vsVersion, suffix, perUser, wow64);

            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
5378
5379
5380
5381
5382
5383
5384

5385
5386
5387
5388
5389
5390
5391
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431







+








        private static bool ProcessVsDataSource(
            MockRegistryKey rootKey,
            Version vsVersion,
            string suffix,
            Package package,
            object clientData,
            bool perUser,
            bool wow64,
            bool throwOnMissing,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
5402
5403
5404
5405
5406
5407
5408
5409
5410


5411
5412
5413
5414
5415
5416


5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429

5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448

5449
5450
5451
5452
5453
5454
5455
5442
5443
5444
5445
5446
5447
5448


5449
5450
5451
5452
5453
5454


5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488

5489
5490
5491
5492
5493
5494
5495
5496







-
-
+
+




-
-
+
+













+


















-
+







                error = "invalid VS callback data";
                return false;
            }

            if (pair.Y)
            {
                return AddVsDataSource(
                    rootKey, vsVersion, suffix, package, wow64, whatIf,
                    verbose, ref error);
                    rootKey, vsVersion, suffix, package, perUser, wow64,
                    whatIf, verbose, ref error);
            }
            else
            {
                return RemoveVsDataSource(
                    rootKey, vsVersion, suffix, package, wow64, whatIf,
                    verbose, ref error);
                    rootKey, vsVersion, suffix, package, perUser, wow64,
                    whatIf, verbose, ref error);
            }
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Visual Studio Data Provider Handling
        private static bool AddVsDataProvider(
            MockRegistryKey rootKey,
            Version vsVersion,
            string suffix,
            Package package,
            string fileName,
            bool perUser,
            bool wow64,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            if (vsVersion == null)
            {
                error = "invalid VS version";
                return false;
            }

            if (package == null)
            {
                error = "invalid VS package";
                return false;
            }

            string keyName = GetVsKeyName(vsVersion, suffix, wow64);
            string keyName = GetVsKeyName(vsVersion, suffix, perUser, wow64);

            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
5558
5559
5560
5561
5562
5563
5564

5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577

5578
5579
5580
5581
5582
5583
5584
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618

5619
5620
5621
5622
5623
5624
5625
5626







+












-
+







        ///////////////////////////////////////////////////////////////////////

        private static bool RemoveVsDataProvider(
            MockRegistryKey rootKey,
            Version vsVersion,
            string suffix,
            Package package,
            bool perUser,
            bool wow64,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            if (vsVersion == null)
            {
                error = "invalid VS version";
                return false;
            }

            string keyName = GetVsKeyName(vsVersion, suffix, wow64);
            string keyName = GetVsKeyName(vsVersion, suffix, perUser, wow64);

            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
5613
5614
5615
5616
5617
5618
5619

5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639


5640
5641
5642
5643
5644
5645


5646
5647
5648
5649
5650
5651
5652
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680


5681
5682
5683
5684
5685
5686


5687
5688
5689
5690
5691
5692
5693
5694
5695







+


















-
-
+
+




-
-
+
+








        private static bool ProcessVsDataProvider(
            MockRegistryKey rootKey,
            Version vsVersion,
            string suffix,
            Package package,
            object clientData,
            bool perUser,
            bool wow64,
            bool throwOnMissing,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            AnyPair<string, bool> pair = clientData as AnyPair<string, bool>;

            if (pair == null)
            {
                error = "invalid VS callback data";
                return false;
            }

            if (pair.Y)
            {
                return AddVsDataProvider(
                    rootKey, vsVersion, suffix, package, pair.X, wow64,
                    whatIf, verbose, ref error);
                    rootKey, vsVersion, suffix, package, pair.X, perUser,
                    wow64, whatIf, verbose, ref error);
            }
            else
            {
                return RemoveVsDataProvider(
                    rootKey, vsVersion, suffix, package, wow64, whatIf,
                    verbose, ref error);
                    rootKey, vsVersion, suffix, package, perUser, wow64,
                    whatIf, verbose, ref error);
            }
        }
        #endregion

        ///////////////////////////////////////////////////////////////////////

        #region Visual Studio Package Handling
5684
5685
5686
5687
5688
5689
5690

5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709

5710
5711
5712
5713
5714
5715
5716
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752

5753
5754
5755
5756
5757
5758
5759
5760







+


















-
+








        private static bool AddVsPackage(
            MockRegistryKey rootKey,
            Version vsVersion,
            string suffix,
            Package package,
            string fileName,
            bool perUser,
            bool wow64,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            if (vsVersion == null)
            {
                error = "invalid VS version";
                return false;
            }

            if (package == null)
            {
                error = "invalid VS package";
                return false;
            }

            string keyName = GetVsKeyName(vsVersion, suffix, wow64);
            string keyName = GetVsKeyName(vsVersion, suffix, perUser, wow64);

            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
5880
5881
5882
5883
5884
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
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







+



















-
+







        ///////////////////////////////////////////////////////////////////////

        private static bool RemoveVsPackage(
            MockRegistryKey rootKey,
            Version vsVersion,
            string suffix,
            Package package,
            bool perUser,
            bool wow64,
            bool throwOnMissing,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            if (vsVersion == null)
            {
                error = "invalid VS version";
                return false;
            }

            if (package == null)
            {
                error = "invalid VS package";
                return false;
            }

            string keyName = GetVsKeyName(vsVersion, suffix, wow64);
            string keyName = GetVsKeyName(vsVersion, suffix, perUser, wow64);

            using (MockRegistryKey key = RegistryHelper.OpenSubKey(
                    rootKey, keyName, false, whatIf, verbose))
            {
                if (key == null)
                {
                    error = String.Format(
5976
5977
5978
5979
5980
5981
5982

5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002


6003
6004
6005
6006
6007

6008
6009
6010
6011
6012
6013
6014
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046


6047
6048
6049
6050
6051
6052

6053
6054
6055
6056
6057
6058
6059
6060







+


















-
-
+
+




-
+








        private static bool ProcessVsPackage(
            MockRegistryKey rootKey,
            Version vsVersion,
            string suffix,
            Package package,
            object clientData,
            bool perUser,
            bool wow64,
            bool throwOnMissing,
            bool whatIf,
            bool verbose,
            ref string error
            )
        {
            AnyPair<string, bool> pair = clientData as AnyPair<string, bool>;

            if (pair == null)
            {
                error = "invalid VS callback data";
                return false;
            }

            if (pair.Y)
            {
                return AddVsPackage(
                    rootKey, vsVersion, suffix, package, pair.X, wow64,
                    whatIf, verbose, ref error);
                    rootKey, vsVersion, suffix, package, pair.X, perUser,
                    wow64, whatIf, verbose, ref error);
            }
            else
            {
                return RemoveVsPackage(
                    rootKey, vsVersion, suffix, package, wow64,
                    rootKey, vsVersion, suffix, package, perUser, wow64,
                    throwOnMissing, whatIf, verbose, ref error);
            }
        }
        #endregion
        #endregion

        ///////////////////////////////////////////////////////////////////////
6130
6131
6132
6133
6134
6135
6136
6137


6138
6139
6140
6141
6142
6143
6144
6176
6177
6178
6179
6180
6181
6182

6183
6184
6185
6186
6187
6188
6189
6190
6191







-
+
+







                            InstallFlags.GlobalAssemblyCache, true) &&
                        configuration.HasFlags(
                            InstallFlags.VsPackageGlobalAssemblyCache, true),
                        ref package);

                    ///////////////////////////////////////////////////////////

                    InitializeFrameworkList(registry.LocalMachine,
                    InitializeFrameworkList(configuration.PerUser ?
                        registry.CurrentUser : registry.LocalMachine,
                        configuration, ref frameworkList);

                    InitializeVsList(configuration.PerUser ?
                        registry.CurrentUser : registry.LocalMachine,
                        configuration, ref vsList);
                    #endregion

6249
6250
6251
6252
6253
6254
6255

6256
6257
6258
6259
6260
6261
6262
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310







+







                    #region .NET AssemblyFolders
                    if (configuration.HasFlags(
                            InstallFlags.AssemblyFolders, true))
                    {
                        if (!ForEachFrameworkRegistry(registry,
                                frameworkList, ProcessAssemblyFolders,
                                configuration.RegistryVersion, directoryData,
                                configuration.PerUser,
                                NetFxIs32BitOnly || configuration.Wow64,
                                configuration.ThrowOnMissing,
                                configuration.WhatIf, configuration.Verbose,
                                ref error))
                        {
                            TraceOps.ShowMessage(TracePriority.Highest,
                                debugCallback, traceCallback, thisAssembly,
6281
6282
6283
6284
6285
6286
6287

6288
6289
6290
6291
6292
6293
6294
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343







+







                        bool saved = false;

                        if (!ForEachFrameworkConfig(registry,
                                frameworkList, ProcessDbProviderFactory,
                                configuration.ConfigVersion, InvariantName,
                                ProviderName, Description, FactoryTypeName,
                                coreAssemblyName, directoryData,
                                configuration.PerUser,
                                NetFxIs32BitOnly || configuration.Wow64,
                                configuration.ThrowOnMissing,
                                configuration.WhatIf, configuration.Verbose,
                                ref saved, ref error))
                        {
                            TraceOps.ShowMessage(TracePriority.Highest,
                                debugCallback, traceCallback, thisAssembly,
6309
6310
6311
6312
6313
6314
6315
6316

6317
6318
6319
6320
6321
6322
6323
6358
6359
6360
6361
6362
6363
6364

6365
6366
6367
6368
6369
6370
6371
6372







-
+







                    #region VS Package
                    if (configuration.HasFlags(
                            InstallFlags.VsPackage, true))
                    {
                        if (!ForEachVsVersionRegistry(registry,
                                vsList, ProcessVsPackage,
                                configuration.VsVersionSuffix, package,
                                fileNameData,
                                fileNameData, configuration.PerUser,
                                VsIs32BitOnly || configuration.Wow64,
                                configuration.ThrowOnMissing,
                                configuration.WhatIf, configuration.Verbose,
                                ref error))
                        {
                            TraceOps.ShowMessage(TracePriority.Highest,
                                debugCallback, traceCallback, thisAssembly,
6338
6339
6340
6341
6342
6343
6344
6345

6346
6347
6348
6349
6350
6351
6352
6387
6388
6389
6390
6391
6392
6393

6394
6395
6396
6397
6398
6399
6400
6401







-
+







                    #region VS DataSource
                    if (configuration.HasFlags(
                            InstallFlags.VsDataSource, true))
                    {
                        if (!ForEachVsVersionRegistry(registry,
                                vsList, ProcessVsDataSource,
                                configuration.VsVersionSuffix, package,
                                fileNameData,
                                fileNameData, configuration.PerUser,
                                VsIs32BitOnly || configuration.Wow64,
                                configuration.ThrowOnMissing,
                                configuration.WhatIf, configuration.Verbose,
                                ref error))
                        {
                            TraceOps.ShowMessage(TracePriority.Highest,
                                debugCallback, traceCallback, thisAssembly,
6367
6368
6369
6370
6371
6372
6373
6374

6375
6376
6377
6378
6379
6380
6381
6416
6417
6418
6419
6420
6421
6422

6423
6424
6425
6426
6427
6428
6429
6430







-
+







                    #region VS DataProvider
                    if (configuration.HasFlags(
                            InstallFlags.VsDataProvider, true))
                    {
                        if (!ForEachVsVersionRegistry(registry,
                                vsList, ProcessVsDataProvider,
                                configuration.VsVersionSuffix, package,
                                fileNameData,
                                fileNameData, configuration.PerUser,
                                VsIs32BitOnly || configuration.Wow64,
                                configuration.ThrowOnMissing,
                                configuration.WhatIf, configuration.Verbose,
                                ref error))
                        {
                            TraceOps.ShowMessage(TracePriority.Highest,
                                debugCallback, traceCallback, thisAssembly,
Changes to tools/install/Properties/AssemblyInfo.cs.
24
25
26
27
28
29
30
31
32


24
25
26
27
28
29
30


31
32







-
-
+
+
// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
[assembly: AssemblyVersion("1.0.83.0")]
[assembly: AssemblyFileVersion("1.0.83.0")]
[assembly: AssemblyVersion("1.0.85.0")]
[assembly: AssemblyFileVersion("1.0.85.0")]
Changes to www/build.wiki.
120
121
122
123
124
125
126

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







+







    <li>
      Make sure the version information is correct for System.Data.SQLite in the
      following files:

      <ul>
        <li>&lt;root&gt;\readme.htm</li>
        <li>&lt;root&gt;\SQLite.nuspec</li>
        <li>&lt;root&gt;\SQLite.Beta.nuspec</li>
        <li>&lt;root&gt;\SQLite.MSIL.nuspec</li>
        <li>&lt;root&gt;\SQLite.x86.nuspec</li>
        <li>&lt;root&gt;\SQLite.x64.nuspec</li>
        <li>&lt;root&gt;\Doc\Extra\dbfactorysupport.html</li>
        <li>&lt;root&gt;\Doc\Extra\welcome.html</li>
        <li>&lt;root&gt;\Membership\Properties\AssemblyInfo.cs</li>
        <li>&lt;root&gt;\SQLite.Designer\AssemblyInfo.cs</li>
Changes to www/downloads.wiki.
251
252
253
254
255
256
257
258

259
260

261
262
263
264
265

266



267























































































268
269
270
271
272
273
274
275
276
277
278
279
280

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
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
361
362
363
364
365
366
367
368
369

370
371

372
373
374
375
376
377

378
379
380
381
382
383

384
385
386
387
388
389
390

391
392

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
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



443
















































































444
445
446
447
448
449
450
451
452
453
454
455
456

457
458

459
460
461
462
463
464


465
466
467

468
469
470
471
472
473
474

475
476

477
478
479
480
481

482
483
484

485
486
487
488
489
490
491
492
493
494
495
496
497

498
499

500
501
502
503
504
505


506
507
508

509
510
511
512
513
514
515

516
517

518
519
520
521
522

523
524
525

526
527
528
529
530
531
532
533
534
535
536
537
538

539
540

541
542
543
544
545
546


547
548
549

550
551
552
553
554
555
556

557
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
587


588
589



590



































































































































































591
592
593
594
595
596
597

598
599

600
601
602
603
604
605



606
607

608
609
610
611
612
613
614
615
616
617
618
619
620

621
622

623
624
625
626
627
628


629
630
631

632
633
634
635
636
637
638

639
640

641
642
643
644
645

646
647
648
649

650
651
652
653
654
655
656
657
658
659
660
661
662

663
664

665
666
667
668
669
670


671
672
673

674
675
676
677
678
679
680

681
682

683
684
685
686
687

688
689
690
691

692
693
694
695
696
697
698
699
700
701
702
703
704

705
706

707
708
709
710
711
712


713
714
715

716
717
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
746

747




























































748

























749
750
751
752
753
754
755



756
757

758
759
760
761
762
763
764

765
766

767
768
769
770
771
772


773
774
775

776
777
778
779
780
781
782
783
784
785
786
787
788

789
790

791
792
793
794
795

796
797
798

799
800
801
802
803
804
805
806
807
808
809
810
811

812
813

814
815
816
817
818
819


820
821
822
823

824
825
826
827
828
829
830

831
832

833
834
835
836
837

838
839
840
841
842
843
844
845

846
847
848
849
850
851
852

853
854

855
856
857
858
859
860
861
862




863
864

865
866
867
868
869
870
871

872
873

874
875
876
877
878
879
880
881




882
883

884
885
886
887
888
889
890
251
252
253
254
255
256
257

258
259

260
261
262
263
264

265
266
267
268
269

270
271
272
273
274
275
276
277
278
279
280
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
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
361
362
363
364
365
366
367
368

369
370

371
372
373
374
375
376

377
378
379
380
381

382
383

384
385
386
387
388
389
390

391
392

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
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
443
444

445
446
447
448
449
450
451
452
453
454
455
456
457

458
459

460
461
462
463
464
465

466
467
468
469
470
471

472
473
474
475
476
477
478

479
480

481
482
483
484
485


486
487
488
489

490
491
492
493
494
495
496
497
498
499
500
501
502

503
504

505
506
507
508
509
510

511
512
513
514
515
516

517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
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
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607

608
609

610
611
612
613
614



615
616
617
618
619
620
621

622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713

714
715

716
717
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
746
747
748
749
750
751
752
753
754

755
756

757
758
759
760
761


762
763
764
765

766
767
768
769
770
771
772

773
774

775
776
777
778
779

780
781
782

783
784
785
786
787
788
789
790
791
792
793
794
795

796
797

798
799
800
801
802


803
804
805
806

807
808
809
810
811
812
813

814
815

816
817
818
819
820

821
822
823

824
825
826
827
828
829
830
831
832
833
834
835
836

837
838

839
840
841
842
843


844
845
846
847
848
849
850

851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
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
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019

1020
1021

1022
1023
1024
1025
1026


1027
1028
1029
1030

1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043

1044
1045

1046
1047
1048
1049
1050


1051
1052
1053
1054

1055
1056
1057
1058
1059
1060
1061

1062
1063

1064
1065
1066
1067
1068

1069
1070
1071
1072

1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085

1086
1087

1088
1089
1090
1091
1092


1093
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

1128
1129

1130
1131
1132
1133
1134


1135
1136
1137
1138

1139
1140
1141
1142
1143
1144
1145

1146
1147

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
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
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
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
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


1279
1280
1281
1282

1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295

1296
1297

1298
1299
1300
1301
1302

1303
1304
1305

1306
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
1349
1350
1351
1352

1353
1354
1355
1356
1357
1358
1359

1360
1361

1362
1363
1364
1365
1366




1367
1368
1369
1370
1371

1372
1373
1374
1375
1376
1377
1378

1379
1380

1381
1382
1383
1384
1385




1386
1387
1388
1389
1390

1391
1392
1393
1394
1395
1396
1397
1398







-
+

-
+




-
+

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












-
+

-
+





-
+




-
+

-
+






-
+

-
+




-
-
+
+


-
+












-
+

-
+





-
+



-
+






-
+

-
+




-
-
+
+


-
+












-
+

-
+





-
+





-
+






-
+

-
+




-
-
+
+


-
+












-
+

-
+





-
+


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






-
+

-
+




-
-
-
+
+
+

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












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
+


-
+












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
+


-
+












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
+


-
+












-
+

-
+




-
-
+
+


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






-
+

-
+




-
-
+
+
+

-
+












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
+



-
+












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
+



-
+












-
+

-
+




-
-
+
+


-
+






-
+

-
+




-
+



-
+












-
+

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




-
-
-
+
+
+

-
+






-
+

-
+




-
-
+
+


-
+












-
+

-
+




-
+


-
+












-
+

-
+




-
-
+
+



-
+






-
+

-
+




-
+







-
+






-
+

-
+




-
-
-
-
+
+
+
+

-
+






-
+

-
+




-
-
-
-
+
+
+
+

-
+







        <b>Source Code</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx-source-1.0.82.0.zip">sqlite-netFx-source-1.0.82.0.zip</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx-source-1.0.84.0.zip">sqlite-netFx-source-1.0.84.0.zip</a>
        <br />
        (2.74 MiB)
        (2.88 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This ZIP archive contains all current source code for System.Data.SQLite
        1.0.82.0 (3.7.14) combined into a single archive file.
        1.0.84.0 (3.7.15.2) combined into a single archive file.
        <br />
        (sha1: 16ab3bdee2fa755af897daa8bc2b4edca75bd6b0)
      </td>
    </tr>
        (sha1: accec84da4a59815078e494afd398eb1b3c64898)

    <tr>
      <td colspan="4">
        <b>Setups for 32-bit Windows (.NET Framework 2.0 SP2)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx20-setup-bundle-x86-2005-1.0.84.0.exe">sqlite-netFx20-setup-bundle-x86-2005-1.0.84.0.exe</a>
        <br />
        (4.09 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package features the mixed-mode assembly and will install all
        the necessary runtime components and dependencies for the x86 version of
        the System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2005
        SP1 runtime for x86 is included.  The .NET Framework 2.0 SP2 is
        required.
        <br />
        <big><b>This setup package is capable of installing the design-time
        components for Visual Studio 2005.</b></big>
        <br />
        (sha1: e1175e117d2425b683aaeaf94bb8f8d494e646ab)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx20-setup-x86-2005-1.0.84.0.exe">sqlite-netFx20-setup-x86-2005-1.0.84.0.exe</a>
        <br />
        (4.08 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package will install all the necessary runtime components and
        dependencies for the x86 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2005 SP1 runtime for x86 is included.
        The .NET Framework 2.0 SP2 is required.
        <br />
        (sha1: 165fba42640af3a3998593de5aae4d8491206cf2)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Setups for 64-bit Windows (.NET Framework 2.0 SP2)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx20-setup-bundle-x64-2005-1.0.84.0.exe">sqlite-netFx20-setup-bundle-x64-2005-1.0.84.0.exe</a>
        <br />
        (4.67 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package features the mixed-mode assembly and will install all
        the necessary runtime components and dependencies for the x64 version of
        the System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2005
        SP1 runtime for x64 is included.  The .NET Framework 2.0 SP2 is
        required.
        <br />
        (sha1: 4d9b2bce86f6e76c1ae918f6c90df96697557f63)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx20-setup-x64-2005-1.0.84.0.exe">sqlite-netFx20-setup-x64-2005-1.0.84.0.exe</a>
        <br />
        (4.66 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package will install all the necessary runtime components and
        dependencies for the x64 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2005 SP1 runtime for x64 is included.
        The .NET Framework 2.0 SP2 is required.
        <br />
        (sha1: 335f35ed4c320b270aae20c7bf8a96c2928dd9a1)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Setups for 32-bit Windows (.NET Framework 3.5 SP1)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx35-setup-bundle-x86-2008-1.0.82.0.exe">sqlite-netFx35-setup-bundle-x86-2008-1.0.82.0.exe</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx35-setup-bundle-x86-2008-1.0.84.0.exe">sqlite-netFx35-setup-bundle-x86-2008-1.0.84.0.exe</a>
        <br />
        (6.07 MiB)
        (6.10 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package features the mixed-mode assembly and will install all
        the necessary runtime components and dependencies for the x86 version of
        the System.Data.SQLite 1.0.82.0 (3.7.14) package.  The Visual C++ 2008
        the System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2008
        SP1 runtime for x86 is included.  The .NET Framework 3.5 SP1 is
        required.
        <br />
        <big><b>This setup package is capable of installing the design-time
        components for Visual Studio 2005 and/or Visual Studio 2008.</b></big>
        components for Visual Studio 2008.</b></big>
        <br />
        (sha1: e38165e4f45e4338d81f2da10050826406aa09b8)
        (sha1: 1685f4bcd63ad8f3456978d2e788a27c2d5136ea)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx35-setup-x86-2008-1.0.82.0.exe">sqlite-netFx35-setup-x86-2008-1.0.82.0.exe</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx35-setup-x86-2008-1.0.84.0.exe">sqlite-netFx35-setup-x86-2008-1.0.84.0.exe</a>
        <br />
        (6.06 MiB)
        (6.09 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package will install all the necessary runtime components and
        dependencies for the x86 version of the System.Data.SQLite 1.0.82.0
        (3.7.14) package.  The Visual C++ 2008 SP1 runtime for x86 is included.
        dependencies for the x86 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2008 SP1 runtime for x86 is included.
        The .NET Framework 3.5 SP1 is required.
        <br />
        (sha1: aed2059188e2ab66a341ce5167b2316c751fdbb1)
        (sha1: 82d48b5f9c032c81c85b85e227d4578f770e9803)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Setups for 64-bit Windows (.NET Framework 3.5 SP1)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx35-setup-bundle-x64-2008-1.0.82.0.exe">sqlite-netFx35-setup-bundle-x64-2008-1.0.82.0.exe</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx35-setup-bundle-x64-2008-1.0.84.0.exe">sqlite-netFx35-setup-bundle-x64-2008-1.0.84.0.exe</a>
        <br />
        (6.81 MiB)
        (6.84 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package features the mixed-mode assembly and will install all
        the necessary runtime components and dependencies for the x64 version of
        the System.Data.SQLite 1.0.82.0 (3.7.14) package.  The Visual C++ 2008
        the System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2008
        SP1 runtime for x64 is included.  The .NET Framework 3.5 SP1 is
        required.
        <br />
        (sha1: aa0f1f958f9febf466807d79f03fae31508993dd)
        (sha1: d4a476cdd96a7d153b4502e74649bfb60b5bd11a)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx35-setup-x64-2008-1.0.82.0.exe">sqlite-netFx35-setup-x64-2008-1.0.82.0.exe</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx35-setup-x64-2008-1.0.84.0.exe">sqlite-netFx35-setup-x64-2008-1.0.84.0.exe</a>
        <br />
        (6.80 MiB)
        (6.83 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package will install all the necessary runtime components and
        dependencies for the x64 version of the System.Data.SQLite 1.0.82.0
        (3.7.14) package.  The Visual C++ 2008 SP1 runtime for x64 is included.
        dependencies for the x64 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2008 SP1 runtime for x64 is included.
        The .NET Framework 3.5 SP1 is required.
        <br />
        (sha1: b5fa5e9c3477a44724356816488ca3fa15a11d4b)
        (sha1: d0e17d8800a53f6bcedb965c2f8eec8f87f7894e)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Setups for 32-bit Windows (.NET Framework 4.0)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx40-setup-bundle-x86-2010-1.0.82.0.exe">sqlite-netFx40-setup-bundle-x86-2010-1.0.82.0.exe</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx40-setup-bundle-x86-2010-1.0.84.0.exe">sqlite-netFx40-setup-bundle-x86-2010-1.0.84.0.exe</a>
        <br />
        (10.40 MiB)
        (10.43 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package features the mixed-mode assembly and will install all
        the necessary runtime components and dependencies for the x86 version of
        the System.Data.SQLite 1.0.82.0 (3.7.14) package.  The Visual C++ 2010
        the System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2010
        SP1 runtime for x86 is included.  The .NET Framework 4.0 is required.
        <br />
        <big><b>This setup package is capable of installing the design-time
        components for Visual Studio 2010.</b></big>
        <br />
        (sha1: bf3defd3b4250e1aa94ea06e10c4b369416d0e2a)
        (sha1: 60bab3d9f579fb070a271420b622127b795ce84c)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx40-setup-x86-2010-1.0.82.0.exe">sqlite-netFx40-setup-x86-2010-1.0.82.0.exe</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx40-setup-x86-2010-1.0.84.0.exe">sqlite-netFx40-setup-x86-2010-1.0.84.0.exe</a>
        <br />
        (10.39 MiB)
        (10.42 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package will install all the necessary runtime components and
        dependencies for the x86 version of the System.Data.SQLite 1.0.82.0
        (3.7.14) package.  The Visual C++ 2010 SP1 runtime for x86 is included.
        dependencies for the x86 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2010 SP1 runtime for x86 is included.
        The .NET Framework 4.0 is required.
        <br />
        (sha1: 8435fe9fd02655d3df95991e68391d487f6a8776)
        (sha1: 344e0406dd463689768ed1055f07adc8c5f2cde7)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Setups for 64-bit Windows (.NET Framework 4.0)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx40-setup-bundle-x64-2010-1.0.82.0.exe">sqlite-netFx40-setup-bundle-x64-2010-1.0.82.0.exe</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx40-setup-bundle-x64-2010-1.0.84.0.exe">sqlite-netFx40-setup-bundle-x64-2010-1.0.84.0.exe</a>
        <br />
        (11.65 MiB)
        (11.68 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package features the mixed-mode assembly and will install all
        the necessary runtime components and dependencies for the x64 version of
        the System.Data.SQLite 1.0.82.0 (3.7.14) package.  The Visual C++ 2010
        the System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2010
        SP1 runtime for x64 is included.  The .NET Framework 4.0 is required.
        <br />
        (sha1: 753bd303e82f9267c607d3729cb1cd80aef89ada)
      </td>
    </tr>
        (sha1: a7fcc7d410df97817eabbbc6f01e1e448f898aab)

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx40-setup-x64-2010-1.0.84.0.exe">sqlite-netFx40-setup-x64-2010-1.0.84.0.exe</a>
        <br />
        (11.67 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package will install all the necessary runtime components and
        dependencies for the x64 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2010 SP1 runtime for x64 is included.
        The .NET Framework 4.0 is required.
        <br />
        (sha1: 190cc80906768905d726ee061e6a0c51a8b2d9cd)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Setups for 32-bit Windows (.NET Framework 4.5)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx45-setup-bundle-x86-2012-1.0.84.0.exe">sqlite-netFx45-setup-bundle-x86-2012-1.0.84.0.exe</a>
        <br />
        (7.82 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package features the mixed-mode assembly and will install all
        the necessary runtime components and dependencies for the x86 version of
        the System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2012
        SP1 runtime for x86 is included.  The .NET Framework 4.5 is required.
        <br />
        <big><b>This setup package is capable of installing the design-time
        components for Visual Studio 2012.</b></big>
        <br />
        (sha1: 6954e6ee073a5965fbac99408e485bf68c1d35cf)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx45-setup-x86-2012-1.0.84.0.exe">sqlite-netFx45-setup-x86-2012-1.0.84.0.exe</a>
        <br />
        (7.85 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package will install all the necessary runtime components and
        dependencies for the x86 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2012 SP1 runtime for x86 is included.
        The .NET Framework 4.5 is required.
        <br />
        (sha1: 6406842a3d916f2977f75ab5c6975debc232ce76)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Setups for 64-bit Windows (.NET Framework 4.5)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx45-setup-bundle-x64-2012-1.0.84.0.exe">sqlite-netFx45-setup-bundle-x64-2012-1.0.84.0.exe</a>
        <br />
        (8.45 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package features the mixed-mode assembly and will install all
        the necessary runtime components and dependencies for the x64 version of
        the System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2012
        SP1 runtime for x64 is included.  The .NET Framework 4.5 is required.
        <br />
        (sha1: 4ee62f74e45fd40ccaecbfe685fb6d08792c0cde)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx40-setup-x64-2010-1.0.82.0.exe">sqlite-netFx40-setup-x64-2010-1.0.82.0.exe</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx45-setup-x64-2012-1.0.84.0.exe">sqlite-netFx45-setup-x64-2012-1.0.84.0.exe</a>
        <br />
        (11.64 MiB)
        (8.50 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This setup package will install all the necessary runtime components and
        dependencies for the x64 version of the System.Data.SQLite 1.0.82.0
        (3.7.14) package.  The Visual C++ 2010 SP1 runtime for x64 is included.
        The .NET Framework 4.0 is required.
        dependencies for the x64 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2012 SP1 runtime for x64 is included.
        The .NET Framework 4.5 is required.
        <br />
        (sha1: 0e24f71a7f2bcdb74bbd7afd807dafeafc64a81e)
      </td>
    </tr>
        (sha1: 0c3d227a1b3c0f3aae1a0b687f17dba18bed6eeb)

    <tr>
      <td colspan="4">
        <b>Precompiled Binaries for 32-bit Windows (.NET Framework 2.0 SP2)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx20-binary-bundle-Win32-2005-1.0.84.0.zip">sqlite-netFx20-binary-bundle-Win32-2005-1.0.84.0.zip</a>
        <br />
        (1.23 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x86 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2005 SP1 runtime for x86 and the .NET
        Framework 2.0 SP2 are required.
        <br />
        (sha1: 655ed614a42c479de46a880df47365297577fd59)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx20-binary-Win32-2005-1.0.84.0.zip">sqlite-netFx20-binary-Win32-2005-1.0.84.0.zip</a>
        <br />
        (1.23 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x86 version of the
        System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2005 SP1
        runtime for x86 and the .NET Framework 2.0 SP2 are required.
        <br />
        (sha1: 853c775833d8ff779a1010482eb8a8472c0df82a)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Binaries for 64-bit Windows (.NET Framework 2.0 SP2)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx20-binary-bundle-x64-2005-1.0.84.0.zip">sqlite-netFx20-binary-bundle-x64-2005-1.0.84.0.zip</a>
        <br />
        (1.42 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x64 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2005 SP1 runtime for x64 and the .NET
        Framework 2.0 SP2 are required.
        <br />
        (sha1: 808001b9c03d94761c30e685ba299ed217b67f91)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx20-binary-x64-2005-1.0.84.0.zip">sqlite-netFx20-binary-x64-2005-1.0.84.0.zip</a>
        <br />
        (1.41 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x64 version of the
        System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2005 SP1
        runtime for x64 and the .NET Framework 2.0 SP2 are required.
        <br />
        (sha1: 9cc8f18efe14716d1bdfd8ff7ded356e47495e4b)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Binaries for 32-bit Windows (.NET Framework 3.5 SP1)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx35-binary-bundle-Win32-2008-1.0.82.0.zip">sqlite-netFx35-binary-bundle-Win32-2008-1.0.82.0.zip</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx35-binary-bundle-Win32-2008-1.0.84.0.zip">sqlite-netFx35-binary-bundle-Win32-2008-1.0.84.0.zip</a>
        <br />
        (1.66 MiB)
        (1.68 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x86 version of the System.Data.SQLite 1.0.82.0
        (3.7.14) package.  The Visual C++ 2008 SP1 runtime for x86 and the .NET
        the binaries for the x86 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2008 SP1 runtime for x86 and the .NET
        Framework 3.5 SP1 are required.
        <br />
        (sha1: cf6ec0622af7a16c5cf32c02d41a29060b91ec79)
        (sha1: 8f2f071cdbb5cf7b7035d4ed7f6a99c4253a7816)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx35-binary-Win32-2008-1.0.82.0.zip">sqlite-netFx35-binary-Win32-2008-1.0.82.0.zip</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx35-binary-Win32-2008-1.0.84.0.zip">sqlite-netFx35-binary-Win32-2008-1.0.84.0.zip</a>
        <br />
        (1.65 MiB)
        (1.67 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x86 version of the
        System.Data.SQLite 1.0.82.0 (3.7.14) package.  The Visual C++ 2008 SP1
        System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2008 SP1
        runtime for x86 and the .NET Framework 3.5 SP1 are required.
        <br />
        (sha1: 5e4724570d0a9e49450d2c0aac0601db4bebed11)
        (sha1: 55edb20a73da43ada0b6eb89d9fb66fe6cf5e51b)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Binaries for 64-bit Windows (.NET Framework 3.5 SP1)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx35-binary-bundle-x64-2008-1.0.82.0.zip">sqlite-netFx35-binary-bundle-x64-2008-1.0.82.0.zip</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx35-binary-bundle-x64-2008-1.0.84.0.zip">sqlite-netFx35-binary-bundle-x64-2008-1.0.84.0.zip</a>
        <br />
        (1.73 MiB)
        (1.75 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x64 version of the System.Data.SQLite 1.0.82.0
        (3.7.14) package.  The Visual C++ 2008 SP1 runtime for x64 and the .NET
        the binaries for the x64 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2008 SP1 runtime for x64 and the .NET
        Framework 3.5 SP1 are required.
        <br />
        (sha1: 15b5625a7f5fa1a4a74c61c0c46e3969d2c6adc2)
        (sha1: c67a430533cf7c7776f4cff86041ee1afc856e4b)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx35-binary-x64-2008-1.0.82.0.zip">sqlite-netFx35-binary-x64-2008-1.0.82.0.zip</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx35-binary-x64-2008-1.0.84.0.zip">sqlite-netFx35-binary-x64-2008-1.0.84.0.zip</a>
        <br />
        (1.72 MiB)
        (1.74 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x64 version of the
        System.Data.SQLite 1.0.82.0 (3.7.14) package.  The Visual C++ 2008 SP1
        System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2008 SP1
        runtime for x64 and the .NET Framework 3.5 SP1 are required.
        <br />
        (sha1: 25abc0ea78f8f45b93c9c2fc1381c2acd863638d)
        (sha1: c32b05f6824071b62a99f7732fbfbcec0c2e4e87)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Binaries for 32-bit Windows (.NET Framework 4.0)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx40-binary-bundle-Win32-2010-1.0.82.0.zip">sqlite-netFx40-binary-bundle-Win32-2010-1.0.82.0.zip</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx40-binary-bundle-Win32-2010-1.0.84.0.zip">sqlite-netFx40-binary-bundle-Win32-2010-1.0.84.0.zip</a>
        <br />
        (1.71 MiB)
        (1.73 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x86 version of the System.Data.SQLite 1.0.82.0
        (3.7.14) package.  The Visual C++ 2010 SP1 runtime for x86 and the .NET
        the binaries for the x86 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2010 SP1 runtime for x86 and the .NET
        Framework 4.0 are required.
        <br />
        (sha1: 6f6cdfddb08f254b744e7088b4825db02bec73da)
        (sha1: 8c673f05e5ca349425a4e46a1b0b13336f6056e7)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx40-binary-Win32-2010-1.0.82.0.zip">sqlite-netFx40-binary-Win32-2010-1.0.82.0.zip</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx40-binary-Win32-2010-1.0.84.0.zip">sqlite-netFx40-binary-Win32-2010-1.0.84.0.zip</a>
        <br />
        (1.70 MiB)
        (1.72 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x86 version of the
        System.Data.SQLite 1.0.82.0 (3.7.14) package.  The Visual C++ 2010 SP1
        System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2010 SP1
        runtime for x86 and the .NET Framework 4.0 are required.
        <br />
        (sha1: 12ffe8323fcf5af25ef6e6effb4f52300df819ee)
        (sha1: cf4ead8c3337d595ff3cc8d1583c458084094793)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Binaries for 64-bit Windows (.NET Framework 4.0)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx40-binary-bundle-x64-2010-1.0.82.0.zip">sqlite-netFx40-binary-bundle-x64-2010-1.0.82.0.zip</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx40-binary-bundle-x64-2010-1.0.84.0.zip">sqlite-netFx40-binary-bundle-x64-2010-1.0.84.0.zip</a>
        <br />
        (1.73 MiB)
        (1.75 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x64 version of the System.Data.SQLite 1.0.82.0
        (3.7.14) package.  The Visual C++ 2010 SP1 runtime for x64 and the .NET
        the binaries for the x64 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2010 SP1 runtime for x64 and the .NET
        Framework 4.0 are required.
        <br />
        (sha1: 32440a943c56d291c9732195b066474d8bcaebca)
      </td>
    </tr>
        (sha1: e1b79aa7763853a68068f43c9edb6382a2c67550)

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx40-binary-x64-2010-1.0.84.0.zip">sqlite-netFx40-binary-x64-2010-1.0.84.0.zip</a>
        <br />
        (1.75 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x64 version of the
        System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2010 SP1
        runtime for x64 and the .NET Framework 4.0 are required.
        <br />
        (sha1: 5c80b715f012d76a4d1f3c936c4b7c2e87032e77)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Binaries for 32-bit Windows (.NET Framework 4.5)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx45-binary-bundle-Win32-2012-1.0.84.0.zip">sqlite-netFx45-binary-bundle-Win32-2012-1.0.84.0.zip</a>
        <br />
        (1.66 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x86 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2012 SP1 runtime for x86 and the .NET
        Framework 4.5 are required.
        <br />
        (sha1: 0dc8d3533375f8589c85d29d3270912666ef61e4)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx45-binary-Win32-2012-1.0.84.0.zip">sqlite-netFx45-binary-Win32-2012-1.0.84.0.zip</a>
        <br />
        (1.70 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x86 version of the
        System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2012 SP1
        runtime for x86 and the .NET Framework 4.5 are required.
        <br />
        (sha1: 1d88fdb25802d6b6ad34d7fa2da2da7003a49e53)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Binaries for 64-bit Windows (.NET Framework 4.5)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx45-binary-bundle-x64-2012-1.0.84.0.zip">sqlite-netFx45-binary-bundle-x64-2012-1.0.84.0.zip</a>
        <br />
        (1.69 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x64 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2012 SP1 runtime for x64 and the .NET
        Framework 4.5 are required.
        <br />
        (sha1: 33e865f0214fef3def4de4f18462832f9788ade4)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx45-binary-x64-2012-1.0.84.0.zip">sqlite-netFx45-binary-x64-2012-1.0.84.0.zip</a>
        <br />
        (1.75 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x64 version of the
        System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2012 SP1
        runtime for x64 and the .NET Framework 4.5 are required.
        <br />
        (sha1: a3970b48c78ecbf9fb92553d52f2af5cbfe01e25)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Statically-Linked Binaries for 32-bit Windows (.NET Framework 2.0 SP2)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx20-static-binary-bundle-Win32-2005-1.0.84.0.zip">sqlite-netFx20-static-binary-bundle-Win32-2005-1.0.84.0.zip</a>
        <br />
        (1.44 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x86 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2005 SP1 runtime for x86 is statically
        linked.  The .NET Framework 2.0 SP2 is required.
        <br />
        (sha1: 0a740fc8011b8a63e83a3ab98ae7952effb3b75e)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx20-static-binary-Win32-2005-1.0.84.0.zip">sqlite-netFx20-static-binary-Win32-2005-1.0.84.0.zip</a>
        <br />
        (1.44 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x86 version of the
        System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2005 SP1
        runtime for x86 is statically linked.  The .NET Framework 2.0 SP2 is
        required.
        <br />
        (sha1: e26b550a43026088101692cddac64938d26fce6a)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Statically-Linked Binaries for 64-bit Windows (.NET Framework 2.0 SP2)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx20-static-binary-bundle-x64-2005-1.0.84.0.zip">sqlite-netFx20-static-binary-bundle-x64-2005-1.0.84.0.zip</a>
        <br />
        (1.57 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x64 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2005 SP1 runtime for x64 is statically
        linked.  The .NET Framework 2.0 SP2 is required.
        <br />
        (sha1: 2f00962575168ffeae32190d6890b6ff60e7230d)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx40-binary-x64-2010-1.0.82.0.zip">sqlite-netFx40-binary-x64-2010-1.0.82.0.zip</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx20-static-binary-x64-2005-1.0.84.0.zip">sqlite-netFx20-static-binary-x64-2005-1.0.84.0.zip</a>
        <br />
        (1.72 MiB)
        (1.57 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x64 version of the
        System.Data.SQLite 1.0.82.0 (3.7.14) package.  The Visual C++ 2010 SP1
        runtime for x64 and the .NET Framework 4.0 are required.
        System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2005 SP1
        runtime for x64 is statically linked.  The .NET Framework 2.0 SP2 is
        required.
        <br />
        (sha1: a91739243166b9ae27be244722acd480d1ce4537)
        (sha1: a16f147da6616a6475859355a7129915e3790108)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Statically-Linked Binaries for 32-bit Windows (.NET Framework 3.5 SP1)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx35-static-binary-bundle-Win32-2008-1.0.82.0.zip">sqlite-netFx35-static-binary-bundle-Win32-2008-1.0.82.0.zip</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx35-static-binary-bundle-Win32-2008-1.0.84.0.zip">sqlite-netFx35-static-binary-bundle-Win32-2008-1.0.84.0.zip</a>
        <br />
        (1.87 MiB)
        (1.89 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x86 version of the System.Data.SQLite 1.0.82.0
        (3.7.14) package.  The Visual C++ 2008 SP1 runtime for x86 is statically
        the binaries for the x86 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2008 SP1 runtime for x86 is statically
        linked.  The .NET Framework 3.5 SP1 is required.
        <br />
        (sha1: 43076280a7ee02b1574bb666d3a14c185d6fe84a)
        (sha1: 60ed2d6a3d980af41e147e08357c285c8a3a1e20)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx35-static-binary-Win32-2008-1.0.82.0.zip">sqlite-netFx35-static-binary-Win32-2008-1.0.82.0.zip</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx35-static-binary-Win32-2008-1.0.84.0.zip">sqlite-netFx35-static-binary-Win32-2008-1.0.84.0.zip</a>
        <br />
        (1.86 MiB)
        (1.89 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x86 version of the
        System.Data.SQLite 1.0.82.0 (3.7.14) package.  The Visual C++ 2008 SP1
        System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2008 SP1
        runtime for x86 is statically linked.  The .NET Framework 3.5 SP1 is
        required.
        <br />
        (sha1: 44f8225d4025d2014ded056b31a2b1a5a8de07cc)
        (sha1: 7b57f575238156098153763a0473ed4e4a787dda)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Statically-Linked Binaries for 64-bit Windows (.NET Framework 3.5 SP1)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx35-static-binary-bundle-x64-2008-1.0.82.0.zip">sqlite-netFx35-static-binary-bundle-x64-2008-1.0.82.0.zip</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx35-static-binary-bundle-x64-2008-1.0.84.0.zip">sqlite-netFx35-static-binary-bundle-x64-2008-1.0.84.0.zip</a>
        <br />
        (1.90 MiB)
        (1.92 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x64 version of the System.Data.SQLite 1.0.82.0
        (3.7.14) package.  The Visual C++ 2008 SP1 runtime for x64 is statically
        the binaries for the x64 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2008 SP1 runtime for x64 is statically
        linked.  The .NET Framework 3.5 SP1 is required.
        <br />
        (sha1: 1e29c539c75e106ddbdd18c83563fc0b9df7c1bf)
        (sha1: bfed5c0a206fa433d308bae303eca1d56883c04d)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx35-static-binary-x64-2008-1.0.82.0.zip">sqlite-netFx35-static-binary-x64-2008-1.0.82.0.zip</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx35-static-binary-x64-2008-1.0.84.0.zip">sqlite-netFx35-static-binary-x64-2008-1.0.84.0.zip</a>
        <br />
        (1.90 MiB)
        (1.92 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x64 version of the
        System.Data.SQLite 1.0.82.0 (3.7.14) package.  The Visual C++ 2008 SP1
        System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2008 SP1
        runtime for x64 is statically linked.  The .NET Framework 3.5 SP1 is
        required.
        <br />
        (sha1: f10532c9c858465852d179dc88ea6c519212234f)
        (sha1: a8d9cd5b94609f060a5f994dad0efa525c1744f9)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Statically-Linked Binaries for 32-bit Windows (.NET Framework 4.0)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx40-static-binary-bundle-Win32-2010-1.0.82.0.zip">sqlite-netFx40-static-binary-bundle-Win32-2010-1.0.82.0.zip</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx40-static-binary-bundle-Win32-2010-1.0.84.0.zip">sqlite-netFx40-static-binary-bundle-Win32-2010-1.0.84.0.zip</a>
        <br />
        (1.92 MiB)
        (1.94 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x86 version of the System.Data.SQLite 1.0.82.0
        (3.7.14) package.  The Visual C++ 2010 SP1 runtime for x86 is statically
        the binaries for the x86 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2010 SP1 runtime for x86 is statically
        linked.  The .NET Framework 4.0 is required.
        <br />
        (sha1: 335da5c15d56b868f948dbf842ad97c94c5c148c)
        (sha1: 9e829efcac6d05dee68f6d0a97a9342773dc9573)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx40-static-binary-Win32-2010-1.0.82.0.zip">sqlite-netFx40-static-binary-Win32-2010-1.0.82.0.zip</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx40-static-binary-Win32-2010-1.0.84.0.zip">sqlite-netFx40-static-binary-Win32-2010-1.0.84.0.zip</a>
        <br />
        (1.91 MiB)
        (1.94 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x86 version of the
        System.Data.SQLite 1.0.82.0 (3.7.14) package.  The Visual C++ 2010 SP1
        System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2010 SP1
        runtime for x86 is statically linked.  The .NET Framework 4.0 is
        required.
        <br />
        (sha1: 22d21e6b97b9b79cd51528fda938e3d601eb1ae4)
        (sha1: 67c7f69a31250db04440330385926df91710bd61)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Statically-Linked Binaries for 64-bit Windows (.NET Framework 4.0)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx40-static-binary-bundle-x64-2010-1.0.82.0.zip">sqlite-netFx40-static-binary-bundle-x64-2010-1.0.82.0.zip</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx40-static-binary-bundle-x64-2010-1.0.84.0.zip">sqlite-netFx40-static-binary-bundle-x64-2010-1.0.84.0.zip</a>
        <br />
        (1.95 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x64 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2010 SP1 runtime for x64 is statically
        linked.  The .NET Framework 4.0 is required.
        <br />
        (sha1: 09e43ce56de8e9db493f895d0440bf58c90867e8)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx40-static-binary-x64-2010-1.0.84.0.zip">sqlite-netFx40-static-binary-x64-2010-1.0.84.0.zip</a>
        <br />
        (1.94 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x64 version of the
        System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2010 SP1
        runtime for x64 is statically linked.  The .NET Framework 4.0 is
        required.
        <br />
        (sha1: 9a439387fe8a836cc6acafa5b4510becc0846cbd)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Statically-Linked Binaries for 32-bit Windows (.NET Framework 4.5)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx45-static-binary-bundle-Win32-2012-1.0.84.0.zip">sqlite-netFx45-static-binary-bundle-Win32-2012-1.0.84.0.zip</a>
        <br />
        (1.98 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x86 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2012 SP1 runtime for x86 is statically
        linked.  The .NET Framework 4.5 is required.
        <br />
        (sha1: 24a13024db3ef732cde9f128b43dcb0a9802dcdd)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx45-static-binary-Win32-2012-1.0.84.0.zip">sqlite-netFx45-static-binary-Win32-2012-1.0.84.0.zip</a>
        <br />
        (1.92 MiB)
        (2.03 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x86 version of the
        System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2012 SP1
        runtime for x86 is statically linked.  The .NET Framework 4.5 is
        required.
        <br />
        (sha1: 40f7633bbe527802f13cb653dc13354d871e4bb7)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Statically-Linked Binaries for 64-bit Windows (.NET Framework 4.5)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.84.0/sqlite-netFx45-static-binary-bundle-x64-2012-1.0.84.0.zip">sqlite-netFx45-static-binary-bundle-x64-2012-1.0.84.0.zip</a>
        <br />
        (1.94 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package features the mixed-mode assembly and contains all
        the binaries for the x64 version of the System.Data.SQLite 1.0.82.0
        (3.7.14) package.  The Visual C++ 2010 SP1 runtime for x64 is statically
        linked.  The .NET Framework 4.0 is required.
        the binaries for the x64 version of the System.Data.SQLite 1.0.84.0
        (3.7.15.2) package.  The Visual C++ 2012 SP1 runtime for x64 is statically
        linked.  The .NET Framework 4.5 is required.
        <br />
        (sha1: 929f1d2a0eb9bb697c4e8725bedef1f4042c076b)
        (sha1: b41daf0cd84393651a8a68a6149dbd0193cdd838)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx40-static-binary-x64-2010-1.0.82.0.zip">sqlite-netFx40-static-binary-x64-2010-1.0.82.0.zip</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx45-static-binary-x64-2012-1.0.84.0.zip">sqlite-netFx45-static-binary-x64-2012-1.0.84.0.zip</a>
        <br />
        (1.92 MiB)
        (2.01 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the x64 version of the
        System.Data.SQLite 1.0.82.0 (3.7.14) package.  The Visual C++ 2010 SP1
        runtime for x64 is statically linked.  The .NET Framework 4.0 is
        System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The Visual C++ 2012 SP1
        runtime for x64 is statically linked.  The .NET Framework 4.5 is
        required.
        <br />
        (sha1: 4c12b0ad3aae3510bd573e49a6159f6a3405d312)
        (sha1: 3516de01e430fbcda5625b8b52b76efd0a260875)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Precompiled Binaries for Windows CE (.NET Compact Framework 3.5)</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="/downloads/1.0.82.0/sqlite-netFx35-binary-PocketPC-2008-1.0.82.0.zip">sqlite-netFx35-binary-PocketPC-2008-1.0.82.0.zip</a>
        <a href="/downloads/1.0.84.0/sqlite-netFx35-binary-PocketPC-2008-1.0.84.0.zip">sqlite-netFx35-binary-PocketPC-2008-1.0.84.0.zip</a>
        <br />
        (0.85 MiB)
        (0.87 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This binary package contains all the binaries for the PocketPC version
        of the System.Data.SQLite 1.0.82.0 (3.7.14) package.  The .NET Compact
        of the System.Data.SQLite 1.0.84.0 (3.7.15.2) package.  The .NET Compact
        Framework 3.5 is required.
        <br />
        (sha1: f9b2393dde3ad5d2f507ebad26d2b81ea7544b70)
        (sha1: b12956304f4bb770459f00827c450397d8473040)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Official NuGet Packages</b>
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="http://nuget.org/api/v2/package/System.Data.SQLite/1.0.82.0">System.Data.SQLite.1.0.82.0.nupkg</a>
        <a href="http://nuget.org/api/v2/package/System.Data.SQLite/1.0.84.0">System.Data.SQLite.1.0.84.0.nupkg</a>
        <br />
        (2.85 MiB)
        (3.19 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This NuGet package contains all the binaries for both the x86 and x64
        versions of System.Data.SQLite 1.0.82.0 (3.7.14).  The .NET Framework
        3.5 SP1 or 4.0 is required.  For the included native binaries, the
        versions of System.Data.SQLite 1.0.84.0 (3.7.15.2).  The .NET Framework
        3.5 SP1, 4.0, or 4.5 is required.  For the included native binaries, the
        version of the Visual C++ runtime corresponding to the .NET Framework
        used by the associated managed assembly is statically linked.
        <br />
        (sha1: 00192e51c6dda124d809c517125c99e46f7de620)
        (sha1: b4d1c9498cf27cd7cfde55fe3ab745f66396e0ad)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="http://nuget.org/api/v2/package/System.Data.SQLite.MSIL/1.0.82.0">System.Data.SQLite.MSIL.1.0.82.0.nupkg</a>
        <a href="http://nuget.org/api/v2/package/System.Data.SQLite.MSIL/1.0.84.0">System.Data.SQLite.MSIL.1.0.84.0.nupkg</a>
        <br />
        (0.26 MiB)
        (0.33 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This NuGet package contains the managed binaries for System.Data.SQLite
        1.0.82.0.  The .NET Framework 3.5 SP1 or 4.0 is required.
        1.0.84.0.  The .NET Framework 3.5 SP1, 4.0, or 4.5 is required.
        <br />
        <big><b>This NuGet package does not include any code from the native
        SQLite core library and will not work properly without the native
        assembly &quot;SQLite.Interop.dll&quot; compiled for the processor
        architecture of the host process being present in a directory in the
        native library search path.</b></big>
        <br />
        (sha1: 8d62c9ff2e22fac2ee0040f6fda49b270e7f27a3)
        (sha1: fe4808f55e3b1f1231ba6b336792f0f8791cdf54)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="http://nuget.org/api/v2/package/System.Data.SQLite.x86/1.0.82.0">System.Data.SQLite.x86.1.0.82.0.nupkg</a>
        <a href="http://nuget.org/api/v2/package/System.Data.SQLite.x86/1.0.84.0">System.Data.SQLite.x86.1.0.84.0.nupkg</a>
        <br />
        (1.47 MiB)
        (1.59 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This NuGet package contains all the binaries for the x86 version of
        System.Data.SQLite 1.0.82.0 (3.7.14).  The .NET Framework 3.5 SP1 or 4.0
        is required.  For the included native binaries, the version of the
        Visual C++ runtime corresponding to the .NET Framework used by the
        associated managed assembly is statically linked.
        System.Data.SQLite 1.0.84.0 (3.7.15.2).  The .NET Framework 3.5 SP1,
        4.0, or 4.5 is required.  For the included native binaries, the version
        of the Visual C++ runtime corresponding to the .NET Framework used by
        the associated managed assembly is statically linked.
        <br />
        (sha1: 598242655955a8827cdab065d4224db8341782fc)
        (sha1: c10145217ed979efe53f5931d2e9b3a49b6c65d5)
      </td>
    </tr>

    <tr>
      <td width="10">&nbsp;</td>
      <td width="30%" valign="top" align="right">
        <a href="http://nuget.org/api/v2/package/System.Data.SQLite.x64/1.0.82.0">System.Data.SQLite.x64.1.0.82.0.nupkg</a>
        <a href="http://nuget.org/api/v2/package/System.Data.SQLite.x64/1.0.84.0">System.Data.SQLite.x64.1.0.84.0.nupkg</a>
        <br />
        (1.67 MiB)
        (1.80 MiB)
      </td>
      <td width="5"></td>
      <td valign="top">
        This NuGet package contains all the binaries for the x64 version of
        System.Data.SQLite 1.0.82.0 (3.7.14).  The .NET Framework 3.5 SP1 or 4.0
        is required.  For the included native binaries, the version of the
        Visual C++ runtime corresponding to the .NET Framework used by the
        associated managed assembly is statically linked.
        System.Data.SQLite 1.0.84.0 (3.7.15.2).  The .NET Framework 3.5 SP1,
        4.0, or 4.5 is required.  For the included native binaries, the version
        of the Visual C++ runtime corresponding to the .NET Framework used by
        the associated managed assembly is statically linked.
        <br />
        (sha1: 1d0a1646f469ea63e74c9ad0778f9911dbde4d30)
        (sha1: 2e2cd4a194f5c308d46f8f70fc50ae3779afee79)
      </td>
    </tr>

    <tr>
      <td colspan="4">
        <b>Legacy Versions</b>
      </td>
919
920
921
922
923
924
925


926
927
928
929
930
931
932
933
934
935
936
937
938
939
940

941
942
943
944
945
946
947
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458







+
+















+







      <li><b>sqlite-</b>framework<b>-setup-</b>cpu<b>-</b>year<b>-</b>version<b>.exe</b></li>
      <li><b>sqlite-</b>framework<b>-setup-bundle-</b>cpu<b>-</b>year<b>-</b>version<b>.exe</b></li>
      <li><b>sqlite-</b>framework<b>-binary-</b>platform<b>-</b>year<b>-</b>version<b>.zip</b></li>
      <li><b>sqlite-</b>framework<b>-binary-bundle-</b>platform<b>-</b>year<b>-</b>version<b>.zip</b></li>
      <li><b>sqlite-</b>framework<b>-static-binary-</b>platform<b>-</b>year<b>-</b>version<b>.zip</b></li>
      <li><b>sqlite-</b>framework<b>-static-binary-bundle-</b>platform<b>-</b>year<b>-</b>version<b>.zip</b></li>
      <li><b>sqlite-netFx-source-</b>date<b>.zip</b></li>
      <li><b>System.Data.SQLite.</b>version<b>.nupkg</b></li>
      <li><b>System.Data.SQLite.</b>variant<b>.</b>version<b>.nupkg</b></li>
    </ol>
  </p>

  <p>
    Templates (1) and (2) are used for source-code packages.  Template (1) is
    used for generic source-code packages and template (2) is used for
    source-code packages that are generally only useful on unix-like platforms.
    Template (3) is used for the setup package.  Template (4) is used for the
    setup package containing the mixed-mode assembly.  Template (5) is used for
    the precompiled binary package.  Template (6) is used for the precompiled
    binary package containing the mixed-mode assembly.  Template (7) is used for
    the precompiled binary package statically linked to the Visual C++ runtime.
    Template (8) is used for the precompiled binary package containing the
    mixed-mode assembly statically linked to the Visual C++ runtime.  Template
    (9) is used for unofficial pre-release &quot;snapshots&quot; of source code.
    Templates (10) and (11) are used for the official NuGet packages.
  </p>

  <p>
    The <b>framework</b> in templates (3), (4), (5), (6), (7), and (8) will be
    one of netFx20, netFx35, netFx40, netFx45.
  </p>

965
966
967
968
969
970
971




972
973
974
975
976
977
978
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493







+
+
+
+







    assembly.
  </p>

  <p>
    The <b>date</b> in template (9) is of the form: YYYYMMDDHHMM
  </p>

  <p>
    The <b>variant</b> in template (11) will be one of Beta, MSIL, x86, x64.
  </p>

  <h3>Canonical Source Code</h3>

  <p>
    The canonical System.Data.SQLite source code is maintained in a Fossil
    repository that is available for anonymous read-only access. Anyone can view
    the repository contents and download historical versions of individual files
    or ZIP archives of historical check-ins.
Changes to www/index.wiki.
30
31
32
33
34
35
36









37
38
39
40
41
42
43
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52







+
+
+
+
+
+
+
+
+







          options.
        </p>
        <p>
          Please refer to the
          <a href="downloads.wiki">download page</a> for a complete list of
          downloadable packages and information on their use.
        </p>
        <p>
          The current documentation for all public types, methods, properties,
          and events is checked into the repository, in
          <a href="http://en.wikipedia.org/wiki/Microsoft_Compiled_HTML_Help">
          <i>Microsoft Compiled HTML Help</i> (&quot;CHM&quot;) format</a>.  It
          can also be
          <a href="/index.html/doc/trunk/Doc/SQLite.NET.chm?mimetype=application/x-chm">
          downloaded directly</a> via the web interface to the repository.
        </p>
      </td>
      <td width="30%" valign="top">
        <table align="right" border="1" cellpadding="10" hspace="10" cellspacing="0">
          <tr>
            <td>
              <ul>
                <li><a href="features.wiki">Features</a></li>
Changes to www/news.wiki.
1
2
3
4
5
6

7
8
9



















10
11
12
13



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

28
29
30

31



32
33
34
35
36
37
38
1
2
3
4
5

6
7
8

9
10
11
12
13
14
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





-
+


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




+
+
+













-
+



+

+
+
+







<title>News</title>

<b>Version History</b>

<p>
    <b>1.0.83.0 - December XX, 2012 <font color="red">(release scheduled)</font></b>
    <b>1.0.85.0 - March XX, 2013 <font color="red">(release scheduled)</font></b>
</p>
<ul>
    <li>Updated to [http://www.sqlite.org/src/info/trunk|SQLite 3.7.15].</li>
    <li>Updated to [http://www.sqlite.org/src/info/trunk|SQLite 3.7.16].</li>
    <li>Add static Execute method to the SQLiteCommand class.</li>
    <li>Add public constructor to the SQLiteDataAdapter class that allows passing the parseViaFramework parameter to the SQLiteConnection constructor.</li>
    <li>When built with the CHECK_STATE compile-time option, skip throwing exceptions from the SQLiteDataReader class when the object is being disposed.</li>
</ul>
<p>
    <b>1.0.84.0 - January 9, 2013</b>
</p>
<ul>
    <li>Updated to [http://www.sqlite.org/releaselog/3_7_15_2.html|SQLite 3.7.15.2].</li>
    <li>Explicitly dispose of all SQLiteCommand objects managed by the DbDataAdapter class. Fix for [6434e23a0f].</li>
    <li>Add Cancel method to the SQLiteConnection class to interrupt a long running query.</li>
    <li>Improve thread safety of the SQLiteLog.LogMessage method.</li>
</ul>
<p>
    <b>1.0.83.0 - December 29, 2012</b>
</p>
<ul>
    <li>Updated to [http://www.sqlite.org/releaselog/3_7_15_1.html|SQLite 3.7.15.1].</li>
    <li>Add Visual Studio 2012 support to all the applicable solution/project files, their associated supporting files, and the test suite.</li>
    <li>Add Visual Studio 2012 support to the redesigned designer support installer.</li>
    <li>Allow opened connections to skip adding the extension functions included in the interop assembly via the new NoExtensionFunctions connection flag.</li>
    <li>Support loading of SQLite extensions via the new EnableExtensions and LoadExtension methods of the SQLiteConnection class. Pursuant to [17045010df].</li>
    <li>Remove one set of surrounding single or double quotes from property names and values parsed from the connection string. Fix for [b4cc611998].</li>
    <li>Modify parsing of connection strings to allow property names and values to be quoted.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>Add ParseViaFramework property to the SQLiteConnection class to allow the built-in (i.e. framework provided) connection string parser to be used when opening a connection. Pursuant to [b4cc611998].</li>
    <li>Add notifications before and after any connection is opened and closed, as well as other related notifications, via the new static Changed event.</li>
    <li>Add an overload of the SQLiteLog.LogMessage method that takes a single string parameter.</li>
    <li>Add an overload of the SQLiteConnection.LogMessage method that takes a SQLiteErrorCode parameter.</li>
    <li>All applicable calls into the SQLite core library now return a SQLiteErrorCode instead of an integer error code.</li>
    <li>Make sure the error code of the SQLiteException class gets serialized.</li>
    <li>Make the test project for the .NET Compact Framework more flexible.</li>
    <li>When available, the new sqlite3_errstr function from the core library is used to get the error message for a specific return code.</li>
    <li>The SetMemoryStatus, Shutdown, ResultCode, ExtendedResultCode, and SetAvRetry methods of the SQLiteConnection class now return a SQLiteErrorCode instead of an integer error code.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>The public constructor for the SQLiteException now takes a SQLiteErrorCode instead of an integer error code.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>The ErrorCode property of the SQLiteException is now an Int32, to allow the property inherited from the base class to be properly overridden.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>The ErrorCode field of the LogEventArgs is now an object instead of an integer.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>The names and messages associated with the SQLiteErrorCode enumeration values have been normalized to match those in the SQLite core library.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>Implement more robust locking semantics for the CriticalHandle derived classes when compiled for the .NET Compact Framework.</li>
    <li>Cache column indexes are they are looked up when using the SQLiteDataReader to improve performance.</li>
    <li>Cache column indexes as they are looked up when using the SQLiteDataReader to improve performance.</li>
    <li>Prevent the SQLiteConnection.Close method from throwing non-fatal exceptions during its disposal.</li>
    <li>Rename the interop assembly functions sqlite3_cursor_rowid, sqlite3_context_collcompare, sqlite3_context_collseq, sqlite3_cursor_rowid, and sqlite3_table_cursor to include an &quot;_interop&quot; suffix.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    <li>Prevent the LastInsertRowId, MemoryUsed, and MemoryHighwater connection properties from throwing NotSupportedException when running on the .NET Compact Framework. Fix for [dd45aba387].</li>
    <li>Improve automatic detection of the sqlite3_close_v2 function when compiled to use the standard SQLite library.</li>
    <li>Add protection against ThreadAbortException asynchronously interrupting native resource initialization and finalization.</li>
    <li>Add native logging callback for use with the sqlite3_log function to the interop assembly, enabled via the INTEROP_LOG preprocessor definition.</li>
    <li>Add various diagnostic messages to the interop assembly, enabled via flags in the INTEROP_DEBUG preprocessor definition.</li>
    <li>Further enhancements to the build and test automation.</li>
    <li>Add test automation for the Windows CE binaries.</li>
</ul>
<p>
    <b>1.0.82.0 - September 3, 2012</b>
</p>
<ul>
    <li>Updated to [http://www.sqlite.org/releaselog/3_7_14.html|SQLite 3.7.14].</li>